bool bpf_probe_map_type()

in compile/remote-compile/lbc/libbpf/src/libbpf_probes.c [200:309]


bool bpf_probe_map_type(enum bpf_map_type map_type, __u32 ifindex)
{
	int key_size, value_size, max_entries, map_flags;
	__u32 btf_key_type_id = 0, btf_value_type_id = 0;
	int fd = -1, btf_fd = -1, fd_inner;

	key_size	= sizeof(__u32);
	value_size	= sizeof(__u32);
	max_entries	= 1;
	map_flags	= 0;

	switch (map_type) {
	case BPF_MAP_TYPE_STACK_TRACE:
		value_size	= sizeof(__u64);
		break;
	case BPF_MAP_TYPE_LPM_TRIE:
		key_size	= sizeof(__u64);
		value_size	= sizeof(__u64);
		map_flags	= BPF_F_NO_PREALLOC;
		break;
	case BPF_MAP_TYPE_CGROUP_STORAGE:
	case BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE:
		key_size	= sizeof(struct bpf_cgroup_storage_key);
		value_size	= sizeof(__u64);
		max_entries	= 0;
		break;
	case BPF_MAP_TYPE_QUEUE:
	case BPF_MAP_TYPE_STACK:
		key_size	= 0;
		break;
	case BPF_MAP_TYPE_SK_STORAGE:
	case BPF_MAP_TYPE_INODE_STORAGE:
	case BPF_MAP_TYPE_TASK_STORAGE:
		btf_key_type_id = 1;
		btf_value_type_id = 3;
		value_size = 8;
		max_entries = 0;
		map_flags = BPF_F_NO_PREALLOC;
		btf_fd = load_local_storage_btf();
		if (btf_fd < 0)
			return false;
		break;
	case BPF_MAP_TYPE_RINGBUF:
		key_size = 0;
		value_size = 0;
		max_entries = 4096;
		break;
	case BPF_MAP_TYPE_UNSPEC:
	case BPF_MAP_TYPE_HASH:
	case BPF_MAP_TYPE_ARRAY:
	case BPF_MAP_TYPE_PROG_ARRAY:
	case BPF_MAP_TYPE_PERF_EVENT_ARRAY:
	case BPF_MAP_TYPE_PERCPU_HASH:
	case BPF_MAP_TYPE_PERCPU_ARRAY:
	case BPF_MAP_TYPE_CGROUP_ARRAY:
	case BPF_MAP_TYPE_LRU_HASH:
	case BPF_MAP_TYPE_LRU_PERCPU_HASH:
	case BPF_MAP_TYPE_ARRAY_OF_MAPS:
	case BPF_MAP_TYPE_HASH_OF_MAPS:
	case BPF_MAP_TYPE_DEVMAP:
	case BPF_MAP_TYPE_DEVMAP_HASH:
	case BPF_MAP_TYPE_SOCKMAP:
	case BPF_MAP_TYPE_CPUMAP:
	case BPF_MAP_TYPE_XSKMAP:
	case BPF_MAP_TYPE_SOCKHASH:
	case BPF_MAP_TYPE_REUSEPORT_SOCKARRAY:
	case BPF_MAP_TYPE_STRUCT_OPS:
	default:
		break;
	}

	if (map_type == BPF_MAP_TYPE_ARRAY_OF_MAPS ||
	    map_type == BPF_MAP_TYPE_HASH_OF_MAPS) {
		LIBBPF_OPTS(bpf_map_create_opts, opts);

		/* TODO: probe for device, once libbpf has a function to create
		 * map-in-map for offload
		 */
		if (ifindex)
			return false;

		fd_inner = bpf_map_create(BPF_MAP_TYPE_HASH, NULL,
					  sizeof(__u32), sizeof(__u32), 1, NULL);
		if (fd_inner < 0)
			return false;

		opts.inner_map_fd = fd_inner;
		fd = bpf_map_create(map_type, NULL, sizeof(__u32), sizeof(__u32), 1, &opts);
		close(fd_inner);
	} else {
		LIBBPF_OPTS(bpf_map_create_opts, opts);

		/* Note: No other restriction on map type probes for offload */
		opts.map_flags = map_flags;
		opts.map_ifindex = ifindex;
		if (btf_fd >= 0) {
			opts.btf_fd = btf_fd;
			opts.btf_key_type_id = btf_key_type_id;
			opts.btf_value_type_id = btf_value_type_id;
		}

		fd = bpf_map_create(map_type, NULL, key_size, value_size, max_entries, &opts);
	}
	if (fd >= 0)
		close(fd);
	if (btf_fd >= 0)
		close(btf_fd);

	return fd >= 0;
}