Skip to content
1 change: 1 addition & 0 deletions cni/network/multitenancy.go
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,7 @@ func (m *Multitenancy) GetAllNetworkContainers(
ifInfo.IPConfigs = append(ifInfo.IPConfigs, ipconfig)
ifInfo.Routes = routes
ifInfo.NICType = cns.InfraNIC
ifInfo.SkipDefaultRoutes = ncResponses[i].SkipDefaultRoutes

// assuming we only assign infra nics in this function
ipamResult.interfaceInfo[m.getInterfaceInfoKey(ifInfo.NICType, i)] = ifInfo
Expand Down
2 changes: 1 addition & 1 deletion cni/network/network_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ func platformInit(cniConfig *cni.NetworkConfig) {}

// isDualNicFeatureSupported returns if the dual nic feature is supported. Currently it's only supported for windows hnsv2 path
func (plugin *NetPlugin) isDualNicFeatureSupported(netNs string) bool {
return false
return true
}

func getOverlayGateway(_ *net.IPNet) (net.IP, error) {
Expand Down
6 changes: 4 additions & 2 deletions cns/NetworkContainerContract.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ type CreateNetworkContainerRequest struct {
Routes []Route
AllowHostToNCCommunication bool
AllowNCToHostCommunication bool
SkipDefaultRoutes bool
EndpointPolicies []NetworkContainerRequestPolicies
NCStatus v1alpha.NCStatus
NetworkInterfaceInfo NetworkInterfaceInfo //nolint // introducing new field for backendnic, to be used later by cni code
Expand Down Expand Up @@ -161,10 +162,10 @@ func (req *CreateNetworkContainerRequest) String() string {
return fmt.Sprintf("CreateNetworkContainerRequest"+
"{Version: %s, NetworkContainerType: %s, NetworkContainerid: %s, PrimaryInterfaceIdentifier: %s, "+
"LocalIPConfiguration: %+v, IPConfiguration: %+v, SecondaryIPConfigs: %+v, MultitenancyInfo: %+v, "+
"AllowHostToNCCommunication: %t, AllowNCToHostCommunication: %t, NCStatus: %s, NetworkInterfaceInfo: %+v}",
"AllowHostToNCCommunication: %t, AllowNCToHostCommunication: %t, SkipDefaultRoutes: %t, NCStatus: %s, NetworkInterfaceInfo: %+v}",
req.Version, req.NetworkContainerType, req.NetworkContainerid, req.PrimaryInterfaceIdentifier, req.LocalIPConfiguration,
req.IPConfiguration, req.SecondaryIPConfigs, req.MultiTenancyInfo, req.AllowHostToNCCommunication, req.AllowNCToHostCommunication,
string(req.NCStatus), req.NetworkInterfaceInfo)
req.SkipDefaultRoutes, string(req.NCStatus), req.NetworkInterfaceInfo)
}

// NetworkContainerRequestPolicies - specifies policies associated with create network request
Expand Down Expand Up @@ -497,6 +498,7 @@ type GetNetworkContainerResponse struct {
Response Response
AllowHostToNCCommunication bool
AllowNCToHostCommunication bool
SkipDefaultRoutes bool
NetworkInterfaceInfo NetworkInterfaceInfo
}

Expand Down
37 changes: 37 additions & 0 deletions cns/NetworkContainerContract_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -240,3 +240,40 @@ func TestPostNetworkContainersRequest_Validate(t *testing.T) {
})
}
}

