Commit Graph

3832 Commits

Author SHA1 Message Date
Rob Murray
0b5e1f904a Use netip.Addr instead of net.IP for legacy links
Signed-off-by: Rob Murray <rob.murray@docker.com>
2025-03-31 11:52:16 +01:00
Rob Murray
725e699741 Simplify iptables setup for legacy links
Include legacy link setup in IptablesNetwork, with the other
per-network rules.

Signed-off-by: Rob Murray <rob.murray@docker.com>
2025-03-31 11:52:16 +01:00
Rob Murray
c5c9dc0376 Merge pull request #49668 from robmry/iptables_network_rules
Bridge: factor out creation of network-level iptables rules
2025-03-31 11:48:45 +01:00
Rob Murray
409707b633 bridge: factor out creation of network-level iptables rules
Create an iptablesNetwork containing all the info needed to
set up per-network iptables rules, give it methods to do
create the rules, and use it instead of per-rule-type calls
from driver.createNetwork().

Signed-off-by: Rob Murray <rob.murray@docker.com>
2025-03-28 16:57:16 +00:00
Rob Murray
0ab6f07c31 Fix TestPassthrough
Doesn't look like it would ever have worked, but:
- init the dbus connection to avoid a segv
- include the chain name when creating the rule
- remove the test rule if it's created

Signed-off-by: Rob Murray <rob.murray@docker.com>
2025-03-27 12:15:16 +00:00
Rob Murray
2d643b6835 Firewalld: skip unit tests that run in their own netns
Firewalld runs in the host netns. So, tests running in
their own netns can't check firewalld's iptables rules.

Signed-off-by: Rob Murray <rob.murray@docker.com>
2025-03-27 12:14:20 +00:00
Paweł Gronowski
264fc2fac8 Merge pull request #49705 from robmry/continue_if_bridge_port_down
Start containers, even when connected to a disabled bridge port
2025-03-26 13:08:03 +00:00
Rob Murray
f5d84a45cc Start containers, even when connected to a disabled bridge port
Commit 9a6e96f ("Before sending ARPs/NAs, check the bridge is ready")
introduced a check that, if a container's veth is connected to a bridge,
the port is forwarding before sending unsolicited ARP/NA messages to
advertise the container's MAC/IP addresses.

It waited for up-to 200ms, but it seems that's not always enough.

If the port isn't forwarding, the ARP/NA messages will be silently
dropped. But, if it comes up within two seconds, one or both of the
resends will succeed.

So - keep the wait for 200ms but, if anything goes wrong with checking
the bridge port's state, or it's not forwarding after that time, just
log an info/warning level message and continue.

Signed-off-by: Rob Murray <rob.murray@docker.com>
2025-03-26 11:46:38 +00:00
Paweł Gronowski
f14c23a90f libnetwork: Update to any from interface{}
Only files that have go build version enforcing tag

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2025-03-25 13:42:51 +01:00
Rob Murray
485cb90b77 Remove duplicate iptables-enabled checks
Signed-off-by: Rob Murray <rob.murray@docker.com>
2025-03-17 10:31:11 +00:00
Rob Murray
fce915897c Combine firewalld reload callbacks for IPv4/IPv6
Signed-off-by: Rob Murray <rob.murray@docker.com>
2025-03-17 10:30:45 +00:00
Albin Kerouanton
d2ad7c36dc Merge pull request #49577 from robmry/routed_no_skip_dnat
Don't skip DNAT for a routed network without userland-proxy
2025-03-13 13:28:26 +01:00
Albin Kerouanton
d1ecb3b828 Merge pull request #49630 from robmry/macvlan_parent_down
Allow macvlan endpoint to start with parent down
2025-03-13 13:12:27 +01:00
Rob Murray
c0ca783edb Allow macvlan endpoint to start with parent down
When a macvlan's parent interface is down it's not possible
to send NA messages. So, ignore the error.

