@@ -2,6 +2,7 @@ package ovssnat
22
33import (
44 "fmt"
5+ "github.com/Azure/azure-container-networking/ebtables"
56 "net"
67 "strings"
78
@@ -30,20 +31,22 @@ const (
3031
3132type 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
5861func (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