Merge pull request #836 from mrjana/rel

Cherry pick overlay fixes
This commit is contained in:
aboch 2015-12-22 16:56:01 -08:00
commit c6a0ee8aaf
3 changed files with 60 additions and 22 deletions

View File

@ -22,15 +22,21 @@ func rawIPTables(args ...string) error {
return nil
}
func chainExists(cname string) bool {
if _, err := iptables.Raw("-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)
}
}
}

View File

@ -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 if already present
deleteVxlan(vxlanName)
err := createVxlan(vxlanName, n.vxlanID(s))
if err != nil {
return err

View File

@ -67,17 +67,39 @@ 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
}
func deleteVxlanByVNI(vni uint32) error {
defer osl.InitOSContext()()
links, err := netlink.LinkList()
if err != nil {
return fmt.Errorf("failed to list interfaces while deleting vxlan interface by vni: %v", err)
}
for _, l := range links {
if l.Type() == "vxlan" && l.(*netlink.Vxlan).VxlanId == int(vni) {
err = netlink.LinkDel(l)
if err != nil {
return fmt.Errorf("error deleting vxlan interface with id %d: %v", vni, err)
}
return nil
}
}
return fmt.Errorf("could not find a vxlan interface to delete with id %d", vni)
}