func TestCreateNetworkContainerRequest_SkipDefaultRoutes(t *testing.T) {
tests := []struct {
name string
req CreateNetworkContainerRequest
expected bool
}{
{
name: "SkipDefaultRoutesTrue",
req: CreateNetworkContainerRequest{
NetworkContainerid: "f47ac10b-58cc-0372-8567-0e02b2c3d479",
SkipDefaultRoutes: true,
},
expected: true,
},
{
name: "SkipDefaultRoutesFalse",
req: CreateNetworkContainerRequest{
NetworkContainerid: "f47ac10b-58cc-0372-8567-0e02b2c3d479",
SkipDefaultRoutes: false,
},
expected: false,
},
{
name: "SkipDefaultRoutesIgnored",
req: CreateNetworkContainerRequest{
NetworkContainerid: "f47ac10b-58cc-0372-8567-0e02b2c3d479",
},
expected: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert.Equal(t, tt.expected, tt.req.SkipDefaultRoutes, "SkipDefaultRoutes value should match expected")
})
}
}
4 changes: 4 additions & 0 deletions cns/restserver/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -530,6 +530,7 @@ func (service *HTTPRestService) getAllNetworkContainerResponses(
LocalIPConfiguration: savedReq.LocalIPConfiguration,
AllowHostToNCCommunication: savedReq.AllowHostToNCCommunication,
AllowNCToHostCommunication: savedReq.AllowNCToHostCommunication,
SkipDefaultRoutes: savedReq.SkipDefaultRoutes,
NetworkInterfaceInfo: savedReq.NetworkInterfaceInfo,
}

Expand Down Expand Up @@ -831,6 +832,8 @@ func (service *HTTPRestService) populateIPConfigInfoUntransacted(ipConfigStatus

primaryIPCfg := ncStatus.CreateNetworkContainerRequest.IPConfiguration

podIPInfo.SkipDefaultRoutes = ncStatus.CreateNetworkContainerRequest.SkipDefaultRoutes

podIPInfo.PodIPConfig = cns.IPSubnet{
IPAddress: ipConfigStatus.IPAddress,
PrefixLength: primaryIPCfg.IPSubnet.PrefixLength,
Expand Down Expand Up @@ -933,6 +936,7 @@ func (service *HTTPRestService) handleGetNetworkContainers(w http.ResponseWriter
LocalIPConfiguration: ncDetails.CreateNetworkContainerRequest.LocalIPConfiguration,
AllowHostToNCCommunication: ncDetails.CreateNetworkContainerRequest.AllowHostToNCCommunication,
AllowNCToHostCommunication: ncDetails.CreateNetworkContainerRequest.AllowNCToHostCommunication,
SkipDefaultRoutes: ncDetails.CreateNetworkContainerRequest.SkipDefaultRoutes,
}
networkContainers[i] = getNcResp
i++
Expand Down
33 changes: 32 additions & 1 deletion network/transparent_vlan_endpointclient_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -400,14 +400,38 @@
return nil
}

// Set ARP proxy on the vlan interface to respond to ARP requests for the gateway IP
func (client *TransparentVlanEndpointClient) setArpProxy(ifName string) error {
cmd := fmt.Sprintf("echo 1 > /proc/sys/net/ipv4/conf/%v/proxy_arp", ifName)
_, err := client.plClient.ExecuteRawCommand(cmd)
if err != nil {
logger.Error("Failed to set ARP proxy", zap.String("interface", ifName), zap.Error(err))
} else {
logger.Info("ARP proxy enabled", zap.String("interface", ifName))
}
return err

Check failure on line 412 in network/transparent_vlan_endpointclient_linux.go

View workflow job for this annotation

GitHub Actions / Lint (ubuntu-latest)

error returned from interface method should be wrapped: sig: func (github.com/Azure/azure-container-networking/platform.ExecClient).ExecuteRawCommand(command string) (string, error) (wrapcheck)
}

func (client *TransparentVlanEndpointClient) AddEndpointRules(epInfo *EndpointInfo) error {
if err := client.AddSnatEndpointRules(); err != nil {
return errors.Wrap(err, "failed to add snat endpoint rules")
}
logger.Info("[transparent-vlan] Adding tunneling rules in vnet namespace")
err := ExecuteInNS(client.nsClient, client.vnetNSName, func() error {
return client.AddVnetRules(epInfo)
if err := client.AddVnetRules(epInfo); err != nil {
return err
}

// Set ARP proxy on vnet veth (inside vnet namespace)
logger.Info("calling setArpProxy for", zap.String("vnetVethName", client.vnetVethName))
if err := client.setArpProxy(client.vnetVethName); err != nil {
logger.Error("setArpProxy failed with", zap.Error(err))
return err
}

return nil
})

return err
}

Expand Down Expand Up @@ -519,9 +543,16 @@
}
}

