Skip to content

Commit b823b09

Browse files
authored
[NPM Lite] Bypassing IPSets for IP CIDR Block Based Network Policies (#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
1 parent faa9c44 commit b823b09

File tree

4 files changed

+298
-192
lines changed

4 files changed

+298
-192
lines changed

npm/pkg/controlplane/translation/translatePolicy.go

Lines changed: 57 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,7 @@ func peerAndPortRule(npmNetPol *policies.NPMNetworkPolicy, direction policies.Di
349349
return err
350350
}
351351

352-
err = checkForNamedPortType(portKind, npmLiteToggle)
352+
err = checkForNamedPortType(npmNetPol, portKind, npmLiteToggle, direction, &ports[i], "")
353353
if err != nil {
354354
return err
355355
}
@@ -362,6 +362,50 @@ func peerAndPortRule(npmNetPol *policies.NPMNetworkPolicy, direction policies.Di
362362
return nil
363363
}
364364

365+
func directPeerAndPortAllowRule(npmNetPol *policies.NPMNetworkPolicy, direction policies.Direction, ports []networkingv1.NetworkPolicyPort, cidr string, npmLiteToggle bool) error {
366+
if len(ports) == 0 {
367+
acl := policies.NewACLPolicy(policies.Allowed, direction)
368+
// bypasses ipset creation for /32 cidrs and directly creates an acl with the cidr
369+
if direction == policies.Ingress {
370+
acl.SrcDirectIPs = []string{cidr}
371+
} else {
372+
acl.DstDirectIPs = []string{cidr}
373+
}
374+
npmNetPol.ACLs = append(npmNetPol.ACLs, acl)
375+
return nil
376+
}
377+
// handle each port separately
378+
for i := range ports {
379+
portKind, err := portType(ports[i])
380+
if err != nil {
381+
return err
382+
}
383+
384+
err = checkForNamedPortType(npmNetPol, portKind, npmLiteToggle, direction, &ports[i], cidr)
385+
if err != nil {
386+
return err
387+
}
388+
389+
acl := policies.NewACLPolicy(policies.Allowed, direction)
390+
391+
// Set direct IP based on direction
392+
if direction == policies.Ingress {
393+
acl.SrcDirectIPs = []string{cidr}
394+
} else {
395+
acl.DstDirectIPs = []string{cidr}
396+
}
397+
398+
// Handle ports
399+
if portKind == numericPortType {
400+
portInfo, protocol := numericPortRule(&ports[i])
401+
acl.DstPorts = portInfo
402+
acl.Protocol = policies.Protocol(protocol)
403+
}
404+
npmNetPol.ACLs = append(npmNetPol.ACLs, acl)
405+
}
406+
return nil
407+
}
408+
365409
// translateRule translates ingress or egress rules and update npmNetPol object.
366410
func translateRule(npmNetPol *policies.NPMNetworkPolicy,
367411
netPolName string,
@@ -405,6 +449,14 @@ func translateRule(npmNetPol *policies.NPMNetworkPolicy,
405449
// #2.1 Handle IPBlock and port if exist
406450
if peer.IPBlock != nil {
407451
if len(peer.IPBlock.CIDR) > 0 {
452+
if npmLiteToggle {
453+
err = directPeerAndPortAllowRule(npmNetPol, direction, ports, peer.IPBlock.CIDR, npmLiteToggle)
454+
if err != nil {
455+
return err
456+
}
457+
continue
458+
}
459+
408460
ipBlockIPSet, ipBlockSetInfo, err := ipBlockRule(netPolName, npmNetPol.Namespace, direction, matchType, ruleIndex, peerIdx, peer.IPBlock)
409461
if err != nil {
410462
return err
@@ -417,12 +469,6 @@ func translateRule(npmNetPol *policies.NPMNetworkPolicy,
417469
}
418470
}
419471

420-
// if npm lite is configured, check network policy only consists of CIDR blocks
421-
err := npmLiteValidPolicy(peer, npmLiteToggle)
422-
if err != nil {
423-
return err
424-
}
425-
426472
// Do not need to run below code to translate PodSelector and NamespaceSelector
427473
// since IPBlock field is exclusive in NetworkPolicyPeer (i.e., peer in this code).
428474

@@ -642,17 +688,10 @@ func TranslatePolicy(npObj *networkingv1.NetworkPolicy, npmLiteToggle bool) (*po
642688
return npmNetPol, nil
643689
}
644690

645-
// validates only CIDR based peer is present + no combination of CIDR with pod/namespace selectors are present
646-
func npmLiteValidPolicy(peer networkingv1.NetworkPolicyPeer, npmLiteEnabled bool) error {
647-
if npmLiteEnabled && (peer.PodSelector != nil || peer.NamespaceSelector != nil) {
648-
return ErrUnsupportedNonCIDR
649-
}
650-
return nil
651-
}
652-
653-
func checkForNamedPortType(portKind netpolPortType, npmLiteToggle bool) error {
691+
func checkForNamedPortType(npmNetPol *policies.NPMNetworkPolicy, portKind netpolPortType, npmLiteToggle bool, direction policies.Direction, port *networkingv1.NetworkPolicyPort, cidr string) error {
654692
if npmLiteToggle && portKind == namedPortType {
655-
return ErrUnsupportedNonCIDR
693+
return fmt.Errorf("named port not supported in policy %s (namespace: %s, direction: %s, cidr: %s, port: %v, protocol: %v): %w",
694+
npmNetPol.PolicyKey, npmNetPol.Namespace, direction, cidr, port.Port, port.Protocol, ErrUnsupportedNamedPort)
656695
}
657696
return nil
658697
}
@@ -673,7 +712,7 @@ func checkOnlyPortRuleExists(
673712
if err != nil {
674713
return err
675714
}
676-
err = checkForNamedPortType(portKind, npmLiteToggle)
715+
err = checkForNamedPortType(npmNetPol, portKind, npmLiteToggle, direction, &ports[i], "")
677716
if err != nil {
678717
return err
679718
}

0 commit comments

Comments
 (0)