120 Commits

Author SHA1 Message Date
Paweł Gronowski
71fd582aa2 modernize: Use strings.Builder instead of string concatenation
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2025-12-15 18:56:34 +01:00
Paweł Gronowski
3df05205f4 modernize: Use range int
Added in Go 1.22

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
2025-12-15 18:56:34 +01:00
Sebastiaan van Stijn
99066209a2 libnetwork/options: GenerateFromModel: use generics
Use generics so that the produced output is already in the right
type.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-12-10 01:48:48 +01:00
Albin Kerouanton
52fae09ec0 libnet/pms/nat: don't bind IPv6 ports if not supported by port driver
In rootless mode, the Engine needs to call the rootless port driver to
know which IP address it should bind to inside of its network namespace.

The slirp4netns port drivers doesn't support binding to IPv6 address, so
we need to detect that before listening on the port.

Before commit 201968cc0, this wasn't a problem because the Engine was
binding the port, then calling rootless port driver to learn whether the
proto/IP family was supported, and listen on the port if so.

Starting with that commit, the Engine does bind + listen in one go, and
then calls the port driver — this is too late. Fix the bug by checking
if the port driver supports the PortBindingReq, and only allocate the
port if so.

Signed-off-by: Albin Kerouanton <albin.kerouanton@docker.com>
2025-11-28 19:40:34 +01:00
Albin Kerouanton
20634eddce Merge pull request #51496 from thaJeztah/discoverapi_cleanups
libnetwork: some minor refactor / cleanups
2025-11-27 12:22:01 +01:00
Rob Murray
a2de9bb334 Unmap more netip.Addr vars created using AddrFromSlice
Signed-off-by: Rob Murray <rob.murray@docker.com>
2025-11-24 16:51:14 +00:00
Rob Murray
ed10b98506 Restore missing nwEndpointsMu.Lock
- introduced by 4f7afb8 (Remove libnet's logic to track a driver's
  port mapping state)

Signed-off-by: Rob Murray <rob.murray@docker.com>
2025-11-18 15:38:48 +00:00
Sebastiaan van Stijn
e59d1b4563 libnetwork/drivers/overlay: DiscoverNew: move logic to setKeys, updateKeys
Make the DiscoverNew switch only responsible for asserting the correct
data type, and push the conversion logic into the setKeys and updateKeys
methods.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-11-16 23:36:04 +01:00
Sebastiaan van Stijn
f40b45ca1f libnetwork/drivers/overlay: use structured logs in some places
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-11-16 23:36:04 +01:00
Rob Murray
7989fea6d2 Merge pull request #51241 from thaJeztah/overlay_pass_context
libnetwork/drivers/overlay: pass context for logger
2025-10-21 14:22:12 +01:00
Sebastiaan van Stijn
ee3cab4158 libnetwork/drivers/overlay: pass context for logger
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-21 15:08:03 +02:00
Sebastiaan van Stijn
bdc7474826 Merge pull request #51229 from olljanat/win-overlay-custom-dns
libnetwork: support custom DNS servers in Windows overlay driver
2025-10-21 14:40:07 +02:00
Olli Janatuinen
48c2d8c458 libnetwork: support custom DNS servers in Windows overlay driver
Signed-off-by: Olli Janatuinen <olli.janatuinen@gmail.com>
2025-10-21 07:33:02 +00:00
Sebastiaan van Stijn
10faa629fe libnetwork/drivers/macvlan, ipvlan: assorted minor cleanups
- Inline some vars and align between drivers
- Remove nested if's where possible
- Use `WithError` for some logs, and use the context if available
- Scope variables locally where only used locally and, the reverse,
  make it clear where a (function-)global variable is used.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-20 08:52:09 +02:00
Sebastiaan van Stijn
a013147c40 libnetwork/drivers/macvlan: parentHasSingleUser: don't create copy of networks
This function was calling driver.getNetworks, which copies the networks map
into a new slice. As we're not mutating the networks, we can just use the
networks map itself to check if there's any networks configured with the
same parent.

While changing;

- Also change the signature to accept the parent to compare to as a string
- Return early once we determined there's more than one user

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-20 08:14:45 +02:00
Sebastiaan van Stijn
65296cd0e7 libnetwork/drivers/macvlan, ipvlan: un-embed mutexes
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-20 08:14:44 +02:00
Sebastiaan van Stijn
a2f4f09f91 libnetwork/drivers/macvlan, ipvlan: remove unused sync.Once
Both were added as part of the initial implementation in commit [moby@ea30113]
([libnetwork@1d6f2c5]), but never used.

