Skip to content

Commit

Permalink
[cni]: dualstack overlay hostIP issue hotfix (#2290)
Browse files Browse the repository at this point in the history
* dualstack overlay hostIP issue
  • Loading branch information
paulyufan2 authored Oct 27, 2023
1 parent 54154ab commit b65b051
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 44 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ stages:
dns: true
portforward: true
service: true
hostport: true
hybridWin: true

- job: failedE2ELogs
Expand Down
7 changes: 6 additions & 1 deletion cni/network/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -782,7 +782,12 @@ func (plugin *NetPlugin) createEndpointInternal(opt *createEndpointInternalOpt)
}

isIPv6Enabled := opt.resultV6 != nil
epPolicies := getPoliciesFromRuntimeCfg(opt.nwCfg, isIPv6Enabled)
epPolicies, err := getPoliciesFromRuntimeCfg(opt.nwCfg, isIPv6Enabled)
if err != nil {
logger.Error("failed to get policies from runtime configurations", zap.Error(err))
return epInfo, plugin.Errorf(err.Error())
}

epInfo.Policies = append(epInfo.Policies, epPolicies...)

// Populate addresses.
Expand Down
4 changes: 2 additions & 2 deletions cni/network/network_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,8 @@ func getEndpointPolicies(PolicyArgs) ([]policy.Policy, error) {

// getPoliciesFromRuntimeCfg returns network policies from network config.
// getPoliciesFromRuntimeCfg is a dummy function for Linux platform.
func getPoliciesFromRuntimeCfg(_ *cni.NetworkConfig, _ bool) []policy.Policy {
return nil
func getPoliciesFromRuntimeCfg(_ *cni.NetworkConfig, _ bool) ([]policy.Policy, error) {
return nil, nil
}

func addIPV6EndpointPolicy(nwInfo network.NetworkInfo) (policy.Policy, error) {
Expand Down
73 changes: 36 additions & 37 deletions cni/network/network_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -248,9 +248,8 @@ func getEndpointDNSSettings(nwCfg *cni.NetworkConfig, result *cniTypesCurr.Resul
}

// getPoliciesFromRuntimeCfg returns network policies from network config.
func getPoliciesFromRuntimeCfg(nwCfg *cni.NetworkConfig, isIPv6Enabled bool) []policy.Policy {
logger.Info("Runtime Info",
zap.Any("config", nwCfg.RuntimeConfig))
func getPoliciesFromRuntimeCfg(nwCfg *cni.NetworkConfig, isIPv6Enabled bool) ([]policy.Policy, error) {
logger.Info("Runtime Info", zap.Any("config", nwCfg.RuntimeConfig))
var policies []policy.Policy
var protocol uint32

Expand All @@ -266,57 +265,57 @@ func getPoliciesFromRuntimeCfg(nwCfg *cni.NetworkConfig, isIPv6Enabled bool) []p

// To support hostport policy mapping
// uint32 NatFlagsLocalRoutedVip = 1
rawPolicy, _ := json.Marshal(&hnsv2.PortMappingPolicySetting{
// To support hostport policy mapping for ipv6 in dualstack overlay mode
// uint32 NatFlagsIPv6 = 2

flag := hnsv2.NatFlagsLocalRoutedVip
if mapping.HostIp != "" {
hostIP, err := netip.ParseAddr(mapping.HostIp)
if err != nil {
return nil, errors.Wrapf(err, "failed to parse hostIP %v", hostIP)
}

if hostIP.Is6() && isIPv6Enabled {
flag = hnsv2.NatFlagsIPv6
}

if hostIP.Is6() && !isIPv6Enabled {
logger.Info("Do not use ipv6 hostIP to create windows pod on ipv4 cluster")
}
}

rawPolicy, err := json.Marshal(&hnsv2.PortMappingPolicySetting{
ExternalPort: uint16(mapping.HostPort),
InternalPort: uint16(mapping.ContainerPort),
VIP: mapping.HostIp,
Protocol: protocol,
Flags: hnsv2.NatFlagsLocalRoutedVip,
Flags: flag,
})

hnsv2Policy, _ := json.Marshal(&hnsv2.EndpointPolicy{
if err != nil {
return nil, errors.Wrap(err, "failed to marshal HNS portMappingPolicySetting")
}

hnsv2Policy, err := json.Marshal(&hnsv2.EndpointPolicy{
Type: hnsv2.PortMapping,
Settings: rawPolicy,
})

policyv4 := policy.Policy{
if err != nil {
return nil, errors.Wrap(err, "failed to marshal HNS endpointPolicy")
}

hnsPolicy := policy.Policy{
Type: policy.EndpointPolicy,
Data: hnsv2Policy,
}

logger.Info("Creating port mapping policyv4",
zap.Any("policy", 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,
}
logger.Info("Creating port mapping policy", zap.Any("policy", hnsPolicy))

logger.Info("Creating port mapping policyv6",
zap.Any("policy", policyv6))
policies = append(policies, policyv6)
}
policies = append(policies, hnsPolicy)
}

return policies
return policies, nil
}

func getEndpointPolicies(args PolicyArgs) ([]policy.Policy, error) {
Expand Down
27 changes: 23 additions & 4 deletions cni/network/network_windows_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -217,8 +217,9 @@ func TestSetEndpointOptions(t *testing.T) {

func TestSetPoliciesFromNwCfg(t *testing.T) {
tests := []struct {
name string
nwCfg cni.NetworkConfig
name string
nwCfg cni.NetworkConfig
isIPv6Enabled bool
}{
{
name: "Runtime network polices",
Expand All @@ -234,6 +235,7 @@ func TestSetPoliciesFromNwCfg(t *testing.T) {
},
},
},
isIPv6Enabled: false,
},
{
name: "Runtime hostPort mapping polices",
Expand All @@ -248,13 +250,30 @@ func TestSetPoliciesFromNwCfg(t *testing.T) {
},
},
},
isIPv6Enabled: false,
},
{
name: "Runtime hostPort mapping polices with ipv6 hostIP",
nwCfg: cni.NetworkConfig{
RuntimeConfig: cni.RuntimeConfig{
PortMappings: []cni.PortMapping{
{
Protocol: "tcp",
HostPort: 44000,
ContainerPort: 80,
HostIp: "2001:2002:2003::1",
},
},
},
},
isIPv6Enabled: true,
},
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
isIPv6Enabled := false
policies := getPoliciesFromRuntimeCfg(&tt.nwCfg, isIPv6Enabled)
policies, err := getPoliciesFromRuntimeCfg(&tt.nwCfg, tt.isIPv6Enabled)
require.NoError(t, err)
require.Condition(t, assert.Comparison(func() bool {
return len(policies) > 0 && policies[0].Type == policy.EndpointPolicy
}))
Expand Down

0 comments on commit b65b051

Please sign in to comment.