-
Notifications
You must be signed in to change notification settings - Fork 260
[NPM Lite] Bypassing IPSets for IP CIDR Block Based Network Policies … #4147
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: release/v1.6
Are you sure you want to change the base?
Conversation
…4107) * added logic to bypass ipsets for /32 cidrs with npm lite * removed logic to only look at /32 pod cidrs and allow all pod cidr * updated code specific to direct ip logic * fixed if else logic * added error for named port * get rid of unneeded comments * got rid of function in utils that was not neede * added unit test for translate policy * resolved pr comments * resolved copilot comments * fixed golinter
|
/azp run Azure Container Networking PR, NPM Scale Test, NPM Conformance Tests |
|
Azure Pipelines successfully started running 3 pipeline(s). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR implements NPM Lite mode optimization for Windows by bypassing IPSet creation for all IP CIDR-based network policies. Instead of creating IPSets for CIDR blocks, the implementation now directly embeds IP addresses in ACL policies, reducing overhead and improving performance for CIDR-based network policies when npm lite is enabled.
Key Changes:
- Added direct IP address fields (
SrcDirectIPs,DstDirectIPs) to ACL policies for npm lite mode - Implemented
directPeerAndPortAllowRulefunction to handle CIDR blocks without IPSets - Enhanced error messages for named port validation with additional context
- Refactored Windows ACL settings to support both IPSet-based and direct IP approaches
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 5 comments.
| File | Description |
|---|---|
| npm/pkg/dataplane/policies/policy.go | Added SrcDirectIPs and DstDirectIPs fields to ACLPolicy struct for direct IP matching; fixed comment formatting |
| npm/pkg/dataplane/policies/policy_windows.go | Implemented direct IP handling in ACL settings conversion; fixed spelling of "definitions" |
| npm/pkg/controlplane/translation/translatePolicy.go | Added directPeerAndPortAllowRule function for npm lite CIDR handling; removed npmLiteValidPolicy function; enhanced checkForNamedPortType with detailed error context |
| npm/pkg/controlplane/translation/translatePolicy_test.go | Added comprehensive tests for direct IP/CIDR handling; removed obsolete TestNpmLiteCidrPolicy; updated TestCheckForNamedPortType for new function signature |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| } | ||
| } | ||
|
|
||
| func TestCheckForNamedPortType(t *testing.T) { |
Copilot
AI
Nov 26, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The removal of TestNpmLiteCidrPolicy leaves a gap in test coverage. While the npmLiteValidPolicy function was removed, the validation logic still exists at line 446-447 in translatePolicy.go which returns ErrUnsupportedNonCIDR when npm lite is enabled and a peer has no IPBlock (i.e., has PodSelector or NamespaceSelector).
Consider adding test cases to TestIngressPolicy and/or TestEgressPolicy that verify the ErrUnsupportedNonCIDR error is returned when npm lite is enabled with:
- PodSelector peers
- NamespaceSelector peers
- Mixed CIDR and selector peers
This will ensure the npm lite validation logic remains properly tested.
| // SrcDirectIPs holds direct IPs for source matching (used for /32 CIDRs on Windows with npm lite enabled) | ||
| SrcDirectIPs []string | ||
| // DstDirectIPs holds direct IPs for destination matching (used for /32 CIDRs on Windows with npm lite enabled) |
Copilot
AI
Nov 26, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The documentation states these fields are "used for /32 CIDRs on Windows with npm lite enabled", but based on the implementation in translatePolicy.go and the test cases (which include /16, /24, /28 subnets), these fields are actually used for ALL CIDR blocks when npm lite is enabled, not just /32 CIDRs.
Please update the documentation to accurately reflect that these fields are used for any CIDR block when npm lite is enabled:
// SrcDirectIPs holds direct IPs for source matching (used for IP CIDR blocks on Windows with npm lite enabled)| // SrcDirectIPs holds direct IPs for source matching (used for /32 CIDRs on Windows with npm lite enabled) | |
| SrcDirectIPs []string | |
| // DstDirectIPs holds direct IPs for destination matching (used for /32 CIDRs on Windows with npm lite enabled) | |
| // SrcDirectIPs holds direct IPs for source matching (used for IP CIDR blocks on Windows with npm lite enabled) | |
| SrcDirectIPs []string | |
| // DstDirectIPs holds direct IPs for destination matching (used for IP CIDR blocks on Windows with npm lite enabled) |
| func directPeerAndPortAllowRule(npmNetPol *policies.NPMNetworkPolicy, direction policies.Direction, ports []networkingv1.NetworkPolicyPort, cidr string, npmLiteToggle bool) error { | ||
| if len(ports) == 0 { | ||
| acl := policies.NewACLPolicy(policies.Allowed, direction) | ||
| // bypasses ipset creation for /32 cidrs and directly creates an acl with the cidr |
Copilot
AI
Nov 26, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comment states "bypasses ipset creation for /32 cidrs" but this function is used for all CIDR blocks when npm lite is enabled, not just /32 CIDRs. The test cases demonstrate this with /16, /24, and /28 subnets. Please update the comment to reflect the actual behavior:
// bypasses ipset creation for IP CIDR blocks and directly creates an acl with the cidr| // bypasses ipset creation for /32 cidrs and directly creates an acl with the cidr | |
| // bypasses ipset creation for IP CIDR blocks and directly creates an acl with the cidr |
| { | ||
| name: "egress tcp port 8000-8100 with /28 subnet", | ||
| direction: policies.Egress, | ||
| ports: []networkingv1.NetworkPolicyPort{ | ||
| { | ||
| Protocol: &tcp, | ||
| Port: &port8000, | ||
| EndPort: &endPort, | ||
| }, | ||
| }, | ||
| cidr: "10.0.1.0/28", | ||
| npmNetPol: &policies.NPMNetworkPolicy{ | ||
| Namespace: defaultNS, | ||
| PolicyKey: namedPortPolicyKey, | ||
| ACLPolicyID: fmt.Sprintf("azure-acl-%s-%s", defaultNS, namedPortPolicyKey), | ||
| ACLs: []*policies.ACLPolicy{ | ||
| { | ||
| Target: policies.Allowed, | ||
| Direction: policies.Egress, | ||
| DstDirectIPs: []string{"10.0.1.0/28"}, | ||
| DstPorts: policies.Ports{ | ||
| Port: 8000, | ||
| EndPort: 8100, | ||
| }, | ||
| Protocol: "TCP", | ||
| }, | ||
| }, | ||
| }, | ||
| }, | ||
| { |
Copilot
AI
Nov 26, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test case is duplicated. The exact same test case "egress tcp port 8000-8100 with /28 subnet" appears twice in the test table (lines 1476-1503 and lines 1559-1586). Please remove one of the duplicate test cases to maintain test clarity and avoid redundant test execution.
| { | |
| name: "egress tcp port 8000-8100 with /28 subnet", | |
| direction: policies.Egress, | |
| ports: []networkingv1.NetworkPolicyPort{ | |
| { | |
| Protocol: &tcp, | |
| Port: &port8000, | |
| EndPort: &endPort, | |
| }, | |
| }, | |
| cidr: "10.0.1.0/28", | |
| npmNetPol: &policies.NPMNetworkPolicy{ | |
| Namespace: defaultNS, | |
| PolicyKey: namedPortPolicyKey, | |
| ACLPolicyID: fmt.Sprintf("azure-acl-%s-%s", defaultNS, namedPortPolicyKey), | |
| ACLs: []*policies.ACLPolicy{ | |
| { | |
| Target: policies.Allowed, | |
| Direction: policies.Egress, | |
| DstDirectIPs: []string{"10.0.1.0/28"}, | |
| DstPorts: policies.Ports{ | |
| Port: 8000, | |
| EndPort: 8100, | |
| }, | |
| Protocol: "TCP", | |
| }, | |
| }, | |
| }, | |
| }, | |
| { | |
| { |
| policySettings.LocalAddresses = "" | ||
| if policySettings.Direction == hcn.DirectionTypeOut { | ||
| // EGRESS: Remote = Destination IPs from policy | ||
| policySettings.RemoteAddresses = dstListStr | ||
| } else { | ||
| // INGRESS: Remote = Source IPs from policy | ||
| policySettings.RemoteAddresses = srcListStr |
Copilot
AI
Nov 26, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Setting LocalAddresses to empty string for all direct IP cases may be incorrect. According to the comments at lines 117-123, for EGRESS traffic with direct IPs, LocalAddresses should be set to Destination IPs, not an empty string. The current logic always sets LocalAddresses to "" and only sets RemoteAddresses based on direction, which doesn't match the documented behavior for EGRESS.
Based on the comments:
- For INGRESS with direct IPs: LocalAddresses = Source IPs, RemoteAddresses = Destination IPs
- For EGRESS with direct IPs: LocalAddresses = Destination IPs, RemoteAddresses = Source IPs
Suggested fix:
if policySettings.Direction == hcn.DirectionTypeOut {
// EGRESS: Local = Destination IPs, Remote = Source IPs
policySettings.LocalAddresses = dstListStr
policySettings.RemoteAddresses = srcListStr
} else {
// INGRESS: Local = Source IPs, Remote = Destination IPs
policySettings.LocalAddresses = srcListStr
policySettings.RemoteAddresses = dstListStr
}| policySettings.LocalAddresses = "" | |
| if policySettings.Direction == hcn.DirectionTypeOut { | |
| // EGRESS: Remote = Destination IPs from policy | |
| policySettings.RemoteAddresses = dstListStr | |
| } else { | |
| // INGRESS: Remote = Source IPs from policy | |
| policySettings.RemoteAddresses = srcListStr | |
| if policySettings.Direction == hcn.DirectionTypeOut { | |
| // EGRESS: Local = Destination IPs, Remote = Source IPs | |
| policySettings.LocalAddresses = dstListStr | |
| policySettings.RemoteAddresses = srcListStr | |
| } else { | |
| // INGRESS: Local = Source IPs, Remote = Destination IPs | |
| policySettings.LocalAddresses = srcListStr | |
| policySettings.RemoteAddresses = dstListStr |
…(#4107)
added logic to bypass ipsets for /32 cidrs with npm lite
removed logic to only look at /32 pod cidrs and allow all pod cidr
updated code specific to direct ip logic
fixed if else logic
added error for named port
get rid of unneeded comments
got rid of function in utils that was not neede
added unit test for translate policy
resolved pr comments
resolved copilot comments
fixed golinter
Reason for Change:
Issue Fixed:
Requirements:
Notes: