diff --git a/libnetwork/drivers/overlay/filter.go b/libnetwork/drivers/overlay/filter.go index 01b4d5b01b..33178ade37 100644 --- a/libnetwork/drivers/overlay/filter.go +++ b/libnetwork/drivers/overlay/filter.go @@ -22,15 +22,21 @@ func rawIPTables(args ...string) error { return nil } +func chainExists(cname string) bool { + if err := rawIPTables("-L", cname); err != nil { + return false + } + + return true +} + func setupGlobalChain() { 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 { - 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 filterOnce.Do(setupGlobalChain) + exists := chainExists(cname) + opt := "-N" // 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 { return fmt.Errorf("failed to flush overlay network chain %s rules: %v", cname, err) } 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 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) + } } } diff --git a/libnetwork/drivers/overlay/ov_network.go b/libnetwork/drivers/overlay/ov_network.go index 6e558c9a3c..0a891c0e5e 100644 --- a/libnetwork/drivers/overlay/ov_network.go +++ b/libnetwork/drivers/overlay/ov_network.go @@ -169,7 +169,7 @@ func (n *network) destroySandbox() { } if s.vxlanName != "" { - err := deleteVxlan(s.vxlanName) + err := deleteInterface(s.vxlanName) if err != nil { logrus.Warnf("could not cleanup sandbox properly: %v", err) } @@ -199,7 +199,7 @@ func setHostMode() { return } - defer deleteVxlan("testvxlan") + defer deleteInterface("testvxlan") path := "/proc/self/ns/net" 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 { - 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 - brName := n.generateBridgeName(s) sbox := n.sandbox() 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) } - 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)) if err != nil { return err diff --git a/libnetwork/drivers/overlay/ov_utils.go b/libnetwork/drivers/overlay/ov_utils.go index 211879c447..42c44b9675 100644 --- a/libnetwork/drivers/overlay/ov_utils.go +++ b/libnetwork/drivers/overlay/ov_utils.go @@ -67,16 +67,16 @@ func createVxlan(name string, vni uint32) error { return nil } -func deleteVxlan(name string) error { +func deleteInterface(name string) error { defer osl.InitOSContext()() link, err := netlink.LinkByName(name) 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 { - return fmt.Errorf("error deleting vxlan interface: %v", err) + return fmt.Errorf("error deleting interface with name %s: %v", name, err) } return nil