Signed-off-by: Rob Murray <rob.murray@docker.com>
2025-03-11 14:35:19 +00:00
Rob Murray
cf3e42abaf Add an opt-out for iptables 'raw' rules
For kernels that don't have CONFIG_IP_NF_RAW, if the env
var DOCKER_INSECURE_NO_IPTABLES_RAW is set to "1", don't
try to create raw rules.

This means direct routing to published ports is possible
from other hosts on the local network, even if the port
is published to a loopback address.

Signed-off-by: Rob Murray <rob.murray@docker.com>
2025-03-10 18:32:49 +00:00
Rob Murray
4d8cff7bd4 Don't skip DNAT for a routed network without userland-proxy
If the userland-proxy is running, packets from one bridge network
addressed to the host port are not DNAT'd - so that docker-proxy
can pick them up, and therefore the packet bypasses the network
isolation rules.

Without the userland-proxy, there's no way for a packet from one
bridge network to bypass the network isolation rules. So, in this
case, DNAT is not skipped - and that at-least allows packets
originating from the network that published the port to access
the host port.

Commit 0546d90 improved support for routed mode networks (allowing
nat-mode networks access to containers in routed-mode networks, as
well as just remote access).

That commit changed the "SKIP DNAT" logic, making sure DNAT was
skipped for a routed-mode network if the userland-proxy was enabled
(so, containers in routed mode networks could access ports published
by other networks).

