From eb9dd2dc301aa046f7984aeb2a54c91a7461fa8a Mon Sep 17 00:00:00 2001 From: Jayanth Varavani <1111446+jayanthvn@users.noreply.github.com> Date: Tue, 12 Sep 2023 17:47:25 +0000 Subject: [PATCH 1/2] Honor except with catchALL --- pkg/ebpf/bpf_client.go | 64 ++++++++++++++++++++---------------------- 1 file changed, 31 insertions(+), 33 deletions(-) diff --git a/pkg/ebpf/bpf_client.go b/pkg/ebpf/bpf_client.go index 9e34867..df830dc 100644 --- a/pkg/ebpf/bpf_client.go +++ b/pkg/ebpf/bpf_client.go @@ -734,43 +734,41 @@ func (l *bpfClient) computeMapEntriesFromEndpointRules(firewallRules []EbpfFirew if !strings.Contains(string(firewallRule.IPCidr), "/") { firewallRule.IPCidr += v1alpha1.NetworkAddress(l.hostMask) } - //TODO - Just Purge both the entries and avoid these calls for every CIDR - if utils.IsCatchAllIPEntry(string(firewallRule.IPCidr)) { - continue - } - if len(firewallRule.L4Info) == 0 { - l.logger.Info("No L4 specified. Add Catch all entry: ", "CIDR: ", firewallRule.IPCidr) - l.addCatchAllL4Entry(&firewallRule) - l.logger.Info("Total L4 entries ", "count: ", len(firewallRule.L4Info)) - } - if utils.IsNonHostCIDR(string(firewallRule.IPCidr)) { - if existingL4Info, ok := nonHostCIDRs[string(firewallRule.IPCidr)]; ok { - firewallRule.L4Info = append(firewallRule.L4Info, existingL4Info...) - } - nonHostCIDRs[string(firewallRule.IPCidr)] = firewallRule.L4Info - } else { - if existingL4Info, ok := ipCIDRs[string(firewallRule.IPCidr)]; ok { - firewallRule.L4Info = append(firewallRule.L4Info, existingL4Info...) + if !isCatchAllIPEntryPresent { + if len(firewallRule.L4Info) == 0 { + l.logger.Info("No L4 specified. Add Catch all entry: ", "CIDR: ", firewallRule.IPCidr) + l.addCatchAllL4Entry(&firewallRule) + l.logger.Info("Total L4 entries ", "count: ", len(firewallRule.L4Info)) } - // Check if the /32 entry is part of any non host CIDRs that we've encountered so far - // If found, we need to include the port and protocol combination against the current entry as well since - // we use LPM TRIE map and the /32 will always win out. - cidrL4Info = l.checkAndDeriveL4InfoFromAnyMatchingCIDRs(string(firewallRule.IPCidr), nonHostCIDRs) - if len(cidrL4Info) > 0 { - firewallRule.L4Info = append(firewallRule.L4Info, cidrL4Info...) + if utils.IsNonHostCIDR(string(firewallRule.IPCidr)) { + if existingL4Info, ok := nonHostCIDRs[string(firewallRule.IPCidr)]; ok { + firewallRule.L4Info = append(firewallRule.L4Info, existingL4Info...) + } + nonHostCIDRs[string(firewallRule.IPCidr)] = firewallRule.L4Info + } else { + if existingL4Info, ok := ipCIDRs[string(firewallRule.IPCidr)]; ok { + firewallRule.L4Info = append(firewallRule.L4Info, existingL4Info...) + } + // Check if the /32 entry is part of any non host CIDRs that we've encountered so far + // If found, we need to include the port and protocol combination against the current entry as well since + // we use LPM TRIE map and the /32 will always win out. + cidrL4Info = l.checkAndDeriveL4InfoFromAnyMatchingCIDRs(string(firewallRule.IPCidr), nonHostCIDRs) + if len(cidrL4Info) > 0 { + firewallRule.L4Info = append(firewallRule.L4Info, cidrL4Info...) + } + ipCIDRs[string(firewallRule.IPCidr)] = firewallRule.L4Info } - ipCIDRs[string(firewallRule.IPCidr)] = firewallRule.L4Info - } - //Include port and protocol combination paired with catch all entries - firewallRule.L4Info = append(firewallRule.L4Info, catchAllIPPorts...) + //Include port and protocol combination paired with catch all entries + firewallRule.L4Info = append(firewallRule.L4Info, catchAllIPPorts...) - l.logger.Info("Updating Map with ", "IP Key:", firewallRule.IPCidr) - _, mapKey, _ = net.ParseCIDR(string(firewallRule.IPCidr)) - // Key format: Prefix length (4 bytes) followed by 4/16byte IP address - key = utils.ComputeTrieKey(*mapKey, l.enableIPv6) - value = utils.ComputeTrieValue(firewallRule.L4Info, l.logger, allowAll, false) - mapEntries[string(key)] = uintptr(unsafe.Pointer(&value[0])) + l.logger.Info("Updating Map with ", "IP Key:", firewallRule.IPCidr) + _, mapKey, _ = net.ParseCIDR(string(firewallRule.IPCidr)) + // Key format: Prefix length (4 bytes) followed by 4/16byte IP address + key = utils.ComputeTrieKey(*mapKey, l.enableIPv6) + value = utils.ComputeTrieValue(firewallRule.L4Info, l.logger, allowAll, false) + mapEntries[string(key)] = uintptr(unsafe.Pointer(&value[0])) + } if firewallRule.Except != nil { for _, exceptCIDR := range firewallRule.Except { _, mapKey, _ = net.ParseCIDR(string(exceptCIDR)) From bef3ce814694f0611d5f157b7a068467ee6c9d72 Mon Sep 17 00:00:00 2001 From: Jayanth Varavani <1111446+jayanthvn@users.noreply.github.com> Date: Sat, 16 Sep 2023 18:08:19 +0000 Subject: [PATCH 2/2] PR feedback --- pkg/ebpf/bpf_client.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/ebpf/bpf_client.go b/pkg/ebpf/bpf_client.go index 03032d9..f38b97b 100644 --- a/pkg/ebpf/bpf_client.go +++ b/pkg/ebpf/bpf_client.go @@ -743,7 +743,7 @@ func (l *bpfClient) computeMapEntriesFromEndpointRules(firewallRules []EbpfFirew continue } - if !isCatchAllIPEntryPresent { + if !utils.IsCatchAllIPEntry(string(firewallRule.IPCidr)) { if len(firewallRule.L4Info) == 0 { l.logger.Info("No L4 specified. Add Catch all entry: ", "CIDR: ", firewallRule.IPCidr) l.addCatchAllL4Entry(&firewallRule)