Skip to content
Merged
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
6 changes: 3 additions & 3 deletions .github/workflows/npa.yml
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ jobs:
git clone --branch v0.1.7 --depth=1 https://github.com/kubernetes-sigs/network-policy-api.git
cd network-policy-api/
go mod download
go test -v ./conformance -run TestConformanceProfiles -args --conformance-profiles=AdminNetworkPolicy,BaselineAdminNetworkPolicy --organization=kubernetes --project=kube-network-policies --url=https://github.com/kubernetes-sigs/kube-network-policies --version=0.1.1 --contact=antonio.ojea.garcia@gmail.com --additional-info=https://github.com/kubernetes-sigs/kube-network-policies
go test -v ./conformance -run TestConformanceProfiles --timeout 20m -args --conformance-profiles=AdminNetworkPolicy,BaselineAdminNetworkPolicy --organization=kubernetes --project=kube-network-policies --url=https://github.com/kubernetes-sigs/kube-network-policies --version=0.1.1 --contact=antonio.ojea.garcia@gmail.com --additional-info=https://github.com/kubernetes-sigs/kube-network-policies
cd -

- name: Upload Junit Reports
Expand Down Expand Up @@ -254,7 +254,7 @@ jobs:
git clone https://github.com/kubernetes-sigs/network-policy-api.git
cd network-policy-api/
go mod download
go test -v ./conformance -run TestConformanceProfiles -args --conformance-profiles=ClusterNetworkPolicy --organization=kubernetes --project=kube-network-policies --url=https://github.com/kubernetes-sigs/kube-network-policies --version=0.1.1 --contact=antonio.ojea.garcia@gmail.com --additional-info=https://github.com/kubernetes-sigs/kube-network-policies
go test -v ./conformance -run TestConformanceProfiles --timeout 20m --args --conformance-profiles=ClusterNetworkPolicy --organization=kubernetes --project=kube-network-policies --url=https://github.com/kubernetes-sigs/kube-network-policies --version=0.1.1 --contact=antonio.ojea.garcia@gmail.com --additional-info=https://github.com/kubernetes-sigs/kube-network-policies
cd -

- name: Upload Junit Reports
Expand All @@ -274,4 +274,4 @@ jobs:
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v5
with:
name: kind-logs-v1alpha2-${{ env.JOB_NAME }}-${{ github.run_id }}
path: ./_artifacts/logs
path: ./_artifacts/logs
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ require (
k8s.io/klog/v2 v2.130.1
k8s.io/utils v0.0.0-20250604170112-4c0f3b243397
// Temporarily reference latest network-policy-api in anticipation of Beta.
sigs.k8s.io/network-policy-api v0.1.8-0.20251003212904-40eeb18096dd
sigs.k8s.io/network-policy-api v0.1.8-0.20260217173220-6bb86defe1a7
)

