Skip to content

Commit a01afb7

Browse files
authored
Added EB rule for ip addresses in conflist for linux (#505)
* Added EB rule for ip addresses in conflist for linux * Made methods more generic and removed line from endpoint struct * Adding log statement * Fixed syntax error * Made review2 changes * Made review3 changes * Made method lowercase
1 parent 3587366 commit a01afb7

File tree

6 files changed

+100
-0
lines changed

6 files changed

+100
-0
lines changed

cni/azure-linux.conflist

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
"type":"azure-vnet",
77
"mode":"bridge",
88
"bridge":"azure0",
9+
"ipsToRouteViaHost":["169.254.20.10"],
910
"ipam":{
1011
"type":"azure-vnet-ipam"
1112
}

cni/netconfig.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ type NetworkConfig struct {
5252
LogTarget string `json:"logTarget,omitempty"`
5353
InfraVnetAddressSpace string `json:"infraVnetAddressSpace,omitempty"`
5454
PodNamespaceForDualNetwork []string `json:"podNamespaceForDualNetwork,omitempty"`
55+
IPsToRouteViaHost []string `json:"ipsToRouteViaHost,omitempty"`
5556
MultiTenancy bool `json:"multiTenancy,omitempty"`
5657
EnableSnatOnHost bool `json:"enableSnatOnHost,omitempty"`
5758
EnableExactMatchForPodName bool `json:"enableExactMatchForPodName,omitempty"`

cni/network/network.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -527,6 +527,7 @@ func (plugin *netPlugin) Add(args *cniSkel.CmdArgs) error {
527527
Data: make(map[string]interface{}),
528528
DNS: epDNSInfo,
529529
Policies: policies,
530+
IPsToRouteViaHost: nwCfg.IPsToRouteViaHost,
530531
EnableSnatOnHost: nwCfg.EnableSnatOnHost,
531532
EnableMultiTenancy: nwCfg.MultiTenancy,
532533
EnableInfraVnet: enableInfraVnet,

ebtables/ebtables.go

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"strings"
1212

1313
"github.com/Azure/azure-container-networking/log"
14+
"github.com/Azure/azure-container-networking/platform"
1415
)
1516

1617
const (
@@ -51,6 +52,68 @@ func SetArpReply(ipAddress net.IP, macAddress net.HardwareAddr, action string) e
5152
return executeShellCommand(command)
5253
}
5354

55+
// SetBrouteAccept sets an EB rule.
56+
func SetBrouteAccept(ipAddress, action string) error {
57+
command := fmt.Sprintf(
58+
"ebtables -t broute %s BROUTING --ip-dst %s -p IPv4 -j redirect --redirect-target ACCEPT",
59+
action, ipAddress)
60+
_, err := platform.ExecuteCommand(command)
61+
62+
return err
63+
}
64+
65+
// GetEbtableRules gets EB rules for a table and chain.
66+
func GetEbtableRules(tableName, chainName string) ([]string, error) {
67+
var (
68+
inChain bool
69+
rules []string
70+
)
71+
72+
command := fmt.Sprintf(
73+
"ebtables -t %s -L %s --Lmac2",
74+
tableName, chainName)
75+
out, err := platform.ExecuteCommand(command)
76+
if err != nil {
77+
return nil, err
78+
}
79+
80+
// Splits lines and finds rules.
81+
lines := strings.Split(out, "\n")
82+
chainTitle := fmt.Sprintf("Bridge chain: %s", chainName)
83+
84+
for _, line := range lines {
85+
if strings.HasPrefix(line, chainTitle) {
86+
inChain = true
87+
continue
88+
}
89+
if inChain {
90+
if strings.HasPrefix(line, "-") {
91+
rules = append(rules, strings.TrimSpace(line))
92+
} else {
93+
break
94+
}
95+
}
96+
}
97+
98+
return rules, nil
99+
}
100+
101+
// EbTableRuleExists checks if eb rule exists in table and chain.
102+
func EbTableRuleExists(tableName, chainName, matchSet string) (bool, error) {
103+
rules, err := GetEbtableRules(tableName, chainName)
104+
if err != nil {
105+
return false, err
106+
}
107+
108+
for _, rule := range rules {
109+
if rule == matchSet {
110+
return true, nil
111+
}
112+
}
113+
114+
return false, nil
115+
}
116+
54117
// SetDnatForArpReplies sets a MAC DNAT rule for ARP replies received on an interface.
55118
func SetDnatForArpReplies(interfaceName string, action string) error {
56119
command := fmt.Sprintf(

network/bridge_endpointclient_linux.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package network
22

33
import (
4+
"fmt"
45
"net"
56

67
"github.com/Azure/azure-container-networking/ebtables"
@@ -81,6 +82,8 @@ func (client *LinuxBridgeEndpointClient) AddEndpointRules(epInfo *EndpointInfo)
8182
}
8283
}
8384

85+
addRuleToRouteViaHost(epInfo)
86+
8487
log.Printf("[net] Setting hairpin for hostveth %v", client.hostVethName)
8588
if err := netlink.SetLinkHairpin(client.hostVethName, true); err != nil {
8689
log.Printf("Setting up hairpin failed for interface %v error %v", client.hostVethName, err)
@@ -174,3 +177,33 @@ func (client *LinuxBridgeEndpointClient) DeleteEndpoints(ep *endpoint) error {
174177

175178
return nil
176179
}
180+
181+
func addRuleToRouteViaHost(epInfo *EndpointInfo) error {
182+
for _, ipAddr := range epInfo.IPsToRouteViaHost {
183+
tableName := "broute"
184+
chainName := "BROUTING"
185+
rule := fmt.Sprintf("-p IPv4 --ip-dst %s -j redirect", ipAddr)
186+
187+
// Check if EB rule exists
188+
log.Printf("[net] Checking if EB rule %s already exists in table %s chain %s", rule, tableName, chainName)
189+
exists, err := ebtables.EbTableRuleExists(tableName, chainName, rule)
190+
if err != nil {
191+
log.Printf("[net] Failed to check if EB table rule exists: %v", err)
192+
return err
193+
}
194+
195+
if exists {
196+
// EB rule already exists.
197+
log.Printf("[net] EB rule %s already exists in table %s chain %s.", rule, tableName, chainName)
198+
} else {
199+
// Add EB rule to route via host.
200+
log.Printf("[net] Adding EB rule to route via host for IP address %v", ipAddr)
201+
if err := ebtables.SetBrouteAccept(ipAddr, ebtables.Append); err != nil {
202+
log.Printf("[net] Failed to add EB rule to route via host: %v", err)
203+
return err
204+
}
205+
}
206+
}
207+
208+
return nil
209+
}

network/endpoint.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ type EndpointInfo struct {
5555
MacAddress net.HardwareAddr
5656
DNS DNSInfo
5757
IPAddresses []net.IPNet
58+
IPsToRouteViaHost []string
5859
InfraVnetIP net.IPNet
5960
Routes []RouteInfo
6061
Policies []policy.Policy

0 commit comments

Comments
 (0)