Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 74 additions & 26 deletions cni/network/invoker_cns.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,19 +44,21 @@ type CNSIPAMInvoker struct {
}

type IPResultInfo struct {
podIPAddress string
ncSubnetPrefix uint8
ncPrimaryIP string
ncGatewayIPAddress string
hostSubnet string
hostPrimaryIP string
hostGateway string
nicType cns.NICType
macAddress string
skipDefaultRoutes bool
routes []cns.Route
pnpID string
endpointPolicies []policy.Policy
podIPAddress string
ncSubnetPrefix uint8
ncPrimaryIP string
ncGatewayIPAddress string
ncGatewayIPv6Address string
hostSubnet string
hostPrimaryIP string
hostGateway string
nicType cns.NICType
macAddress string
skipDefaultRoutes bool
routes []cns.Route
pnpID string
endpointPolicies []policy.Policy
secondaryIPs map[string]cns.SecondaryIPConfig
}

func (i IPResultInfo) MarshalLogObject(encoder zapcore.ObjectEncoder) error {
Expand Down Expand Up @@ -149,19 +151,21 @@ func (invoker *CNSIPAMInvoker) Add(addConfig IPAMAddConfig) (IPAMAddResult, erro

for i := 0; i < len(response.PodIPInfo); i++ {
info := IPResultInfo{
podIPAddress: response.PodIPInfo[i].PodIPConfig.IPAddress,
ncSubnetPrefix: response.PodIPInfo[i].NetworkContainerPrimaryIPConfig.IPSubnet.PrefixLength,
ncPrimaryIP: response.PodIPInfo[i].NetworkContainerPrimaryIPConfig.IPSubnet.IPAddress,
ncGatewayIPAddress: response.PodIPInfo[i].NetworkContainerPrimaryIPConfig.GatewayIPAddress,
hostSubnet: response.PodIPInfo[i].HostPrimaryIPInfo.Subnet,
hostPrimaryIP: response.PodIPInfo[i].HostPrimaryIPInfo.PrimaryIP,
hostGateway: response.PodIPInfo[i].HostPrimaryIPInfo.Gateway,
nicType: response.PodIPInfo[i].NICType,
macAddress: response.PodIPInfo[i].MacAddress,
skipDefaultRoutes: response.PodIPInfo[i].SkipDefaultRoutes,
routes: response.PodIPInfo[i].Routes,
pnpID: response.PodIPInfo[i].PnPID,
endpointPolicies: response.PodIPInfo[i].EndpointPolicies,
podIPAddress: response.PodIPInfo[i].PodIPConfig.IPAddress,
ncSubnetPrefix: response.PodIPInfo[i].NetworkContainerPrimaryIPConfig.IPSubnet.PrefixLength,
ncPrimaryIP: response.PodIPInfo[i].NetworkContainerPrimaryIPConfig.IPSubnet.IPAddress,
ncGatewayIPAddress: response.PodIPInfo[i].NetworkContainerPrimaryIPConfig.GatewayIPAddress,
ncGatewayIPv6Address: response.PodIPInfo[i].NetworkContainerPrimaryIPConfig.GatewayIPv6Address,
hostSubnet: response.PodIPInfo[i].HostPrimaryIPInfo.Subnet,
hostPrimaryIP: response.PodIPInfo[i].HostPrimaryIPInfo.PrimaryIP,
hostGateway: response.PodIPInfo[i].HostPrimaryIPInfo.Gateway,
nicType: response.PodIPInfo[i].NICType,
macAddress: response.PodIPInfo[i].MacAddress,
skipDefaultRoutes: response.PodIPInfo[i].SkipDefaultRoutes,
routes: response.PodIPInfo[i].Routes,
pnpID: response.PodIPInfo[i].PnPID,
endpointPolicies: response.PodIPInfo[i].EndpointPolicies,
secondaryIPs: response.PodIPInfo[i].SecondaryIPConfigs,
}

logger.Info("Received info for pod",
Expand Down Expand Up @@ -505,9 +509,53 @@ func configureSecondaryAddResult(info *IPResultInfo, addResult *IPAMAddResult, p
SkipDefaultRoutes: info.skipDefaultRoutes,
}

if len(info.secondaryIPs) > 0 {
// assumtion that first address is the only important one and that it is IPv6
secIPConfig, err := BuildIPConfigForV6(info.secondaryIPs, info.ncGatewayIPv6Address)

if err == nil {
// If BuildIPConfigForV6 returns a value, take its address
ifaceInfo := addResult.interfaceInfo[key]
ifaceInfo.IPConfigs = append(ifaceInfo.IPConfigs, &secIPConfig)
addResult.interfaceInfo[key] = ifaceInfo
}
}

return nil
}

// BuildIPConfigForV6 takes SecondaryIPConfigs and returns an IPConfig.
// Assumes map has at least one element and uses the first one found.
func BuildIPConfigForV6(secondaryIPs map[string]cns.SecondaryIPConfig, gatewayIPv6 string) (network.IPConfig, error) {
for _, v := range secondaryIPs {
ip, ipnet, err := net.ParseCIDR(v.IPAddress)
if err != nil {
return network.IPConfig{}, fmt.Errorf("invalid IPAddress %q: %w", v.IPAddress, err)
}
if ip.To4() != nil {
return network.IPConfig{}, fmt.Errorf("expected IPv6, got IPv4: %q", v.IPAddress)
}

gwIP := net.ParseIP(gatewayIPv6)
if gwIP == nil {
return network.IPConfig{}, fmt.Errorf("invalid Gateway IPAddress %q: %w", gatewayIPv6, err)
}
if gwIP.To4() != nil {
return network.IPConfig{}, fmt.Errorf("expected IPv6 Gateway, got IPv4 Gateway: %q", gatewayIPv6)
}

return network.IPConfig{
Address: net.IPNet{
IP: ip,
Mask: ipnet.Mask,
},
Gateway: gwIP, // derived from /64 base
}, nil
}

return network.IPConfig{}, fmt.Errorf("map is empty")
}

func addBackendNICToResult(info *IPResultInfo, addResult *IPAMAddResult, key string) error {
macAddress, err := net.ParseMAC(info.macAddress)
if err != nil {
Expand Down
2 changes: 2 additions & 0 deletions cns/NetworkContainerContract.go
Original file line number Diff line number Diff line change
Expand Up @@ -490,6 +490,7 @@ type GetNetworkContainerRequest struct {
type GetNetworkContainerResponse struct {
NetworkContainerID string
IPConfiguration IPConfiguration
SecondaryIPConfigs map[string]SecondaryIPConfig // uuid is key
Routes []Route
CnetAddressSpace []IPSubnet
MultiTenancyInfo MultiTenancyInfo
Expand All @@ -503,6 +504,7 @@ type GetNetworkContainerResponse struct {

type PodIpInfo struct {
PodIPConfig IPSubnet
SecondaryIPConfigs map[string]SecondaryIPConfig // uuid is key
NetworkContainerPrimaryIPConfig IPConfiguration
HostPrimaryIPInfo HostIPInfo
NICType NICType
Expand Down
1 change: 1 addition & 0 deletions cns/restserver/ipam.go
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ func (service *HTTPRestService) requestIPConfigHandlerHelperStandalone(ctx conte
MacAddress: resp[i].NetworkInterfaceInfo.MACAddress,
NICType: resp[i].NetworkInterfaceInfo.NICType,
NetworkContainerPrimaryIPConfig: resp[i].IPConfiguration,
SecondaryIPConfigs: resp[i].SecondaryIPConfigs,
}
podIPInfoList = append(podIPInfoList, podIPInfo)
}
Expand Down
1 change: 1 addition & 0 deletions cns/restserver/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -523,6 +523,7 @@ func (service *HTTPRestService) getAllNetworkContainerResponses(
getNetworkContainerResponse = cns.GetNetworkContainerResponse{
NetworkContainerID: savedReq.NetworkContainerid,
IPConfiguration: savedReq.IPConfiguration,
SecondaryIPConfigs: savedReq.SecondaryIPConfigs,
Routes: savedReq.Routes,
CnetAddressSpace: savedReq.CnetAddressSpace,
MultiTenancyInfo: savedReq.MultiTenancyInfo,
Expand Down
8 changes: 7 additions & 1 deletion network/network_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -289,13 +289,19 @@ func (nm *networkManager) configureHcnNetwork(nwInfo *EndpointInfo, extIf *exter

// Populate subnets.
for _, subnet := range nwInfo.Subnets {
// Choose route based on IP family
routeDest := defaultRouteCIDR
if subnet.Prefix.IP.To4() == nil {
routeDest = defaultIPv6Route
}

hnsSubnet := hcn.Subnet{
IpAddressPrefix: subnet.Prefix.String(),
// Set the Gateway route
Routes: []hcn.Route{
{
NextHop: subnet.Gateway.String(),
DestinationPrefix: defaultRouteCIDR,
DestinationPrefix: routeDest,
},
},
}
Expand Down