[moby@ea30113]: ea30113303
[libnetwork@1d6f2c5]: 1d6f2c59c4

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-20 08:14:44 +02:00
Sebastiaan van Stijn
5276dd8e9a libnetwork/drivers/ipvlan: remove ifaceGateway utility
This utility was only called with two constant values;

    const (
        defaultV4RouteCidr = "0.0.0.0/0"
        defaultV6RouteCidr = "::/0"
    )

However;

- calling it would always execute a `net.ParseCIDR`
- verify if it would produce an error (which would be very unlikely)
- it used a `staticRoute` struct that was ONLY used for this function
- and immediately deconstructed into its components
- furthermore, the `NextHop` field would be discarded by jinfo.AddStaticRoute,
  which only used the third argument for `routeType == types.NEXTHOP`

This patch:

- removes the `ifaceGateway` and associated `staticRoute` and consts
- defines two package-level vars for `defaultV4Net` and `defaultV6Net`,
  which can be reused (no need to parse / construct them for every join)

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-20 08:14:44 +02:00
Sebastiaan van Stijn
d481c09fa7 libnetwork/drivers/macvlan, ipvlan: make driver.leave a stub
These drivers did not do anything meaningful in the `Leave` method; they
would check if the network and/or endpoint were missing, in which case
they produced an error, but the network and endpoint (if present) would
not be used, so it was only validation.

Such validation could still be relevant elsewhere, but looking at where
this method is called; the `Driver.Leave()` is called in two places, both
of which don't handle the error, other than logging it as a warning / error;

It's called by `Endpoint.sbJoin()`, as part of the rollback;
d5c838dc5e/daemon/libnetwork/endpoint.go (L539-L545)

And `Endpoint.sbLeave()`, which also discards the error;
d5c838dc5e/daemon/libnetwork/endpoint.go (L772-L776)

Based on he above, this code looks to be redundant, so replacing it with
a stub; returning `nil`.

