Просмотр исходного кода

Merge pull request #834 from mrjana/overlay

Check existence of network chain before creating
aboch 9 лет назад
Родитель
Сommit
e5beba7a53

+ 21 - 9
libnetwork/drivers/overlay/filter.go

@@ -22,15 +22,21 @@ func rawIPTables(args ...string) error {
 	return nil
 	return nil
 }
 }
 
 
+func chainExists(cname string) bool {
+	if err := rawIPTables("-L", cname); err != nil {
+		return false
+	}
+
+	return true
+}
+
 func setupGlobalChain() {
 func setupGlobalChain() {
 	if err := rawIPTables("-N", globalChain); err != nil {
 	if err := rawIPTables("-N", globalChain); err != nil {
-		logrus.Errorf("could not create global overlay chain: %v", err)
-		return
+		logrus.Debugf("could not create global overlay chain: %v", err)
 	}
 	}
 
 
 	if err := rawIPTables("-A", globalChain, "-j", "RETURN"); err != nil {
 	if err := rawIPTables("-A", globalChain, "-j", "RETURN"); err != nil {
-		logrus.Errorf("could not install default return chain in the overlay global chain: %v", err)
-		return
+		logrus.Debugf("could not install default return chain in the overlay global chain: %v", err)
 	}
 	}
 }
 }
 
 
@@ -38,22 +44,28 @@ func setNetworkChain(cname string, remove bool) error {
 	// Initialize the onetime global overlay chain
 	// Initialize the onetime global overlay chain
 	filterOnce.Do(setupGlobalChain)
 	filterOnce.Do(setupGlobalChain)
 
 
+	exists := chainExists(cname)
+
 	opt := "-N"
 	opt := "-N"
 	// In case of remove, make sure to flush the rules in the chain
 	// In case of remove, make sure to flush the rules in the chain
-	if remove {
+	if remove && exists {
 		if err := rawIPTables("-F", cname); err != nil {
 		if err := rawIPTables("-F", cname); err != nil {
 			return fmt.Errorf("failed to flush overlay network chain %s rules: %v", cname, err)
 			return fmt.Errorf("failed to flush overlay network chain %s rules: %v", cname, err)
 		}
 		}
 		opt = "-X"
 		opt = "-X"
 	}
 	}
 
 
-	if err := rawIPTables(opt, cname); err != nil {
-		return fmt.Errorf("failed network chain operation %q for chain %s: %v", opt, cname, err)
+	if (!remove && !exists) || (remove && exists) {
+		if err := rawIPTables(opt, cname); err != nil {
+			return fmt.Errorf("failed network chain operation %q for chain %s: %v", opt, cname, err)
+		}
 	}
 	}
 
 
 	if !remove {
 	if !remove {
-		if err := rawIPTables("-A", cname, "-j", "DROP"); err != nil {
-			return fmt.Errorf("failed adding default drop rule to overlay network chain %s: %v", cname, err)
+		if !iptables.Exists(iptables.Filter, cname, "-j", "DROP") {
+			if err := rawIPTables("-A", cname, "-j", "DROP"); err != nil {
+				return fmt.Errorf("failed adding default drop rule to overlay network chain %s: %v", cname, err)
+			}
 		}
 		}
 	}
 	}
 
 

+ 14 - 10
libnetwork/drivers/overlay/ov_network.go

@@ -169,7 +169,7 @@ func (n *network) destroySandbox() {
 			}
 			}
 
 
 			if s.vxlanName != "" {
 			if s.vxlanName != "" {
-				err := deleteVxlan(s.vxlanName)
+				err := deleteInterface(s.vxlanName)
 				if err != nil {
 				if err != nil {
 					logrus.Warnf("could not cleanup sandbox properly: %v", err)
 					logrus.Warnf("could not cleanup sandbox properly: %v", err)
 				}
 				}
@@ -199,7 +199,7 @@ func setHostMode() {
 		return
 		return
 	}
 	}
 
 
-	defer deleteVxlan("testvxlan")
+	defer deleteInterface("testvxlan")
 
 
 	path := "/proc/self/ns/net"
 	path := "/proc/self/ns/net"
 	f, err := os.OpenFile(path, os.O_RDONLY, 0)
 	f, err := os.OpenFile(path, os.O_RDONLY, 0)
@@ -251,12 +251,21 @@ func isOverlap(nw *net.IPNet) bool {
 }
 }
 
 
 func (n *network) initSubnetSandbox(s *subnet) error {
 func (n *network) initSubnetSandbox(s *subnet) error {
-	if hostMode && isOverlap(s.subnetIP) {
-		return fmt.Errorf("overlay subnet %s has conflicts in the host while running in host mode", s.subnetIP.String())
+	brName := n.generateBridgeName(s)
+	vxlanName := n.generateVxlanName(s)
+
+	if hostMode {
+		// Try to delete stale bridge interface if it exists
+		deleteInterface(brName)
+		// Try to delete the vxlan interface by vni if already present
+		deleteVxlanByVNI(n.vxlanID(s))
+
+		if isOverlap(s.subnetIP) {
+			return fmt.Errorf("overlay subnet %s has conflicts in the host while running in host mode", s.subnetIP.String())
+		}
 	}
 	}
 
 
 	// create a bridge and vxlan device for this subnet and move it to the sandbox
 	// create a bridge and vxlan device for this subnet and move it to the sandbox
-	brName := n.generateBridgeName(s)
 	sbox := n.sandbox()
 	sbox := n.sandbox()
 
 
 	if err := sbox.AddInterface(brName, "br",
 	if err := sbox.AddInterface(brName, "br",
@@ -265,11 +274,6 @@ func (n *network) initSubnetSandbox(s *subnet) error {
 		return fmt.Errorf("bridge creation in sandbox failed for subnet %q: %v", s.subnetIP.String(), err)
 		return fmt.Errorf("bridge creation in sandbox failed for subnet %q: %v", s.subnetIP.String(), err)
 	}
 	}
 
 
-	vxlanName := n.generateVxlanName(s)
-
-	// Try to delete the vxlan interface by vni if already present
-	deleteVxlanByVNI(n.vxlanID(s))
-
 	err := createVxlan(vxlanName, n.vxlanID(s))
 	err := createVxlan(vxlanName, n.vxlanID(s))
 	if err != nil {
 	if err != nil {
 		return err
 		return err

+ 3 - 3
libnetwork/drivers/overlay/ov_utils.go

@@ -67,16 +67,16 @@ func createVxlan(name string, vni uint32) error {
 	return nil
 	return nil
 }
 }
 
 
-func deleteVxlan(name string) error {
+func deleteInterface(name string) error {
 	defer osl.InitOSContext()()
 	defer osl.InitOSContext()()
 
 
 	link, err := netlink.LinkByName(name)
 	link, err := netlink.LinkByName(name)
 	if err != nil {
 	if err != nil {
-		return fmt.Errorf("failed to find vxlan interface with name %s: %v", name, err)
+		return fmt.Errorf("failed to find interface with name %s: %v", name, err)
 	}
 	}
 
 
 	if err := netlink.LinkDel(link); err != nil {
 	if err := netlink.LinkDel(link); err != nil {
-		return fmt.Errorf("error deleting vxlan interface: %v", err)
+		return fmt.Errorf("error deleting interface with name %s: %v", name, err)
 	}
 	}
 
 
 	return nil
 	return nil