plugins: replace arping package with arp_notify

this replaces the arping package with the linux arp_notify feature.

Resolves: #588
Signed-off-by: Michael Zappa <Michael.Zappa@stateless.net>
This commit is contained in:
Michael Zappa
2021-12-24 21:20:05 -07:00
parent cc32993e9e
commit 5d073d690c
21 changed files with 42 additions and 715 deletions

View File

@ -25,7 +25,6 @@ import (
"syscall"
"time"
"github.com/j-keck/arping"
"github.com/vishvananda/netlink"
"github.com/containernetworking/cni/pkg/skel"
@ -324,6 +323,11 @@ func ensureVlanInterface(br *netlink.Bridge, vlanId int) (netlink.Link, error) {
if err != nil {
return nil, fmt.Errorf("failed to lookup %q: %v", brGatewayIface.Name, err)
}
err = netlink.LinkSetUp(brGatewayVeth)
if err != nil {
return nil, fmt.Errorf("failed to up %q: %v", brGatewayIface.Name, err)
}
}
return brGatewayVeth, nil
@ -524,6 +528,8 @@ func cmdAdd(args *skel.CmdArgs) error {
}
}
_, _ = sysctl.Sysctl(fmt.Sprintf("net/ipv4/conf/%s/arp_notify", args.IfName), "1")
// Add the IP to the interface
if err := ipam.ConfigureIface(args.IfName, result); err != nil {
return err
@ -551,23 +557,6 @@ func cmdAdd(args *skel.CmdArgs) error {
}
}
// Send a gratuitous arp
if err := netns.Do(func(_ ns.NetNS) error {
contVeth, err := net.InterfaceByName(args.IfName)
if err != nil {
return err
}
for _, ipc := range result.IPs {
if ipc.Address.IP.To4() != nil {
_ = arping.GratuitousArpOverIface(ipc.Address.IP, *contVeth)
}
}
return nil
}); err != nil {
return err
}
if n.IsGW {
var firstV4Addr net.IP
var vlanInterface *current.Interface
@ -618,6 +607,20 @@ func cmdAdd(args *skel.CmdArgs) error {
}
}
}
} else {
if err := netns.Do(func(_ ns.NetNS) error {
link, err := netlink.LinkByName(args.IfName)
if err != nil {
return fmt.Errorf("failed to retrieve link: %v", err)
}
// If layer 2 we still need to set the container veth to up
if err = netlink.LinkSetUp(link); err != nil {
return fmt.Errorf("failed to set %q up: %v", args.IfName, err)
}
return nil
}); err != nil {
return err
}
}
// Refetch the bridge since its MAC address may change when the first

View File

@ -28,8 +28,8 @@ import (
"github.com/containernetworking/cni/pkg/skel"
"github.com/containernetworking/cni/pkg/types"
"github.com/containernetworking/cni/pkg/types/040"
"github.com/containernetworking/cni/pkg/types/100"
types040 "github.com/containernetworking/cni/pkg/types/040"
types100 "github.com/containernetworking/cni/pkg/types/100"
"github.com/containernetworking/plugins/pkg/ip"
"github.com/containernetworking/plugins/pkg/ns"
"github.com/containernetworking/plugins/pkg/testutils"

View File

@ -18,10 +18,8 @@ import (
"encoding/json"
"errors"
"fmt"
"net"
"runtime"
"github.com/j-keck/arping"
"github.com/vishvananda/netlink"
"github.com/containernetworking/cni/pkg/skel"
@ -33,6 +31,7 @@ import (
"github.com/containernetworking/plugins/pkg/ipam"
"github.com/containernetworking/plugins/pkg/ns"
bv "github.com/containernetworking/plugins/pkg/utils/buildversion"
"github.com/containernetworking/plugins/pkg/utils/sysctl"
)
type NetConf struct {
@ -256,20 +255,11 @@ func cmdAdd(args *skel.CmdArgs) error {
result.Interfaces = []*current.Interface{ipvlanInterface}
err = netns.Do(func(_ ns.NetNS) error {
_, _ = sysctl.Sysctl(fmt.Sprintf("net/ipv4/conf/%s/arp_notify", args.IfName), "1")
if err := ipam.ConfigureIface(args.IfName, result); err != nil {
return err
}
contVeth, err := net.InterfaceByName(args.IfName)
if err != nil {
return fmt.Errorf("failed to look up %q: %v", args.IfName, err)
}
for _, ipc := range result.IPs {
if ipc.Address.IP.To4() != nil {
_ = arping.GratuitousArpOverIface(ipc.Address.IP, *contVeth)
}
}
return nil
})
if err != nil {

View File

@ -21,7 +21,6 @@ import (
"net"
"runtime"
"github.com/j-keck/arping"
"github.com/vishvananda/netlink"
"github.com/containernetworking/cni/pkg/skel"
@ -33,6 +32,7 @@ import (
"github.com/containernetworking/plugins/pkg/ipam"
"github.com/containernetworking/plugins/pkg/ns"
bv "github.com/containernetworking/plugins/pkg/utils/buildversion"
"github.com/containernetworking/plugins/pkg/utils/sysctl"
)
type NetConf struct {
@ -294,20 +294,11 @@ func cmdAdd(args *skel.CmdArgs) error {
}
err = netns.Do(func(_ ns.NetNS) error {
_, _ = sysctl.Sysctl(fmt.Sprintf("net/ipv4/conf/%s/arp_notify", args.IfName), "1")
if err := ipam.ConfigureIface(args.IfName, result); err != nil {
return err
}
contVeth, err := net.InterfaceByName(args.IfName)
if err != nil {
return fmt.Errorf("failed to look up %q: %v", args.IfName, err)
}
for _, ipc := range result.IPs {
if ipc.Address.IP.To4() != nil {
_ = arping.GratuitousArpOverIface(ipc.Address.IP, *contVeth)
}
}
return nil
})
if err != nil {

View File

@ -22,7 +22,6 @@ import (
"os"
"runtime"
"github.com/j-keck/arping"
"github.com/vishvananda/netlink"
"github.com/containernetworking/cni/pkg/skel"
@ -35,6 +34,7 @@ import (
"github.com/containernetworking/plugins/pkg/ns"
"github.com/containernetworking/plugins/pkg/utils"
bv "github.com/containernetworking/plugins/pkg/utils/buildversion"
"github.com/containernetworking/plugins/pkg/utils/sysctl"
)
func init() {
@ -83,15 +83,17 @@ func setupContainerVeth(netns ns.NetNS, ifName string, mtu int, pr *current.Resu
pr.Interfaces = []*current.Interface{hostInterface, containerInterface}
if err = ipam.ConfigureIface(ifName, pr); err != nil {
return err
}
contVeth, err := net.InterfaceByName(ifName)
if err != nil {
return fmt.Errorf("failed to look up %q: %v", ifName, err)
}
_, _ = sysctl.Sysctl(fmt.Sprintf("net/ipv4/conf/%s/arp_notify", ifName), "1")
if err = ipam.ConfigureIface(ifName, pr); err != nil {
return err
}
for _, ipc := range pr.IPs {
// Delete the route that was automatically added
route := netlink.Route{
@ -139,13 +141,6 @@ 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.Address.IP.To4() != nil {
_ = arping.GratuitousArpOverIface(ipc.Address.IP, *contVeth)
}
}
return nil
})
if err != nil {