-
Notifications
You must be signed in to change notification settings - Fork 30
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Handle overlaps in except and allow CIDRs #344
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -175,31 +175,18 @@ func TestBpfClient_IsEBPFProbeAttached(t *testing.T) { | |
} | ||
} | ||
|
||
func TestBpfClient_CheckAndDeriveCatchAllIPPorts(t *testing.T) { | ||
func TestBpfClient_CheckAndDeriveL4InfoFromAnyMatchingCIDRs(t *testing.T) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We need more test cases here that will cover for the scenarios described in the description of the PR are handled by the test case.
The code change and the logic looks good to me. As noted in the review of the design doc, I wanted to see if there is any simpler way, but handling all except at the end looks alright. Coverage with test case can help us push this PR to finish line here. Thank you. |
||
protocolTCP := corev1.ProtocolTCP | ||
var port80 int32 = 80 | ||
|
||
type want struct { | ||
catchAllL4Info []v1alpha1.Port | ||
isCatchAllIPEntryPresent bool | ||
allowAllPortAndProtocols bool | ||
} | ||
|
||
l4InfoWithCatchAllEntry := []EbpfFirewallRules{ | ||
{ | ||
IPCidr: "0.0.0.0/0", | ||
L4Info: []v1alpha1.Port{ | ||
{ | ||
Protocol: &protocolTCP, | ||
Port: &port80, | ||
}, | ||
}, | ||
}, | ||
matchingCIDRL4Info []v1alpha1.Port | ||
} | ||
|
||
l4InfoWithNoCatchAllEntry := []EbpfFirewallRules{ | ||
{ | ||
IPCidr: "1.1.1.1/32", | ||
sampleCidrsMap := map[string]EbpfFirewallRules{ | ||
"1.1.1.0/24": { | ||
IPCidr: "1.1.1.0/24", | ||
Except: []v1alpha1.NetworkAddress{}, | ||
L4Info: []v1alpha1.Port{ | ||
{ | ||
Protocol: &protocolTCP, | ||
|
@@ -209,96 +196,16 @@ func TestBpfClient_CheckAndDeriveCatchAllIPPorts(t *testing.T) { | |
}, | ||
} | ||
|
||
l4InfoWithCatchAllEntryAndAllProtocols := []EbpfFirewallRules{ | ||
{ | ||
IPCidr: "0.0.0.0/0", | ||
}, | ||
} | ||
|
||
tests := []struct { | ||
name string | ||
firewallRules []EbpfFirewallRules | ||
want want | ||
}{ | ||
{ | ||
name: "Catch All Entry present", | ||
firewallRules: l4InfoWithCatchAllEntry, | ||
want: want{ | ||
catchAllL4Info: []v1alpha1.Port{ | ||
{ | ||
Protocol: &protocolTCP, | ||
Port: &port80, | ||
}, | ||
}, | ||
isCatchAllIPEntryPresent: true, | ||
allowAllPortAndProtocols: false, | ||
}, | ||
}, | ||
|
||
{ | ||
name: "No Catch All Entry present", | ||
firewallRules: l4InfoWithNoCatchAllEntry, | ||
want: want{ | ||
isCatchAllIPEntryPresent: false, | ||
allowAllPortAndProtocols: false, | ||
}, | ||
}, | ||
|
||
{ | ||
name: "Catch All Entry With no Port info", | ||
firewallRules: l4InfoWithCatchAllEntryAndAllProtocols, | ||
want: want{ | ||
isCatchAllIPEntryPresent: true, | ||
allowAllPortAndProtocols: true, | ||
}, | ||
}, | ||
} | ||
|
||
for _, tt := range tests { | ||
t.Run(tt.name, func(t *testing.T) { | ||
testBpfClient := &bpfClient{ | ||
nodeIP: "10.1.1.1", | ||
logger: logr.New(&log.NullLogSink{}), | ||
enableIPv6: false, | ||
hostMask: "/32", | ||
IngressPodToProgMap: new(sync.Map), | ||
EgressPodToProgMap: new(sync.Map), | ||
} | ||
gotCatchAllL4Info, gotIsCatchAllIPEntryPresent, gotAllowAllPortAndProtocols := testBpfClient.checkAndDeriveCatchAllIPPorts(tt.firewallRules) | ||
assert.Equal(t, tt.want.catchAllL4Info, gotCatchAllL4Info) | ||
assert.Equal(t, tt.want.isCatchAllIPEntryPresent, gotIsCatchAllIPEntryPresent) | ||
assert.Equal(t, tt.want.allowAllPortAndProtocols, gotAllowAllPortAndProtocols) | ||
}) | ||
} | ||
} | ||
|
||
func TestBpfClient_CheckAndDeriveL4InfoFromAnyMatchingCIDRs(t *testing.T) { | ||
protocolTCP := corev1.ProtocolTCP | ||
var port80 int32 = 80 | ||
|
||
type want struct { | ||
matchingCIDRL4Info []v1alpha1.Port | ||
} | ||
|
||
sampleNonHostCIDRs := map[string][]v1alpha1.Port{ | ||
"1.1.1.0/24": { | ||
{ | ||
Protocol: &protocolTCP, | ||
Port: &port80, | ||
}, | ||
}, | ||
} | ||
|
||
tests := []struct { | ||
name string | ||
firewallRule string | ||
nonHostCIDRs map[string][]v1alpha1.Port | ||
cidrsMap map[string]EbpfFirewallRules | ||
want want | ||
}{ | ||
{ | ||
name: "Match Present", | ||
firewallRule: "1.1.1.2/32", | ||
nonHostCIDRs: sampleNonHostCIDRs, | ||
cidrsMap: sampleCidrsMap, | ||
want: want{ | ||
matchingCIDRL4Info: []v1alpha1.Port{ | ||
{ | ||
|
@@ -312,7 +219,7 @@ func TestBpfClient_CheckAndDeriveL4InfoFromAnyMatchingCIDRs(t *testing.T) { | |
{ | ||
name: "No Match", | ||
firewallRule: "2.1.1.2/32", | ||
nonHostCIDRs: sampleNonHostCIDRs, | ||
cidrsMap: sampleCidrsMap, | ||
want: want{}, | ||
}, | ||
} | ||
|
@@ -327,7 +234,7 @@ func TestBpfClient_CheckAndDeriveL4InfoFromAnyMatchingCIDRs(t *testing.T) { | |
IngressPodToProgMap: new(sync.Map), | ||
EgressPodToProgMap: new(sync.Map), | ||
} | ||
gotMatchingCIDRL4Info := testBpfClient.checkAndDeriveL4InfoFromAnyMatchingCIDRs(tt.firewallRule, tt.nonHostCIDRs) | ||
gotMatchingCIDRL4Info := testBpfClient.checkAndDeriveL4InfoFromAnyMatchingCIDRs(tt.firewallRule, tt.cidrsMap) | ||
assert.Equal(t, tt.want.matchingCIDRL4Info, gotMatchingCIDRL4Info) | ||
}) | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -201,7 +201,8 @@ int handle_egress(struct __sk_buff *skb) | |
return BPF_DROP; | ||
} | ||
|
||
if ((trie_val->protocol == ANY_IP_PROTOCOL) || (trie_val->protocol == ip->protocol && | ||
if ((trie_val->protocol == ANY_IP_PROTOCOL && ((trie_val->start_port == ANY_PORT) || (l4_dst_port == trie_val->start_port) || | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Enhancement Request: We can format this and explain the behavior of in the comment. |
||
(l4_dst_port > trie_val->start_port && l4_dst_port <= trie_val->end_port))) || (trie_val->protocol == ip->protocol && | ||
((trie_val->start_port == ANY_PORT) || (l4_dst_port == trie_val->start_port) || | ||
(l4_dst_port > trie_val->start_port && l4_dst_port <= trie_val->end_port)))) { | ||
//Inject in to conntrack map | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As an enhancement, could you document the behavior of this function as function doc string itself. We pack a lot inside the function here.