Skip to content

Commit

Permalink
package/docker-engine: fix port forwarding for hosts without IPv6
Browse files Browse the repository at this point in the history
docker-engine 20.10.6 broke container port forwarding for hosts without IPv6
support:

docker: Error response from daemon: driver failed programming external
connectivity on endpoint naughty_moore
(038e9ed4b5ea77e1c52462d6d04ad001fbad9beb185a6511aadc217c8a271608): Error
starting userland proxy: listen tcp6 [::]:80: socket: address family not
supported by protocol.

Add a libnetwork patch from an upstream pull request to fix this, after
adjusting the patch to apply to docker-engine (which has libnetwork vendored
under vendor/github.com/docker/libnetwork):

- moby/libnetwork#2635,
- moby/moby#42322

Signed-off-by: Peter Korsgaard <[email protected]>
  • Loading branch information
jacmet committed May 14, 2021
1 parent 6ad1c7f commit 2fd3390
Showing 1 changed file with 74 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
From 7b9c2905883df5171fda10a364a81b8c6176c8e2 Mon Sep 17 00:00:00 2001
From: Akihiro Suda <[email protected]>
Date: Mon, 26 Apr 2021 15:28:40 +0900
Subject: [PATCH] fix port forwarding with ipv6.disable=1

Make `docker run -p 80:80` functional again on environments with kernel boot parameter `ipv6.disable=1`.

Fix moby/moby issue 42288

Signed-off-by: Akihiro Suda <[email protected]>
[Upstream: https://github.com/moby/libnetwork/pull/2635,
https://github.com/moby/moby/pull/42322]
[Rework path/drop test for docker-engine]
Signed-off-by: Peter Korsgaard <[email protected]>
---
vendor/github.com/docker/libnetwork/drivers/bridge/port_mapping.go | 31 +++++++++++++++++++++++++++++++
1 file changed, 35 insertions(+), 0 deletion(-)

diff --git a/vendor/github.com/docker/libnetwork/drivers/bridge/port_mapping.go b/vendor/github.com/docker/libnetwork/drivers/bridge/port_mapping.go
index 946130ec..17bf36f9 100644
--- a/vendor/github.com/docker/libnetwork/drivers/bridge/port_mapping.go
+++ b/vendor/github.com/docker/libnetwork/drivers/bridge/port_mapping.go
@@ -5,6 +5,7 @@ import (
"errors"
"fmt"
"net"
+ "sync"

"github.com/docker/libnetwork/types"
"github.com/ishidawataru/sctp"
@@ -50,6 +51,13 @@ func (n *bridgeNetwork) allocatePortsInternal(bindings []types.PortBinding, cont
bs = append(bs, bIPv4)
}

+ // skip adding implicit v6 addr, when the kernel was booted with `ipv6.disable=1`
+ // https://github.com/moby/moby/issues/42288
+ isV6Binding := c.HostIP != nil && c.HostIP.To4() == nil
+ if !isV6Binding && !IsV6Listenable() {
+ continue
+ }
+
// Allocate IPv6 Port mappings
// If the container has no IPv6 address, allow proxying host IPv6 traffic to it
// by setting up the binding with the IPv4 interface if the userland proxy is enabled
@@ -211,3 +219,26 @@ func (n *bridgeNetwork) releasePort(bnd types.PortBinding) error {

return portmapper.Unmap(host)
}
+
+var (
+ v6ListenableCached bool
+ v6ListenableOnce sync.Once
+)
+
+// IsV6Listenable returns true when `[::1]:0` is listenable.
+// IsV6Listenable returns false mostly when the kernel was booted with `ipv6.disable=1` option.
+func IsV6Listenable() bool {
+ v6ListenableOnce.Do(func() {
+ ln, err := net.Listen("tcp6", "[::1]:0")
+ if err != nil {
+ // When the kernel was booted with `ipv6.disable=1`,
+ // we get err "listen tcp6 [::1]:0: socket: address family not supported by protocol"
+ // https://github.com/moby/moby/issues/42288
+ logrus.Debugf("port_mapping: v6Listenable=false (%v)", err)
+ } else {
+ v6ListenableCached = true
+ ln.Close()
+ }
+ })
+ return v6ListenableCached
+}
--
2.20.1

0 comments on commit 2fd3390

Please sign in to comment.