From e76165b44ff545df232c389d16cb1709c198ed0f Mon Sep 17 00:00:00 2001 From: Casey Callendrello Date: Wed, 7 Jun 2017 16:08:41 +0200 Subject: [PATCH] ptp, macvlan: don't change mac address; send gratuitous arp --- plugins/main/macvlan/macvlan.go | 31 +++++++------------- plugins/main/macvlan/macvlan_test.go | 4 --- plugins/main/ptp/ptp.go | 43 +++++++++------------------- 3 files changed, 24 insertions(+), 54 deletions(-) diff --git a/plugins/main/macvlan/macvlan.go b/plugins/main/macvlan/macvlan.go index 4ee9abb4..98e46a40 100644 --- a/plugins/main/macvlan/macvlan.go +++ b/plugins/main/macvlan/macvlan.go @@ -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 { diff --git a/plugins/main/macvlan/macvlan_test.go b/plugins/main/macvlan/macvlan_test.go index 7ae26f30..406264dc 100644 --- a/plugins/main/macvlan/macvlan_test.go +++ b/plugins/main/macvlan/macvlan_test.go @@ -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)) diff --git a/plugins/main/ptp/ptp.go b/plugins/main/ptp/ptp.go index af93312d..42b26707 100644 --- a/plugins/main/ptp/ptp.go +++ b/plugins/main/ptp/ptp.go @@ -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 {