ptp, macvlan: don't change mac address; send gratuitous arp

This commit is contained in:
Casey Callendrello 2017-06-07 16:08:41 +02:00
parent 94e6489466
commit e76165b44f
3 changed files with 24 additions and 54 deletions

View File

@ -29,6 +29,7 @@ import (
"github.com/containernetworking/plugins/pkg/ipam" "github.com/containernetworking/plugins/pkg/ipam"
"github.com/containernetworking/plugins/pkg/ns" "github.com/containernetworking/plugins/pkg/ns"
"github.com/containernetworking/plugins/pkg/utils/sysctl" "github.com/containernetworking/plugins/pkg/utils/sysctl"
"github.com/j-keck/arping"
"github.com/vishvananda/netlink" "github.com/vishvananda/netlink"
) )
@ -176,36 +177,26 @@ func cmdAdd(args *skel.CmdArgs) error {
} }
result.Interfaces = []*current.Interface{macvlanInterface} result.Interfaces = []*current.Interface{macvlanInterface}
var firstV4Addr net.IP
for _, ipc := range result.IPs { for _, ipc := range result.IPs {
// All addresses apply to the container macvlan interface // All addresses apply to the container macvlan interface
ipc.Interface = 0 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 { err = netns.Do(func(_ ns.NetNS) error {
if err := ip.SetHWAddrByIP(args.IfName, firstV4Addr, nil /* TODO IPv6 */); err != nil { if err := ipam.ConfigureIface(args.IfName, result); err != nil {
return err return err
} }
return ipam.ConfigureIface(args.IfName, result) contVeth, err := net.InterfaceByName(args.IfName)
})
if err != nil { if err != nil {
return err return fmt.Errorf("failed to look up %q: %v", args.IfName, err)
}
} }
// Re-fetch macvlan interface as its MAC address may have changed for _, ipc := range result.IPs {
err = netns.Do(func(_ ns.NetNS) error { if ipc.Version == "4" {
link, err := netlink.LinkByName(args.IfName) _ = arping.GratuitousArpOverIface(ipc.Address.IP, *contVeth)
if err != nil { }
return fmt.Errorf("failed to re-fetch macvlan interface: %v", err)
} }
macvlanInterface.Mac = link.Attrs().HardwareAddr.String()
return nil return nil
}) })
if err != nil { if err != nil {

View File

@ -24,7 +24,6 @@ import (
"github.com/containernetworking/cni/pkg/types/current" "github.com/containernetworking/cni/pkg/types/current"
"github.com/containernetworking/plugins/pkg/ns" "github.com/containernetworking/plugins/pkg/ns"
"github.com/containernetworking/plugins/pkg/testutils" "github.com/containernetworking/plugins/pkg/testutils"
"github.com/containernetworking/plugins/pkg/utils/hwaddr"
"github.com/vishvananda/netlink" "github.com/vishvananda/netlink"
@ -153,9 +152,6 @@ var _ = Describe("macvlan Operations", func() {
Expect(err).NotTo(HaveOccurred()) Expect(err).NotTo(HaveOccurred())
Expect(link.Attrs().Name).To(Equal(IFNAME)) 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) hwaddr, err := net.ParseMAC(result.Interfaces[0].Mac)
Expect(err).NotTo(HaveOccurred()) Expect(err).NotTo(HaveOccurred())
Expect(link.Attrs().HardwareAddr).To(Equal(hwaddr)) Expect(link.Attrs().HardwareAddr).To(Equal(hwaddr))

View File

@ -22,8 +22,6 @@ import (
"os" "os"
"runtime" "runtime"
"github.com/vishvananda/netlink"
"github.com/containernetworking/cni/pkg/skel" "github.com/containernetworking/cni/pkg/skel"
"github.com/containernetworking/cni/pkg/types" "github.com/containernetworking/cni/pkg/types"
"github.com/containernetworking/cni/pkg/types/current" "github.com/containernetworking/cni/pkg/types/current"
@ -32,6 +30,8 @@ import (
"github.com/containernetworking/plugins/pkg/ipam" "github.com/containernetworking/plugins/pkg/ipam"
"github.com/containernetworking/plugins/pkg/ns" "github.com/containernetworking/plugins/pkg/ns"
"github.com/containernetworking/plugins/pkg/utils" "github.com/containernetworking/plugins/pkg/utils"
"github.com/j-keck/arping"
"github.com/vishvananda/netlink"
) )
func init() { func init() {
@ -73,42 +73,18 @@ func setupContainerVeth(netns ns.NetNS, ifName string, mtu int, pr *current.Resu
containerInterface.Mac = contVeth0.HardwareAddr.String() containerInterface.Mac = contVeth0.HardwareAddr.String()
containerInterface.Sandbox = netns.Path() containerInterface.Sandbox = netns.Path()
var firstV4Addr net.IP
for _, ipc := range pr.IPs { for _, ipc := range pr.IPs {
// All addresses apply to the container veth interface // All addresses apply to the container veth interface
ipc.Interface = 1 ipc.Interface = 1
if ipc.Address.IP.To4() != nil && firstV4Addr == nil {
firstV4Addr = ipc.Address.IP
}
} }
pr.Interfaces = []*current.Interface{hostInterface, containerInterface} 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 { if err = ipam.ConfigureIface(ifName, pr); err != nil {
return err return err
} }
if err := ip.SetHWAddrByIP(contVeth0.Name, firstV4Addr, nil /* TODO IPv6 */); err != nil { contVeth, err := net.InterfaceByName(ifName)
return fmt.Errorf("failed to set hardware addr by IP: %v", err)
}
// Re-fetch container veth to update attributes
contVeth, err := netlink.LinkByName(ifName)
if err != nil { if err != nil {
return fmt.Errorf("failed to look up %q: %v", ifName, err) 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 { for _, ipc := range pr.IPs {
// Delete the route that was automatically added // Delete the route that was automatically added
route := netlink.Route{ route := netlink.Route{
LinkIndex: contVeth.Attrs().Index, LinkIndex: contVeth.Index,
Dst: &net.IPNet{ Dst: &net.IPNet{
IP: ipc.Address.IP.Mask(ipc.Address.Mask), IP: ipc.Address.IP.Mask(ipc.Address.Mask),
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{ for _, r := range []netlink.Route{
netlink.Route{ netlink.Route{
LinkIndex: contVeth.Attrs().Index, LinkIndex: contVeth.Index,
Dst: &net.IPNet{ Dst: &net.IPNet{
IP: ipc.Gateway, IP: ipc.Gateway,
Mask: net.CIDRMask(32, 32), 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, Src: ipc.Address.IP,
}, },
netlink.Route{ netlink.Route{
LinkIndex: contVeth.Attrs().Index, LinkIndex: contVeth.Index,
Dst: &net.IPNet{ Dst: &net.IPNet{
IP: ipc.Address.IP.Mask(ipc.Address.Mask), IP: ipc.Address.IP.Mask(ipc.Address.Mask),
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 return nil
}) })
if err != nil { if err != nil {