ptp, macvlan: don't change mac address; send gratuitous arp
authorCasey Callendrello <casey.callendrello@coreos.com>
Wed, 7 Jun 2017 14:08:41 +0000 (16:08 +0200)
committerCasey Callendrello <casey.callendrello@coreos.com>
Wed, 7 Jun 2017 14:08:41 +0000 (16:08 +0200)
plugins/main/macvlan/macvlan.go
plugins/main/macvlan/macvlan_test.go
plugins/main/ptp/ptp.go

index 4ee9abb..98e46a4 100644 (file)
@@ -29,6 +29,7 @@ import (
        "github.com/containernetworking/plugins/pkg/ipam"
        "github.com/containernetworking/plugins/pkg/ns"
        "github.com/containernetworking/plugins/pkg/utils/sysctl"
+       "github.com/j-keck/arping"
        "github.com/vishvananda/netlink"
 )
 
@@ -176,36 +177,26 @@ func cmdAdd(args *skel.CmdArgs) error {
        }
        result.Interfaces = []*current.Interface{macvlanInterface}
 
-       var firstV4Addr net.IP
        for _, ipc := range result.IPs {
                // All addresses apply to the container macvlan interface
                ipc.Interface = 0
-
-               if ipc.Address.IP.To4() != nil && firstV4Addr == nil {
-                       firstV4Addr = ipc.Address.IP
-               }
        }
 
