1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00

Check existence of network chain before creating

We check for existence of all filter rules in
overlay driver before creating it. We should
also do this for chain creation, because even though
we cleanup network chains when the last container
stops, there is a possibility of a stale network
chain in case of ungraceful restart.

Also cleaned up stale bridges if any exist due to
ungraceful shutdown of daemon.

Signed-off-by: Jana Radhakrishnan <mrjana@docker.com>
This commit is contained in:
Jana Radhakrishnan 2015-12-22 10:12:23 -08:00
parent 438314977f
commit 6cff09f710
3 changed files with 38 additions and 22 deletions

View file

@ -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) logrus.Debugf("could not create global overlay chain: %v", err)
return
} }
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) logrus.Debugf("could not install default return chain in the overlay global chain: %v", err)
return
} }
} }
@ -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 { if (!remove && !exists) || (remove && exists) {
return fmt.Errorf("failed network chain operation %q for chain %s: %v", opt, cname, err) 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 { if !iptables.Exists(iptables.Filter, cname, "-j", "DROP") {
return fmt.Errorf("failed adding default drop rule to overlay network chain %s: %v", cname, err) 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)
}
} }
} }

View file

@ -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) { brName := n.generateBridgeName(s)
return fmt.Errorf("overlay subnet %s has conflicts in the host while running in host mode", s.subnetIP.String()) 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

View file

@ -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