ptp, macvlan: don't change mac address; send gratuitous arp
This commit is contained in:
parent
94e6489466
commit
e76165b44f
@ -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 {
|
||||||
|
@ -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))
|
||||||
|
@ -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 {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user