Skip to content

Commit 57fbd94

Browse files
Drop arp request for snatbridge apipa range (#912)
* added snatbridge mac same as eth0 added drop rule for arp request for snat bridge ip * tested the fix and updated ebtable rules * updated function names
1 parent b138a42 commit 57fbd94

File tree

3 files changed

+62
-13
lines changed

3 files changed

+62
-13
lines changed

ebtables/ebtables.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,20 @@ func SetBrouteAcceptByInterface(ifName string, protocol, action, target string)
194194
return runEbCmd(table, action, chain, rule)
195195
}
196196

197+
func SetArpDropRuleForIpCidr(ipCidr string, ifName string) error {
198+
rule := fmt.Sprintf("-p ARP -o %s --arp-op Request --arp-ip-dst %s -j DROP", ifName, ipCidr)
199+
exists, err := EbTableRuleExists(Nat, PostRouting, rule)
200+
if err != nil {
201+
return err
202+
}
203+
204+
if exists {
205+
return nil
206+
}
207+
208+
return runEbCmd(Nat, Append, PostRouting, rule)
209+
}
210+
197211
// EbTableRuleExists checks if eb rule exists in table and chain.
198212
func EbTableRuleExists(tableName, chainName, matchSet string) (bool, error) {
199213
rules, err := GetEbtableRules(tableName, chainName)

network/ovs_endpoint_snatroute_linux.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ func NewSnatClient(client *OVSEndpointClient, snatBridgeIP string, localIP strin
1212
hostIfName := fmt.Sprintf("%s%s", snatVethInterfacePrefix, epInfo.Id[:7])
1313
contIfName := fmt.Sprintf("%s%s-2", snatVethInterfacePrefix, epInfo.Id[:7])
1414

15-
client.snatClient = ovssnat.NewSnatClient(hostIfName, contIfName, localIP, snatBridgeIP, epInfo.DNS.Servers)
15+
client.snatClient = ovssnat.NewSnatClient(hostIfName, contIfName, localIP, snatBridgeIP, client.hostPrimaryMac, epInfo.DNS.Servers)
1616
}
1717
}
1818

network/ovssnat/ovssnat.go

Lines changed: 47 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package ovssnat
22

33
import (
44
"fmt"
5+
"github.com/Azure/azure-container-networking/ebtables"
56
"net"
67
"strings"
78

@@ -30,20 +31,22 @@ const (
3031

3132
type OVSSnatClient struct {
3233
hostSnatVethName string
34+
hostPrimaryMac string
3335
containerSnatVethName string
3436
localIP string
3537
snatBridgeIP string
3638
SkipAddressesFromBlock []string
3739
containerSnatVethMac net.HardwareAddr
3840
}
3941

40-
func NewSnatClient(hostIfName string, contIfName string, localIP string, snatBridgeIP string, skipAddressesFromBlock []string) OVSSnatClient {
42+
func NewSnatClient(hostIfName string, contIfName string, localIP string, snatBridgeIP string, hostPrimaryMac string, skipAddressesFromBlock []string) OVSSnatClient {
4143
log.Printf("Initialize new snat client")
4244
snatClient := OVSSnatClient{
4345
hostSnatVethName: hostIfName,
4446
containerSnatVethName: contIfName,
4547
localIP: localIP,
4648
snatBridgeIP: snatBridgeIP,
49+
hostPrimaryMac: hostPrimaryMac,
4750
}
4851

4952
for _, address := range skipAddressesFromBlock {
@@ -57,7 +60,7 @@ func NewSnatClient(hostIfName string, contIfName string, localIP string, snatBri
5760

5861
func (client *OVSSnatClient) CreateSnatEndpoint(bridgeName string) error {
5962
// Create linux Bridge for outbound connectivity
60-
if err := CreateSnatBridge(client.snatBridgeIP, bridgeName); err != nil {
63+
if err := CreateSnatBridge(client.snatBridgeIP, client.hostPrimaryMac, bridgeName); err != nil {
6164
log.Printf("creating snat bridge failed with error %v", err)
6265
return err
6366
}
@@ -311,26 +314,58 @@ func (client *OVSSnatClient) DeleteSnatEndpoint() error {
311314
return nil
312315
}
313316

317+
func setBridgeMac(hostPrimaryMac string) error {
318+
hwAddr, err := net.ParseMAC(hostPrimaryMac)
319+
if err != nil {
320+
log.Errorf("Error while parsing host primary mac: %s error:%+v", hostPrimaryMac, err)
321+
return err
322+
}
323+
324+
if err = netlink.SetLinkAddress(SnatBridgeName, hwAddr); err != nil {
325+
log.Errorf("Error while setting macaddr on bridge: %s error:%+v", hwAddr.String(), err)
326+
}
327+
return err
328+
}
329+
330+
func dropArpForSnatBridgeApipaRange(snatBridgeIP, azSnatVethIfName string) error {
331+
var err error
332+
_, ipCidr, _ := net.ParseCIDR(snatBridgeIP)
333+
if err = ebtables.SetArpDropRuleForIpCidr(ipCidr.String(), azSnatVethIfName); err != nil {
334+
log.Errorf("Error setting arp drop rule for snatbridge ip :%s", snatBridgeIP)
335+
}
336+
337+
return err
338+
}
339+
314340
/**
315341
This function creates linux bridge which will be used for outbound connectivity by NCs
316342
**/
317-
func CreateSnatBridge(snatBridgeIP string, mainInterface string) error {
343+
func CreateSnatBridge(snatBridgeIP string, hostPrimaryMac string, mainInterface string) error {
318344
_, err := net.InterfaceByName(SnatBridgeName)
319345
if err == nil {
320346
log.Printf("Snat Bridge already exists")
321-
return nil
322-
}
347+
} else {
348+
log.Printf("[net] Creating Snat bridge %v.", SnatBridgeName)
349+
350+
link := netlink.BridgeLink{
351+
LinkInfo: netlink.LinkInfo{
352+
Type: netlink.LINK_TYPE_BRIDGE,
353+
Name: SnatBridgeName,
354+
},
355+
}
323356

324-
log.Printf("[net] Creating Snat bridge %v.", SnatBridgeName)
357+
if err := netlink.AddLink(&link); err != nil {
358+
return err
359+
}
360+
}
325361

326-
link := netlink.BridgeLink{
327-
LinkInfo: netlink.LinkInfo{
328-
Type: netlink.LINK_TYPE_BRIDGE,
329-
Name: SnatBridgeName,
330-
},
362+
log.Printf("Setting snat bridge mac: %s", hostPrimaryMac)
363+
if err := setBridgeMac(hostPrimaryMac); err != nil {
364+
return err
331365
}
332366

333-
if err := netlink.AddLink(&link); err != nil {
367+
log.Printf("Drop ARP for snat bridge ip: %s", snatBridgeIP)
368+
if err := dropArpForSnatBridgeApipaRange(snatBridgeIP, azureSnatVeth0); err != nil {
334369
return err
335370
}
336371

0 commit comments

Comments
 (0)