diff --git a/cni/network/network.go b/cni/network/network.go index e7d47a384b..3f7e02054a 100644 --- a/cni/network/network.go +++ b/cni/network/network.go @@ -637,14 +637,12 @@ func (plugin *NetPlugin) createNetworkInternal( NetNs: ipamAddConfig.args.Netns, Options: ipamAddConfig.options, DisableHairpinOnHostInterface: ipamAddConfig.nwCfg.DisableHairpinOnHostInterface, - IPV6Mode: ipamAddConfig.nwCfg.IPV6Mode, + IPV6Mode: ipamAddConfig.nwCfg.IPV6Mode, // TODO: check if IPV6Mode field can be deprecated IPAMType: ipamAddConfig.nwCfg.IPAM.Type, ServiceCidrs: ipamAddConfig.nwCfg.ServiceCidrs, + IsIPv6Enabled: ipamAddResult.ipv6Result != nil, } - // set IPv6Mode to dualStackOverlay mode - nwInfo.IPV6Mode = ipamAddConfig.nwCfg.IPAM.Mode - if err = addSubnetToNetworkInfo(ipamAddResult, &nwInfo); err != nil { log.Printf("[cni-net] Failed to add subnets to networkInfo due to %+v", err) return nwInfo, err @@ -764,7 +762,8 @@ func (plugin *NetPlugin) createEndpointInternal(opt *createEndpointInternalOpt) NATInfo: opt.natInfo, } - epPolicies := getPoliciesFromRuntimeCfg(opt.nwCfg) + isIPv6Enabled := opt.resultV6 != nil + epPolicies := getPoliciesFromRuntimeCfg(opt.nwCfg, isIPv6Enabled) epInfo.Policies = append(epInfo.Policies, epPolicies...) // Populate addresses. @@ -774,7 +773,7 @@ func (plugin *NetPlugin) createEndpointInternal(opt *createEndpointInternalOpt) if opt.resultV6 != nil { // inject ipv6 routes to Linux pod - epInfo.IPV6Mode = string(util.IpamMode(opt.nwCfg.IPAM.Mode)) + epInfo.IPV6Mode = string(util.IpamMode(opt.nwCfg.IPAM.Mode)) // TODO: check IPV6Mode field can be deprecated and can we add IsIPv6Enabled flag for generic working for _, ipconfig := range opt.resultV6.IPs { epInfo.IPAddresses = append(epInfo.IPAddresses, ipconfig.Address) } diff --git a/cni/network/network_linux.go b/cni/network/network_linux.go index 54789bcf79..86cda418c1 100644 --- a/cni/network/network_linux.go +++ b/cni/network/network_linux.go @@ -124,7 +124,7 @@ func getEndpointPolicies(PolicyArgs) ([]policy.Policy, error) { // getPoliciesFromRuntimeCfg returns network policies from network config. // getPoliciesFromRuntimeCfg is a dummy function for Linux platform. -func getPoliciesFromRuntimeCfg(nwCfg *cni.NetworkConfig) []policy.Policy { +func getPoliciesFromRuntimeCfg(_ *cni.NetworkConfig, _ bool) []policy.Policy { return nil } diff --git a/cni/network/network_windows.go b/cni/network/network_windows.go index d315e3728f..31a8b3e385 100644 --- a/cni/network/network_windows.go +++ b/cni/network/network_windows.go @@ -238,10 +238,11 @@ func getEndpointDNSSettings(nwCfg *cni.NetworkConfig, result *cniTypesCurr.Resul } // getPoliciesFromRuntimeCfg returns network policies from network config. -func getPoliciesFromRuntimeCfg(nwCfg *cni.NetworkConfig) []policy.Policy { +func getPoliciesFromRuntimeCfg(nwCfg *cni.NetworkConfig, isIPv6Enabled bool) []policy.Policy { log.Printf("[net] RuntimeConfigs: %+v", nwCfg.RuntimeConfig) var policies []policy.Policy var protocol uint32 + for _, mapping := range nwCfg.RuntimeConfig.PortMappings { cfgProto := strings.ToUpper(strings.TrimSpace(mapping.Protocol)) @@ -267,13 +268,39 @@ func getPoliciesFromRuntimeCfg(nwCfg *cni.NetworkConfig) []policy.Policy { Settings: rawPolicy, }) - policy := policy.Policy{ + policyv4 := policy.Policy{ Type: policy.EndpointPolicy, Data: hnsv2Policy, } - log.Printf("[net] Creating port mapping policy: %+v", policy) - policies = append(policies, policy) + log.Printf("[net] Creating port mapping policy: %+v", policyv4) + policies = append(policies, policyv4) + + // add port mapping policy for v6 if we have IPV6 enabled + if isIPv6Enabled { + // To support hostport policy mapping for ipv6 in dualstack overlay mode + // uint32 NatFlagsIPv6 = 2 + rawPolicyv6, _ := json.Marshal(&hnsv2.PortMappingPolicySetting{ // nolint + ExternalPort: uint16(mapping.HostPort), + InternalPort: uint16(mapping.ContainerPort), + VIP: mapping.HostIp, + Protocol: protocol, + Flags: hnsv2.NatFlagsIPv6, + }) + + hnsv2Policyv6, _ := json.Marshal(&hnsv2.EndpointPolicy{ // nolint + Type: hnsv2.PortMapping, + Settings: rawPolicyv6, + }) + + policyv6 := policy.Policy{ + Type: policy.EndpointPolicy, + Data: hnsv2Policyv6, + } + + log.Printf("[net] Creating port mapping policy v6: %+v", policyv6) + policies = append(policies, policyv6) + } } return policies diff --git a/cni/network/network_windows_test.go b/cni/network/network_windows_test.go index 56c84f2e9f..bf9af5d619 100644 --- a/cni/network/network_windows_test.go +++ b/cni/network/network_windows_test.go @@ -253,7 +253,8 @@ func TestSetPoliciesFromNwCfg(t *testing.T) { for _, tt := range tests { tt := tt t.Run(tt.name, func(t *testing.T) { - policies := getPoliciesFromRuntimeCfg(&tt.nwCfg) + isIPv6Enabled := false + policies := getPoliciesFromRuntimeCfg(&tt.nwCfg, isIPv6Enabled) require.Condition(t, assert.Comparison(func() bool { return len(policies) > 0 && policies[0].Type == policy.EndpointPolicy })) diff --git a/cns/client/client.go b/cns/client/client.go index d3fe3d9a94..16b85710e2 100644 --- a/cns/client/client.go +++ b/cns/client/client.go @@ -400,7 +400,6 @@ func (c *Client) RequestIPs(ctx context.Context, ipconfig cns.IPConfigsRequest) } req.Header.Set(headerContentType, contentTypeJSON) res, err := c.client.Do(req) - if err != nil { return nil, errors.Wrap(err, "http request failed") } diff --git a/network/network.go b/network/network.go index f09725b027..c34d743383 100644 --- a/network/network.go +++ b/network/network.go @@ -74,6 +74,7 @@ type NetworkInfo struct { IPV6Mode string IPAMType string ServiceCidrs string + IsIPv6Enabled bool } // SubnetInfo contains subnet information for a container network. diff --git a/network/network_windows.go b/network/network_windows.go index b6a86ac88f..858db47a6e 100644 --- a/network/network_windows.go +++ b/network/network_windows.go @@ -12,7 +12,6 @@ import ( "strings" "time" - "github.com/Azure/azure-container-networking/cni/util" "github.com/Azure/azure-container-networking/log" "github.com/Azure/azure-container-networking/network/hnswrapper" "github.com/Azure/azure-container-networking/network/policy" @@ -404,8 +403,8 @@ func (nm *networkManager) newNetworkImplHnsV2(nwInfo *NetworkInfo, extIf *extern if err != nil { // if network not found, create the HNS network. if errors.As(err, &hcn.NetworkNotFoundError{}) { - // in dualStackOverlay mode, add net routes to windows node - if nwInfo.IPV6Mode == string(util.DualStackOverlay) { + // add net routes to windows node if we have IPv6 enabled + if nwInfo.IsIPv6Enabled { if err := nm.addNewNetRules(nwInfo); err != nil { // nolint log.Printf("[net] Failed to add net rules due to %+v", err) return nil, err