It was only used in a single place, and did not implement an errdef;
the type itself was not used as sentinel error.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Since commit 933fcc9 (Re-remove the SetKey OCI prestart hook),
the network namespace will be set up before endpoints are
created in most cases, apart from build containers.
So, when possible, create the veth with one end in that netns
to save moving it in later. On my host, that saves about 20ms
for each bridge network a container is connected to.
Signed-off-by: Rob Murray <rob.murray@docker.com>
Now a gratuitous/unsolicted ARP is sent, there's no need to
use an IPv4-based MAC address to preserve arp-cache mappings
between an endpoint's IP addresses and its MAC addresses.
Because a random MAC address is used for the default bridge,
it no longer makes sense to derive container IPv6 addresses
from the MAC address. This "postIPv6" behaviour was needed
before IPv6 addresses could be configured, but not now. So,
IPv6 addresses will now be IPAM-allocated on the default
bridge network, just as they are for user-defined bridges.
Signed-off-by: Rob Murray <rob.murray@docker.com>
Since commit 0f8fc31, the bridge driver will try to load kernel
module br_netfilter if the userland proxy is disabled. If it fails,
we're in unknown territory, so it's treated as an error. At the
very least, containers will not be able to access host ports
mapped to other containers in the same network.
Before that, and before commit 5c499fc delayed the module load
until it was needed - it was loaded unconditionally, but errors
were only logged.
So, on systems where the module is not available, or could not be
loaded/configured, no error was reported and things "worked" (as
long as you didn't try to use something that didn't work).
That behaviour has been useful to some. So, make it possible to
ignore the problem by setting env var:
DOCKER_IGNORE_BR_NETFILTER_ERROR=1
Signed-off-by: Rob Murray <rob.murray@docker.com>
When a NAT-based port mapping is created with a HostIP specified, we
insert a DNAT rule in nat-DOCKER to replace the dest addr with the
container IP. Then, in filter chains, we allow access to the container
port for any packet not coming from the container's network itself (if
hairpinning is disabled), nor from another host bridge.
However we don't set any rule that prevents a rogue neighbor that shares
a L2 segment with the host, but not the one where the port binding is
expected to be published, from sending packets destined to that HostIP.
For instance, if a port binding is created with HostIP == '127.0.0.1',
this port should not be accessible from anything but the lo interface.
That's currently not the case and this provides a false sense of
security.
Since nat-DOCKER mangles the dest addr, and the nat table rejects DROP
rules, this change adds rules into raw-PREROUTING to filter ingress
packets destined to mapped ports based on the input interface, the dest
addr and the dest port.
Interfaces are dynamically resolved when packets hit the host, thanks
to iptables' addrtype extension. This extension does a fib lookup of the
dest addr and checks that it's associated with the interface reached.
Also, when a proxy-based port mapping is created, as is the case when an
IPv6 HostIP is specified but the container is only IPv4-capable, we
don't set any sort of filtering. So the same issue might happen. The
reason is a bit different - in that case, that's just how the kernel
works. But, in order to stay consistent with NAT-based mappings, these
rules are also applied.
The env var `DOCKER_DISABLE_INPUT_IFACE_FILTERING` can be set to any
true-ish value to globally disable this behavior.
Signed-off-by: Albin Kerouanton <albinker@gmail.com>
This field was initialized by `driver.createNetwork` instead of being
initialized by the `newDriver` constructor. That's currently the single
place where it's initialized -- no tests override it, so it seems the
'current' netns is always used.
Signed-off-by: Albin Kerouanton <albinker@gmail.com>
An "--internal" bridge network will never set up a default route
and, with "-o com.docker.network.bridge.inhibit_ipv4", no Gateway
address will be assigned to the bridge.
So, implement the SkipGwAlloc interface in the bridge driver, and
use it to to indicate that no Gateway address is required in this
specific case.
Signed-off-by: Rob Murray <rob.murray@docker.com>
This code has some gnarly string-matching to detect "not found" errors
returned by hcsshim.
Hcsshim at some point changed this error to lowercase;
6d67a30859
It looks like we ran into that problem in integration tests, which was
fixed in c530c9cbb0 when updating hcsshim,
however, it was only fixed in tests, and hiding the actual issue in our
code.
It looks like hcsshim has some utilities to detect error-types, such as the
IsElementNotFoundError function in hcn, which is the newer API that also wraps
the "HNS" service;
d9a4231b9d/hcn/hcnerrors.go (L75-L77)
But unfortunately, the hns API used by us, does not return typed errors, and
returns HNS errors as a untyped formatted string.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Also updated some existing ones to use `%v` instead of `%s` for consistency.
caught by go1.24
# github.com/docker/docker/libnetwork/drivers/windows/overlay
# github.com/docker/docker/libnetwork/drivers/windows/overlay/ov_network_windows.go:206:32: non-constant format string in call to github.com/docker/docker/libnetwork/types.ForbiddenErrorf
FAIL github.com/docker/docker/libnetwork/drivers/windows/overlay [build failed]
# github.com/docker/docker/libnetwork/drivers/windows
# github.com/docker/docker/libnetwork/drivers/windows/windows.go:449:33: non-constant format string in call to github.com/docker/docker/libnetwork/types.ForbiddenErrorf
FAIL github.com/docker/docker/libnetwork/drivers/windows [build failed]
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Before that change, we were passing the datastore to network drivers
through a `map[string]interface{}`. Then, each driver that needed the
store would cast the datastore to the correct type.
This was not a good design, as it was not clear which drivers were using
the store and which were not. Not all unit tests were passing the store,
leading to logs about uninitialized store being written.
This change makes the store a parameter of the `RegisterX` functions.
All unit tests are now passing a valid datastore to the drivers. A new
testutil func is added for that purpose.
Signed-off-by: Albin Kerouanton <albinker@gmail.com>
The `ProgramChain` method was called exclusively by the bridge driver
to insert totally unrelated ipt rules in two different table-chains.
Break down this method into two functions, and move them into the bridge
pkg.
The new function `addNATJumpRules` inserts rules that aren't related to
any specific network, and depends solely on the driver config. Call it
during driver configuration instead of during network setup.
Signed-off-by: Albin Kerouanton <albinker@gmail.com>
setupIPTablesInternal is/was called from setupIPTables to set
up some rules for a network ... "internal" behaviour of the
outer function.
Then commit 7b64b1c2 added support for "--internal" bridge
networks, calling setupInternalNetworkRules from setupIPTables
instead of setupIPTablesInternal.
So, setupIPTablesInternal is the function that deals with
everything except "--internal" networks ... rename it.
Signed-off-by: Rob Murray <rob.murray@docker.com>
- Move variable declarations closer to where they're used.
- Put comments in the blocks they apply to.
Signed-off-by: Rob Murray <rob.murray@docker.com>
Rules no longer need to be rearranged when creating a network.
Per-network rules are always appended to the FORWARD chain so,
after adding them, there's no need to delete the per-driver
rules to re-insert them at the top of the chain.
Signed-off-by: Rob Murray <rob.murray@docker.com>
The output variable was renamed in 0503cf2510,
but that commit failed to change this defer, which was now checking the
wrong error.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Since 89470a7 we ignore errors returned by `LinkSetMTU` when the MTU is
greater than 1500 but lower than 65535 to let CentOS/RHEL 7 users set
an MTU in that range (despite their kernel rejecting that value).
We dropped support for those distros, so we can now remove this code
and unconditionally error out if `LinkSetMTU` returns an error.
Commit 89470a7 introduced two unit tests - these are kept, and both now
have a proper GoDoc describing what they're testing.
Signed-off-by: Albin Kerouanton <albinker@gmail.com>
An ioctl() call to get the "interface index" for a kernel module triggers
the kernel to try to load the module, if the process is running with
CAP_SYS_MODULE. This tends to be more reliable than "modprobe" for
docker-in-docker.
If the ioctl() method fails, fall back to trying "modprobe".
Signed-off-by: Rob Murray <rob.murray@docker.com>
Env var DOCKER_TEST_CREATE_DEFAULT_BRIDGE could be set to
override the name of the default bridge - without the bridge
being user-managed (unlike the '--bridge' daemon option).
It was needed by tests looking at docker0 behaviour, using
their own instance of the daemon, without breaking the
docker0 instance belonging to CI's daemon.
Now, those tests run in their own netns using the name docker0.
So, remove the unused env var.
Signed-off-by: Rob Murray <rob.murray@docker.com>
Same as "nat" mode, there's masquerading and port mapping from the
host - but no port/protocol filtering for direct access to the
container's address from remote hosts.
This is the old default behaviour for IPv4 when the filter-FORWARD
chain's default policy was "ACCEPT" (the daemon would only set it
to "DROP" when it set sysctl "ip_forward" itself, but it didn't set
up DROP rules for unpublished ports).
Now, port filtering doesn't depend on the filter-FORWARD policy. So,
this mode is added as a way to restore the old/surprising/insecure
behaviour for anyone who's depending on it. Networks will need to
be re-created with this new gateway mode.
Signed-off-by: Rob Murray <rob.murray@docker.com>
Checking for `/proc/sys/net/bridge` directory alone is not enough to
decide if bridge, br_netfilter module to be loaded.
Check for specific file for br_netfilter module and then
do modprobe if the file is not found under `/proc/sys/net/bridge`
Loading br_netfilter implicitly loads bridge module.
fixes: #48948
Signed-off-by: Shreenidhi Shedi <shreenidhi.shedi@broadcom.com>
If a values is non-nil when we don't expect it, it would be quite
helpful to get an error message explaining what happened.
find . -type f -name "*_test.go" | \
xargs gofmt -w -r "assert.Assert(t, a == nil) -> assert.Assert(t, is.Nil(a))"
find . -type f -name "*_test.go" | \
xargs gofmt -w -r "assert.Check(t, a == nil) -> assert.Check(t, is.Nil(a))"
Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
Field 'generic' in 'libnetwork.Network' is used to store driver options,
it has type 'options.Generic', which is 'map[string]any'.
In that map, there may be a key 'netlabel.GenericData' holding options
known as "network generic options", used for options like:
-o com.docker.network.bridge.name=br-foo
The value type for key 'netlabel.GenericData' is always 'map[string]string'
when created via an API request. But, some unit tests use type
'options.Generic'.
That works because the bridge, ipvlan and macvlan drivers look for type
'options.Generic' as well as 'map[string]string'. If they find
'options.Generic', Go reflection is used to map keys to fields of the
config struct with the expectation that the value has the same type as
that field. But, that's only used in unit tests (so the tests aren't
testing the same code path as the API would use). The 'options.Generic'
form of the bridge name option is:
"BridgeName": "br-foo"
(Because "BridgeName" is the name of the field in the bridge driver's
network config struct.)
The libnetwork code expects "network generic options" to have type
'map[string]string', and makes no provision for 'options.Generic'. So,
for example, function Network.DriverOptions will panic if called when
'Network.generic[netlabel.GenericData]' has type 'options.Generic'.
The type of 'Network.generic[netlabel.GenericData]' can't be statically
checked, because it's just a field in a 'map[string]any'.
So - remove the driver code that converts "network generic options"
from type 'options.Generic', as it's only used in tests and just makes
things more confusing.
This should reduce the chances of things appearing to work when the
type is wrong, and converting unit tests to use 'map[string]string'
means they're testing the right thing.
Signed-off-by: Rob Murray <rob.murray@docker.com>
The default for a user-defined chain is RETURN anyway.
This opens up the possibilty of sorting rules into two groups
by using insert or append, without having to deal with appending
after the unconditional RETURN.
Signed-off-by: Rob Murray <rob.murray@docker.com>