Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 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
2 changes: 1 addition & 1 deletion apiserver/deps.txt

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion app-policy/deps.txt

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion calicoctl/deps.txt

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion cni-plugin/deps.txt

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion confd/deps.txt

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion e2e/deps.txt

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion felix/deps.txt

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ require (
sigs.k8s.io/controller-runtime v0.22.3
sigs.k8s.io/kind v0.30.0
sigs.k8s.io/knftables v0.0.19
sigs.k8s.io/network-policy-api v0.1.8-0.20251216172012-399040aaf83d
sigs.k8s.io/network-policy-api v0.1.8-0.20260205105847-196cf8e0d449
sigs.k8s.io/yaml v1.6.0
)

Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1087,8 +1087,8 @@ sigs.k8s.io/kustomize/api v0.20.1 h1:iWP1Ydh3/lmldBnH/S5RXgT98vWYMaTUL1ADcr+Sv7I
sigs.k8s.io/kustomize/api v0.20.1/go.mod h1:t6hUFxO+Ph0VxIk1sKp1WS0dOjbPCtLJ4p8aADLwqjM=
sigs.k8s.io/kustomize/kyaml v0.20.1 h1:PCMnA2mrVbRP3NIB6v9kYCAc38uvFLVs8j/CD567A78=
sigs.k8s.io/kustomize/kyaml v0.20.1/go.mod h1:0EmkQHRUsJxY8Ug9Niig1pUMSCGHxQ5RklbpV/Ri6po=
sigs.k8s.io/network-policy-api v0.1.8-0.20251216172012-399040aaf83d h1:mdzh06UcLpN7gcODfc4NqSNtDI0NWLJ2jlS4KhchgG0=
sigs.k8s.io/network-policy-api v0.1.8-0.20251216172012-399040aaf83d/go.mod h1:xYIHRc47QPAIiPkl+oXfu5we8jACNlt7WuKc7ZP0sGU=
sigs.k8s.io/network-policy-api v0.1.8-0.20260205105847-196cf8e0d449 h1:PLQPDVCmIitKwwC16gD13TqT2lgHnUrz51g68IVpWcQ=
sigs.k8s.io/network-policy-api v0.1.8-0.20260205105847-196cf8e0d449/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
2 changes: 1 addition & 1 deletion hack/deps.txt

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion kube-controllers/deps.txt

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion libcalico-go/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ KIND_CONFIG = $(KIND_DIR)/kind-single.config
# NETPOL_CNP_REF = refs/heads/main
# For a commit, just use the commit ID:
# NETPOL_CNP_REF = <commit ID>
NETPOL_CNP_REF = 1f80acbe25809162f3f81ffa254eb24318ea387b
NETPOL_CNP_REF = 196cf8e0d449e108f4bb36cb97e127a37d24e428
NETPOL_CNP_CRD_URL = https://raw.githubusercontent.com/kubernetes-sigs/network-policy-api/$(NETPOL_CNP_REF)/config/crd/standard
NETPOL_CNP_CRD = policy.networking.k8s.io_clusternetworkpolicies.yaml

Expand Down
2 changes: 1 addition & 1 deletion libcalico-go/deps.txt

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

97 changes: 51 additions & 46 deletions libcalico-go/lib/backend/k8s/conversion/clusternetworkpolicy.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2025 Tigera, Inc. All rights reserved.
// Copyright (c) 2025-2026 Tigera, Inc. All rights reserved.

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -165,15 +165,15 @@ func k8sClusterNetPolIngressRuleToCalico(rule clusternetpol.ClusterNetworkPolicy
if err != nil {
return nil, err
}
return combinePortsWithCNPIngressPeers(rule.Ports, rule.From, rule.Name, action)
return combinePortsWithCNPIngressPeers(rule.Protocols, rule.From, rule.Name, action)
}

func k8sClusterNetPolEgressRuleToCalico(rule clusternetpol.ClusterNetworkPolicyEgressRule) ([]apiv3.Rule, error) {
action, err := K8sClusterNetworkPolicyActionToCalico(rule.Action)
if err != nil {
return nil, err
}
return combinePortsWithCNPEgressPeers(rule.Ports, rule.To, rule.Name, action)
return combinePortsWithCNPEgressPeers(rule.Protocols, rule.To, rule.Name, action)
}

