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/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 {

View 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))

View 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 {