But, it still skipped DNAT for a routed mode network if the userland
proxy was disabled - packets from the routed mode network aimed at
any other network would be dropped by the network isolation rules
anyway, and containers in a routed mode network don't need access to
ports published from that network (because, by definition, there
can't be any).

However, network isolation rules can be worked-around with a rule
in the DOCKER-USER chain, but the SKIP DNAT rule is harder to deal
with.

So, for routed-mode, only skip DNAT if the userland-proxy is
enabled (just like nat-mode networks).

Signed-off-by: Rob Murray <rob.murray@docker.com>
2025-03-10 17:15:10 +00:00
Sebastiaan van Stijn
01d8303167 Merge pull request #49582 from robmry/flush_bridge_chains
Flush iptables chains DOCKER-CT, DOCKER-BRIDGE on startup
2025-03-05 18:38:10 +01:00
Sebastiaan van Stijn
3c817d02a9 Merge pull request #49575 from thaJeztah/refactor_resolvconf_build
libnetwork/resolvconf: re-implement "Build" with the new libnetwork/internal/resolvconf code
2025-03-05 13:17:47 +01:00
Rob Murray
26edf2d0a7 Flush iptables chains DOCKER-CT, DOCKER-BRIDGE on startup
These chains were added in commit 76417bf ("Don't use ipset"), but
not included in the list of chains that get flushed and deleted
on daemon startup.

Signed-off-by: Rob Murray <rob.murray@docker.com>
2025-03-05 11:47:36 +00:00
Sebastiaan van Stijn
c62f5aff42 libnetwork: fix naked returns
libnetwork/drivers/remote/driver_test.go:29:2: naked return in func `decodeToMap` with 3 lines of code (nakedret)
        return
        ^
    libnetwork/ipams/remote/remote_test.go:23:2: naked return in func `decodeToMap` with 3 lines of code (nakedret)
        return
        ^

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-03-04 13:55:46 +01:00
Sebastiaan van Stijn
8978b30b1a libnetwork/types: fix naked returns
libnetwork/types/types.go:330:2: naked return in func `ParseCIDR` with 6 lines of code (nakedret)
        return
        ^

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-03-04 13:55:46 +01:00
Sebastiaan van Stijn
619e8f8148 libnetwork/osl: fix naked returns
libnetwork/osl/namespace_linux.go:324:2: naked return in func `DisableARPForVIP` with 28 lines of code (nakedret)
        return
        ^

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-03-04 13:55:46 +01:00
Sebastiaan van Stijn
02b4c7cc52 libnetwork/drivers/overlay: fix naked returns, output variables
libnetwork/drivers/overlay/encryption.go:370:2: naked return in func `programSA` with 64 lines of code (nakedret)
        return
        ^

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-03-04 13:55:46 +01:00
Sebastiaan van Stijn
94afddb18d libnetwork/cmd/networkdb-test: fix naked return
libnetwork/cmd/networkdb-test/dbclient/ndbClient.go:251:5: naked return in func `checkTable` with 42 lines of code (nakedret)
                    return
                    ^

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-03-04 13:55:45 +01:00
Sebastiaan van Stijn
00bd916203 libnetwork/resolvconf: Build: re-implement using new implementation
Re-implement the Build function using  the new implementation from
libnetwork/internal/resolvconf.

BuildKit is the only consumer of the Build function currently, and we
should consider either moving the internal package out of internal, or
to provide a more customized variant of Build that fits BuildKit's
needs (i.e., only patch content, but not write to a file).

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-03-04 12:34:09 +01:00
Sebastiaan van Stijn
2f19577877 libnetwork/resolvconf: Build: align order with new implementation
The new resolvconf implementation in libnetwork/internal/resolvconf
uses a different order for "search" and puts it after the resolvers.

While this changes the checksum of the file, and thus would be potentially
detected as "user modified", we no longer use this function ourselves,
and BuildKit (which uses this function) only consumes the Content field,
and discards the Hash; https://github.com/moby/buildkit/blob/v0.20.0/executor/oci/resolvconf.go#L99-L103

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-03-04 12:26:30 +01:00
Sebastiaan van Stijn
03aeedcca9 libnetwork/resolvconf: update tests to use more correct values
The tests were depending on the implementation ignoring invalid
nameservers, as these should always be an IP-address, not a hostname.

Update the tests to use correct values, instead of codifying the
bad behavior.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-03-04 12:23:03 +01:00
Sebastiaan van Stijn
b8b2400a5b Merge pull request #49512 from thaJeztah/portallocator_unexport
libnet/portallocator: un-export errors that were not used as sentinel  errors
2025-03-03 12:38:43 +01:00
Brian Goff
7194b508b6 Merge pull request #48638 from robmry/iptables-nft
Use iptables-nft in the dev container / CI
2025-02-27 12:03:14 -08:00
Rob Murray
558da63444 Jump to DOCKER-INGRESS from DOCKER-FORWARD
A jump to DOCKER-INGRESS chain is only created when Swarm needs
it. That's always after jumps to DOCKER-USER and DOCKER-FORWARD
have been inserted at the top of the FORWARD chain. The
DOCKER-INGRESS rule needs to be between those two other jumps.

Placing the jump to DOCKER-INGRESS at the top of the DOCKER-FORWARD
chain puts it in the right place, without needing to shuffle any
other rules around when it's added.

Signed-off-by: Rob Murray <rob.murray@docker.com>
2025-02-25 17:17:36 +00:00
Rob Murray
76417bf763 Don't use ipset
Commit 0546d90 introduced the use of ipset to reduce the number
of rules that need to be processed per-packet, and make the code
a bit simpler.

But, docker's used on embedded kernels compiled without support
for ipset, so the change is too disruptive.

Replace the two ipset rules with a new chain that writes out the
rule's actions long-hand. So ..

This rule:
  -A FORWARD -m set --match-set docker-ext-bridges-v4 dst \
    -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
Is transformed into a per-bridge rule in new chain DOCKER-CT:
  -A DOCKER-FORWARD -j DOCKER-CT
  -A DOCKER-CT -o docker0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
  -A DOCKER-CT -o bridge1 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

And:
  -A FORWARD -m set --match-set docker-ext-bridges-v4 dst -j DOCKER
Is transformed into a per-bridge rule in new chain DOCKER-BRIDGE:
  -A DOCKER-FORWARD -j DOCKER-BRIDGE
  -A DOCKER-BRIDGE -o docker0 -j DOCKER
  -A DOCKER-BRIDGE -o bridge1 -j DOCKER

Signed-off-by: Rob Murray <rob.murray@docker.com>
2025-02-25 15:24:25 +00:00
Rob Murray
0274c630c9 Merge pull request #49518 from robmry/docker_forward_chain
Add chain DOCKER-FORWARD
2025-02-25 11:25:55 +00:00
Rob Murray
f344ab14b3 Merge pull request #49525 from robmry/startup_ip6_disabled
Fix daemon startup on a no-IPv6 host
2025-02-24 20:51:10 +00:00
Rob Murray
468c2c814d Fix swarm network creation from a config-only network
Creating a swarm network from a config-only network failed
because the new EnableIPv4 wasn't validated/propagated
correctly.

So:
- Always initialise EnableIPv4 to true, including for a config
  only network, and on load from the store.
- Treat enableIPv4=true as the no-overridden state when checking
  params for a config-from network.
- Propagate settings from the config 'Network' objects attributes
  to its generic options, because the network driver only sees
  generic options.
  - This was happening already for Network.internal, after the
    config-only network options were processed. Move that to
    'applyConfigurationTo'.
  - Add enableIPv4/enableIpv6 - enableIPv6 will normaly be present
    anyway. But, for a network created pre-28.x and restored from
    the store, there was no entry for 'netlabel.EnableIpv4'.
- Extend TestSwarmScopedNetFromConfig to start a service and
  check it's ok.

Signed-off-by: Rob Murray <rob.murray@docker.com>
2025-02-24 17:48:23 +00:00
Rob Murray
8e6cc4ac48 Fix swarm net validation for config-from networks
For swarm networks, Controller.NewNetwork is called to validate
network config ... nothing gets created, but ManagerRedirectError
is returned if the config is ok - then swarm does its own thing.

So, for a --config-from network, merge config before checking
whether it'll have IPv4 enabled.

Signed-off-by: Rob Murray <rob.murray@docker.com>
2025-02-24 17:48:23 +00:00
Rob Murray
8cc4d1d4a2 Fix daemon startup on a no-IPv6 host
With ip6tables enabled (by default), the daemon should start on a
host with IPv6 disabled - then error if IPv6 network creation is
attempted.

That regressed in commit 255fff4 - so, only try to set up network
isolation rules for a network if it's IPv6-enabled.

Signed-off-by: Rob Murray <rob.murray@docker.com>
2025-02-24 17:41:44 +00:00
Rob Murray
984a610a21 Add chain DOCKER-FORWARD
In 28.0.0, Docker appended to the FORWARD chain - breaking other
applications that had appended their own rules that needed to execute
after Docker's rules.

Move most of Docker's rules out of the filter-FORWARD chain into a
new DOCKER-FORWARD chain, so that Docker can append to DOCKER-FORWARD
without affecting the order of rules in the FORWARD chain.

After daemon startup inserts jumps to DOCKER-USER and DOCKER-FORWARD,
the bridge driver will not touch the FORWARD chain again. DOCKER-INGRESS
is still added to the FORWARD chain, if used, as it was in 27.x and
earlier.

Signed-off-by: Rob Murray <rob.murray@docker.com>
2025-02-24 17:09:09 +00:00
Rob Murray
33244704ef Merge pull request #49524 from robmry/missing_ip_set_errors
Better error message for missing ip_set kernel modules
2025-02-24 14:29:35 +00:00
Rob Murray
a92d20bcc4 Better error message for missing ip_set kernel modules
Signed-off-by: Rob Murray <rob.murray@docker.com>
2025-02-24 12:18:36 +00:00
Paweł Gronowski
a5008d4a41 Merge pull request #49526 from akerouanton/fix-setsockopt-i386
libnet/d/bridge: fix compilation on i386
2025-02-24 09:26:56 +00:00
Albin Kerouanton
73f2a5336d libnet/d/bridge: fix compilation on i386
On i386, Linux doesn't provide direct socket syscall but instead
multiplexes them through the socketcall syscall (see `man 2 socketcall`).
This commit fixes compilation for i386 by wrapping the offending syscall
in a new function that uses the socketcall syscall on i386, and
the `setsockopt` syscall on other archs.

Signed-off-by: Albin Kerouanton <albinker@gmail.com>
2025-02-23 12:01:59 +01:00
Akihiro Suda
501ce33bab Fix v28 regression protocol "tcp" is not supported by the RootlessKit port driver "slirp4netns"
`DOCKERD_ROOTLESS_ROOTLESSKIT_PORT_DRIVER=slirp4netns` was broken
since f1e0746c08 (PR 48132, v28).

Fix issue 49499

ref: https://github.com/rootless-containers/rootlesskit/blob/v2.3.2/cmd/rootlesskit-docker-proxy/main.go#L196-L204
(used until Docker v27)

Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
2025-02-21 13:25:23 +09:00
Sebastiaan van Stijn
c37690b98e libnet/portallocator: un-export errors that were not used as sentinel errors
The `ErrPortAlreadyAllocated` error was introduced in ffd68badc0,
and at the time used as sentinel error in the bridge driver. It was later
integrated into libnetwork ([libnetwork@672ced7]), and brought back when
libnetwork was integrated in v1.7.0; 272f8cd4bc
After libnetwork was integrated, the error was unused as sentinel error,
except for locally inside the package as part of a test;

    git rev-parse --verify HEAD
    496bc46c88

    git grep '\.ErrPortAlreadyAllocated'

Which is still the case Today;

    git describe --tags --match="v[0-9]*" HEAD
    v28.0.0
    git rev-parse --verify HEAD
    af898abe44
    git grep '\.ErrPortAlreadyAllocated'

Same for the `ErrAllPortsAllocated` (added in 739d124480)
and `ErrUnknownProtocol` (added in 303ed3c830)
errors, which were never used as sentinel errors, and still aren't;

    git grep '\.ErrAllPortsAllocated'
    git grep '\.ErrUnknownProtocol'
    vendor/github.com/moby/buildkit/client/llb/source.go:   if errors.Is(err, gitutil.ErrUnknownProtocol) {

This patch;

- un-exports these errors as they are not used as sentinel errors
- strips down the `ErrPortAlreadyAllocated`, removing the methods that
  were added, but never used.
- removes the `newErrPortAlreadyAllocated` constructor
- renames `ErrPortAlreadyAllocated` to `alreadyAllocatedErr` to follow
  go conventions.

[libnetwork@672ced7]: c0474b6438

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-02-20 23:58:44 +01:00
Rob Murray
cfc049c938 Use iptables-nft in the dev container / CI
Replaces iptables-legacy.

Signed-off-by: Rob Murray <rob.murray@docker.com>
2025-02-18 16:14:48 +00:00
Rob Murray
5719e8edf9 Don't create iptables rules when iptables is disabled
New iptables rules were added by:
- commit 27adcd5 (libnet/d/bridge: port mappings: drop direct-access
  when gw_mode=nat)
- commit d216084 (libnet/d/bridge: drop remote connections to port
  mapped on lo)

But they're added even when iptables=false or ip6tables=false in daemon
config.

So, group those rules with the other per-port rules, behind a config
check.

Signed-off-by: Rob Murray <rob.murray@docker.com>
2025-02-14 12:55:12 +00:00
Sebastiaan van Stijn
6ee1558852 Merge pull request #49417 from thaJeztah/fix_linting_step1
Fix linting issues to allow enabling more linters
2025-02-13 23:58:24 +01:00
Rob Murray
96dc9cb693 Don't log a warning when an IP address is already in an ipset
It's situation-normal when firewalld is reloaded.

Signed-off-by: Rob Murray <rob.murray@docker.com>
2025-02-11 11:59:41 +00:00
Rob Murray
b23b8f1567 Restore more iptables rules on firewalld reload
In the bridge network driver, filterPortMappedOnLoopback and
filterDirectAccess each set up some per-port iptables rules - but
they're not called by setPerPortIptables.

So, make sure they're called when firewalld is reloaded.

Signed-off-by: Rob Murray <rob.murray@docker.com>
2025-02-11 11:59:41 +00:00
Sebastiaan van Stijn
6929a3fd22 libnetwork/networkdb: make switches exhaustive (exhaustive)
Adding a `default` statement so that disabling the "default-signifies-exhaustive"
linter option will  make it show up.

    libnetwork/networkdb/delegate.go:49:2: missing cases in switch of type networkdb.NodeEvent_Type: networkdb.NodeEventTypeInvalid (exhaustive)
        switch nEvent.Type {
        ^
    libnetwork/networkdb/delegate.go:223:2: missing cases in switch of type networkdb.TableEvent_Type: networkdb.TableEventTypeInvalid (exhaustive)
        switch tEvent.Type {
        ^
    libnetwork/networkdb/nodemgmt.go:51:2: missing cases in switch of type networkdb.nodeState: networkdb.nodeNotFound (exhaustive)
        switch newState {
        ^

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-02-09 13:22:51 +01:00
Sebastiaan van Stijn
1a047bbe8b libnetwork: ignore unchecked json (Un)Marshal errors (errchkjson)
These need revisiting, similar to similar code in libnetwork/drivers/bridge.
There was already a TODO in place for this, so ignoring these for now.

    libnetwork/endpoint.go:148:11: Error return value of `encoding/json.Marshal` is not checked: unsafe type `interface{}` found (errchkjson)
        ib, _ := json.Marshal(epMap["ep_iface"])
                 ^
    libnetwork/endpoint.go:151:11: Error return value of `encoding/json.Marshal` is not checked: unsafe type `interface{}` found (errchkjson)
        jb, _ := json.Marshal(epMap["joinInfo"])
                 ^
    libnetwork/endpoint.go:154:11: Error return value of `encoding/json.Marshal` is not checked: unsafe type `interface{}` found (errchkjson)
        tb, _ := json.Marshal(epMap["exposed_ports"])
                 ^
    libnetwork/endpoint.go:159:11: Error return value of `encoding/json.Marshal` is not checked: unsafe type `interface{}` found (errchkjson)
        cb, _ := json.Marshal(epMap["sandbox"])
                 ^
    libnetwork/endpoint.go:237:12: Error return value of `encoding/json.Marshal` is not checked: unsafe type `interface{}` found (errchkjson)
        sal, _ := json.Marshal(epMap["svcAliases"])
                  ^
    libnetwork/endpoint.go:242:11: Error return value of `encoding/json.Marshal` is not checked: unsafe type `interface{}` found (errchkjson)
        pc, _ := json.Marshal(epMap["ingressPorts"])
                 ^
    libnetwork/endpoint.go:247:11: Error return value of `encoding/json.Marshal` is not checked: unsafe type `interface{}` found (errchkjson)
        ma, _ := json.Marshal(epMap["myAliases"])
                 ^
    libnetwork/endpoint.go:252:11: Error return value of `encoding/json.Marshal` is not checked: unsafe type `interface{}` found (errchkjson)
        dn, _ := json.Marshal(epMap["dnsNames"])
                 ^
    libnetwork/endpoint_info.go:123:11: Error return value of `encoding/json.Marshal` is not checked: unsafe type `interface{}` found (errchkjson)
        rb, _ := json.Marshal(epMap["routes"])
                 ^
    libnetwork/endpoint_info.go:490:12: Error return value of `encoding/json.Marshal` is not checked: unsafe type `interface{}` found (errchkjson)
            tb, _ := json.Marshal(v)
                     ^
    libnetwork/network.go:161:11: Error return value of `encoding/json.Marshal` is not checked: unsafe type `interface{}` found (errchkjson)
            b, _ := json.Marshal(v)
                    ^

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-02-09 13:22:50 +01:00