Browse code

vendor: docker/libnetwork b3507428be5b458cb0e2b4086b13531fb0706e46

full diff: https://github.com/docker/libnetwork/compare/fa125a3512ee0f6187721c88582bf8c4378bd4d7...b3507428be5b458cb0e2b4086b13531fb0706e46

- fixed IPv6 iptables rules for enabled firewalld (libnetwork#2609)
- fixes "Docker uses 'iptables' instead of 'ip6tables' for IPv6 NAT rule, crashes"
- Fix regression in docker-proxy
- introduced in "Fix IPv6 Port Forwarding for the Bridge Driver" (libnetwork#2604)
- fixes/addresses: "IPv4 and IPv6 addresses are not bound by default anymore" (libnetwork#2607)
- fixes/addresses "IPv6 is no longer proxied by default anymore" (moby#41858)
- Use hostIP to decide on Portmapper version
- fixes docker-proxy not being stopped correctly

Port mapping of containers now contain separatet mappings for IPv4 and IPv6 addresses, when
listening on "any" IP address. Various tests had to be updated to take multiple mappings into
account.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 045072826763e4f66dae721675761e00101867fa)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>

Sebastiaan van Stijn authored on 2021/01/21 01:48:05
Showing 5 changed files
... ...
@@ -3,7 +3,7 @@
3 3
 # LIBNETWORK_COMMIT is used to build the docker-userland-proxy binary. When
4 4
 # updating the binary version, consider updating github.com/docker/libnetwork
5 5
 # in vendor.conf accordingly
6
-: "${LIBNETWORK_COMMIT:=fa125a3512ee0f6187721c88582bf8c4378bd4d7}"
6
+: "${LIBNETWORK_COMMIT:=b3507428be5b458cb0e2b4086b13531fb0706e46}"
7 7
 
8 8
 install_proxy() {
9 9
 	case "$1" in
... ...
@@ -20,13 +20,13 @@ func (s *DockerSuite) TestPortList(c *testing.T) {
20 20
 
21 21
 	out, _ = dockerCmd(c, "port", firstID, "80")
22 22
 
23
-	err := assertPortList(c, out, []string{"0.0.0.0:9876"})
23
+	err := assertPortList(c, out, []string{"0.0.0.0:9876", "[::]:9876"})
24 24
 	// Port list is not correct
25 25
 	assert.NilError(c, err)
26 26
 
27 27
 	out, _ = dockerCmd(c, "port", firstID)
28 28
 
29
-	err = assertPortList(c, out, []string{"80/tcp -> 0.0.0.0:9876"})
29
+	err = assertPortList(c, out, []string{"80/tcp -> 0.0.0.0:9876", "80/tcp -> [::]:9876"})
30 30
 	// Port list is not correct
31 31
 	assert.NilError(c, err)
32 32
 
... ...
@@ -42,7 +42,7 @@ func (s *DockerSuite) TestPortList(c *testing.T) {
42 42
 
43 43
 	out, _ = dockerCmd(c, "port", ID, "80")
44 44
 
45
-	err = assertPortList(c, out, []string{"0.0.0.0:9876"})
45
+	err = assertPortList(c, out, []string{"0.0.0.0:9876", "[::]:9876"})
46 46
 	// Port list is not correct
47 47
 	assert.NilError(c, err)
48 48
 
... ...
@@ -50,8 +50,11 @@ func (s *DockerSuite) TestPortList(c *testing.T) {
50 50
 
51 51
 	err = assertPortList(c, out, []string{
52 52
 		"80/tcp -> 0.0.0.0:9876",
53
+		"80/tcp -> [::]:9876",
53 54
 		"81/tcp -> 0.0.0.0:9877",
55
+		"81/tcp -> [::]:9877",
54 56
 		"82/tcp -> 0.0.0.0:9878",
57
+		"82/tcp -> [::]:9878",
55 58
 	})
56 59
 	// Port list is not correct
57 60
 	assert.NilError(c, err)
... ...
@@ -69,7 +72,7 @@ func (s *DockerSuite) TestPortList(c *testing.T) {
69 69
 
70 70
 	out, _ = dockerCmd(c, "port", ID, "80")
71 71
 
72
-	err = assertPortList(c, out, []string{"0.0.0.0:9876", "0.0.0.0:9999"})
72
+	err = assertPortList(c, out, []string{"0.0.0.0:9876", "[::]:9876", "0.0.0.0:9999", "[::]:9999"})
73 73
 	// Port list is not correct
74 74
 	assert.NilError(c, err)
75 75
 
... ...
@@ -78,8 +81,12 @@ func (s *DockerSuite) TestPortList(c *testing.T) {
78 78
 	err = assertPortList(c, out, []string{
79 79
 		"80/tcp -> 0.0.0.0:9876",
80 80
 		"80/tcp -> 0.0.0.0:9999",
81
+		"80/tcp -> [::]:9876",
82
+		"80/tcp -> [::]:9999",
81 83
 		"81/tcp -> 0.0.0.0:9877",
84
+		"81/tcp -> [::]:9877",
82 85
 		"82/tcp -> 0.0.0.0:9878",
86
+		"82/tcp -> [::]:9878",
83 87
 	})
84 88
 	// Port list is not correct
85 89
 	assert.NilError(c, err)
... ...
@@ -94,7 +101,10 @@ func (s *DockerSuite) TestPortList(c *testing.T) {
94 94
 
95 95
 			out, _ = dockerCmd(c, "port", IDs[i])
96 96
 
97
-			err = assertPortList(c, out, []string{fmt.Sprintf("80/tcp -> 0.0.0.0:%d", 9090+i)})
97
+			err = assertPortList(c, out, []string{
98
+				fmt.Sprintf("80/tcp -> 0.0.0.0:%d", 9090+i),
99
+				fmt.Sprintf("80/tcp -> [::]:%d", 9090+i),
100
+			})
98 101
 			// Port list is not correct
99 102
 			assert.NilError(c, err)
100 103
 		}
... ...
@@ -127,9 +137,13 @@ func (s *DockerSuite) TestPortList(c *testing.T) {
127 127
 
128 128
 	err = assertPortList(c, out, []string{
129 129
 		"80/tcp -> 0.0.0.0:9800",
130
+		"80/tcp -> [::]:9800",
130 131
 		"81/tcp -> 0.0.0.0:9801",
132
+		"81/tcp -> [::]:9801",
131 133
 		"82/tcp -> 0.0.0.0:9802",
134
+		"82/tcp -> [::]:9802",
132 135
 		"83/tcp -> 0.0.0.0:9803",
136
+		"83/tcp -> [::]:9803",
133 137
 	})
134 138
 	// Port list is not correct
135 139
 	assert.NilError(c, err)
... ...
@@ -305,7 +319,7 @@ func (s *DockerSuite) TestPortHostBinding(c *testing.T) {
305 305
 
306 306
 	out, _ = dockerCmd(c, "port", firstID, "80")
307 307
 
308
-	err := assertPortList(c, out, []string{"0.0.0.0:9876"})
308
+	err := assertPortList(c, out, []string{"0.0.0.0:9876", "[::]:9876"})
309 309
 	// Port list is not correct
310 310
 	assert.NilError(c, err)
311 311
 
... ...
@@ -47,7 +47,7 @@ github.com/grpc-ecosystem/go-grpc-middleware        3c51f7f332123e8be5a157c0802a
47 47
 # libnetwork
48 48
 
49 49
 # When updating, also update LIBNETWORK_COMMIT in hack/dockerfile/install/proxy.installer accordingly
50
-github.com/docker/libnetwork                        fa125a3512ee0f6187721c88582bf8c4378bd4d7 
50
+github.com/docker/libnetwork                        b3507428be5b458cb0e2b4086b13531fb0706e46
51 51
 github.com/docker/go-events                         e31b211e4f1cd09aa76fe4ac244571fab96ae47f
52 52
 github.com/armon/go-radix                           e39d623f12e8e41c7b5529e9a9dd67a1e2261f80
53 53
 github.com/armon/go-metrics                         eb0af217e5e9747e41dd5303755356b62d28e3ec
... ...
@@ -49,8 +49,16 @@ func (n *bridgeNetwork) allocatePortsInternal(bindings []types.PortBinding, cont
49 49
 			}
50 50
 			bs = append(bs, bIPv4)
51 51
 		}
52
+
52 53
 		// Allocate IPv6 Port mappings
53
-		if ok := n.validatePortBindingIPv6(&bIPv6, containerIPv6, defHostIP); ok {
54
+		// If the container has no IPv6 address, allow proxying host IPv6 traffic to it
55
+		// by setting up the binding with the IPv4 interface if the userland proxy is enabled
56
+		// This change was added to keep backward compatibility
57
+		containerIP := containerIPv6
58
+		if ulPxyEnabled && (containerIPv6 == nil) {
59
+			containerIP = containerIPv4
60
+		}
61
+		if ok := n.validatePortBindingIPv6(&bIPv6, containerIP, defHostIP); ok {
54 62
 			if err := n.allocatePort(&bIPv6, ulPxyEnabled); err != nil {
55 63
 				// On allocation failure, release previously allocated ports. On cleanup error, just log a warning message
56 64
 				if cuErr := n.releasePortsInternal(bs); cuErr != nil {
... ...
@@ -67,7 +75,7 @@ func (n *bridgeNetwork) allocatePortsInternal(bindings []types.PortBinding, cont
67 67
 // validatePortBindingIPv4 validates the port binding, populates the missing Host IP field and returns true
68 68
 // if this is a valid IPv4 binding, else returns false
69 69
 func (n *bridgeNetwork) validatePortBindingIPv4(bnd *types.PortBinding, containerIPv4, defHostIP net.IP) bool {
70
-	//Return early if there is a valid Host IP, but its not a IPv6 address
70
+	//Return early if there is a valid Host IP, but its not a IPv4 address
71 71
 	if len(bnd.HostIP) > 0 && bnd.HostIP.To4() == nil {
72 72
 		return false
73 73
 	}
... ...
@@ -85,10 +93,10 @@ func (n *bridgeNetwork) validatePortBindingIPv4(bnd *types.PortBinding, containe
85 85
 }
86 86
 
87 87
 // validatePortBindingIPv6 validates the port binding, populates the missing Host IP field and returns true
88
-// if this is a valid IP6v binding, else returns false
89
-func (n *bridgeNetwork) validatePortBindingIPv6(bnd *types.PortBinding, containerIPv6, defHostIP net.IP) bool {
90
-	// Return early if there is no IPv6 container endpoint
91
-	if containerIPv6 == nil {
88
+// if this is a valid IPv6 binding, else returns false
89
+func (n *bridgeNetwork) validatePortBindingIPv6(bnd *types.PortBinding, containerIP, defHostIP net.IP) bool {
90
+	// Return early if there is no container endpoint
91
+	if containerIP == nil {
92 92
 		return false
93 93
 	}
94 94
 	// Return early if there is a valid Host IP, which is a IPv4 address
... ...
@@ -108,9 +116,8 @@ func (n *bridgeNetwork) validatePortBindingIPv6(bnd *types.PortBinding, containe
108 108
 			return false
109 109
 		}
110 110
 	}
111
-	bnd.IP = containerIPv6
111
+	bnd.IP = containerIP
112 112
 	return true
113
-
114 113
 }
115 114
 
116 115
 func (n *bridgeNetwork) allocatePort(bnd *types.PortBinding, ulPxyEnabled bool) error {
... ...
@@ -132,7 +139,7 @@ func (n *bridgeNetwork) allocatePort(bnd *types.PortBinding, ulPxyEnabled bool)
132 132
 
133 133
 	portmapper := n.portMapper
134 134
 
135
-	if bnd.IP.To4() == nil {
135
+	if bnd.HostIP.To4() == nil {
136 136
 		portmapper = n.portMapperV6
137 137
 	}
138 138
 
... ...
@@ -512,8 +512,14 @@ func filterOutput(start time.Time, output []byte, args ...string) []byte {
512 512
 // Raw calls 'iptables' system command, passing supplied arguments.
513 513
 func (iptable IPTable) Raw(args ...string) ([]byte, error) {
514 514
 	if firewalldRunning {
515
+		// select correct IP version for firewalld
516
+		ipv := Iptables
517
+		if iptable.Version == IPv6 {
518
+			ipv = IP6Tables
519
+		}
520
+
515 521
 		startTime := time.Now()
516
-		output, err := Passthrough(Iptables, args...)
522
+		output, err := Passthrough(ipv, args...)
517 523
 		if err == nil || !strings.Contains(err.Error(), "was not provided by any .service files") {
518 524
 			return filterOutput(startTime, output, args...), err
519 525
 		}