func()

in pkg/ebpf/bpf_client.go [1005:1118]


func (l *bpfClient) computeMapEntriesFromEndpointRules(firewallRules []EbpfFirewallRules) (map[string][]byte, error) {

	firewallMap := make(map[string][]byte)
	ipCIDRs := make(map[string][]v1alpha1.Port)
	nonHostCIDRs := make(map[string][]v1alpha1.Port)
	isCatchAllIPEntryPresent, allowAll := false, false
	var catchAllIPPorts []v1alpha1.Port

	//Traffic from the local node should always be allowed. Add NodeIP by default to map entries.
	_, mapKey, _ := net.ParseCIDR(l.nodeIP + l.hostMask)
	key := utils.ComputeTrieKey(*mapKey, l.enableIPv6)
	value := utils.ComputeTrieValue([]v1alpha1.Port{}, l.logger, true, false)
	firewallMap[string(key)] = value

	//Sort the rules
	sortFirewallRulesByPrefixLength(firewallRules, l.hostMask)

	//Check and aggregate L4 Port Info for Catch All Entries.
	catchAllIPPorts, isCatchAllIPEntryPresent, allowAll = l.checkAndDeriveCatchAllIPPorts(firewallRules)
	if isCatchAllIPEntryPresent {
		//Add the Catch All IP entry
		_, mapKey, _ := net.ParseCIDR("0.0.0.0/0")
		key := utils.ComputeTrieKey(*mapKey, l.enableIPv6)
		value := utils.ComputeTrieValue(catchAllIPPorts, l.logger, allowAll, false)
		firewallMap[string(key)] = value
	}

	for _, firewallRule := range firewallRules {
		var cidrL4Info []v1alpha1.Port

		if !strings.Contains(string(firewallRule.IPCidr), "/") {
			firewallRule.IPCidr += v1alpha1.NetworkAddress(l.hostMask)
		}

		if utils.IsNodeIP(l.nodeIP, string(firewallRule.IPCidr)) {
			continue
		}

		if l.enableIPv6 && !strings.Contains(string(firewallRule.IPCidr), "::") {
			l.logger.Info("Skipping ipv4 rule in ipv6 cluster: ", "CIDR: ", string(firewallRule.IPCidr))
			continue
		}

		if !l.enableIPv6 && strings.Contains(string(firewallRule.IPCidr), "::") {
			l.logger.Info("Skipping ipv6 rule in ipv4 cluster: ", "CIDR: ", string(firewallRule.IPCidr))
			continue
		}

		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)
				l.logger.Info("Total L4 entries ", "count: ", len(firewallRule.L4Info))
			}
			if utils.IsNonHostCIDR(string(firewallRule.IPCidr)) {
				existingL4Info, ok := nonHostCIDRs[string(firewallRule.IPCidr)]
				if ok {
					firewallRule.L4Info = append(firewallRule.L4Info, existingL4Info...)
				} else {
					// Check if the /m entry is part of any /n 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 /m will always win out.
					cidrL4Info = l.checkAndDeriveL4InfoFromAnyMatchingCIDRs(string(firewallRule.IPCidr), nonHostCIDRs)
					if len(cidrL4Info) > 0 {
						firewallRule.L4Info = append(firewallRule.L4Info, cidrL4Info...)
					}
				}
				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
			}
			//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)
			_, firewallMapKey, _ := net.ParseCIDR(string(firewallRule.IPCidr))
			// Key format: Prefix length (4 bytes) followed by 4/16byte IP address
			firewallKey := utils.ComputeTrieKey(*firewallMapKey, l.enableIPv6)

			if len(firewallRule.L4Info) != 0 {
				mergedL4Info := mergeDuplicateL4Info(firewallRule.L4Info)
				firewallRule.L4Info = mergedL4Info

			}
			firewallValue := utils.ComputeTrieValue(firewallRule.L4Info, l.logger, allowAll, false)
			firewallMap[string(firewallKey)] = firewallValue
		}
		if firewallRule.Except != nil {
			for _, exceptCIDR := range firewallRule.Except {
				_, mapKey, _ := net.ParseCIDR(string(exceptCIDR))
				key := utils.ComputeTrieKey(*mapKey, l.enableIPv6)
				l.logger.Info("Parsed Except CIDR", "IP Key: ", mapKey)
				if len(firewallRule.L4Info) != 0 {
					mergedL4Info := mergeDuplicateL4Info(firewallRule.L4Info)
					firewallRule.L4Info = mergedL4Info
				}
				value := utils.ComputeTrieValue(firewallRule.L4Info, l.logger, false, true)
				firewallMap[string(key)] = value
			}
		}
	}

	return firewallMap, nil
}