From f4b7d613c518485e8360580564678b42cebe2d30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E6=89=AC?= <503582241@qq.com> Date: Wed, 24 Mar 2021 11:09:07 +0800 Subject: [PATCH] support egress to namedport without dst address (#1037) --- pkg/controllers/netpol/policy.go | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/pkg/controllers/netpol/policy.go b/pkg/controllers/netpol/policy.go index 6168f0405..93b5d2040 100644 --- a/pkg/controllers/netpol/policy.go +++ b/pkg/controllers/netpol/policy.go @@ -362,6 +362,13 @@ func (npc *NetworkPolicyController) processEgressRules(policy networkPolicyInfo, return err } } + for _, portProtocol := range egressRule.namedPorts { + comment := "rule to ACCEPT traffic from source pods to all destinations selected by policy name: " + + policy.name + " namespace " + policy.namespace + if err := npc.appendRuleToPolicyChain(policyChainName, comment, targetSourcePodIPSetName, "", portProtocol.protocol, portProtocol.port); err != nil { + return err + } + } } // case where nether ports nor from details are speified in the egress rule @@ -540,6 +547,17 @@ func (npc *NetworkPolicyController) buildNetworkPoliciesInfo() ([]networkPolicyI // If this field is empty or missing in the spec, this rule matches all sources if len(specEgressRule.To) == 0 { egressRule.matchAllDestinations = true + // if rule.To is empty but rule.Ports not, we must try to grab NamedPort from pods that in same namespace, + // so that we can design iptables rule to describe "match all dst but match some named dst-port" egress rule + if policyRulePortsHasNamedPort(specEgressRule.Ports) { + matchingPeerPods, _ := npc.ListPodsByNamespaceAndLabels(policy.Namespace, labels.Everything()) + for _, peerPod := range matchingPeerPods { + if peerPod.Status.PodIP == "" { + continue + } + npc.grabNamedPortFromPod(peerPod, &namedPort2EgressEps) + } + } } else { egressRule.matchAllDestinations = false for _, peer := range specEgressRule.To { @@ -749,3 +767,12 @@ func policyIndexedEgressNamedPortIPSetName(namespace, policyName string, egressR encoded := base32.StdEncoding.EncodeToString(hash[:]) return kubeDestinationIPSetPrefix + encoded[:16] } + +func policyRulePortsHasNamedPort(npPorts []networking.NetworkPolicyPort) bool { + for _, npPort := range npPorts { + if npPort.Port != nil && npPort.Port.Type == intstr.String { + return true + } + } + return false +}