require (
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -288,8 +288,8 @@ k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 h1:hwvWFiBzdWw1FhfY1FooPn3kzWuJ8
k8s.io/utils v0.0.0-20250604170112-4c0f3b243397/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE=
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg=
sigs.k8s.io/network-policy-api v0.1.8-0.20251003212904-40eeb18096dd h1:PgKfYtCMrBE8ORSI2yPld0QBB2+EfZEULd5cA0dOzCU=
sigs.k8s.io/network-policy-api v0.1.8-0.20251003212904-40eeb18096dd/go.mod h1:vBELsuxm/GD1hlMmg2cD/enDqxM7KZmSWq6VP6b5yw0=
sigs.k8s.io/network-policy-api v0.1.8-0.20260217173220-6bb86defe1a7 h1:pi2y+2LjP907yJM9XFty5BVBx4VI+KlwjQHcIGAY9Gg=
sigs.k8s.io/network-policy-api v0.1.8-0.20260217173220-6bb86defe1a7/go.mod h1:xYIHRc47QPAIiPkl+oXfu5we8jACNlt7WuKc7ZP0sGU=
sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU=
sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=
sigs.k8s.io/structured-merge-diff/v6 v6.3.0 h1:jTijUJbW353oVOd9oTlifJqOGEkUw2jB/fXCbTiQEco=
Expand Down
12 changes: 11 additions & 1 deletion pkg/api/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,18 @@ type PolicyEvaluator interface {
// Ready returns true if the evaluator is initialized and ready to work.
Ready() bool

// EvaluateIngress/EvaluateEgress perform the runtime packet evaluation.
// EvaluateIngress performs runtime packet evaluation on the path into the
// Pod.
//
// srcPod can be nil if the source of the network traffic is not a
// Kubernetes pod (e.g. external traffic).
EvaluateIngress(ctx context.Context, p *network.Packet, srcPod, dstPod *PodInfo) (Verdict, error)

// EvaluateEgress performs runtime packet evaluation on the path coming out
// from the Pod.
//
// dstPod can be nil if the destination of the network traffic is not a
// Kubernetes pod (e.g., external traffic).
EvaluateEgress(ctx context.Context, p *network.Packet, srcPod, dstPod *PodInfo) (Verdict, error)

// SetDataplaneSyncCallback allows the dataplane to provide a callback function.
Expand Down
81 changes: 52 additions & 29 deletions plugins/npa-v1alpha2/clusternetworkpolicy.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,8 +144,8 @@ func (c *ClusterNetworkPolicy) evaluateClusterEgress(
) npav1alpha2.ClusterNetworkPolicyRuleAction {
for _, policy := range policies {
for _, rule := range policy.Spec.Egress {
if rule.Ports != nil {
if !evaluateClusterNetworkPolicyPort(*rule.Ports, dstPod, dstPort, protocol) {
if rule.Protocols != nil {
if !evaluateProtocols(rule.Protocols, dstPod, dstPort, protocol) {
continue
}
}
Expand Down Expand Up @@ -197,8 +197,8 @@ func (c *ClusterNetworkPolicy) evaluateClusterIngress(
}
for _, policy := range policies {
for _, rule := range policy.Spec.Ingress {
if rule.Ports != nil {
if !evaluateClusterNetworkPolicyPort(*rule.Ports, dstPod, dstPort, protocol) {
if rule.Protocols != nil {
if !evaluateProtocols(rule.Protocols, dstPod, dstPort, protocol) {
continue
}
}
Expand All @@ -218,40 +218,63 @@ func (c *ClusterNetworkPolicy) evaluateClusterIngress(
return npav1alpha2.ClusterNetworkPolicyRuleActionPass
}

// evaluateClusterNetworkPolicyPort checks if a specific port and protocol match any port selectors.
func evaluateClusterNetworkPolicyPort(
policyPorts []npav1alpha2.ClusterNetworkPolicyPort,
func matchProtocolDestinationNamedPort(namedPort string, pod *api.PodInfo, protocol v1.Protocol, port int) bool {
if pod == nil {
return false
}
for _, containerPort := range pod.ContainerPorts {
if containerPort.Name == namedPort && v1.Protocol(containerPort.Protocol) == protocol && containerPort.Port == int32(port) {
return true
}
}
return false
}

func matchPort(policyPort *npav1alpha2.Port, port int) bool {
if policyPort == nil {
// If DestinationPort is nil, it means all ports are allowed for that protocol.
return true
}
if policyPort.Number != 0 && policyPort.Number == int32(port) {
return true
}
if policyPort.Range != nil &&
policyPort.Range.Start <= int32(port) &&
policyPort.Range.End >= int32(port) {
return true
}
return false
}

// evaluateProtocols checks if a specific port and protocol match any protocol selectors.
func evaluateProtocols(
policyProtocols []npav1alpha2.ClusterNetworkPolicyProtocol,
pod *api.PodInfo,
port int,
protocol v1.Protocol,
) bool {
if len(policyPorts) == 0 {
if len(policyProtocols) == 0 {
return true
}

for _, policyPort := range policyPorts {
if policyPort.PortNumber != nil &&
policyPort.PortNumber.Port == int32(port) &&
policyPort.PortNumber.Protocol == protocol {
return true
}

if policyPort.NamedPort != nil {
if pod == nil {
continue
for _, policyProtocol := range policyProtocols {
switch {
case policyProtocol.DestinationNamedPort != "":
if matchProtocolDestinationNamedPort(policyProtocol.DestinationNamedPort, pod, protocol, port) {
return true
}
for _, containerPort := range pod.ContainerPorts {
if containerPort.Name == *policyPort.NamedPort && v1.Protocol(containerPort.Protocol) == protocol && containerPort.Port == int32(port) {
return true
}
case policyProtocol.TCP != nil && protocol == v1.ProtocolTCP:
if matchPort(policyProtocol.TCP.DestinationPort, port) {
return true

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If DestinationPort is nil, then the policy is invalid. In the future, if/when we add something like flags, this clause will still not be correct. So just remove this.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missed this comment, let me check that I incorporated.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it makes sense now... if we add flags in the future, there'd be a second

if matchTCPFlags(policyProtocol.TCP.Flags, tcpFlags) {
	return true
}

here, which would also do "if nil { return true }". And then if either property was filled in, it would get checked, and if it wasn't, then it wouldn't.

}
case policyProtocol.UDP != nil && protocol == v1.ProtocolUDP:
if matchPort(policyProtocol.UDP.DestinationPort, port) {
return true
}
case policyProtocol.SCTP != nil && protocol == v1.ProtocolSCTP:
if matchPort(policyProtocol.SCTP.DestinationPort, port) {
return true
}
}

if policyPort.PortRange != nil &&
policyPort.PortRange.Protocol == protocol &&
policyPort.PortRange.Start <= int32(port) &&
policyPort.PortRange.End >= int32(port) {
return true
}
}
return false
Expand Down
Loading
Loading