summaryrefslogtreecommitdiff
path: root/libnetwork/service_linux.go
diff options
context:
space:
mode:
authorBilly Ridgway <wrridgwa@us.ibm.com>2017-11-28 15:15:55 -0600
committerBenjamin Böhmke <benjamin@boehmke.net>2020-07-19 16:16:51 +0200
commit8dbb5b5a7d42f55cd112048dc579868793179660 (patch)
treeaa1450ab1b7ea5a2f17642d58d9d79f31900445b /libnetwork/service_linux.go
parentc37654e9d3a601a7ed30fa5158bd45f8944ba41c (diff)
downloaddocker-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.go70
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)
}