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>
After an error, there's no need for it to roll back rules
it's created, the caller already does that.
Signed-off-by: Rob Murray <rob.murray@docker.com>
This was introduced in 18327745c00d4d2e98e5ea7241c1a1ef43b0401b;
make BIND_DIR=. shell
make -C ./internal/gocompat/
GO111MODULE=on go test -v
# github.com/docker/docker/libnetwork
../../libnetwork/sandbox.go:588:6: implicit function instantiation requires go1.18 or later (-lang was set to go1.16; check go.mod)
FAIL gocompat [build failed]
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Delete the entries that were added, rather than looking at the service
map (DNS config) and trying to delete entries without accounting for
the container's --hostname.
Signed-off-by: Rob Murray <rob.murray@docker.com>
When a container is connected to a network, it gets /etc/hosts
entries for its addresses on that network. So, when it's connected
to two networks, it has a hosts entry for each. For example, if
the hostname is the default short-id and it's connected to two
networks (172.19.0.0/16 and 172.20.0.0/17, plus IPv6 address for
each), the hosts file might include:
172.19.0.2 4b92a573912d
fd8c:c894:d68::2 4b92a573912d
172.20.0.2 4b92a573912d
fd8c:c894:d68:1::2 4b92a573912d
If the container is disconnected from 172.19.0.2, only remove
the hosts entries with addresses on that network.
Signed-off-by: Rob Murray <rob.murray@docker.com>
libnetwork/ipams/defaultipam/parallel_test.go:231:3: The copy of the 'for' variable "index" can be deleted (Go 1.22+) (copyloopvar)
index := index
^
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
libnetwork/bitmap/sequence_test.go:1210:3: The copy of the 'for' variable "tt" can be deleted (Go 1.22+) (copyloopvar)
tt := tt
^
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
libnetwork/drivers/overlay/encryption.go:682:3: The copy of the 'for' variable "sp" can be deleted (Go 1.22+) (copyloopvar)
sp := sp
^
libnetwork/drivers/overlay/encryption.go:692:3: The copy of the 'for' variable "sa" can be deleted (Go 1.22+) (copyloopvar)
sa := sa
^
libnetwork/drivers/overlay/peerdb.go:134:3: The copy of the 'for' variable "pEntry" can be deleted (Go 1.22+) (copyloopvar)
pEntry := pEntry
^
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
libnetwork/drivers/bridge/bridge_linux_test.go:1079:3: The copy of the 'for' variable "tc" can be deleted (Go 1.22+) (copyloopvar)
tc := tc
^
libnetwork/drivers/bridge/port_mapping_linux_test.go:763:3: The copy of the 'for' variable "tc" can be deleted (Go 1.22+) (copyloopvar)
tc := tc
^
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
libnetwork/endpoint_info.go:467:3: The copy of the 'for' variable "r" can be deleted (Go 1.22+) (copyloopvar)
r := r
^
libnetwork/firewall_linux_test.go:52:3: The copy of the 'for' variable "tc" can be deleted (Go 1.22+) (copyloopvar)
tc := tc
^
libnetwork/libnetwork_internal_test.go:403:3: The copy of the 'for' variable "tc" can be deleted (Go 1.22+) (copyloopvar)
tc := tc
^
libnetwork/libnetwork_linux_test.go:2045:3: The copy of the 'for' variable "i" can be deleted (Go 1.22+) (copyloopvar)
i := i
^
libnetwork/libnetwork_linux_test.go:2165:3: The copy of the 'for' variable "tc" can be deleted (Go 1.22+) (copyloopvar)
tc := tc
^
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
commit a0807e7cfe configured golangci-lint
to use go1.23 semantics, which alowed linters like `copyloopvar` to lint
using thee correct semantics.
go1.22 now creates a copy of variables when assigned in a loop; make sure we
don't have files that may downgrade semantics to go1.21 in case that also means
disabling that feature; https://go.dev/ref/spec#Go_1.22
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
When a container sends a packet to one of its own published ports on the
host, it's normally picked up by the userland proxy and sent back.
When the userland proxy is disabled, a masquerade rule is needed in
order for responses to the container to have the host's source address.
The masquerade rule matches the container's address as source and dest,
and the published port as the dest. It's only used for the no-proxy
case.
So, when the userland proxy is enabled, don't create the masquerade
rule.
Signed-off-by: Rob Murray <rob.murray@docker.com>
The daemon no longer depends on the iptables/ip6tables filter-FORWARD
chain's policy being DROP in order to implement its port filtering
rules.
However, if the daemon enables IP forwarding in the host's system
config, by default it will set the policy to DROP to avoid potential
security issues for other applications/networks.
If docker does need to enable IP forwarding, but other applications
on the host require filter-FORWARD's policies to be ACCEPT, this
option can be used to tell the daemon to leave the policy unchanged.
(Equivalent to enabling IP forwarding before starting the daemon,
but without needing to do that.)
Signed-off-by: Rob Murray <rob.murray@docker.com>
Before this change, for IPv4:
- sysctl net.ipv4.ip_forward was enabled during bridge driver
initialisation, if:
- not already enabled
- ip-forward=true, and
- iptables=true.
- the filter-FORWARD chain's policy was set to DROP, if the daemon
updated the sysctl.
- if setting the policy failed, the sysctl change was reverted.
But, for IPv6:
- sysctls net.ipv6.conf.[default|all].forwarding were both enabled
when creating the first IPv6-enabled network, if:
- they weren't already enabled,
- ip-forward=true, and
- ip6tables=true.
- the filter-FORWARD chain's policy was set to DROP when creating
an IPv4 enabled bridge network (inc. the default bridge), if:
- ip6tables=true.
- (this happened whether or not the daemon would ever enable
IPv6 forwarding, or even create an IPv6 network.)
The bridge driver no longer needs the default policy to be DROP to
implement its own port-filtering rules. But, enabling IP forwarding
without setting the filter-FORWARD policy to DROP would potentially
be a security risk.
This change aligns IPv4 and IPv6 behaviours:
- only try to set the sysctls when creating a bridge network that
needs them (for IPv4, that's still during daemon init because
the default bridge is IPv4 enabled).
- only check/set the filter-FORWARD policy after updating sysctls.
- if the filter-FORWARD policy can't be set, treat it as an error
and revert sysctl changes.
We enabled ip6tables by default in 27.0. Setting the filter-FORWARD
policy to DROP even when no IPv6 enabled network was created
caused issues for some users. In particular, those running with
iptables=false suddenly got the IPv6 DROP policy enabled (which
broke unrelated services on the host). This change solves that by
only setting the policy when necessary.
Signed-off-by: Rob Murray <rob.murray@docker.com>
A dual-stack endpoint still has priority when selecting a gateway
Endpoint for a Sandbox. But, now there are IPv6-only networks, it
is possible to have a Sandbox with only IPv4-only and IPv6-only
endpoints. This change means they are both gateway endpoints.
Tell the network driver it mustn't proxy host-IPv6 to endpoint-IPv4
when there's an IPv6 gateway endpoint (which may belong to a different
net driver). Update that when networks are connected/disconnected.
Signed-off-by: Rob Murray <rob.murray@docker.com>
When the host has IPv6 support but the container doesn't, the
default bind address is 0.0.0.0, and a port mapping does not
include a host address - the default behaviour (of the bridge
driver) is to run a docker-proxy to map from any IPv6 host
address to the IPv4 address of a container's gateway endpoint.
Driver option com.docker.network.driver.private.no_proxy_6to4
can now be used to disable that behaviour when configuring
a Sandbox's external connectivity.
Signed-off-by: Rob Murray <rob.murray@docker.com>
Call the respective (`etchosts.BuildNoIPv6` or `etchosts.Build`) functions
directly instead of using the intermediate `buildf` variable.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
The `mergeRecords` function wasn't actually _merging_ anything, but only
appended records to the existing `/etc/hosts` content. However, doing so
was split across two functions; `Add` and `mergeRecords()`;
- `Add()` obtains a lock for the given path
- then calls `mergeRecords` which reads the file-content and appends the
new records to the content.
- Closes the file and returns the new content
- Then `Add` does a `os.WriteFile` to ... the same file
Given that we're appending, we won't have to read the file's content, and
we can append to the file itself.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This regex is constructed using user-input, which could technically
produce an invalid regex.
Given that we have an error-return to our availability, let's return
any error we get, instead of panicking.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Also, libnetwork: Sandbox.buildHostsFile: rename var that shadowed type
Co-authored-by: Sebastiaan van Stijn <github@gone.nl>
Signed-off-by: Rob Murray <rob.murray@docker.com>
libnetwork/service_linux.go:226:7: shadow: declaration of "ep" shadows declaration at line 175 (govet)
if ep := sb.getGatewayEndpoint(); ep != nil {
^
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
libnetwork/bitmap/sequence_test.go:746:5: shadow: declaration of "o" shadows declaration at line 738 (govet)
if o, err := hnd.SetAnyInRange(0, uint64(blockLen), false); err == nil {
^
libnetwork/bitmap/sequence_test.go:750:5: shadow: declaration of "o" shadows declaration at line 738 (govet)
if o, err := hnd.SetAnyInRange(0, firstAv-1, false); err == nil {
^
libnetwork/bitmap/sequence_test.go:754:5: shadow: declaration of "o" shadows declaration at line 738 (govet)
if o, err := hnd.SetAnyInRange(111*uint64(blockLen), 161*uint64(blockLen), false); err == nil {
^
libnetwork/bitmap/sequence_test.go:793:6: shadow: declaration of "o" shadows declaration at line 738 (govet)
if o, err := hnd.SetAnyInRange(0, 7, false); err != nil {
^
libnetwork/bitmap/sequence_test.go:808:6: shadow: declaration of "o" shadows declaration at line 738 (govet)
if o, err := hnd.SetAnyInRange(8, 15, false); err != nil {
^
libnetwork/bitmap/sequence_test.go:824:6: shadow: declaration of "o" shadows declaration at line 738 (govet)
if o, err := hnd.SetAnyInRange(28, 29, false); err != nil {
^
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
looks like this was added in [libnetwork@be153a1], but not spotted.
libnetwork/endpoint_info.go:467:20: nilness: range of nil slice (govet)
for _, r := range tStaticRoute {
^
[libnetwork@be153a1]: be153a13e4
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Interface DNSBackend.ResolveName, implemented by Network,
Sandbox (and noopDNSBackend) had a bool return value that
meant 'ipv6Miss'.
But, it was always set to true on a hit, and callers had
to deal with that.
So, changed the meaning of the return value to indicate
whether the name was found - which will also work for
'ipv4Miss' when we have IPv6-only containers/networks.
Signed-off-by: Rob Murray <rob.murray@docker.com>
When a container doesn't support IPv6 and it's joined to an IPv6
network, don't allocate an IPv6 address for it.
Update the DNS resolver to understand that it can have an 'ipv6miss'
(meaning an IPv4 address exists, but no IPv6) when a network is
IPv6 enabled.
Signed-off-by: Rob Murray <rob.murray@docker.com>
If config for legacy links needs to be added to a libnetwork.Sandbox,
add it when constructing the Endpoint that needs it - removing the
constraint on ordering of Endpoint construction, and the dependency
between Endpoint and Sandbox construction.
So, now a Sandbox can be constructed in one place, before the first
Endpoint.
Signed-off-by: Rob Murray <rob.murray@docker.com>
Second attempt to stop using the OCI prestart hook to call SetKey
to set up the OS Sandbox's key and perform network config in the
new network namespace.
The first attempt was reverted because it made it impossible to
use --sysctl to set per-interface sysctls on an interface that had
not yet been moved into the new network namespace.
Now, per-interface sysctls can be used to do that (with less
ambiguity because the setting is not tied to the interface using
an unpredictably assigned name).
Signed-off-by: Rob Murray <rob.murray@docker.com>
It only removed the test host's libnet Bolt db file, and didn't
need to do that because the tests use a TempDir for it.
Signed-off-by: Rob Murray <rob.murray@docker.com>
In 27.x and earlier releases libnetwork's database file was in a
sub-directory "network/files" under the daemon's root data dir.
That part of the path got lost in commit ed08486ec7
So, libnet data ended up in the daemon's main Bolt db. Then, on
upgrade, config in the original file was no longer accessible.
libnet doesn't need access to any data outside its sub-dir, so
change the meaning of its OptionDataDir - it now points at libnet's
sub-dir, so the db will be created in the right place. Also, update
other uses of that data dir to match.
Signed-off-by: Rob Murray <rob.murray@docker.com>
Added in 26.1.0, commit 6c68be24a2
Default changed to true in 27.0.0, commit 33f9a5329a
No sign of problems so, remove.
Signed-off-by: Rob Murray <rob.murray@docker.com>