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
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.

103 changes: 57 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,72 @@ 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

// TODO: Add support for NamedPorts
if len(cnpProto.DestinationNamedPort) != 0 {
err = fmt.Errorf("named ports are not supported yet.")
return
}

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