Skip to content

Commit 2f33a42

Browse files
author
Mugesh SP
committed
feat: implement ARP proxy setting and custom route addition for VLAN interfaces
1 parent 2ddbf89 commit 2f33a42

File tree

1 file changed

+67
-2
lines changed

1 file changed

+67
-2
lines changed

network/transparent_vlan_endpointclient_linux.go

Lines changed: 67 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,18 @@ func (client *TransparentVlanEndpointClient) PopulateVnet(epInfo *EndpointInfo)
400400
return nil
401401
}
402402

403+
// Set ARP proxy on the vlan interface to respond to ARP requests for the gateway IP
404+
func (client *TransparentVlanEndpointClient) setArpProxy(ifName string) error {
405+
cmd := fmt.Sprintf("echo 1 > /proc/sys/net/ipv4/conf/%v/proxy_arp", ifName)
406+
_, err := client.plClient.ExecuteRawCommand(cmd)
407+
if err != nil {
408+
logger.Error("Failed to set ARP proxy", zap.String("interface", ifName), zap.Error(err))
409+
} else {
410+
logger.Info("ARP proxy enabled", zap.String("interface", ifName))
411+
}
412+
return err
413+
}
414+
403415
func (client *TransparentVlanEndpointClient) AddEndpointRules(epInfo *EndpointInfo) error {
404416
if err := client.AddSnatEndpointRules(); err != nil {
405417
return errors.Wrap(err, "failed to add snat endpoint rules")
@@ -408,6 +420,17 @@ func (client *TransparentVlanEndpointClient) AddEndpointRules(epInfo *EndpointIn
408420
err := ExecuteInNS(client.nsClient, client.vnetNSName, func() error {
409421
return client.AddVnetRules(epInfo)
410422
})
423+
if err == nil {
424+
logger.Info("calling setArpProxy for", zap.String("vlanIfName", client.vlanIfName))
425+
if err := client.setArpProxy(client.vlanIfName); err != nil {
426+
logger.Error("setArpProxy failed with", zap.Error(err))
427+
return err
428+
}
429+
if err != nil {
430+
logger.Error("setArpProxy failed for VLAN interface", zap.Error(err))
431+
}
432+
}
433+
411434
return err
412435
}
413436

@@ -519,9 +542,19 @@ func (client *TransparentVlanEndpointClient) ConfigureContainerInterfacesAndRout
519542
}
520543
}
521544

522-
if err := client.addDefaultRoutes(client.containerVethName, 0); err != nil {
523-
return errors.Wrap(err, "failed container ns add default routes")
545+
if epInfo.SkipDefaultRoutes {
546+
logger.Info("Skipping adding default routes in container ns as requested")
547+
if err := client.addCustomRoutes(client.containerVethName, epInfo.Subnets[0].Gateway, epInfo.IPAddresses[0]); err != nil {
548+
return errors.Wrap(err, "failed container ns add custom routes")
549+
}
550+
return nil
551+
} else {
552+
logger.Info("Adding default routes in container ns")
553+
if err := client.addDefaultRoutes(client.containerVethName, 0); err != nil {
554+
return errors.Wrap(err, "failed container ns add default routes")
555+
}
524556
}
557+
525558
if err := client.AddDefaultArp(client.containerVethName, client.vnetMac.String()); err != nil {
526559
return errors.Wrap(err, "failed container ns add default arp")
527560
}
@@ -614,6 +647,38 @@ func (client *TransparentVlanEndpointClient) addDefaultRoutes(linkToName string,
614647
return nil
615648
}
616649

650+
// Helper that creates routing rules for the current NS which direct packets
651+
// to the virtual gateway ip on linkToName device interface
652+
// Route 1: 169.254.2.1 dev <linkToName>
653+
// Route 2: default via 169.254.2.1 dev <linkToName>
654+
func (client *TransparentVlanEndpointClient) addCustomRoutes(linkToName string, gatewayIP net.IP, subnetCIDR net.IPNet, table int) error {
655+
// Add route for virtualgwip (ip route add <gatewayIP> dev <linkToName>)
656+
gWIP, gwNet, _ := net.ParseCIDR(gatewayIP.String() + "/32")
657+
routeInfo := RouteInfo{
658+
Dst: *gwNet,
659+
Scope: netlink.RT_SCOPE_LINK,
660+
Table: table,
661+
}
662+
// Difference between interface name in addRoutes and DevName: in RouteInfo?
663+
if err := addRoutes(client.netlink, client.netioshim, linkToName, []RouteInfo{routeInfo}); err != nil {
664+
return err
665+
}
666+
667+
// Add subnet route (ip route add <subnetCIDR> via <gatewayIP> dev <linkToName>)
668+
_, subnetIPNet, _ := net.ParseCIDR(subnetCIDR.String())
669+
dstIP := net.IPNet{IP: net.ParseIP(defaultGw), Mask: subnetIPNet.Mask}
670+
routeInfo = RouteInfo{
671+
Dst: dstIP,
672+
Gw: gWIP,
673+
Table: table,
674+
}
675+
676+
if err := addRoutes(client.netlink, client.netioshim, linkToName, []RouteInfo{routeInfo}); err != nil {
677+
return err
678+
}
679+
return nil
680+
}
681+
617682
// Helper that creates arp entry for the current NS which maps the virtual
618683
// gateway (169.254.2.1) to destMac on a particular interfaceName
619684
// Example: (169.254.2.1) at 12:34:56:78:9a:bc [ether] PERM on <interfaceName>

0 commit comments

Comments
 (0)