Search code examples
cpointersebpf

ebpf bpf_map_lookup_elem use const char* as key type, can't get the value from bpf map


When I want to get a value from bpf map, the input key type is const char*, it can't get the map value; But when the key type is char name[192], it can get the correct value. What is the difference of above two key type? why it happend in this situation?

This is the ebpf code:

struct {
    __uint(type, BPF_MAP_TYPE_HASH_OF_MAPS);
    __uint(key_size, CLUSTER_NAME_MAX_LEN);
    __uint(value_size, sizeof(__u32));
    __uint(max_entries, MAP_SIZE_OF_CLUSTER);
    __uint(map_flags, BPF_F_NO_PREALLOC);
    __array(values, struct inner_of_maglev);
}outer_of_maglev SEC(".maps");   // CLUSTER_NAME_MAX_LEN equal 192

static inline void *loadbalance(struct cluster_endpoints *eps, const char* name,ctx_buff_t *ctx) 
{
    if (!eps || eps->ep_num == 0)
        return NULL;
    __u32 *res1;
    __u32 *res2;
    
    char c_name[192] = "outbound|5000||helloworld.default.svc.cluster.local";
    res1 = (__u32 *)bpf_map_lookup_elem(&outer_of_maglev,name);
    res2 = (__u32 *)bpf_map_lookup_elem(&outer_of_maglev,c_name);
    if (res1) {
        BPF_LOG(INFO, CLUSTER, "loadbalance_maglev test res %u\n",res);
    }
    return NULL;
}

As the above statement, the res1 is NULL, res2 is not NULL,which is the correct value of map. In addition, the content of variable name is same as the c_name;


Solution

  • I think the issue is what comes after your string in memory. As all keys to the map must have the same size (in your case, 192 bytes size) and the entire key is used for the search (not just the part up to the null terminator)

    In your char[192] argument, the rest of the array is zeroed. In case of the char* argument, that depends on how you created it. If you didn't allocate it as a 192-bytes zeroed array and only then copied your string, than random bytes from memory are used as well for your key and you don't get the expected result.