macvlan and ipvlan: rename tmp iface name prior to calling IPAM
authorEugene Yakubovich <eugene.yakubovich@coreos.com>
Tue, 19 May 2015 18:55:06 +0000 (11:55 -0700)
committerEugene Yakubovich <eugene.yakubovich@coreos.com>
Wed, 20 May 2015 00:43:44 +0000 (17:43 -0700)
plugins/main/ipvlan/ipvlan.go
plugins/main/macvlan/macvlan.go

index 2a5a897..0d2ba7a 100644 (file)
@@ -56,9 +56,7 @@ func loadConf(bytes []byte) (*NetConf, error) {
 
 func modeFromString(s string) (netlink.IPVlanMode, error) {
        switch s {
-       case "":
-               return netlink.IPVLAN_MODE_L2, nil
-       case "l2":
+       case "", "l2":
                return netlink.IPVLAN_MODE_L2, nil
        case "l3":
                return netlink.IPVLAN_MODE_L3, nil
@@ -78,6 +76,13 @@ func createIpvlan(conf *NetConf, ifName string, netns *os.File) error {
                return fmt.Errorf("failed to lookup master %q: %v", conf.Master, err)
        }
 
+       // due to kernel bug we have to create with tmpname or it might
+       // collide with the name on the host and error out
+       tmpName, err := ip.RandomVethName()
+       if err != nil {
+               return err
+       }
+
        mv := &netlink.IPVlan{
                LinkAttrs: netlink.LinkAttrs{
                        MTU:         conf.MTU,
@@ -92,7 +97,13 @@ func createIpvlan(conf *NetConf, ifName string, netns *os.File) error {
                return fmt.Errorf("failed to create ipvlan: %v", err)
        }
 
-       return err
+       return ns.WithNetNS(netns, func(_ *os.File) error {
+               err := renameLink(tmpName, ifName)
+               if err != nil {
+                       return fmt.Errorf("failed to rename ipvlan to %q: %v", ifName, err)
+               }
+               return nil
+       })
 }
 
 func cmdAdd(args *skel.CmdArgs) error {
@@ -107,12 +118,7 @@ func cmdAdd(args *skel.CmdArgs) error {
        }
        defer netns.Close()
 
-       tmpName, err := ip.RandomVethName()
-       if err != nil {
-               return err
-       }
-
-       if err = createIpvlan(n, tmpName, netns); err != nil {
+       if err = createIpvlan(n, args.IfName, netns); err != nil {
                return err
        }
 
@@ -126,11 +132,6 @@ func cmdAdd(args *skel.CmdArgs) error {
        }
 
        err = ns.WithNetNS(netns, func(_ *os.File) error {
-               err := renameLink(tmpName, args.IfName)
-               if err != nil {
-                       return fmt.Errorf("failed to rename ipvlan to %q: %v", args.IfName, err)
-               }
-
                return plugin.ConfigureIface(args.IfName, result)
        })
        if err != nil {
index 874abc5..31a17ea 100644 (file)
@@ -56,14 +56,12 @@ func loadConf(bytes []byte) (*NetConf, error) {
 
 func modeFromString(s string) (netlink.MacvlanMode, error) {
        switch s {
-       case "":
+       case "", "bridge":
                return netlink.MACVLAN_MODE_BRIDGE, nil
        case "private":
                return netlink.MACVLAN_MODE_PRIVATE, nil
        case "vepa":
                return netlink.MACVLAN_MODE_VEPA, nil
-       case "bridge":
-               return netlink.MACVLAN_MODE_BRIDGE, nil
        case "passthru":
                return netlink.MACVLAN_MODE_PASSTHRU, nil
        default:
@@ -82,10 +80,17 @@ func createMacvlan(conf *NetConf, ifName string, netns *os.File) error {
                return fmt.Errorf("failed to lookup master %q: %v", conf.Master, err)
        }
 
+       // due to kernel bug we have to create with tmpname or it might
+       // collide with the name on the host and error out
+       tmpName, err := ip.RandomVethName()
+       if err != nil {
+               return err
+       }
+
        mv := &netlink.Macvlan{
                LinkAttrs: netlink.LinkAttrs{
                        MTU:         conf.MTU,
-                       Name:        ifName,
+                       Name:        tmpName,
                        ParentIndex: m.Attrs().Index,
                        Namespace:   netlink.NsFd(int(netns.Fd())),
                },
@@ -96,7 +101,13 @@ func createMacvlan(conf *NetConf, ifName string, netns *os.File) error {
                return fmt.Errorf("failed to create macvlan: %v", err)
        }
 
-       return err
+       return ns.WithNetNS(netns, func(_ *os.File) error {
+               err := renameLink(tmpName, ifName)
+               if err != nil {
+                       return fmt.Errorf("failed to rename macvlan to %q: %v", ifName, err)
+               }
+               return nil
+       })
 }
 
 func cmdAdd(args *skel.CmdArgs) error {
@@ -111,12 +122,7 @@ func cmdAdd(args *skel.CmdArgs) error {
        }
        defer netns.Close()
 
-       tmpName, err := ip.RandomVethName()
-       if err != nil {
-               return err
-       }
-
-       if err = createMacvlan(n, tmpName, netns); err != nil {
+       if err = createMacvlan(n, args.IfName, netns); err != nil {
                return err
        }
 
@@ -130,11 +136,6 @@ func cmdAdd(args *skel.CmdArgs) error {
        }
 
        err = ns.WithNetNS(netns, func(_ *os.File) error {
-               err := renameLink(tmpName, args.IfName)
-               if err != nil {
-                       return fmt.Errorf("failed to rename macvlan to %q: %v", args.IfName, err)
-               }
-
                return plugin.ConfigureIface(args.IfName, result)
        })
        if err != nil {