-       if firstV4Addr != nil {
-               err = netns.Do(func(_ ns.NetNS) error {
-                       if err := ip.SetHWAddrByIP(args.IfName, firstV4Addr, nil /* TODO IPv6 */); err != nil {
-                               return err
-                       }
-
-                       return ipam.ConfigureIface(args.IfName, result)
-               })
-               if err != nil {
+       err = netns.Do(func(_ ns.NetNS) error {
+               if err := ipam.ConfigureIface(args.IfName, result); err != nil {
                        return err
                }
-       }
 
-       // Re-fetch macvlan interface as its MAC address may have changed
-       err = netns.Do(func(_ ns.NetNS) error {
-               link, err := netlink.LinkByName(args.IfName)
+               contVeth, err := net.InterfaceByName(args.IfName)
                if err != nil {
-                       return fmt.Errorf("failed to re-fetch macvlan interface: %v", err)
+                       return fmt.Errorf("failed to look up %q: %v", args.IfName, err)
+               }
+
+               for _, ipc := range result.IPs {
+                       if ipc.Version == "4" {
+                               _ = arping.GratuitousArpOverIface(ipc.Address.IP, *contVeth)
+                       }
                }
-               macvlanInterface.Mac = link.Attrs().HardwareAddr.String()
                return nil
        })
        if err != nil {
index 7ae26f3..406264d 100644 (file)
@@ -24,7 +24,6 @@ import (
        "github.com/containernetworking/cni/pkg/types/current"
        "github.com/containernetworking/plugins/pkg/ns"
        "github.com/containernetworking/plugins/pkg/testutils"
-       "github.com/containernetworking/plugins/pkg/utils/hwaddr"
 
        "github.com/vishvananda/netlink"
 
@@ -153,9 +152,6 @@ var _ = Describe("macvlan Operations", func() {
                        Expect(err).NotTo(HaveOccurred())
                        Expect(link.Attrs().Name).To(Equal(IFNAME))
 
-                       hwaddrString := fmt.Sprintf("%s", link.Attrs().HardwareAddr)
-                       Expect(hwaddrString).To(HavePrefix(hwaddr.PrivateMACPrefixString))
-
                        hwaddr, err := net.ParseMAC(result.Interfaces[0].Mac)
                        Expect(err).NotTo(HaveOccurred())
                        Expect(link.Attrs().HardwareAddr).To(Equal(hwaddr))
index af93312..42b2670 100644 (file)
@@ -22,8 +22,6 @@ import (
        "os"
        "runtime"
 
-       "github.com/vishvananda/netlink"
-
        "github.com/containernetworking/cni/pkg/skel"
        "github.com/containernetworking/cni/pkg/types"
        "github.com/containernetworking/cni/pkg/types/current"
@@ -32,6 +30,8 @@ import (
        "github.com/containernetworking/plugins/pkg/ipam"
        "github.com/containernetworking/plugins/pkg/ns"
        "github.com/containernetworking/plugins/pkg/utils"
+       "github.com/j-keck/arping"
+       "github.com/vishvananda/netlink"
 )
 
 func init() {
@@ -73,42 +73,18 @@ func setupContainerVeth(netns ns.NetNS, ifName string, mtu int, pr *current.Resu
                containerInterface.Mac = contVeth0.HardwareAddr.String()
                containerInterface.Sandbox = netns.Path()
 
-               var firstV4Addr net.IP
                for _, ipc := range pr.IPs {
                        // All addresses apply to the container veth interface
                        ipc.Interface = 1
-
-                       if ipc.Address.IP.To4() != nil && firstV4Addr == nil {
-                               firstV4Addr = ipc.Address.IP
-                       }
                }
 
                pr.Interfaces = []*current.Interface{hostInterface, containerInterface}
 
-               if firstV4Addr != nil {
-                       err = hostNS.Do(func(_ ns.NetNS) error {
-                               hostVethName := hostVeth.Name
-                               if err := ip.SetHWAddrByIP(hostVethName, firstV4Addr, nil /* TODO IPv6 */); err != nil {
-                                       return fmt.Errorf("failed to set hardware addr by IP: %v", err)
-                               }
-
-                               return nil
-                       })
-                       if err != nil {
-                               return err
-                       }
-               }
-
                if err = ipam.ConfigureIface(ifName, pr); err != nil {
                        return err
                }
 
-               if err := ip.SetHWAddrByIP(contVeth0.Name, firstV4Addr, nil /* TODO IPv6 */); err != nil {
-                       return fmt.Errorf("failed to set hardware addr by IP: %v", err)
-               }
-
-               // Re-fetch container veth to update attributes
-               contVeth, err := netlink.LinkByName(ifName)
+               contVeth, err := net.InterfaceByName(ifName)
                if err != nil {
                        return fmt.Errorf("failed to look up %q: %v", ifName, err)
                }
@@ -116,7 +92,7 @@ func setupContainerVeth(netns ns.NetNS, ifName string, mtu int, pr *current.Resu
                for _, ipc := range pr.IPs {
                        // Delete the route that was automatically added
                        route := netlink.Route{
-                               LinkIndex: contVeth.Attrs().Index,
+                               LinkIndex: contVeth.Index,
                                Dst: &net.IPNet{
                                        IP:   ipc.Address.IP.Mask(ipc.Address.Mask),
                                        Mask: ipc.Address.Mask,
@@ -130,7 +106,7 @@ func setupContainerVeth(netns ns.NetNS, ifName string, mtu int, pr *current.Resu
 
                        for _, r := range []netlink.Route{
                                netlink.Route{
-                                       LinkIndex: contVeth.Attrs().Index,
+                                       LinkIndex: contVeth.Index,
                                        Dst: &net.IPNet{
                                                IP:   ipc.Gateway,
                                                Mask: net.CIDRMask(32, 32),
@@ -139,7 +115,7 @@ func setupContainerVeth(netns ns.NetNS, ifName string, mtu int, pr *current.Resu
                                        Src:   ipc.Address.IP,
                                },
                                netlink.Route{
-                                       LinkIndex: contVeth.Attrs().Index,
+                                       LinkIndex: contVeth.Index,
                                        Dst: &net.IPNet{
                                                IP:   ipc.Address.IP.Mask(ipc.Address.Mask),
                                                Mask: ipc.Address.Mask,
@@ -155,6 +131,13 @@ func setupContainerVeth(netns ns.NetNS, ifName string, mtu int, pr *current.Resu
                        }
                }
 
+               // Send a gratuitous arp for all v4 addresses
+               for _, ipc := range pr.IPs {
+                       if ipc.Version == "4" {
+                               _ = arping.GratuitousArpOverIface(ipc.Address.IP, *contVeth)
+                       }
+               }
+
                return nil
        })
        if err != nil {