Skip to content

Commit 41b7122

Browse files
authored
fix: return error on interface not found and always clean up snat ep (#3226)
* return error on interface not found and always clean up snat ep * modify snat client to accept interfaces for unit testing * address linter issues
1 parent 021cab2 commit 41b7122

9 files changed

+68
-23
lines changed

network/endpoint.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ type apipaClient interface {
151151
}
152152

153153
func (epInfo *EndpointInfo) PrettyString() string {
154-
return fmt.Sprintf("Id:%s ContainerID:%s NetNsPath:%s IfName:%s IfIndex:%d MacAddr:%s IPAddrs:%v Gateways:%v Data:%+v NICType: %s NetworkContainerID: %s HostIfName: %s NetNs: %s Options: %v",
154+
return fmt.Sprintf("EndpointID:%s ContainerID:%s NetNsPath:%s IfName:%s IfIndex:%d MacAddr:%s IPAddrs:%v Gateways:%v Data:%+v NICType: %s NetworkContainerID: %s HostIfName: %s NetNs: %s Options: %v",
155155
epInfo.EndpointID, epInfo.ContainerID, epInfo.NetNsPath, epInfo.IfName, epInfo.IfIndex, epInfo.MacAddress.String(), epInfo.IPAddresses,
156156
epInfo.Gateways, epInfo.Data, epInfo.NICType, epInfo.NetworkContainerID, epInfo.HostIfName, epInfo.NetNs, epInfo.Options)
157157
}

network/endpoint_linux.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,6 @@ func (nw *network) deleteEndpointImpl(nl netlink.NetlinkInterface, plc platform.
279279
epInfo := ep.getInfo()
280280
if nw.Mode == opModeTransparentVlan {
281281
epClient = NewTransparentVlanEndpointClient(nw, epInfo, ep.HostIfName, "", ep.VlanID, ep.LocalIP, nl, plc, nsc, iptc)
282-
283282
} else {
284283
epClient = NewOVSEndpointClient(nw, epInfo, ep.HostIfName, "", ep.VlanID, ep.LocalIP, nl, ovsctl.NewOvsctl(), plc, iptc)
285284
}

network/manager.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,7 @@ func (nm *networkManager) UpdateEndpointState(eps []*endpoint) error {
439439
logger.Info("Update endpoint API returend ", zap.String("podname: ", response.ReturnCode.String()))
440440
return nil
441441
}
442+
442443
func validateUpdateEndpointState(endpointID string, ifNameToIPInfoMap map[string]*restserver.IPInfo) error {
443444
if endpointID == "" {
444445
return errors.New("endpoint id empty while validating update endpoint state")

network/ovs_endpoint_snatroute_linux.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ func (client *OVSEndpointClient) NewSnatClient(snatBridgeIP, localIP string, epI
3333
client.netlink,
3434
client.plClient,
3535
client.iptablesClient,
36+
client.netioshim,
3637
)
3738
}
3839
}

network/snat/snat_linux.go

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"github.com/Azure/azure-container-networking/cni/log"
1212
"github.com/Azure/azure-container-networking/ebtables"
1313
"github.com/Azure/azure-container-networking/iptables"
14+
"github.com/Azure/azure-container-networking/netio"
1415
"github.com/Azure/azure-container-networking/netlink"
1516
"github.com/Azure/azure-container-networking/network/networkutils"
1617
"github.com/Azure/azure-container-networking/platform"
@@ -55,6 +56,7 @@ type Client struct {
5556
netlink netlink.NetlinkInterface
5657
plClient platform.ExecClient
5758
ipTablesClient ipTablesClient
59+
netioClient netio.NetIOInterface
5860
}
5961

6062
func NewSnatClient(hostIfName string,
@@ -67,6 +69,7 @@ func NewSnatClient(hostIfName string,
6769
nl netlink.NetlinkInterface,
6870
plClient platform.ExecClient,
6971
iptc ipTablesClient,
72+
nio netio.NetIOInterface,
7073
) Client {
7174
snatClient := Client{
7275
hostSnatVethName: hostIfName,
@@ -78,6 +81,7 @@ func NewSnatClient(hostIfName string,
7881
netlink: nl,
7982
plClient: plClient,
8083
ipTablesClient: iptc,
84+
netioClient: nio,
8185
}
8286

8387
snatClient.SkipAddressesFromBlock = append(snatClient.SkipAddressesFromBlock, skipAddressesFromBlock...)
@@ -223,7 +227,11 @@ func (client *Client) AllowInboundFromHostToNC() error {
223227
return newErrorSnatClient(err.Error())
224228
}
225229

226-
snatContainerVeth, _ := net.InterfaceByName(client.containerSnatVethName)
230+
snatContainerVeth, err := client.netioClient.GetNetworkInterfaceByName(client.containerSnatVethName)
231+
if err != nil {
232+
logger.Info("Could not find interface", zap.String("containerSnatVethName", client.containerSnatVethName))
233+
return errors.Wrap(newErrorSnatClient(err.Error()), "could not find container snat veth name for allow host to nc")
234+
}
227235

228236
// Add static arp entry for localIP to prevent arp going out of VM
229237
logger.Info("Adding static arp entry for ip", zap.Any("containerIP", containerIP),
@@ -319,7 +327,11 @@ func (client *Client) AllowInboundFromNCToHost() error {
319327
return err
320328
}
321329

322-
snatContainerVeth, _ := net.InterfaceByName(client.containerSnatVethName)
330+
snatContainerVeth, err := client.netioClient.GetNetworkInterfaceByName(client.containerSnatVethName)
331+
if err != nil {
332+
logger.Info("Could not find interface", zap.String("containerSnatVethName", client.containerSnatVethName))
333+
return errors.Wrap(newErrorSnatClient(err.Error()), "could not find container snat veth name for allow nc to host")
334+
}
323335

324336
// Add static arp entry for localIP to prevent arp going out of VM
325337
logger.Info("Adding static arp entry for ip", zap.Any("containerIP", containerIP), zap.String("HardwareAddr", snatContainerVeth.HardwareAddr.String()))
@@ -416,7 +428,7 @@ func (client *Client) DropArpForSnatBridgeApipaRange(snatBridgeIP, azSnatVethIfN
416428

417429
// This function creates linux bridge which will be used for outbound connectivity by NCs
418430
func (client *Client) createSnatBridge(snatBridgeIP, hostPrimaryMac string) error {
419-
_, err := net.InterfaceByName(SnatBridgeName)
431+
_, err := client.netioClient.GetNetworkInterfaceByName(SnatBridgeName)
420432
if err == nil {
421433
logger.Info("Snat Bridge already exists")
422434
} else {

network/snat/snat_linux_test.go

Lines changed: 43 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,30 @@ import (
44
"os"
55
"testing"
66

7-
"github.com/Azure/azure-container-networking/iptables"
7+
"github.com/Azure/azure-container-networking/netio"
88
"github.com/Azure/azure-container-networking/netlink"
99
)
1010

1111
var anyInterface = "dummy"
1212

13+
type mockIPTablesClient struct{}
14+
15+
func (c mockIPTablesClient) InsertIptableRule(_, _, _, _, _ string) error {
16+
return nil
17+
}
18+
19+
func (c mockIPTablesClient) AppendIptableRule(_, _, _, _, _ string) error {
20+
return nil
21+
}
22+
23+
func (c mockIPTablesClient) DeleteIptableRule(_, _, _, _, _ string) error {
24+
return nil
25+
}
26+
27+
func (c mockIPTablesClient) CreateChain(_, _, _ string) error {
28+
return nil
29+
}
30+
1331
func TestMain(m *testing.M) {
1432
exitCode := m.Run()
1533

@@ -18,16 +36,22 @@ func TestMain(m *testing.M) {
1836
os.Exit(exitCode)
1937
}
2038

21-
func TestAllowInboundFromHostToNC(t *testing.T) {
22-
nl := netlink.NewNetlink()
23-
iptc := iptables.NewClient()
24-
client := &Client{
39+
func GetTestClient(nl netlink.NetlinkInterface, iptc ipTablesClient, nio netio.NetIOInterface) *Client {
40+
return &Client{
2541
SnatBridgeIP: "169.254.0.1/16",
2642
localIP: "169.254.0.4/16",
2743
containerSnatVethName: anyInterface,
2844
netlink: nl,
2945
ipTablesClient: iptc,
46+
netioClient: nio,
3047
}
48+
}
49+
50+
func TestAllowInboundFromHostToNC(t *testing.T) {
51+
nl := netlink.NewMockNetlink(false, "")
52+
iptc := &mockIPTablesClient{}
53+
nio := netio.NewMockNetIO(false, 0)
54+
client := GetTestClient(nl, iptc, nio)
3155

3256
if err := nl.AddLink(&netlink.DummyLink{
3357
LinkInfo: netlink.LinkInfo{
@@ -65,18 +89,18 @@ func TestAllowInboundFromHostToNC(t *testing.T) {
6589
if err := nl.DeleteLink(SnatBridgeName); err != nil {
6690
t.Errorf("Error removing snat bridge: %v", err)
6791
}
92+
93+
client.netioClient = netio.NewMockNetIO(true, 1)
94+
if err := client.AllowInboundFromHostToNC(); err == nil {
95+
t.Errorf("Expected error when interface not found in allow host to nc but got nil")
96+
}
6897
}
6998

7099
func TestAllowInboundFromNCToHost(t *testing.T) {
71-
nl := netlink.NewNetlink()
72-
iptc := iptables.NewClient()
73-
client := &Client{
74-
SnatBridgeIP: "169.254.0.1/16",
75-
localIP: "169.254.0.4/16",
76-
containerSnatVethName: anyInterface,
77-
netlink: nl,
78-
ipTablesClient: iptc,
79-
}
100+
nl := netlink.NewMockNetlink(false, "")
101+
iptc := &mockIPTablesClient{}
102+
nio := netio.NewMockNetIO(false, 0)
103+
client := GetTestClient(nl, iptc, nio)
80104

81105
if err := nl.AddLink(&netlink.DummyLink{
82106
LinkInfo: netlink.LinkInfo{
@@ -114,4 +138,9 @@ func TestAllowInboundFromNCToHost(t *testing.T) {
114138
if err := nl.DeleteLink(SnatBridgeName); err != nil {
115139
t.Errorf("Error removing snat bridge: %v", err)
116140
}
141+
142+
client.netioClient = netio.NewMockNetIO(true, 1)
143+
if err := client.AllowInboundFromNCToHost(); err == nil {
144+
t.Errorf("Expected error when interface not found in allow nc to host but got nil")
145+
}
117146
}

network/transparent_vlan_endpoint_snatroute_linux.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ func (client *TransparentVlanEndpointClient) NewSnatClient(snatBridgeIP, localIP
2121
client.netlink,
2222
client.plClient,
2323
client.iptablesClient,
24+
client.netioshim,
2425
)
2526
}
2627
}

network/transparent_vlan_endpointclient_linux.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -635,7 +635,7 @@ func (client *TransparentVlanEndpointClient) DeleteEndpoints(ep *endpoint) error
635635
return client.DeleteEndpointsImpl(ep, getNumRoutesLeft)
636636
})
637637
if err != nil {
638-
return err
638+
logger.Warn("could not delete transparent vlan endpoints", zap.String("errorMsg", err.Error()))
639639
}
640640

641641
// VM NS

network/transparent_vlan_endpointclient_linux_test.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,11 @@ import (
1515
"github.com/stretchr/testify/require"
1616
)
1717

18-
var errNetnsMock = errors.New("mock netns error")
19-
var errMockNetIOFail = errors.New("netio fail")
20-
var errMockNetIONoIfFail = &net.OpError{Op: "route", Net: "ip+net", Source: nil, Addr: nil, Err: errors.New("no such network interface")}
18+
var (
19+
errNetnsMock = errors.New("mock netns error")
20+
errMockNetIOFail = errors.New("netio fail")
21+
errMockNetIONoIfFail = &net.OpError{Op: "route", Net: "ip+net", Source: nil, Addr: nil, Err: errors.New("no such network interface")}
22+
)
2123

2224
func newNetnsErrorMock(errStr string) error {
2325
return errors.Wrap(errNetnsMock, errStr)

0 commit comments

Comments
 (0)