diff --git a/pkg/netpol/eval/check.go b/pkg/netpol/eval/check.go index 5d1c4062..7ef3b382 100644 --- a/pkg/netpol/eval/check.go +++ b/pkg/netpol/eval/check.go @@ -494,7 +494,7 @@ func (pe *PolicyEngine) determineAllowedConnsPerDirection(policy *k8s.NetworkPol case policy.IngressPolicyExposure.ClusterWideExposure.AllowAll && src.PeerType() == k8s.PodType: return policy.IngressPolicyExposure.ClusterWideExposure, nil default: - return policy.GetIngressAllowedConns(src, dst) + return policy.GetXgressAllowedConns(src, dst, true) } } // else get egress allowed conns between src and dst @@ -504,7 +504,7 @@ func (pe *PolicyEngine) determineAllowedConnsPerDirection(policy *k8s.NetworkPol case policy.EgressPolicyExposure.ClusterWideExposure.AllowAll && dst.PeerType() == k8s.PodType: return policy.EgressPolicyExposure.ClusterWideExposure, nil default: - return policy.GetEgressAllowedConns(dst) + return policy.GetXgressAllowedConns(src, dst, false) } } diff --git a/pkg/netpol/eval/internal/k8s/adminnetpol.go b/pkg/netpol/eval/internal/k8s/adminnetpol.go index 7b945bb5..0f1eb029 100644 --- a/pkg/netpol/eval/internal/k8s/adminnetpol.go +++ b/pkg/netpol/eval/internal/k8s/adminnetpol.go @@ -168,8 +168,8 @@ func updatePolicyConns(rulePorts *[]apisv1a.AdminNetworkPolicyPort, ruleName str // ruleConnections returns the connectionSet from the current rule.Ports func ruleConnections(ports *[]apisv1a.AdminNetworkPolicyPort, ruleName string, dst Peer, isIngress bool) (*common.ConnectionSet, error) { - if ports == nil { - return common.MakeAllConnectionSetWithRule(ruleName, isIngress), nil // If Ports is not set then the rule does not filter traffic via port. + if ports == nil { // If Ports is not set then the rule does not filter traffic via port. + return common.MakeAllConnectionSetWithRule(ruleName, isIngress), nil } res := common.MakeConnectionSet(false) for _, anpPort := range *ports { diff --git a/pkg/netpol/eval/internal/k8s/netpol.go b/pkg/netpol/eval/internal/k8s/netpol.go index 260b66ff..2e7fbb60 100644 --- a/pkg/netpol/eval/internal/k8s/netpol.go +++ b/pkg/netpol/eval/internal/k8s/netpol.go @@ -118,6 +118,13 @@ func isEmptyPortRange(start, end int32) bool { return start == common.NoPort && end == common.NoPort } +func (np *NetworkPolicy) rulePeersAndPorts(ruleIdx int, isIngress bool) ([]netv1.NetworkPolicyPeer, []netv1.NetworkPolicyPort) { + if isIngress { + return np.Spec.Ingress[ruleIdx].From, np.Spec.Ingress[ruleIdx].Ports + } + return np.Spec.Egress[ruleIdx].To, np.Spec.Egress[ruleIdx].Ports +} + func (np *NetworkPolicy) ruleConnections(rulePorts []netv1.NetworkPolicyPort, dst Peer, ruleIdx int, isIngress bool) (*common.ConnectionSet, error) { if len(rulePorts) == 0 { @@ -354,60 +361,34 @@ func (np *NetworkPolicy) nameWithDirection(isIngress bool) string { return fmt.Sprintf("%s//%s", np.fullName(), xgress) } -// GetEgressAllowedConns returns the set of allowed connections from any captured pod to the destination peer -func (np *NetworkPolicy) GetEgressAllowedConns(dst Peer) (*common.ConnectionSet, error) { +// GetXgressAllowedConns returns the set of allowed connections to a captured dst pod from the src peer (for Ingress) +// or from any captured pod to the dst peer (for Egress) +func (np *NetworkPolicy) GetXgressAllowedConns(src, dst Peer, isIngress bool) (*common.ConnectionSet, error) { res := common.MakeConnectionSet(false) - if len(np.Spec.Egress) == 0 { - res.AddCommonImplyingRule(np.nameWithDirection(false), false) + if (isIngress && len(np.Spec.Ingress) == 0) || (!isIngress && len(np.Spec.Egress) == 0) { + res.AddCommonImplyingRule(np.nameWithDirection(isIngress), isIngress) return res, nil } - dstSelectedByAnyRule := false - for idx, rule := range np.Spec.Egress { - rulePeers := rule.To - rulePorts := rule.Ports - peerSelected, err := np.ruleSelectsPeer(rulePeers, dst) - if err != nil { - return res, err - } - if !peerSelected { - continue - } - dstSelectedByAnyRule = true - ruleConns, err := np.ruleConnections(rulePorts, dst, idx, false) - if err != nil { - return res, err - } - res.Union(ruleConns) - if res.AllowAll { - return res, nil - } - } - if !dstSelectedByAnyRule { - res.AddCommonImplyingRule(np.nameWithDirection(false), false) - } - return res, nil -} - -// GetIngressAllowedConns returns the set of allowed connections to a captured dst pod from the src peer -func (np *NetworkPolicy) GetIngressAllowedConns(src, dst Peer) (*common.ConnectionSet, error) { - res := common.MakeConnectionSet(false) - if len(np.Spec.Ingress) == 0 { - res.AddCommonImplyingRule(np.nameWithDirection(true), true) - return res, nil + peerSelectedByAnyRule := false + numOfRules := len(np.Spec.Egress) + if isIngress { + numOfRules = len(np.Spec.Ingress) } - srcSelectedByAnyRule := false - for idx, rule := range np.Spec.Ingress { - rulePeers := rule.From - rulePorts := rule.Ports - peerSelected, err := np.ruleSelectsPeer(rulePeers, src) + for idx := 0; idx < numOfRules; idx++ { + rulePeers, rulePorts := np.rulePeersAndPorts(idx, isIngress) + peerToSelect := dst + if isIngress { + peerToSelect = src + } + peerSelected, err := np.ruleSelectsPeer(rulePeers, peerToSelect) if err != nil { return res, err } if !peerSelected { continue } - srcSelectedByAnyRule = true - ruleConns, err := np.ruleConnections(rulePorts, dst, idx, true) + peerSelectedByAnyRule = true + ruleConns, err := np.ruleConnections(rulePorts, dst, idx, isIngress) if err != nil { return res, err } @@ -416,8 +397,8 @@ func (np *NetworkPolicy) GetIngressAllowedConns(src, dst Peer) (*common.Connecti return res, nil } } - if !srcSelectedByAnyRule { - res.AddCommonImplyingRule(np.nameWithDirection(true), true) + if !peerSelectedByAnyRule { + res.AddCommonImplyingRule(np.nameWithDirection(isIngress), isIngress) } return res, nil }