if epInfo.SkipDefaultRoutes {
logger.Info("Skipping adding routes in container ns as requested")
return nil
}

logger.Info("Adding default routes in container ns")
if err := client.addDefaultRoutes(client.containerVethName, 0); err != nil {
return errors.Wrap(err, "failed container ns add default routes")
}

if err := client.AddDefaultArp(client.containerVethName, client.vnetMac.String()); err != nil {
return errors.Wrap(err, "failed container ns add default arp")
}
Expand Down
72 changes: 72 additions & 0 deletions network/transparent_vlan_endpointclient_linux_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -867,6 +867,74 @@
wantErr: true,
wantErrMsg: "failed container ns add default routes: addRoutes failed: " + netio.ErrMockNetIOFail.Error() + ":B1veth0",
},
{
name: "Configure interface and routes good path with SkipDefaultRoutes set to true for container",
client: &TransparentVlanEndpointClient{
primaryHostIfName: "eth0",
vlanIfName: "eth0.1",
vnetVethName: "A1veth0",
containerVethName: "B1veth0",
vnetNSName: "az_ns_1",
vnetMac: vnetMac,
netlink: netlink.NewMockNetlink(false, ""),
plClient: platform.NewMockExecClient(false),
netUtilsClient: networkutils.NewNetworkUtils(nl, plc),
netioshim: netio.NewMockNetIO(false, 0),
},
epInfo: &EndpointInfo{
SkipDefaultRoutes: true,
IPAddresses: []net.IPNet{
{
IP: net.ParseIP("192.168.0.4"),
Mask: net.CIDRMask(subnetv4Mask, ipv4Bits),
},
},
Subnets: []SubnetInfo{
{
Gateway: net.ParseIP("192.168.0.1"),
Prefix: net.IPNet{
IP: net.ParseIP("192.168.0.0"),
Mask: net.CIDRMask(subnetv4Mask, ipv4Bits),
},
},
},
},
wantErr: false,
},
{
name: "Configure interface and routes good path with SkipDefaultRoutes set to false for container",
client: &TransparentVlanEndpointClient{
primaryHostIfName: "eth0",
vlanIfName: "eth0.1",
vnetVethName: "A1veth0",
containerVethName: "B1veth0",
vnetNSName: "az_ns_1",
vnetMac: vnetMac,
netlink: netlink.NewMockNetlink(false, ""),
plClient: platform.NewMockExecClient(false),
netUtilsClient: networkutils.NewNetworkUtils(nl, plc),
netioshim: netio.NewMockNetIO(false, 0),
},
epInfo: &EndpointInfo{
SkipDefaultRoutes: true,
IPAddresses: []net.IPNet{
{
IP: net.ParseIP("192.168.0.4"),
Mask: net.CIDRMask(subnetv4Mask, ipv4Bits),
},
},
Subnets: []SubnetInfo{
{
Gateway: net.ParseIP("192.168.0.1"),
Prefix: net.IPNet{
IP: net.ParseIP("192.168.0.0"),
Mask: net.CIDRMask(subnetv4Mask, ipv4Bits),
},
},
},
},
wantErr: false,
},
}

for _, tt := range tests {
Expand Down Expand Up @@ -1008,3 +1076,7 @@
})
}
}

func TestAddCustomRoutes(t *testing.T) {

Check failure on line 1080 in network/transparent_vlan_endpointclient_linux_test.go

View workflow job for this annotation

GitHub Actions / Lint (ubuntu-latest)

unused-parameter: parameter 't' seems to be unused, consider removing or renaming it as _ (revive)

Check failure on line 1081 in network/transparent_vlan_endpointclient_linux_test.go

View workflow job for this annotation

GitHub Actions / Lint (ubuntu-latest)

File is not properly formatted (gofumpt)
}
Loading