Skip to content

Commit 6cdc585

Browse files
committed
Prefix on NIC v6 support
1 parent dbd474a commit 6cdc585

File tree

13 files changed

+84
-235
lines changed

13 files changed

+84
-235
lines changed

azure-ipam/ipam.go

Lines changed: 28 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ func (p *IPAMPlugin) CmdAdd(args *cniSkel.CmdArgs) error {
8181
p.logger.Debug("Making request to CNS")
8282
// if this fails, the caller plugin should execute again with cmdDel before returning error.
8383
// https://www.cni.dev/docs/spec/#delegated-plugin-execution-procedure
84-
resp, err := p.cnsClient.RequestIPs(context.TODO(), req) // need to add interfaces to this response
84+
resp, err := p.cnsClient.RequestIPs(context.TODO(), req)
8585
if err != nil {
8686
if cnscli.IsUnsupportedAPI(err) {
8787
p.logger.Error("Failed to request IPs using RequestIPs from CNS, going to try RequestIPAddress", zap.Error(err), zap.Any("request", req))
@@ -113,10 +113,9 @@ func (p *IPAMPlugin) CmdAdd(args *cniSkel.CmdArgs) error {
113113
}
114114
}
115115
p.logger.Debug("Received CNS IP config response", zap.Any("response", resp))
116-
// resp.PodIPInfo
117116

118117
// Get Pod IP and gateway IP from ip config response
119-
podIPNet, gatewayIP, err := ipconfig.ProcessIPConfigsResp(resp) // need to get interfaces out of the response and add it here
118+
podIPNet, gatewayIP, err := ipconfig.ProcessIPConfigsResp(resp)
120119
if err != nil {
121120
p.logger.Error("Failed to interpret CNS IPConfigResponse", zap.Error(err), zap.Any("response", resp))
122121
return cniTypes.NewError(ErrProcessIPConfigResponse, err.Error(), "failed to interpret CNS IPConfigResponse")
@@ -131,37 +130,43 @@ func (p *IPAMPlugin) CmdAdd(args *cniSkel.CmdArgs) error {
131130
IP: net.ParseIP(ipNet.Addr().String()),
132131
Mask: net.CIDRMask(ipNet.Bits(), 32), // nolint
133132
}
134-
135-
ipConfig.Gateway = (*gatewayIP)[i]
136-
p.logger.Debug("Gatewayv4", zap.String("Gatewayv4", ipConfig.Gateway.String()))
137133
} else {
138134
ipConfig.Address = net.IPNet{
139135
IP: net.ParseIP(ipNet.Addr().String()),
140136
Mask: net.CIDRMask(ipNet.Bits(), 128), // nolint
141137
}
142-
143-
ipConfig.Gateway = (*gatewayIP)[i]
144-
p.logger.Debug("Gatewayv6", zap.String("Gatewayv6", ipConfig.Gateway.String()))
145-
//ipConfig.Gateway = net.ParseIP("fd00:aec6:6946:1::")
146-
if ipConfig.Gateway == nil {
147-
//ipConfig.Gateway = net.ParseIP("fd00:aec6:6946:1::")
148-
//p.logger.Debug("DummyGatewayv6", zap.String("Gatewayv6", ipConfig.Gateway.String()))
149-
}
150138
}
139+
ipConfig.Gateway = (*gatewayIP)[i]
151140
cniResult.IPs[i] = ipConfig
152141
}
153142

154-
p.logger.Info("MACAddress:", zap.Any("MACAddress", resp.PodIPInfo[0].MacAddress))
143+
cniResult.Interfaces = []*types100.Interface{}
144+
seenInterfaces := map[string]bool{}
155145

156-
cniResult.Interfaces = make([]*types100.Interface, 1)
157-
interface_test := &types100.Interface{
158-
Name: "eth1",
159-
//Mac: "00-0D-3A-6F-11-DE",
160-
Mac: resp.PodIPInfo[0].MacAddress,
161-
}
162-
cniResult.Interfaces[0] = interface_test
146+
for _, podIPInfo := range resp.PodIPInfo {
147+
if podIPInfo.MacAddress == "" {
148+
continue
149+
}
163150

164-
p.logger.Info("Created CNIResult:", zap.Any("result", cniResult))
151+
// Skip if interface already seen
152+
// This is to avoid duplicate interfaces in the result
153+
// which can happen if multiple IPs are assigned to the same interface
154+
// or if multiple interfaces are assigned to the same pod
155+
if seenInterfaces[podIPInfo.MacAddress] {
156+
continue
157+
}
158+
159+
infMac, err := net.ParseMAC(podIPInfo.MacAddress)
160+
if err != nil {
161+
p.logger.Error("Failed to parse interface MAC address", zap.Error(err), zap.String("macAddress", podIPInfo.MacAddress))
162+
return cniTypes.NewError(cniTypes.ErrUnsupportedField, err.Error(), "failed to parse interface MAC address")
163+
}
164+
165+
cniResult.Interfaces = append(cniResult.Interfaces, &types100.Interface{
166+
Mac: infMac.String(),
167+
})
168+
seenInterfaces[podIPInfo.MacAddress] = true
169+
}
165170

166171
// Get versioned result
167172
versionedCniResult, err := cniResult.GetAsVersion(nwCfg.CNIVersion)

azure-ipam/ipconfig/ipconfig.go

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ func ProcessIPConfigsResp(resp *cns.IPConfigsResponse) (*[]netip.Prefix, *[]net.
6969
gatewaysIPs := make([]net.IP, len(resp.PodIPInfo))
7070

7171
for i := range resp.PodIPInfo {
72+
var gatewayIP net.IP
73+
7274
podCIDR := fmt.Sprintf(
7375
"%s/%d",
7476
resp.PodIPInfo[i].PodIPConfig.IPAddress,
@@ -81,21 +83,14 @@ func ProcessIPConfigsResp(resp *cns.IPConfigsResponse) (*[]netip.Prefix, *[]net.
8183
podIPNets[i] = podIPNet
8284

8385
if podIPNet.Addr().Is4() {
84-
gatewayIP := net.ParseIP(resp.PodIPInfo[i].NetworkContainerPrimaryIPConfig.GatewayIPAddress)
85-
86-
if gatewayIP == nil {
87-
return nil, nil, errors.New("cns returned invalid gateway IP address")
88-
}
89-
gatewaysIPs[i] = gatewayIP
86+
gatewayIP = net.ParseIP(resp.PodIPInfo[i].NetworkContainerPrimaryIPConfig.GatewayIPAddress)
9087
} else if podIPNet.Addr().Is6() {
91-
gatewayIP := net.ParseIP(resp.PodIPInfo[i].NetworkContainerPrimaryIPConfig.GatewayIPv6Address)
88+
gatewayIP = net.ParseIP(resp.PodIPInfo[i].NetworkContainerPrimaryIPConfig.GatewayIPv6Address)
89+
}
9290

93-
if gatewayIP == nil {
94-
return nil, nil, errors.New("cns returned invalid gateway IPv6 address")
95-
}
91+
if gatewayIP != nil {
9692
gatewaysIPs[i] = gatewayIP
9793
}
98-
9994
}
10095

10196
return &podIPNets, &gatewaysIPs, nil

cns/NetworkContainerContract.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,6 @@ type CreateNetworkContainerRequest struct {
129129
EndpointPolicies []NetworkContainerRequestPolicies
130130
NCStatus v1alpha.NCStatus
131131
NetworkInterfaceInfo NetworkInterfaceInfo //nolint // introducing new field for backendnic, to be used later by cni code
132-
IPFamilies map[IPFamily]struct{}
133132
}
134133

135134
func (req *CreateNetworkContainerRequest) Validate() error {

cns/imds/client.go

Lines changed: 0 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,9 @@ package imds
66
import (
77
"context"
88
"encoding/json"
9-
"fmt"
10-
"io/ioutil"
119
"net/http"
1210
"net/url"
1311

14-
"github.com/Azure/azure-container-networking/cns/logger"
1512
"github.com/avast/retry-go/v4"
1613
"github.com/pkg/errors"
1714
)
@@ -62,17 +59,6 @@ var (
6259
ErrUnexpectedStatusCode = errors.New("imds returned an unexpected status code")
6360
)
6461

65-
// Define struct for Network Interface
66-
type NetworkInterface struct {
67-
MacAddress string `json:"macAddress"`
68-
NcID string `json:"ncId"`
69-
}
70-
71-
// Define struct for Network
72-
type Network struct {
73-
Interface []NetworkInterface `json:"interface"`
74-
}
75-
7662
// NewClient creates a new imds client
7763
func NewClient(opts ...ClientOption) *Client {
7864
config := clientConfig{
@@ -94,41 +80,15 @@ func (c *Client) GetVMUniqueID(ctx context.Context) (string, error) {
9480
var vmUniqueID string
9581
err := retry.Do(func() error {
9682
computeDoc, err := c.getInstanceComputeMetadata(ctx)
97-
9883
if err != nil {
9984
return errors.Wrap(err, "error getting IMDS compute metadata")
10085
}
101-
102-
// logger.Printf("Complete IMDS call response: %v", computeDoc)
103-
// macaddressData, ok1 := computeDoc["macaddress"].(string)
104-
// if !ok1 {
105-
// return errors.New("unable to parse IMDS macaddress metadata")
106-
// }
107-
// logger.Printf("Complete IMDS call response[network]: %v", macaddressData)
108-
109-
// ncidData, ok2 := computeDoc["ncId"].(string)
110-
// if !ok2 {
111-
// return errors.New("unable to parse IMDS ncid metadata")
112-
// }
113-
// logger.Printf("Complete IMDS call response[network][macaddress]: %v", ncidData)
114-
11586
vmUniqueIDUntyped := computeDoc[vmUniqueIDProperty]
11687
var ok bool
11788
vmUniqueID, ok = vmUniqueIDUntyped.(string)
11889
if !ok {
11990
return errors.New("unable to parse IMDS compute metadata, vmId property is not a string")
12091
}
121-
122-
networkDoc, err := c.getInstanceInterfaceMacaddress(ctx)
123-
124-
if err != nil {
125-
errors.Wrap(err, "error getting IMDS interface metadata")
126-
} else {
127-
for _, int := range networkDoc.Interface {
128-
logger.Printf("Complete IMDS call [macaddress]: %s, [ncId]: %s", int.MacAddress, int.NcID)
129-
}
130-
}
131-
13292
return nil
13393
}, retry.Context(ctx), retry.Attempts(c.config.retryAttempts), retry.DelayType(retry.BackOffDelay))
13494
if err != nil {
@@ -166,52 +126,10 @@ func (c *Client) getInstanceComputeMetadata(ctx context.Context) (map[string]any
166126
return nil, errors.Wrapf(ErrUnexpectedStatusCode, "unexpected status code %d", resp.StatusCode)
167127
}
168128

169-
logger.Printf("Complete IMDS call response body: %v", resp.Body)
170-
171129
var m map[string]any
172130
if err := json.NewDecoder(resp.Body).Decode(&m); err != nil {
173131
return nil, errors.Wrap(err, "error decoding IMDS response as json")
174132
}
175133

176134
return m, nil
177135
}
178-
179-
func (c *Client) getInstanceInterfaceMacaddress(ctx context.Context) (Network, error) {
180-
imdsComputeURL, err := url.JoinPath(c.config.endpoint, "/metadata/instance/network")
181-
if err != nil {
182-
return Network{}, errors.Wrap(err, "unable to build path to IMDS interface metadata")
183-
}
184-
imdsComputeURL = imdsComputeURL + "?" + imdsComputeAPIVersion + "&" + imdsFormatJSON
185-
186-
req, err := http.NewRequestWithContext(ctx, http.MethodGet, imdsComputeURL, http.NoBody)
187-
if err != nil {
188-
return Network{}, errors.Wrap(err, "error building IMDS http request")
189-
}
190-
191-
// IMDS requires the "Metadata: true" header
192-
req.Header.Add(metadataHeaderKey, metadataHeaderValue)
193-
resp, err := c.cli.Do(req)
194-
if err != nil {
195-
return Network{}, errors.Wrap(err, "error querying IMDS")
196-
}
197-
defer resp.Body.Close()
198-
199-
if resp.StatusCode != http.StatusOK {
200-
return Network{}, errors.Wrapf(ErrUnexpectedStatusCode, "unexpected status code %d", resp.StatusCode)
201-
}
202-
203-
body, err := ioutil.ReadAll(resp.Body)
204-
if err != nil {
205-
fmt.Println("Error reading response:", err)
206-
return Network{}, err
207-
}
208-
209-
logger.Printf("Complete IMDS call response body: %v", body)
210-
211-
var m Network
212-
if err := json.Unmarshal(body, &m); err != nil { // .NewDecoder(resp.Body).Decode(&m); err != nil {
213-
return Network{}, errors.Wrap(err, "error decoding IMDS response as json")
214-
}
215-
216-
return m, nil
217-
}

cns/kubecontroller/nodenetworkconfig/conversion.go

Lines changed: 0 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,7 @@ import (
77
"strings"
88

99
"github.com/Azure/azure-container-networking/cns"
10-
"github.com/Azure/azure-container-networking/cns/logger"
1110
"github.com/Azure/azure-container-networking/crd/nodenetworkconfig/api/v1alpha"
12-
"github.com/Azure/azure-container-networking/netlink"
1311
"github.com/pkg/errors"
1412
)
1513

@@ -104,46 +102,5 @@ func CreateNCRequestFromStaticNC(nc v1alpha.NetworkContainer) (*cns.CreateNetwor
104102
return nil, errors.Wrapf(err, "error while creating NC request from static NC")
105103
}
106104

107-
logger.Printf("[CreateNCRequestFromStaticNC] Created NC request %+v", req)
108-
109-
err = assignIPToDelegatedNIC(nc)
110-
111105
return req, err
112106
}
113-
114-
func assignIPToDelegatedNIC(nc v1alpha.NetworkContainer) error {
115-
logger.Printf("[assignIPToDelegatedNIC] Before Assign IP to the Delegated NIC")
116-
117-
// Assign IP to the Delegated NIC
118-
nl := netlink.NewNetlink()
119-
120-
if nl == nil {
121-
logger.Printf("failed to create netlink handle")
122-
return errors.New("failed to create netlink handle")
123-
}
124-
125-
ip, addr, _ := net.ParseCIDR(nc.PrimaryIP)
126-
127-
logger.Printf("[assignIPToDelegatedNIC] ip %s addr %s", ip, addr)
128-
129-
err := nl.AddIPAddress("eth1", ip, addr)
130-
131-
if err != nil {
132-
errors.Wrapf(err, "failed to assign IP to delegated NIC")
133-
}
134-
135-
ipv6, addrv6, _ := net.ParseCIDR(nc.PrimaryIPv6)
136-
137-
logger.Printf("[assignIPToDelegatedNIC] ip %s addr %s", ipv6, addrv6)
138-
139-
if ipv6 != nil {
140-
errv6 := nl.AddIPAddress("eth1", ipv6, addrv6)
141-
142-
if errv6 != nil {
143-
errors.Wrapf(errv6, "failed to assign V6 IP to delegated NIC")
144-
}
145-
}
146-
147-
logger.Printf("[assignIPToDelegatedNIC] After Assign IP to the Delegated NIC")
148-
return err
149-
}

cns/kubecontroller/nodenetworkconfig/conversion_linux.go

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

33
import (
4-
"fmt"
54
"net/netip"
65
"strconv"
76

@@ -16,7 +15,6 @@ import (
1615
//nolint:gocritic //ignore hugeparam
1716
func createNCRequestFromStaticNCHelper(nc v1alpha.NetworkContainer, primaryIPPrefix netip.Prefix, subnet cns.IPSubnet) (*cns.CreateNetworkContainerRequest, error) {
1817
secondaryIPConfigs := map[string]cns.SecondaryIPConfig{}
19-
ipFamilies := map[cns.IPFamily]struct{}{}
2018

2119
// in the case of vnet prefix on swift v2 the primary IP is a /32 and should not be added to secondary IP configs
2220
if !primaryIPPrefix.IsSingleIP() {
@@ -28,20 +26,12 @@ func createNCRequestFromStaticNCHelper(nc v1alpha.NetworkContainer, primaryIPPre
2826
NCVersion: int(nc.Version),
2927
}
3028
}
31-
32-
// adds the IPFamily of the primary CIDR to the set
33-
if primaryIPPrefix.Addr().Is4() {
34-
ipFamilies[cns.IPv4Family] = struct{}{}
35-
} else {
36-
ipFamilies[cns.IPv6Family] = struct{}{}
37-
}
3829
}
3930

4031
// Add IPs from CIDR block to the secondary IPConfigs
4132
if nc.Type == v1alpha.VNETBlock {
4233

4334
for _, ipAssignment := range nc.IPAssignments {
44-
// Here we would need to check all other assigned CIDR Blocks that aren't the primary.
4535
cidrPrefix, err := netip.ParsePrefix(ipAssignment.IP)
4636
if err != nil {
4737
return nil, errors.Wrapf(err, "invalid CIDR block: %s", ipAssignment.IP)
@@ -55,18 +45,9 @@ func createNCRequestFromStaticNCHelper(nc v1alpha.NetworkContainer, primaryIPPre
5545
NCVersion: int(nc.Version),
5646
}
5747
}
58-
59-
// adds the IPFamily of the secondary CIDR to the set
60-
if cidrPrefix.Addr().Is4() {
61-
ipFamilies[cns.IPv4Family] = struct{}{}
62-
} else {
63-
ipFamilies[cns.IPv6Family] = struct{}{}
64-
}
6548
}
6649
}
6750

68-
fmt.Printf("IPFamilies found on NC %+v are %+v", nc.ID, ipFamilies)
69-
7051
return &cns.CreateNetworkContainerRequest{
7152
HostPrimaryIP: nc.NodeIP,
7253
SecondaryIPConfigs: secondaryIPConfigs,
@@ -76,10 +57,9 @@ func createNCRequestFromStaticNCHelper(nc v1alpha.NetworkContainer, primaryIPPre
7657
IPConfiguration: cns.IPConfiguration{
7758
IPSubnet: subnet,
7859
GatewayIPAddress: nc.DefaultGateway,
79-
GatewayIPv6Address: nc.DefaultGatewayIPv6,
60+
GatewayIPv6Address: nc.DefaultGatewayV6,
8061
},
81-
NCStatus: nc.Status,
82-
IPFamilies: ipFamilies,
62+
NCStatus: nc.Status,
8363
NetworkInterfaceInfo: cns.NetworkInterfaceInfo{
8464
MACAddress: nc.MacAddress,
8565
},

0 commit comments

Comments
 (0)