As replacing the code removed the use of network.getEndpoint, which was effectively
a copy of network.endpoint (which didn't have error handling), I merged the two
methods, and removed custom error-handling elsewhere.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-20 08:14:44 +02:00
Sebastiaan van Stijn
aec6e7f7b6 libnetwork/drivers/macvlan, ipvlan: remove networkTable, endpointTable
These types were just a straight map[string]XXX, with no methods or other
properties attached.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-20 08:14:44 +02:00
Sebastiaan van Stijn
bf7277f8fe libnetwork/drivers/macvlan, ipvlan: remove getSubnetforIPv6, getSubnetforIPv4
These methods were just wrappers around getSubnetforIP; let's peel away the
abstraction and call it directly; we're already checking for n.config.Ipv4Subnet
and n.config.Ipv6Subnets on the call-site, so may as well just pass it in.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-20 08:14:34 +02:00
Sebastiaan van Stijn
a294445345 ibnetwork/drivers/macvlan, ipvlan: align and fix potential panic
There were some missing checks whether ep.addr, ep.addrv6 were nil,
which could panic in getSubnetForIP.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-19 13:35:25 +02:00
Sebastiaan van Stijn
17425cff08 libnetwork/drivers/macvlan, ipvlan: driver.Join: don't fetch endpoint twice
The function was fetching a reference to the endpoint twice; while this
did give the option for an early return, in practice it didn't mean much,
because it could still fail if the endpoint was removed in between.

This code still has a race condition, because while a reference to the
endpoint is retrieved while acquiring a lock, the result is mutated without.
This probably needs to either have some accessor, or the function should
keep a lock for the whole operation (possibly switching to an RWMutex).

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-10-19 13:17:56 +02:00
Rob Murray
9912ccd7b3 Clean up bridge device on network create error
When the bridge driver encounters an error during network
creation, delete the bridge device if one has been added.

Signed-off-by: Rob Murray <rob.murray@docker.com>
2025-10-09 15:52:25 +01:00
Cory Snider
d5c838dc5e internal: move sliceutil from daemon/internal
These utilities are very handy to use in integration tests, too. Move
the package so it can be imported by them.

Signed-off-by: Cory Snider <csnider@mirantis.com>
2025-10-03 21:39:14 +02:00
Cory Snider
46ab36ae46 daemon/internal: move netiputil from libnetwork
These utilities are going to be needed elsewhere in the daemon to handle
netip values from API requests.

Signed-off-by: Cory Snider <csnider@mirantis.com>
2025-10-03 21:39:13 +02:00
Rob Murray
b26972f9f2 Merge pull request #51033 from robmry/use-libnftables
Use libnftables in dynamically linked binary
2025-10-03 16:53:06 +01:00
Sebastiaan van Stijn
8905c3052b daemon/libnetwork: use t.Context() in tests
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-25 22:53:41 +02:00
Rob Murray
6db6de2c20 Use libnftables in dynamically linked binary
Signed-off-by: Rob Murray <rob.murray@docker.com>
2025-09-24 18:27:17 +01:00
Rob Murray
de5e64b3bd Add option WithSetNsHandles for testutil SetupTestOSContextEx
Allow tests to run in parallel with separate network namespaces,
without modifying the global-state namespace/netlink handles in
the "ns" package ... only useful for tests that don't depend on
package "ns".

Use the new option in iptabler/nftabler tests.

Signed-off-by: Rob Murray <rob.murray@docker.com>
2025-09-23 17:35:58 +01:00
Rob Murray
07453abab3 Merge pull request #50929 from robmry/mac_ip_vlan_gateway_config
macvlan, ipvlan-l2: only configure a default route when a gateway address is supplied
2025-09-16 18:09:30 +01:00
Rob Murray
b0226d5074 Merge pull request #48971 from robmry/ipv6_disabled_on_interface
Release IPv6 address if IPv6 is disabled on an interface
2025-09-16 17:53:06 +01:00
Rob Murray
2bb0443ae9 Release IPv6 address if unused due to sysctl setting
When running:
  docker network create --ipv6 b46
  docker run --rm -ti \
    --network name=b46,driver-opt=com.docker.network.endpoint.sysctls=net.ipv6.conf.IFNAME.disable_ipv6=1 \
     busybox

IPv6 is enabled in the container and the network, so an IPv6 address
will be allocated for the endpoint.

But, when the sysctl is applied, the IPv6 address will be removed
from the interface ... so, no unsolicited neighbour advertisement
should be (or can be) sent and, the endpoint should not be treated
as dual-stack when selecting a gateway endpoint and, if it is
selected as the gateway endpoint, setting up an IPv6 route via the
network will fail.

So, if the IPv6 address disappears after sysctls have been applied,
release the address and remove it from the endpoint's config.

Signed-off-by: Rob Murray <rob.murray@docker.com>
2025-09-15 10:39:08 +01:00
Rob Murray
9129094b98 Windows containers: report HNS network name in inspect
After creating a new network, inspect shows that there's no value
for option "com.docker.network.windowsshim.networkname". After
restarting the daemon, it shows up with the docker network name
(not the HNS network name, which defaults to the docker network's
id).

Creating the network with "-o com.docker.network.windowsshim.networkname"
sets the HNS network name, and it shows up in inspect. Until the
daemon is restarted, then it shows the docker network name.

So - set the option value to the HNS network name on creation (the id
if no name is given), and on restore after restart use the name
reported by HNS.

Signed-off-by: Rob Murray <rob.murray@docker.com>
2025-09-12 16:03:36 +01:00
Rob Murray
aa78f19066 ipvlan-l2: do not allocate a gateway address from IPAM
When ipvlan in "l2" mode is given no '--gateway' option, an
address is allocated from IPAM and a default route is set up
via that gateway. But, the gateway address is not assigned to
anything in the Docker ipvlan network - it must be external,
and IPAM shouldn't try to guess it.

So ...

- always disable IPAM gateway address allocation for ipvlan-l2
  - tell libnet to assume the endpoint has a gateway instead
- update the Join code to allow for no configured gateway
- always disable 'docker_gwbridge' connection for ipvlan
  networks, so it's not hooked up when there is no gateway
  address.

Signed-off-by: Rob Murray <rob.murray@docker.com>
2025-09-12 14:29:15 +01:00
Rob Murray
468e3521b0 macvlan: do not allocate a gateway address from IPAM
When macvlan is given no '--gateway' option, an address is
allocated from IPAM and a default route is set up via that
gateway. But, the gateway address is not assigned to anything
in the Docker macvlan network - it must be external, and
IPAM shouldn't try to guess it.

When IPv6 auto-configuration is enabled in the network the
macvlan is connected to, the macvlan driver races against it
to set up the gateway. When autoconfig wins, container creation
fails because the default route already exists.

So ...

- disable IPAM gateway address allocation for macvlan
- update the Join code to allow for no configured gateway
- always disable 'docker_gwbridge' connection for macvlan
  networks, so it's not hooked up when there is no gateway
  address.

Libnet assumes an endpoint with no statically configured default
gateway or route does not provide external connectivity. So, it
disables external DNS access, and will not select the endpoint
as gateway for containers. So, where an IPAM allocated gateway
address would have been assigned before, tell libnet to assume
there will be an auto-configured gateway.

Signed-off-by: Rob Murray <rob.murray@docker.com>
2025-09-12 14:29:15 +01:00
Albin Kerouanton
f835ff6987 Merge pull request #50289 from akerouanton/cleanup-windows-portmapper
libnet/portmapper: clean up windows port mapper
2025-09-08 22:52:45 +02:00
Albin Kerouanton
2f1015482f libnet/d/windows: ReleasePorts: use errors.Join
Signed-off-by: Albin Kerouanton <albinker@gmail.com>
2025-09-08 11:40:09 +02:00
Albin Kerouanton
fc86411353 libnet/d/windows: inline releasePort
releasePort is a one-liner and is called only in one place. Inline it.

Signed-off-by: Albin Kerouanton <albinker@gmail.com>
2025-09-08 11:37:08 +02:00
Albin Kerouanton
9efc1cc264 libnet/portmapper: rename, move PortMapper to portallocator
The only viable way to allocate a port is to bind and listen to it. So,
the windows PortMapper was really a PortAllocator in disguise.

Rename it to OSAllocator and move it to the portallocator package.

Signed-off-by: Albin Kerouanton <albinker@gmail.com>
2025-09-08 11:32:21 +02:00
Sebastiaan van Stijn
4b230a4909 internal/testutils: merge with internal/testutil
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2025-09-08 10:08:35 +02:00
Albin Kerouanton
af677b61a5 libnet/portmapper: clean up windows port mapper
The windows port mapper is needlessly complex while its job is pretty
straightforward: reserve a port through the port allocator, and start a
dummy proxy to allocate it from the OS.

The biggest source of complexity is the use of the `net.Addr` interface
to pass the host IP, port and proto. `MapRange` now has a proto arg, and
returns the allocated port.

`MapRange` is also instantiating a `mapping` struct whose fields are
all unused, except for its `stopUserlandProxy`. Instead, store
`stopProxy` callbacks directly into the `PortMapper`.

Signed-off-by: Albin Kerouanton <albinker@gmail.com>
2025-09-08 10:05:29 +02:00
Albin Kerouanton
f37094ad4f libnet/d/bridge: CreateEndpoint: use d.config directly
newDriver, which creates a new instance of the bridge driver, is the
only place where the driver config field is set. So there's no need to
gate access to it with a mutex.

Signed-off-by: Albin Kerouanton <albinker@gmail.com>
2025-09-03 12:10:16 +02:00
Albin Kerouanton
ae24edfc0d libnet/d/bridge: merge configure into newDriver
configure must be called every time newDriver is called... so merge them
together.

Signed-off-by: Albin Kerouanton <albinker@gmail.com>
2025-09-03 12:10:16 +02:00
Albin Kerouanton
2436458227 libnet/d/bridge: Register: pass a Configuration struct
Libnetwork passes a map[string]any to the bridge driver's Register
function. This forces the daemon to convert its configuration into a
map, and the driver to convert that map back into a struct.

This is unnecessary complexity, and makes it harder to track down where
and how bridge driver configuration fields are set.

Refactor libnetwork to let the daemon register the bridge.Configuration
directly through a new option `OptionBridgeConfig`.

The bridge driver now takes a `Configuration` param that needs no
special treatment.

Signed-off-by: Albin Kerouanton <albinker@gmail.com>
2025-09-03 12:10:10 +02:00
Albin Kerouanton
6e512cc292 libnet/d/ipvlan: Register: remove unused config param
Signed-off-by: Albin Kerouanton <albinker@gmail.com>
2025-09-03 11:23:07 +02:00
Albin Kerouanton
459f4f431d libnet/d/macvlan: Register: remove unused config param
Signed-off-by: Albin Kerouanton <albinker@gmail.com>
2025-09-03 11:23:07 +02:00
Albin Kerouanton
43014a891b libnet/d/overlay: Register: remove unused config param
The overlaydrivers takes a config parameter, but actually never uses
it — drop it.

Signed-off-by: Albin Kerouanton <albinker@gmail.com>
2025-09-03 11:23:07 +02:00
Albin Kerouanton
4ea085187a libnet/d/bridge: export Configuration
Signed-off-by: Albin Kerouanton <albinker@gmail.com>
2025-09-03 11:23:07 +02:00
Albin Kerouanton
4d2a293ff3 libnet/drvapi: make NetworkAllocate optional
This method is only used by the cnmallocator to allocate Swarm-scoped
network resources. Its only concrete implementation is in the ovmanager.
Other network drivers are implementing it too to adhere to the
driverapi.Driver interface, but they all return a 'not implemented'
error.

Extract this method into a separate interface, and add a dedicated
RegisterNetworkAllocator to the driver registry. Update the cnmallocator
to load 'network allocators' instead of 'drivers'.

Signed-off-by: Albin Kerouanton <albinker@gmail.com>
2025-09-02 21:55:03 +02:00