"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"
)
}
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 {
"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"
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))
"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"
"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() {
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)
}
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,
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),
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,
}
}
+ // 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 {