ソースを参照

Merge pull request #1485 from aboch/ipe

Check for presence before installing forward rules
Santhosh Manohar 8 年 前
コミット
ab217f0ea9
1 ファイル変更30 行追加25 行削除
  1. 30 25
      libnetwork/iptables/iptables.go

+ 30 - 25
libnetwork/iptables/iptables.go

@@ -206,7 +206,8 @@ func (c *ChainInfo) Forward(action Action, ip net.IP, port int, proto, destAddr
 		// value" by both iptables and ip6tables.
 		// value" by both iptables and ip6tables.
 		daddr = "0/0"
 		daddr = "0/0"
 	}
 	}
-	args := []string{"-t", string(Nat), string(action), c.Name,
+
+	args := []string{
 		"-p", proto,
 		"-p", proto,
 		"-d", daddr,
 		"-d", daddr,
 		"--dport", strconv.Itoa(port),
 		"--dport", strconv.Itoa(port),
@@ -215,33 +216,31 @@ func (c *ChainInfo) Forward(action Action, ip net.IP, port int, proto, destAddr
 	if !c.HairpinMode {
 	if !c.HairpinMode {
 		args = append(args, "!", "-i", bridgeName)
 		args = append(args, "!", "-i", bridgeName)
 	}
 	}
-	if output, err := Raw(args...); err != nil {
+	if err := ProgramRule(Nat, c.Name, action, args); err != nil {
 		return err
 		return err
-	} else if len(output) != 0 {
-		return ChainError{Chain: "FORWARD", Output: output}
 	}
 	}
 
 
-	if output, err := Raw("-t", string(Filter), string(action), c.Name,
+	args = []string{
 		"!", "-i", bridgeName,
 		"!", "-i", bridgeName,
 		"-o", bridgeName,
 		"-o", bridgeName,
 		"-p", proto,
 		"-p", proto,
 		"-d", destAddr,
 		"-d", destAddr,
 		"--dport", strconv.Itoa(destPort),
 		"--dport", strconv.Itoa(destPort),
-		"-j", "ACCEPT"); err != nil {
+		"-j", "ACCEPT",
+	}
+	if err := ProgramRule(Filter, c.Name, action, args); err != nil {
 		return err
 		return err
-	} else if len(output) != 0 {
-		return ChainError{Chain: "FORWARD", Output: output}
 	}
 	}
 
 
-	if output, err := Raw("-t", string(Nat), string(action), "POSTROUTING",
+	args = []string{
 		"-p", proto,
 		"-p", proto,
 		"-s", destAddr,
 		"-s", destAddr,
 		"-d", destAddr,
 		"-d", destAddr,
 		"--dport", strconv.Itoa(destPort),
 		"--dport", strconv.Itoa(destPort),
-		"-j", "MASQUERADE"); err != nil {
+		"-j", "MASQUERADE",
+	}
+	if err := ProgramRule(Nat, "POSTROUTING", action, args); err != nil {
 		return err
 		return err
-	} else if len(output) != 0 {
-		return ChainError{Chain: "FORWARD", Output: output}
 	}
 	}
 
 
 	return nil
 	return nil
@@ -250,31 +249,37 @@ func (c *ChainInfo) Forward(action Action, ip net.IP, port int, proto, destAddr
 // Link adds reciprocal ACCEPT rule for two supplied IP addresses.
 // Link adds reciprocal ACCEPT rule for two supplied IP addresses.
 // Traffic is allowed from ip1 to ip2 and vice-versa
 // Traffic is allowed from ip1 to ip2 and vice-versa
 func (c *ChainInfo) Link(action Action, ip1, ip2 net.IP, port int, proto string, bridgeName string) error {
 func (c *ChainInfo) Link(action Action, ip1, ip2 net.IP, port int, proto string, bridgeName string) error {
-	if output, err := Raw("-t", string(Filter), string(action), c.Name,
+	// forward
+	args := []string{
 		"-i", bridgeName, "-o", bridgeName,
 		"-i", bridgeName, "-o", bridgeName,
 		"-p", proto,
 		"-p", proto,
 		"-s", ip1.String(),
 		"-s", ip1.String(),
 		"-d", ip2.String(),
 		"-d", ip2.String(),
 		"--dport", strconv.Itoa(port),
 		"--dport", strconv.Itoa(port),
-		"-j", "ACCEPT"); err != nil {
+		"-j", "ACCEPT",
+	}
+	if err := ProgramRule(Filter, c.Name, action, args); err != nil {
 		return err
 		return err
-	} else if len(output) != 0 {
-		return fmt.Errorf("Error iptables forward: %s", output)
 	}
 	}
-	if output, err := Raw("-t", string(Filter), string(action), c.Name,
-		"-i", bridgeName, "-o", bridgeName,
-		"-p", proto,
-		"-s", ip2.String(),
-		"-d", ip1.String(),
-		"--sport", strconv.Itoa(port),
-		"-j", "ACCEPT"); err != nil {
+	// reverse
+	args[7], args[9] = args[9], args[7]
+	args[10] = "--sport"
+	if err := ProgramRule(Filter, c.Name, action, args); err != nil {
 		return err
 		return err
-	} else if len(output) != 0 {
-		return fmt.Errorf("Error iptables forward: %s", output)
 	}
 	}
 	return nil
 	return nil
 }
 }
 
 
+// ProgramRule adds the rule specified by args only if the
+// rule is not already present in the chain. Reciprocally,
+// it removes the rule only if present.
+func ProgramRule(table Table, chain string, action Action, args []string) error {
+	if Exists(table, chain, args...) != (action == Delete) {
+		return nil
+	}
+	return RawCombinedOutput(append([]string{"-t", string(table), string(action), chain}, args...)...)
+}
+
 // Prerouting adds linking rule to nat/PREROUTING chain.
 // Prerouting adds linking rule to nat/PREROUTING chain.
 func (c *ChainInfo) Prerouting(action Action, args ...string) error {
 func (c *ChainInfo) Prerouting(action Action, args ...string) error {
 	a := []string{"-t", string(Nat), string(action), "PREROUTING"}
 	a := []string{"-t", string(Nat), string(action), "PREROUTING"}