When a endpoint's net.IPNet is loaded from store and converted
to a netip.Addr, unmap it so that iptables rules don't contain
IPv4-mapped IPv6 addresses.
Signed-off-by: Rob Murray <rob.murray@docker.com>
(cherry picked from commit 071e6472db)
Signed-off-by: Rob Murray <rob.murray@docker.com>
The bridge driver should figure out whether it's running in
a mirrored WSL2 setup, and tell the firewaller.
So, move the WSL2-deciding code back into the bridge driver
and unit test it there. Use TestIptabler to check the rules
are constructed properly.
Signed-off-by: Rob Murray <rob.murray@docker.com>
Per-network option com.docker.network.bridge.trusted-host-interfaces
accepts a list of interfaces that are allowed to route
directly to a container's published ports in a bridge
network with nat enabled.
This daemon level option disables direct access filtering,
enabling direct access to published ports on container
addresses in all bridge networks, via all host interfaces.
It overlaps with short-term env-var workaround:
DOCKER_INSECURE_NO_IPTABLES_RAW=1
- it does not allow packets sent from outside the host to reach
ports published only to 127.0.0.1
- it will outlive iptables (the workaround was initially intended
for hosts that do not have kernel support for the "raw" iptables
table).
Signed-off-by: Rob Murray <rob.murray@docker.com>
trusted_host_interface have access to published ports on container
addresses - enabling direct routing to the container via those
interfaces.
Signed-off-by: Rob Murray <rob.murray@docker.com>
Commit 27adcd5 ("libnet/d/bridge: drop connections to lo mappings, and
direct remote connections") introduced an iptables rule to drop 'direct'
remote connections made to the container's IP address - for each
published port on the container.
The normal filter-FORWARD rules would then drop packets sent directly to
unpublished ports. This rule was only created along with the rest of port
publishing (when a container's endpoint was selected as its gateway). Until
then, all packets addressed directly to the container's ports were dropped
by the filter-FORWARD rules.
But, the rule doesn't need to be per-port. Just drop packets sent
directly to a container's address unless they originate on the host.
That means fewer rules, that can be created along with the endpoint (then
directly-routed get dropped at the same point whether or not the endpoint
is currently the gateway - very slightly earlier than when it's not the
gateway).
Signed-off-by: Rob Murray <rob.murray@docker.com>
Plumb context from the API down to libnet driver method `CreateNetwork`,
and add an OTel span to the bridge driver's `createNetwork` method.
Include a few attributes describing the network configuration (e.g.
IPv4/IPv6, ICC, internal and MTU).
A new util function, `RecordStatus`, is added to the `otelutil` package
to easily record any error, and update the span status accordingly.
Signed-off-by: Albin Kerouanton <albinker@gmail.com>
Using iptables.OnReloaded to restore individual per-network rules
on firewalld reload means rules for deleted networks pop back in
to existence (because there was no way to delete the callbacks on
network-delete).
So, on firewalld reload, walk over current networks and ask them
to restore their iptables rules.
Signed-off-by: Rob Murray <rob.murray@docker.com>
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>
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>
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>
To support this, a new netlabel is added: `com.docker.network.endpoint.ifname`.
It gives the ability to specify the interface name to be set by
netdrivers when the interface is added / moved into the container's
network namespace.
All builtin netdrivers support it.
Signed-off-by: Albin Kerouanton <albinker@gmail.com>
It can only be set on a "--internal" network, and the only difference is
that no address is assigned to the bridge. So, there's no route to a
host address.
Signed-off-by: Rob Murray <rob.murray@docker.com>
These errors implement errdefs interfaces, and are only used internally
for convenience. Un-export their implemetations because the types themselves
are not used as sentinel errors.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
It's a generic errdefs.ErrInvalidParameter, and the type itself is not
used as sentinel error anywhere.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
It's a generic errdefs.ErrInvalidParameter, and the type itself is not
used as sentinel error anywhere.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
It's a generic error, doesn't implement an errdefs type, is poorly formatted,
and not used as sentinel error anywhere. Let's remove it, and update the error
produced to be slightly more informative (include the invalid type). Worth
noting that there's no need to include the name of the driver in the error,
because the only uses of the error (in `registerNetworkDrivers`) already
decorates it; 5fd7ed2937/libnetwork/drivers_linux.go (L34-L36)
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>
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>
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>