func K8sClusterNetworkPolicyActionToCalico(action clusternetpol.ClusterNetworkPolicyRuleAction) (apiv3.Action, error) {
Expand All @@ -189,12 +189,12 @@ func K8sClusterNetworkPolicyActionToCalico(action clusternetpol.ClusterNetworkPo
}

func combinePortsWithCNPIngressPeers(
cnpPorts *[]clusternetpol.ClusterNetworkPolicyPort,
cnpProtocols []clusternetpol.ClusterNetworkPolicyProtocol,
cnpPeers []clusternetpol.ClusterNetworkPolicyIngressPeer,
ruleName string,
action apiv3.Action,
) (rules []apiv3.Rule, err error) {
protocolPorts, sortedProtocols, err := unpackCNPPorts(cnpPorts)
protocolPorts, sortedProtocols, err := unpackCNPProtocols(cnpProtocols)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -248,12 +248,12 @@ func combinePortsWithCNPIngressPeers(
}

func combinePortsWithCNPEgressPeers(
cnpPorts *[]clusternetpol.ClusterNetworkPolicyPort,
cnpProtocols []clusternetpol.ClusterNetworkPolicyProtocol,
cnpPeers []clusternetpol.ClusterNetworkPolicyEgressPeer,
ruleName string,
action apiv3.Action,
) (rules []apiv3.Rule, err error) {
protocolPorts, sortedProtocols, err := unpackCNPPorts(cnpPorts)
protocolPorts, sortedProtocols, err := unpackCNPProtocols(cnpProtocols)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -317,22 +317,22 @@ func combinePortsWithCNPEgressPeers(
return rules, nil
}

func unpackCNPPorts(k8sPorts *[]clusternetpol.ClusterNetworkPolicyPort) (
func unpackCNPProtocols(cnpProtocols []clusternetpol.ClusterNetworkPolicyProtocol) (
map[string][]numorstring.Port,
[]string, error,
) {
// If there are no ports, represent that as zero struct.
ports := []clusternetpol.ClusterNetworkPolicyPort{{}}
if k8sPorts != nil && len(*k8sPorts) != 0 {
ports = *k8sPorts
protocols := []clusternetpol.ClusterNetworkPolicyProtocol{{}}
if cnpProtocols != nil && len(cnpProtocols) != 0 {
protocols = cnpProtocols
}

protocolPorts := map[string][]numorstring.Port{}

for _, port := range ports {
protocol, calicoPort, err := k8sCNPPortToCalicoFields(&port)
for _, p := range protocols {
protocol, calicoPort, err := k8sCNPPortToCalicoFields(&p)
if err != nil {
return nil, nil, fmt.Errorf("failed to parse k8s port: %s", err)
return nil, nil, fmt.Errorf("failed to parse k8s protocol: %s", err)
}

if protocol == nil && calicoPort == nil {
Expand All @@ -354,61 +354,66 @@ func unpackCNPPorts(k8sPorts *[]clusternetpol.ClusterNetworkPolicyPort) (
}
}

protocols := make([]string, 0, len(protocolPorts))
for k := range protocolPorts {
protocols = append(protocols, k)
protos := make([]string, 0, len(protocolPorts))
for p := range protocolPorts {
protos = append(protos, p)
}
// Ensure deterministic output
sort.Strings(protocols)
return protocolPorts, protocols, nil
sort.Strings(protos)
return protocolPorts, protos, nil
}

func k8sCNPPortToCalicoFields(port *clusternetpol.ClusterNetworkPolicyPort) (
func k8sCNPPortToCalicoFields(cnpProto *clusternetpol.ClusterNetworkPolicyProtocol) (
protocol *numorstring.Protocol,
dstPort *numorstring.Port,
err error,
) {
// If no port info, return zero values for all fields (protocol, dstPorts).
if port == nil {
if cnpProto == nil {
return
}
// Only one of the PortNumber or PortRange is set.
if port.PortNumber != nil {
dstPort = k8sCNPPortToCalico(port.PortNumber)
proto := ensureProtocol(port.PortNumber.Protocol)
protocol = k8sProtocolToCalico(&proto)

if cnpProto.TCP != nil {
dstPort, err = k8sCNPPortToCalico(cnpProto.TCP.DestinationPort)
p := numorstring.ProtocolFromString(numorstring.ProtocolTCP)
protocol = &p
return
}
if port.PortRange != nil {
dstPort, err = k8sCNPPortRangeToCalico(port.PortRange)
if err != nil {
return
}
proto := ensureProtocol(port.PortRange.Protocol)
protocol = k8sProtocolToCalico(&proto)

if cnpProto.UDP != nil {
dstPort, err = k8sCNPPortToCalico(cnpProto.UDP.DestinationPort)
p := numorstring.ProtocolFromString(numorstring.ProtocolUDP)
protocol = &p
return
}
// TODO: Add support for NamedPorts

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

What about named ports? We should at least fail/skip the rule if the proto struct has an unknown field, I think.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

As we discussed, I updated the code to return error for named ports for the moment.
I'm going to work on adding named ports in another PR. Tracking it here: https://tigera.atlassian.net/browse/CORE-12345

return
}

func k8sCNPPortToCalico(port *clusternetpol.Port) *numorstring.Port {
if port == nil {
return nil
if cnpProto.SCTP != nil {
dstPort, err = k8sCNPPortToCalico(cnpProto.SCTP.DestinationPort)
p := numorstring.ProtocolFromString(numorstring.ProtocolSCTP)
Comment thread
mazdakn marked this conversation as resolved.
protocol = &p
return
}
p := numorstring.SinglePort(uint16(port.Port))
return &p

return
}

func k8sCNPPortRangeToCalico(port *clusternetpol.PortRange) (*numorstring.Port, error) {
func k8sCNPPortToCalico(port *clusternetpol.Port) (*numorstring.Port, error) {
// Only one of the Number or Range is set.
if port == nil {
return nil, nil
}
p, err := numorstring.PortFromRange(uint16(port.Start), uint16(port.End))
if err != nil {
return nil, err
if port.Number != 0 {
p := numorstring.SinglePort(uint16(port.Number))
return &p, nil
}
Comment thread
mazdakn marked this conversation as resolved.
if port.Range != nil {
p, err := numorstring.PortFromRange(uint16(port.Range.Start), uint16(port.Range.End))
if err != nil {
return nil, err
}
return &p, nil
}
return &p, nil
return nil, nil
}

func k8sClusterNetworkPolicyToCalicoMetadata(ruleName string) *apiv3.RuleMetadata {
Expand Down
Loading