diff --git a/npc/analyser.go b/npc/analyser.go index f94dde8f..a19bb711 100644 --- a/npc/analyser.go +++ b/npc/analyser.go @@ -136,7 +136,7 @@ func (ns *ns) analysePolicy(policy *networkingv1.NetworkPolicy) ( nsSelectors[dstSelector.key] = dstSelector dstRuleHost = dstSelector } else if peer.IPBlock != nil { - ipBlock := newIPBlockSpec(peer.IPBlock) + ipBlock := newIPBlockSpec(peer.IPBlock, ns.name) ipBlocks[ipBlock.key] = ipBlock dstRuleHost = ipBlock } diff --git a/npc/controller_test.go b/npc/controller_test.go index fac426dd..21488f03 100644 --- a/npc/controller_test.go +++ b/npc/controller_test.go @@ -514,15 +514,16 @@ func TestNewTargetSelector(t *testing.T) { func TestEgressPolicyWithIPBlock(t *testing.T) { const ( - fooPodIP = "10.32.0.10" - exceptIPSetName = "weave-LKf)d{$q[dkYlH3Ko6eFcdc7z" + fooPodIP = "10.32.0.10" + exceptIPSetName = "weave-j:W$5om!$8JS})buYAD7q^#sX" + exceptIPSetNameInNonDefault = "weave-|*P{aL2C@#N/1IZ!IvQItv_pt" ) m := newMockIPSet() ipt := newMockIPTables() controller := New("foo", ipt, &m) - netpol := &networkingv1.NetworkPolicy{ + netpolFoo := &networkingv1.NetworkPolicy{ ObjectMeta: metav1.ObjectMeta{ UID: "netpol-foo", Name: "allow-from-bar-to-foo", @@ -546,7 +547,8 @@ func TestEgressPolicyWithIPBlock(t *testing.T) { }}, }, } - controller.AddNetworkPolicy(netpol) + err := controller.AddNetworkPolicy(netpolFoo) + require.NoError(t, err) require.Equal(t, 2, len(m.sets[exceptIPSetName].subSets)) require.True(t, m.entryExists(exceptIPSetName, "192.168.48.1/32")) @@ -558,4 +560,35 @@ func TestEgressPolicyWithIPBlock(t *testing.T) { require.Contains(t, rule, "-d 192.168.48.0/24 -m set ! --match-set "+exceptIPSetName+" dst") } + // Check that we create a new ipset for the ipBlock bellow. An ipset with the + // same content already exists (created by netpolFoo), but we need to create + // a new one, as netpolBar is in a different namespace and weave-npc does + // object refcounting only within namespace boundaries. + netpolBar := &networkingv1.NetworkPolicy{ + ObjectMeta: metav1.ObjectMeta{ + UID: "netpol-foo-bar", + Name: "allow-from-bar-to-foo-in-non-default", + Namespace: "non-default", + }, + Spec: networkingv1.NetworkPolicySpec{ + PolicyTypes: []networkingv1.PolicyType{ + networkingv1.PolicyTypeEgress, + }, + PodSelector: metav1.LabelSelector{MatchLabels: map[string]string{"run": "bar"}}, + Egress: []networkingv1.NetworkPolicyEgressRule{{ + To: []networkingv1.NetworkPolicyPeer{{ + IPBlock: &networkingv1.IPBlock{ + CIDR: "192.168.48.0/24", + Except: []string{ + "192.168.48.1/32", + "192.168.48.2/32", + }, + }, + }}, + }}, + }, + } + err = controller.AddNetworkPolicy(netpolBar) + require.NoError(t, err) + require.Equal(t, 2, len(m.sets[exceptIPSetNameInNonDefault].subSets)) } diff --git a/npc/ipblock.go b/npc/ipblock.go index 517ffb20..7d2579d0 100644 --- a/npc/ipblock.go +++ b/npc/ipblock.go @@ -16,15 +16,16 @@ type ipBlockSpec struct { key string ipsetName ipset.Name // ipset for storing excepted CIDRs ipBlock *networkingv1.IPBlock + nsName string // Namespace name } -func newIPBlockSpec(ipb *networkingv1.IPBlock) *ipBlockSpec { - spec := &ipBlockSpec{ipBlock: ipb} +func newIPBlockSpec(ipb *networkingv1.IPBlock, nsName string) *ipBlockSpec { + spec := &ipBlockSpec{ipBlock: ipb, nsName: nsName} if len(ipb.Except) > 0 { sort.Strings(ipb.Except) spec.key = strings.Join(ipb.Except, " ") - spec.ipsetName = ipset.Name(IpsetNamePrefix + shortName("ipblock-except:"+spec.key)) + spec.ipsetName = ipset.Name(IpsetNamePrefix + shortName(nsName+":"+"ipblock-except:"+spec.key)) } return spec