diff options
author | Billy Ridgway <wrridgwa@us.ibm.com> | 2017-11-28 15:15:55 -0600 |
---|---|---|
committer | Benjamin Böhmke <benjamin@boehmke.net> | 2020-07-19 16:16:51 +0200 |
commit | 8dbb5b5a7d42f55cd112048dc579868793179660 (patch) | |
tree | aa1450ab1b7ea5a2f17642d58d9d79f31900445b /libnetwork/service_linux.go | |
parent | c37654e9d3a601a7ed30fa5158bd45f8944ba41c (diff) | |
download | docker-8dbb5b5a7d42f55cd112048dc579868793179660.tar.gz |
Implement NAT IPv6 to fix the issue https://github.com/moby/moby/issues/25407
Signed-off-by: Billy Ridgway <wrridgwa@us.ibm.com>
Signed-off-by: Benjamin Böhmke <benjamin@boehmke.net>
Diffstat (limited to 'libnetwork/service_linux.go')
-rw-r--r-- | libnetwork/service_linux.go | 70 |
1 files changed, 38 insertions, 32 deletions
diff --git a/libnetwork/service_linux.go b/libnetwork/service_linux.go index 02ea8ff6bc..bb94141c0c 100644 --- a/libnetwork/service_linux.go +++ b/libnetwork/service_linux.go @@ -302,6 +302,9 @@ func filterPortConfigs(ingressPorts []*PortConfig, isDelete bool) []*PortConfig } func programIngress(gwIP net.IP, ingressPorts []*PortConfig, isDelete bool) error { + + iptable := iptables.GetIptable(iptables.IPv4) + addDelOpt := "-I" rollbackAddDelOpt := "-D" if isDelete { @@ -312,19 +315,19 @@ func programIngress(gwIP net.IP, ingressPorts []*PortConfig, isDelete bool) erro ingressMu.Lock() defer ingressMu.Unlock() - chainExists := iptables.ExistChain(ingressChain, iptables.Nat) - filterChainExists := iptables.ExistChain(ingressChain, iptables.Filter) + chainExists := iptable.ExistChain(ingressChain, iptables.Nat) + filterChainExists := iptable.ExistChain(ingressChain, iptables.Filter) ingressOnce.Do(func() { // Flush nat table and filter table ingress chain rules during init if it // exists. It might contain stale rules from previous life. if chainExists { - if err := iptables.RawCombinedOutput("-t", "nat", "-F", ingressChain); err != nil { + if err := iptable.RawCombinedOutput("-t", "nat", "-F", ingressChain); err != nil { logrus.Errorf("Could not flush nat table ingress chain rules during init: %v", err) } } if filterChainExists { - if err := iptables.RawCombinedOutput("-F", ingressChain); err != nil { + if err := iptable.RawCombinedOutput("-F", ingressChain); err != nil { logrus.Errorf("Could not flush filter table ingress chain rules during init: %v", err) } } @@ -332,38 +335,38 @@ func programIngress(gwIP net.IP, ingressPorts []*PortConfig, isDelete bool) erro if !isDelete { if !chainExists { - if err := iptables.RawCombinedOutput("-t", "nat", "-N", ingressChain); err != nil { + if err := iptable.RawCombinedOutput("-t", "nat", "-N", ingressChain); err != nil { return fmt.Errorf("failed to create ingress chain: %v", err) } } if !filterChainExists { - if err := iptables.RawCombinedOutput("-N", ingressChain); err != nil { + if err := iptable.RawCombinedOutput("-N", ingressChain); err != nil { return fmt.Errorf("failed to create filter table ingress chain: %v", err) } } - if !iptables.Exists(iptables.Nat, ingressChain, "-j", "RETURN") { - if err := iptables.RawCombinedOutput("-t", "nat", "-A", ingressChain, "-j", "RETURN"); err != nil { + if !iptable.Exists(iptables.Nat, ingressChain, "-j", "RETURN") { + if err := iptable.RawCombinedOutput("-t", "nat", "-A", ingressChain, "-j", "RETURN"); err != nil { return fmt.Errorf("failed to add return rule in nat table ingress chain: %v", err) } } - if !iptables.Exists(iptables.Filter, ingressChain, "-j", "RETURN") { - if err := iptables.RawCombinedOutput("-A", ingressChain, "-j", "RETURN"); err != nil { + if !iptable.Exists(iptables.Filter, ingressChain, "-j", "RETURN") { + if err := iptable.RawCombinedOutput("-A", ingressChain, "-j", "RETURN"); err != nil { return fmt.Errorf("failed to add return rule to filter table ingress chain: %v", err) } } for _, chain := range []string{"OUTPUT", "PREROUTING"} { - if !iptables.Exists(iptables.Nat, chain, "-m", "addrtype", "--dst-type", "LOCAL", "-j", ingressChain) { - if err := iptables.RawCombinedOutput("-t", "nat", "-I", chain, "-m", "addrtype", "--dst-type", "LOCAL", "-j", ingressChain); err != nil { + if !iptable.Exists(iptables.Nat, chain, "-m", "addrtype", "--dst-type", "LOCAL", "-j", ingressChain) { + if err := iptable.RawCombinedOutput("-t", "nat", "-I", chain, "-m", "addrtype", "--dst-type", "LOCAL", "-j", ingressChain); err != nil { return fmt.Errorf("failed to add jump rule in %s to ingress chain: %v", chain, err) } } } - if !iptables.Exists(iptables.Filter, "FORWARD", "-j", ingressChain) { - if err := iptables.RawCombinedOutput("-I", "FORWARD", "-j", ingressChain); err != nil { + if !iptable.Exists(iptables.Filter, "FORWARD", "-j", ingressChain) { + if err := iptable.RawCombinedOutput("-I", "FORWARD", "-j", ingressChain); err != nil { return fmt.Errorf("failed to add jump rule to %s in filter table forward chain: %v", ingressChain, err) } arrangeUserFilterRule() @@ -380,8 +383,8 @@ func programIngress(gwIP net.IP, ingressPorts []*PortConfig, isDelete bool) erro } ruleArgs := strings.Fields(fmt.Sprintf("-m addrtype --src-type LOCAL -o %s -j MASQUERADE", oifName)) - if !iptables.Exists(iptables.Nat, "POSTROUTING", ruleArgs...) { - if err := iptables.RawCombinedOutput(append([]string{"-t", "nat", "-I", "POSTROUTING"}, ruleArgs...)...); err != nil { + if !iptable.Exists(iptables.Nat, "POSTROUTING", ruleArgs...) { + if err := iptable.RawCombinedOutput(append([]string{"-t", "nat", "-I", "POSTROUTING"}, ruleArgs...)...); err != nil { return fmt.Errorf("failed to add ingress localhost POSTROUTING rule for %s: %v", oifName, err) } } @@ -395,7 +398,7 @@ func programIngress(gwIP net.IP, ingressPorts []*PortConfig, isDelete bool) erro if portErr != nil && !isDelete { filterPortConfigs(filteredPorts, !isDelete) for _, rule := range rollbackRules { - if err := iptables.RawCombinedOutput(rule...); err != nil { + if err := iptable.RawCombinedOutput(rule...); err != nil { logrus.Warnf("roll back rule failed, %v: %v", rule, err) } } @@ -403,10 +406,10 @@ func programIngress(gwIP net.IP, ingressPorts []*PortConfig, isDelete bool) erro }() for _, iPort := range filteredPorts { - if iptables.ExistChain(ingressChain, iptables.Nat) { + if iptable.ExistChain(ingressChain, iptables.Nat) { rule := strings.Fields(fmt.Sprintf("-t nat %s %s -p %s --dport %d -j DNAT --to-destination %s:%d", addDelOpt, ingressChain, strings.ToLower(PortConfig_Protocol_name[int32(iPort.Protocol)]), iPort.PublishedPort, gwIP, iPort.PublishedPort)) - if portErr = iptables.RawCombinedOutput(rule...); portErr != nil { + if portErr = iptable.RawCombinedOutput(rule...); portErr != nil { errStr := fmt.Sprintf("set up rule failed, %v: %v", rule, portErr) if !isDelete { return fmt.Errorf("%s", errStr) @@ -423,7 +426,7 @@ func programIngress(gwIP net.IP, ingressPorts []*PortConfig, isDelete bool) erro // 2) unmanaged containers on bridge networks rule := strings.Fields(fmt.Sprintf("%s %s -m state -p %s --sport %d --state ESTABLISHED,RELATED -j ACCEPT", addDelOpt, ingressChain, strings.ToLower(PortConfig_Protocol_name[int32(iPort.Protocol)]), iPort.PublishedPort)) - if portErr = iptables.RawCombinedOutput(rule...); portErr != nil { + if portErr = iptable.RawCombinedOutput(rule...); portErr != nil { errStr := fmt.Sprintf("set up rule failed, %v: %v", rule, portErr) if !isDelete { return fmt.Errorf("%s", errStr) @@ -436,7 +439,7 @@ func programIngress(gwIP net.IP, ingressPorts []*PortConfig, isDelete bool) erro rule = strings.Fields(fmt.Sprintf("%s %s -p %s --dport %d -j ACCEPT", addDelOpt, ingressChain, strings.ToLower(PortConfig_Protocol_name[int32(iPort.Protocol)]), iPort.PublishedPort)) - if portErr = iptables.RawCombinedOutput(rule...); portErr != nil { + if portErr = iptable.RawCombinedOutput(rule...); portErr != nil { errStr := fmt.Sprintf("set up rule failed, %v: %v", rule, portErr) if !isDelete { return fmt.Errorf("%s", errStr) @@ -461,13 +464,14 @@ func programIngress(gwIP net.IP, ingressPorts []*PortConfig, isDelete bool) erro // This chain has the rules to allow access to the published ports for swarm tasks // from local bridge networks and docker_gwbridge (ie:taks on other swarm networks) func arrangeIngressFilterRule() { - if iptables.ExistChain(ingressChain, iptables.Filter) { - if iptables.Exists(iptables.Filter, "FORWARD", "-j", ingressChain) { - if err := iptables.RawCombinedOutput("-D", "FORWARD", "-j", ingressChain); err != nil { + iptable := iptables.GetIptable(iptables.IPv4) + if iptable.ExistChain(ingressChain, iptables.Filter) { + if iptable.Exists(iptables.Filter, "FORWARD", "-j", ingressChain) { + if err := iptable.RawCombinedOutput("-D", "FORWARD", "-j", ingressChain); err != nil { logrus.Warnf("failed to delete jump rule to ingressChain in filter table: %v", err) } } - if err := iptables.RawCombinedOutput("-I", "FORWARD", "-j", ingressChain); err != nil { + if err := iptable.RawCombinedOutput("-I", "FORWARD", "-j", ingressChain); err != nil { logrus.Warnf("failed to add jump rule to ingressChain in filter table: %v", err) } } @@ -606,6 +610,7 @@ func invokeFWMarker(path string, vip net.IP, fwMark uint32, ingressPorts []*Port // Firewall marker reexec function. func fwMarker() { + iptable := iptables.GetIptable(iptables.IPv4) runtime.LockOSThread() defer runtime.UnlockOSThread() @@ -660,7 +665,7 @@ func fwMarker() { } ruleParams := strings.Fields(fmt.Sprintf("-m ipvs --ipvs -d %s -j SNAT --to-source %s", subnet, eIP)) - if !iptables.Exists("nat", "POSTROUTING", ruleParams...) { + if !iptable.Exists("nat", "POSTROUTING", ruleParams...) { rule := append(strings.Fields("-t nat -A POSTROUTING"), ruleParams...) rules = append(rules, rule) @@ -676,7 +681,7 @@ func fwMarker() { rules = append(rules, rule) for _, rule := range rules { - if err := iptables.RawCombinedOutputNative(rule...); err != nil { + if err := iptable.RawCombinedOutputNative(rule...); err != nil { logrus.Errorf("set up rule failed, %v: %v", rule, err) os.Exit(8) } @@ -711,6 +716,7 @@ func addRedirectRules(path string, eIP *net.IPNet, ingressPorts []*PortConfig) e // Redirector reexec function. func redirector() { + iptable := iptables.GetIptable(iptables.IPv4) runtime.LockOSThread() defer runtime.UnlockOSThread() @@ -763,7 +769,7 @@ func redirector() { } for _, rule := range rules { - if err := iptables.RawCombinedOutputNative(rule...); err != nil { + if err := iptable.RawCombinedOutputNative(rule...); err != nil { logrus.Errorf("set up rule failed, %v: %v", rule, err) os.Exit(6) } @@ -779,15 +785,15 @@ func redirector() { {"-d", eIP.String(), "-p", "udp", "-j", "DROP"}, {"-d", eIP.String(), "-p", "tcp", "-j", "DROP"}, } { - if !iptables.ExistsNative(iptables.Filter, "INPUT", rule...) { - if err := iptables.RawCombinedOutputNative(append([]string{"-A", "INPUT"}, rule...)...); err != nil { + if !iptable.ExistsNative(iptables.Filter, "INPUT", rule...) { + if err := iptable.RawCombinedOutputNative(append([]string{"-A", "INPUT"}, rule...)...); err != nil { logrus.Errorf("set up rule failed, %v: %v", rule, err) os.Exit(7) } } rule[0] = "-s" - if !iptables.ExistsNative(iptables.Filter, "OUTPUT", rule...) { - if err := iptables.RawCombinedOutputNative(append([]string{"-A", "OUTPUT"}, rule...)...); err != nil { + if !iptable.ExistsNative(iptables.Filter, "OUTPUT", rule...) { + if err := iptable.RawCombinedOutputNative(append([]string{"-A", "OUTPUT"}, rule...)...); err != nil { logrus.Errorf("set up rule failed, %v: %v", rule, err) os.Exit(8) } |