浏览代码

Check ipt options before looking for ip6t

iptables package has a function `detectIptables()` called to initialize
some local variables. Since v20.10.0, it first looks for iptables bin,
then ip6tables and finally it checks what iptables flags are available
(including -C). It early exits when ip6tables isn't available, and
doesn't execute the last check.

To remove port mappings (eg. when a container stops/dies), Docker
first checks if those NAT rules exist and then deletes them. However, in
the particular case where there's no ip6tables bin available, iptables
`-C` flag is considered unavailable and thus it looks for NAT rules by
using some substring matching. This substring matching then fails
because `iptables -t nat -S POSTROUTING` dumps rules in a slighly format
than what's expected.

For instance, here's what `iptables -t nat -S POSTROUTING` dumps:

```
-A POSTROUTING -s 172.18.0.2/32 -d 172.18.0.2/32 -p tcp -m tcp --dport 9999 -j MASQUERADE
```

And here's what Docker looks for:

```
POSTROUTING -p tcp -s 172.18.0.2 -d 172.18.0.2 --dport 9999 -j MASQUERADE
```

Because of that, those rules are considered non-existant by Docker and
thus never deleted. To fix that, this change reorders the code in
`detectIptables()`.

Fixes #42127.

Signed-off-by: Albin Kerouanton <albinker@gmail.com>
Albin Kerouanton 3 年之前
父节点
当前提交
af7236f85a
共有 1 个文件被更改,包括 8 次插入5 次删除
  1. 8 5
      libnetwork/iptables/iptables.go

+ 8 - 5
libnetwork/iptables/iptables.go

@@ -116,11 +116,7 @@ func detectIptables() {
 		return
 	}
 	iptablesPath = path
-	path, err = exec.LookPath("ip6tables")
-	if err != nil {
-		return
-	}
-	ip6tablesPath = path
+
 	supportsXlock = exec.Command(iptablesPath, "--wait", "-L", "-n").Run() == nil
 	mj, mn, mc, err := GetVersion()
 	if err != nil {
@@ -128,6 +124,13 @@ func detectIptables() {
 		return
 	}
 	supportsCOpt = supportsCOption(mj, mn, mc)
+
+	path, err = exec.LookPath("ip6tables")
+	if err != nil {
+		return
+	} else {
+		ip6tablesPath = path
+	}
 }
 
 func initDependencies() {