diff --git a/npc/analyser.go b/npc/analyser.go index 376ffa6b..94d45e8e 100644 --- a/npc/analyser.go +++ b/npc/analyser.go @@ -125,57 +125,109 @@ func (ns *ns) analysePolicy(policy *networkingv1.NetworkPolicy) ( // an invalid content of the "default-allow" ipset. addIfNotExist(dstSelector, podSelectors) - // If ingress is empty then this NetworkPolicy does not allow any traffic - if policy.Spec.Ingress == nil || len(policy.Spec.Ingress) == 0 { - return - } - - for _, ingressRule := range policy.Spec.Ingress { - // If Ports is empty or missing, this rule matches all ports - allPorts := ingressRule.Ports == nil || len(ingressRule.Ports) == 0 - // If From is empty or missing, this rule matches all sources - allSources := ingressRule.From == nil || len(ingressRule.From) == 0 - - if allSources { - if allPorts { - rule := newRuleSpec(ingressPolicy, nil, nil, dstSelector, nil) - rules[rule.key] = rule - } else { - withNormalisedProtoAndPort(ingressRule.Ports, func(proto, port string) { - rule := newRuleSpec(ingressPolicy, &proto, nil, dstSelector, &port) - rules[rule.key] = rule - }) - } - } else { - for _, peer := range ingressRule.From { - var srcSelector *selectorSpec - - // NetworkPolicyPeer describes a peer to allow traffic from. - // Exactly one of its fields must be specified. - if peer.PodSelector != nil { - srcSelector, err = newSelectorSpec(peer.PodSelector, false, nil, ns.name, ipset.HashIP) - if err != nil { - return nil, nil, nil, err - } - addIfNotExist(srcSelector, podSelectors) - - } else if peer.NamespaceSelector != nil { - srcSelector, err = newSelectorSpec(peer.NamespaceSelector, false, nil, "", ipset.ListSet) - if err != nil { - return nil, nil, nil, err - } - nsSelectors[srcSelector.key] = srcSelector - } + // If ingress is empty then this NetworkPolicy does not allow any ingress traffic + if policy.Spec.Ingress != nil && len(policy.Spec.Ingress) != 0 { + for _, ingressRule := range policy.Spec.Ingress { + // If Ports is empty or missing, this rule matches all ports + allPorts := ingressRule.Ports == nil || len(ingressRule.Ports) == 0 + // If From is empty or missing, this rule matches all sources + allSources := ingressRule.From == nil || len(ingressRule.From) == 0 + if allSources { if allPorts { - rule := newRuleSpec(ingressPolicy, nil, srcSelector, dstSelector, nil) + rule := newRuleSpec(ingressPolicy, nil, nil, dstSelector, nil) rules[rule.key] = rule } else { withNormalisedProtoAndPort(ingressRule.Ports, func(proto, port string) { - rule := newRuleSpec(ingressPolicy, &proto, srcSelector, dstSelector, &port) + rule := newRuleSpec(ingressPolicy, &proto, nil, dstSelector, &port) rules[rule.key] = rule }) } + } else { + for _, peer := range ingressRule.From { + var srcSelector *selectorSpec + + // NetworkPolicyPeer describes a peer to allow traffic from. + // Exactly one of its fields must be specified. + if peer.PodSelector != nil { + srcSelector, err = newSelectorSpec(peer.PodSelector, false, nil, ns.name, ipset.HashIP) + if err != nil { + return nil, nil, nil, err + } + addIfNotExist(srcSelector, podSelectors) + + } else if peer.NamespaceSelector != nil { + srcSelector, err = newSelectorSpec(peer.NamespaceSelector, false, nil, "", ipset.ListSet) + if err != nil { + return nil, nil, nil, err + } + nsSelectors[srcSelector.key] = srcSelector + } + + if allPorts { + rule := newRuleSpec(ingressPolicy, nil, srcSelector, dstSelector, nil) + rules[rule.key] = rule + } else { + withNormalisedProtoAndPort(ingressRule.Ports, func(proto, port string) { + rule := newRuleSpec(ingressPolicy, &proto, srcSelector, dstSelector, &port) + rules[rule.key] = rule + }) + } + } + } + } + } + + // If egress is empty then this NetworkPolicy does not allow any egress traffic + if policy.Spec.Egress != nil && len(policy.Spec.Egress) != 0 { + for _, egressRule := range policy.Spec.Egress { + // If Ports is empty or missing, this rule matches all ports + allPorts := egressRule.Ports == nil || len(egressRule.Ports) == 0 + // If To is empty or missing, this rule matches all destinations + allDestinations := egressRule.To == nil || len(egressRule.To) == 0 + + if allDestinations { + if allPorts { + rule := newRuleSpec(egressPolicy, nil, dstSelector, nil, nil) + rules[rule.key] = rule + } else { + withNormalisedProtoAndPort(egressRule.Ports, func(proto, port string) { + rule := newRuleSpec(egressPolicy, &proto, dstSelector, nil, &port) + rules[rule.key] = rule + }) + } + } else { + for _, peer := range egressRule.To { + // TODO(brb) s/selector/dstSelector/ after s/dstSelector/targetSelector/ + var selector *selectorSpec + + // NetworkPolicyPeer describes a peer to allow traffic from. + // Exactly one of its fields must be specified. + if peer.PodSelector != nil { + selector, err = newSelectorSpec(peer.PodSelector, false, nil, ns.name, ipset.HashIP) + if err != nil { + return nil, nil, nil, err + } + addIfNotExist(selector, podSelectors) + + } else if peer.NamespaceSelector != nil { + selector, err = newSelectorSpec(peer.NamespaceSelector, false, nil, "", ipset.ListSet) + if err != nil { + return nil, nil, nil, err + } + nsSelectors[selector.key] = selector + } + + if allPorts { + rule := newRuleSpec(egressPolicy, nil, dstSelector, selector, nil) + rules[rule.key] = rule + } else { + withNormalisedProtoAndPort(egressRule.Ports, func(proto, port string) { + rule := newRuleSpec(egressPolicy, &proto, dstSelector, selector, &port) + rules[rule.key] = rule + }) + } + } } } }