diff options
author | David S. Miller <davem@davemloft.net> | 2018-07-29 00:02:21 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-07-29 00:02:21 -0400 |
commit | 958b4cd8fa4c2eff0c257b07f2bb753b7c7a6f52 (patch) | |
tree | cc6a3a903383ded1ab81996266098a5a4beedea8 | |
parent | b0753408aadf32c7ece9e6b765017881e54af833 (diff) | |
parent | 71eb5255f55bdb484d35ff7c9a1803f453dfbf82 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf
Daniel Borkmann says:
====================
pull-request: bpf 2018-07-28
The following pull-request contains BPF updates for your *net* tree.
The main changes are:
1) API fixes for libbpf's BTF mapping of map key/value types in order
to make them compatible with iproute2's BPF_ANNOTATE_KV_PAIR()
markings, from Martin.
2) Fix AF_XDP to not report POLLIN prematurely by using the non-cached
consumer pointer of the RX queue, from Björn.
3) Fix __xdp_return() to check for NULL pointer after the rhashtable
lookup that retrieves the allocator object, from Taehee.
4) Fix x86-32 JIT to adjust ebp register in prologue and epilogue
by 4 bytes which got removed from overall stack usage, from Wang.
5) Fix bpf_skb_load_bytes_relative() length check to use actual
packet length, from Daniel.
6) Fix uninitialized return code in libbpf bpf_perf_event_read_simple()
handler, from Thomas.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | arch/x86/net/bpf_jit_comp32.c | 8 | ||||
-rw-r--r-- | kernel/bpf/arraymap.c | 2 | ||||
-rw-r--r-- | kernel/bpf/btf.c | 14 | ||||
-rw-r--r-- | net/core/filter.c | 12 | ||||
-rw-r--r-- | net/core/lwt_bpf.c | 2 | ||||
-rw-r--r-- | net/core/xdp.c | 3 | ||||
-rw-r--r-- | net/xdp/xsk_queue.h | 2 | ||||
-rw-r--r-- | tools/include/uapi/linux/btf.h | 2 | ||||
-rw-r--r-- | tools/lib/bpf/btf.c | 39 | ||||
-rw-r--r-- | tools/lib/bpf/btf.h | 10 | ||||
-rw-r--r-- | tools/lib/bpf/libbpf.c | 87 | ||||
-rw-r--r-- | tools/lib/bpf/libbpf.h | 4 | ||||
-rw-r--r-- | tools/testing/selftests/bpf/bpf_helpers.h | 9 | ||||
-rw-r--r-- | tools/testing/selftests/bpf/test_btf.c | 114 | ||||
-rw-r--r-- | tools/testing/selftests/bpf/test_btf_haskv.c | 7 |
15 files changed, 225 insertions, 90 deletions
diff --git a/arch/x86/net/bpf_jit_comp32.c b/arch/x86/net/bpf_jit_comp32.c index 55799873ebe5..8f6cc71e0848 100644 --- a/arch/x86/net/bpf_jit_comp32.c +++ b/arch/x86/net/bpf_jit_comp32.c | |||
@@ -1441,8 +1441,8 @@ static void emit_prologue(u8 **pprog, u32 stack_depth) | |||
1441 | 1441 | ||
1442 | /* sub esp,STACK_SIZE */ | 1442 | /* sub esp,STACK_SIZE */ |
1443 | EMIT2_off32(0x81, 0xEC, STACK_SIZE); | 1443 | EMIT2_off32(0x81, 0xEC, STACK_SIZE); |
1444 | /* sub ebp,SCRATCH_SIZE+4+12*/ | 1444 | /* sub ebp,SCRATCH_SIZE+12*/ |
1445 | EMIT3(0x83, add_1reg(0xE8, IA32_EBP), SCRATCH_SIZE + 16); | 1445 | EMIT3(0x83, add_1reg(0xE8, IA32_EBP), SCRATCH_SIZE + 12); |
1446 | /* xor ebx,ebx */ | 1446 | /* xor ebx,ebx */ |
1447 | EMIT2(0x31, add_2reg(0xC0, IA32_EBX, IA32_EBX)); | 1447 | EMIT2(0x31, add_2reg(0xC0, IA32_EBX, IA32_EBX)); |
1448 | 1448 | ||
@@ -1475,8 +1475,8 @@ static void emit_epilogue(u8 **pprog, u32 stack_depth) | |||
1475 | /* mov edx,dword ptr [ebp+off]*/ | 1475 | /* mov edx,dword ptr [ebp+off]*/ |
1476 | EMIT3(0x8B, add_2reg(0x40, IA32_EBP, IA32_EDX), STACK_VAR(r0[1])); | 1476 | EMIT3(0x8B, add_2reg(0x40, IA32_EBP, IA32_EDX), STACK_VAR(r0[1])); |
1477 | 1477 | ||
1478 | /* add ebp,SCRATCH_SIZE+4+12*/ | 1478 | /* add ebp,SCRATCH_SIZE+12*/ |
1479 | EMIT3(0x83, add_1reg(0xC0, IA32_EBP), SCRATCH_SIZE + 16); | 1479 | EMIT3(0x83, add_1reg(0xC0, IA32_EBP), SCRATCH_SIZE + 12); |
1480 | 1480 | ||
1481 | /* mov ebx,dword ptr [ebp-12]*/ | 1481 | /* mov ebx,dword ptr [ebp-12]*/ |
1482 | EMIT3(0x8B, add_2reg(0x40, IA32_EBP, IA32_EBX), -12); | 1482 | EMIT3(0x8B, add_2reg(0x40, IA32_EBP, IA32_EBX), -12); |
diff --git a/kernel/bpf/arraymap.c b/kernel/bpf/arraymap.c index 544e58f5f642..2aa55d030c77 100644 --- a/kernel/bpf/arraymap.c +++ b/kernel/bpf/arraymap.c | |||
@@ -378,7 +378,7 @@ static int array_map_check_btf(const struct bpf_map *map, const struct btf *btf, | |||
378 | return -EINVAL; | 378 | return -EINVAL; |
379 | 379 | ||
380 | value_type = btf_type_id_size(btf, &btf_value_id, &value_size); | 380 | value_type = btf_type_id_size(btf, &btf_value_id, &value_size); |
381 | if (!value_type || value_size > map->value_size) | 381 | if (!value_type || value_size != map->value_size) |
382 | return -EINVAL; | 382 | return -EINVAL; |
383 | 383 | ||
384 | return 0; | 384 | return 0; |
diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c index 9704934252b3..2590700237c1 100644 --- a/kernel/bpf/btf.c +++ b/kernel/bpf/btf.c | |||
@@ -1519,9 +1519,9 @@ static s32 btf_struct_check_meta(struct btf_verifier_env *env, | |||
1519 | { | 1519 | { |
1520 | bool is_union = BTF_INFO_KIND(t->info) == BTF_KIND_UNION; | 1520 | bool is_union = BTF_INFO_KIND(t->info) == BTF_KIND_UNION; |
1521 | const struct btf_member *member; | 1521 | const struct btf_member *member; |
1522 | u32 meta_needed, last_offset; | ||
1522 | struct btf *btf = env->btf; | 1523 | struct btf *btf = env->btf; |
1523 | u32 struct_size = t->size; | 1524 | u32 struct_size = t->size; |
1524 | u32 meta_needed; | ||
1525 | u16 i; | 1525 | u16 i; |
1526 | 1526 | ||
1527 | meta_needed = btf_type_vlen(t) * sizeof(*member); | 1527 | meta_needed = btf_type_vlen(t) * sizeof(*member); |
@@ -1534,6 +1534,7 @@ static s32 btf_struct_check_meta(struct btf_verifier_env *env, | |||
1534 | 1534 | ||
1535 | btf_verifier_log_type(env, t, NULL); | 1535 | btf_verifier_log_type(env, t, NULL); |
1536 | 1536 | ||
1537 | last_offset = 0; | ||
1537 | for_each_member(i, t, member) { | 1538 | for_each_member(i, t, member) { |
1538 | if (!btf_name_offset_valid(btf, member->name_off)) { | 1539 | if (!btf_name_offset_valid(btf, member->name_off)) { |
1539 | btf_verifier_log_member(env, t, member, | 1540 | btf_verifier_log_member(env, t, member, |
@@ -1555,6 +1556,16 @@ static s32 btf_struct_check_meta(struct btf_verifier_env *env, | |||
1555 | return -EINVAL; | 1556 | return -EINVAL; |
1556 | } | 1557 | } |
1557 | 1558 | ||
1559 | /* | ||
1560 | * ">" instead of ">=" because the last member could be | ||
1561 | * "char a[0];" | ||
1562 | */ | ||
1563 | if (last_offset > member->offset) { | ||
1564 | btf_verifier_log_member(env, t, member, | ||
1565 | "Invalid member bits_offset"); | ||
1566 | return -EINVAL; | ||
1567 | } | ||
1568 | |||
1558 | if (BITS_ROUNDUP_BYTES(member->offset) > struct_size) { | 1569 | if (BITS_ROUNDUP_BYTES(member->offset) > struct_size) { |
1559 | btf_verifier_log_member(env, t, member, | 1570 | btf_verifier_log_member(env, t, member, |
1560 | "Memmber bits_offset exceeds its struct size"); | 1571 | "Memmber bits_offset exceeds its struct size"); |
@@ -1562,6 +1573,7 @@ static s32 btf_struct_check_meta(struct btf_verifier_env *env, | |||
1562 | } | 1573 | } |
1563 | 1574 | ||
1564 | btf_verifier_log_member(env, t, member, NULL); | 1575 | btf_verifier_log_member(env, t, member, NULL); |
1576 | last_offset = member->offset; | ||
1565 | } | 1577 | } |
1566 | 1578 | ||
1567 | return meta_needed; | 1579 | return meta_needed; |
diff --git a/net/core/filter.c b/net/core/filter.c index 06da770f543f..9dfd145eedcc 100644 --- a/net/core/filter.c +++ b/net/core/filter.c | |||
@@ -1712,24 +1712,26 @@ static const struct bpf_func_proto bpf_skb_load_bytes_proto = { | |||
1712 | BPF_CALL_5(bpf_skb_load_bytes_relative, const struct sk_buff *, skb, | 1712 | BPF_CALL_5(bpf_skb_load_bytes_relative, const struct sk_buff *, skb, |
1713 | u32, offset, void *, to, u32, len, u32, start_header) | 1713 | u32, offset, void *, to, u32, len, u32, start_header) |
1714 | { | 1714 | { |
1715 | u8 *end = skb_tail_pointer(skb); | ||
1716 | u8 *net = skb_network_header(skb); | ||
1717 | u8 *mac = skb_mac_header(skb); | ||
1715 | u8 *ptr; | 1718 | u8 *ptr; |
1716 | 1719 | ||
1717 | if (unlikely(offset > 0xffff || len > skb_headlen(skb))) | 1720 | if (unlikely(offset > 0xffff || len > (end - mac))) |
1718 | goto err_clear; | 1721 | goto err_clear; |
1719 | 1722 | ||
1720 | switch (start_header) { | 1723 | switch (start_header) { |
1721 | case BPF_HDR_START_MAC: | 1724 | case BPF_HDR_START_MAC: |
1722 | ptr = skb_mac_header(skb) + offset; | 1725 | ptr = mac + offset; |
1723 | break; | 1726 | break; |
1724 | case BPF_HDR_START_NET: | 1727 | case BPF_HDR_START_NET: |
1725 | ptr = skb_network_header(skb) + offset; | 1728 | ptr = net + offset; |
1726 | break; | 1729 | break; |
1727 | default: | 1730 | default: |
1728 | goto err_clear; | 1731 | goto err_clear; |
1729 | } | 1732 | } |
1730 | 1733 | ||
1731 | if (likely(ptr >= skb_mac_header(skb) && | 1734 | if (likely(ptr >= mac && ptr + len <= end)) { |
1732 | ptr + len <= skb_tail_pointer(skb))) { | ||
1733 | memcpy(to, ptr, len); | 1735 | memcpy(to, ptr, len); |
1734 | return 0; | 1736 | return 0; |
1735 | } | 1737 | } |
diff --git a/net/core/lwt_bpf.c b/net/core/lwt_bpf.c index e7e626fb87bb..e45098593dc0 100644 --- a/net/core/lwt_bpf.c +++ b/net/core/lwt_bpf.c | |||
@@ -217,7 +217,7 @@ static int bpf_parse_prog(struct nlattr *attr, struct bpf_lwt_prog *prog, | |||
217 | if (!tb[LWT_BPF_PROG_FD] || !tb[LWT_BPF_PROG_NAME]) | 217 | if (!tb[LWT_BPF_PROG_FD] || !tb[LWT_BPF_PROG_NAME]) |
218 | return -EINVAL; | 218 | return -EINVAL; |
219 | 219 | ||
220 | prog->name = nla_memdup(tb[LWT_BPF_PROG_NAME], GFP_KERNEL); | 220 | prog->name = nla_memdup(tb[LWT_BPF_PROG_NAME], GFP_ATOMIC); |
221 | if (!prog->name) | 221 | if (!prog->name) |
222 | return -ENOMEM; | 222 | return -ENOMEM; |
223 | 223 | ||
diff --git a/net/core/xdp.c b/net/core/xdp.c index 9d1f22072d5d..6771f1855b96 100644 --- a/net/core/xdp.c +++ b/net/core/xdp.c | |||
@@ -345,7 +345,8 @@ static void __xdp_return(void *data, struct xdp_mem_info *mem, bool napi_direct, | |||
345 | rcu_read_lock(); | 345 | rcu_read_lock(); |
346 | /* mem->id is valid, checked in xdp_rxq_info_reg_mem_model() */ | 346 | /* mem->id is valid, checked in xdp_rxq_info_reg_mem_model() */ |
347 | xa = rhashtable_lookup(mem_id_ht, &mem->id, mem_id_rht_params); | 347 | xa = rhashtable_lookup(mem_id_ht, &mem->id, mem_id_rht_params); |
348 | xa->zc_alloc->free(xa->zc_alloc, handle); | 348 | if (!WARN_ON_ONCE(!xa)) |
349 | xa->zc_alloc->free(xa->zc_alloc, handle); | ||
349 | rcu_read_unlock(); | 350 | rcu_read_unlock(); |
350 | default: | 351 | default: |
351 | /* Not possible, checked in xdp_rxq_info_reg_mem_model() */ | 352 | /* Not possible, checked in xdp_rxq_info_reg_mem_model() */ |
diff --git a/net/xdp/xsk_queue.h b/net/xdp/xsk_queue.h index 52ecaf770642..8a64b150be54 100644 --- a/net/xdp/xsk_queue.h +++ b/net/xdp/xsk_queue.h | |||
@@ -250,7 +250,7 @@ static inline bool xskq_full_desc(struct xsk_queue *q) | |||
250 | 250 | ||
251 | static inline bool xskq_empty_desc(struct xsk_queue *q) | 251 | static inline bool xskq_empty_desc(struct xsk_queue *q) |
252 | { | 252 | { |
253 | return xskq_nb_free(q, q->prod_tail, 1) == q->nentries; | 253 | return xskq_nb_free(q, q->prod_tail, q->nentries) == q->nentries; |
254 | } | 254 | } |
255 | 255 | ||
256 | void xskq_set_umem(struct xsk_queue *q, struct xdp_umem_props *umem_props); | 256 | void xskq_set_umem(struct xsk_queue *q, struct xdp_umem_props *umem_props); |
diff --git a/tools/include/uapi/linux/btf.h b/tools/include/uapi/linux/btf.h index 0b5ddbe135a4..972265f32871 100644 --- a/tools/include/uapi/linux/btf.h +++ b/tools/include/uapi/linux/btf.h | |||
@@ -76,7 +76,7 @@ struct btf_type { | |||
76 | */ | 76 | */ |
77 | #define BTF_INT_ENCODING(VAL) (((VAL) & 0x0f000000) >> 24) | 77 | #define BTF_INT_ENCODING(VAL) (((VAL) & 0x0f000000) >> 24) |
78 | #define BTF_INT_OFFSET(VAL) (((VAL & 0x00ff0000)) >> 16) | 78 | #define BTF_INT_OFFSET(VAL) (((VAL & 0x00ff0000)) >> 16) |
79 | #define BTF_INT_BITS(VAL) ((VAL) & 0x0000ffff) | 79 | #define BTF_INT_BITS(VAL) ((VAL) & 0x000000ff) |
80 | 80 | ||
81 | /* Attributes stored in the BTF_INT_ENCODING */ | 81 | /* Attributes stored in the BTF_INT_ENCODING */ |
82 | #define BTF_INT_SIGNED (1 << 0) | 82 | #define BTF_INT_SIGNED (1 << 0) |
diff --git a/tools/lib/bpf/btf.c b/tools/lib/bpf/btf.c index 8c54a4b6f187..2d270c560df3 100644 --- a/tools/lib/bpf/btf.c +++ b/tools/lib/bpf/btf.c | |||
@@ -2,7 +2,6 @@ | |||
2 | /* Copyright (c) 2018 Facebook */ | 2 | /* Copyright (c) 2018 Facebook */ |
3 | 3 | ||
4 | #include <stdlib.h> | 4 | #include <stdlib.h> |
5 | #include <stdint.h> | ||
6 | #include <string.h> | 5 | #include <string.h> |
7 | #include <unistd.h> | 6 | #include <unistd.h> |
8 | #include <errno.h> | 7 | #include <errno.h> |
@@ -27,13 +26,13 @@ struct btf { | |||
27 | struct btf_type **types; | 26 | struct btf_type **types; |
28 | const char *strings; | 27 | const char *strings; |
29 | void *nohdr_data; | 28 | void *nohdr_data; |
30 | uint32_t nr_types; | 29 | __u32 nr_types; |
31 | uint32_t types_size; | 30 | __u32 types_size; |
32 | uint32_t data_size; | 31 | __u32 data_size; |
33 | int fd; | 32 | int fd; |
34 | }; | 33 | }; |
35 | 34 | ||
36 | static const char *btf_name_by_offset(const struct btf *btf, uint32_t offset) | 35 | static const char *btf_name_by_offset(const struct btf *btf, __u32 offset) |
37 | { | 36 | { |
38 | if (offset < btf->hdr->str_len) | 37 | if (offset < btf->hdr->str_len) |
39 | return &btf->strings[offset]; | 38 | return &btf->strings[offset]; |
@@ -45,7 +44,7 @@ static int btf_add_type(struct btf *btf, struct btf_type *t) | |||
45 | { | 44 | { |
46 | if (btf->types_size - btf->nr_types < 2) { | 45 | if (btf->types_size - btf->nr_types < 2) { |
47 | struct btf_type **new_types; | 46 | struct btf_type **new_types; |
48 | u32 expand_by, new_size; | 47 | __u32 expand_by, new_size; |
49 | 48 | ||
50 | if (btf->types_size == BTF_MAX_NR_TYPES) | 49 | if (btf->types_size == BTF_MAX_NR_TYPES) |
51 | return -E2BIG; | 50 | return -E2BIG; |
@@ -72,7 +71,7 @@ static int btf_add_type(struct btf *btf, struct btf_type *t) | |||
72 | static int btf_parse_hdr(struct btf *btf, btf_print_fn_t err_log) | 71 | static int btf_parse_hdr(struct btf *btf, btf_print_fn_t err_log) |
73 | { | 72 | { |
74 | const struct btf_header *hdr = btf->hdr; | 73 | const struct btf_header *hdr = btf->hdr; |
75 | u32 meta_left; | 74 | __u32 meta_left; |
76 | 75 | ||
77 | if (btf->data_size < sizeof(struct btf_header)) { | 76 | if (btf->data_size < sizeof(struct btf_header)) { |
78 | elog("BTF header not found\n"); | 77 | elog("BTF header not found\n"); |
@@ -151,7 +150,7 @@ static int btf_parse_type_sec(struct btf *btf, btf_print_fn_t err_log) | |||
151 | 150 | ||
152 | while (next_type < end_type) { | 151 | while (next_type < end_type) { |
153 | struct btf_type *t = next_type; | 152 | struct btf_type *t = next_type; |
154 | uint16_t vlen = BTF_INFO_VLEN(t->info); | 153 | __u16 vlen = BTF_INFO_VLEN(t->info); |
155 | int err; | 154 | int err; |
156 | 155 | ||
157 | next_type += sizeof(*t); | 156 | next_type += sizeof(*t); |
@@ -190,8 +189,7 @@ static int btf_parse_type_sec(struct btf *btf, btf_print_fn_t err_log) | |||
190 | return 0; | 189 | return 0; |
191 | } | 190 | } |
192 | 191 | ||
193 | static const struct btf_type *btf_type_by_id(const struct btf *btf, | 192 | const struct btf_type *btf__type_by_id(const struct btf *btf, __u32 type_id) |
194 | uint32_t type_id) | ||
195 | { | 193 | { |
196 | if (type_id > btf->nr_types) | 194 | if (type_id > btf->nr_types) |
197 | return NULL; | 195 | return NULL; |
@@ -209,7 +207,7 @@ static bool btf_type_is_void_or_null(const struct btf_type *t) | |||
209 | return !t || btf_type_is_void(t); | 207 | return !t || btf_type_is_void(t); |
210 | } | 208 | } |
211 | 209 | ||
212 | static int64_t btf_type_size(const struct btf_type *t) | 210 | static __s64 btf_type_size(const struct btf_type *t) |
213 | { | 211 | { |
214 | switch (BTF_INFO_KIND(t->info)) { | 212 | switch (BTF_INFO_KIND(t->info)) { |
215 | case BTF_KIND_INT: | 213 | case BTF_KIND_INT: |
@@ -226,15 +224,15 @@ static int64_t btf_type_size(const struct btf_type *t) | |||
226 | 224 | ||
227 | #define MAX_RESOLVE_DEPTH 32 | 225 | #define MAX_RESOLVE_DEPTH 32 |
228 | 226 | ||
229 | int64_t btf__resolve_size(const struct btf *btf, uint32_t type_id) | 227 | __s64 btf__resolve_size(const struct btf *btf, __u32 type_id) |
230 | { | 228 | { |
231 | const struct btf_array *array; | 229 | const struct btf_array *array; |
232 | const struct btf_type *t; | 230 | const struct btf_type *t; |
233 | uint32_t nelems = 1; | 231 | __u32 nelems = 1; |
234 | int64_t size = -1; | 232 | __s64 size = -1; |
235 | int i; | 233 | int i; |
236 | 234 | ||
237 | t = btf_type_by_id(btf, type_id); | 235 | t = btf__type_by_id(btf, type_id); |
238 | for (i = 0; i < MAX_RESOLVE_DEPTH && !btf_type_is_void_or_null(t); | 236 | for (i = 0; i < MAX_RESOLVE_DEPTH && !btf_type_is_void_or_null(t); |
239 | i++) { | 237 | i++) { |
240 | size = btf_type_size(t); | 238 | size = btf_type_size(t); |
@@ -259,7 +257,7 @@ int64_t btf__resolve_size(const struct btf *btf, uint32_t type_id) | |||
259 | return -EINVAL; | 257 | return -EINVAL; |
260 | } | 258 | } |
261 | 259 | ||
262 | t = btf_type_by_id(btf, type_id); | 260 | t = btf__type_by_id(btf, type_id); |
263 | } | 261 | } |
264 | 262 | ||
265 | if (size < 0) | 263 | if (size < 0) |
@@ -271,9 +269,9 @@ int64_t btf__resolve_size(const struct btf *btf, uint32_t type_id) | |||
271 | return nelems * size; | 269 | return nelems * size; |
272 | } | 270 | } |
273 | 271 | ||
274 | int32_t btf__find_by_name(const struct btf *btf, const char *type_name) | 272 | __s32 btf__find_by_name(const struct btf *btf, const char *type_name) |
275 | { | 273 | { |
276 | uint32_t i; | 274 | __u32 i; |
277 | 275 | ||
278 | if (!strcmp(type_name, "void")) | 276 | if (!strcmp(type_name, "void")) |
279 | return 0; | 277 | return 0; |
@@ -302,10 +300,9 @@ void btf__free(struct btf *btf) | |||
302 | free(btf); | 300 | free(btf); |
303 | } | 301 | } |
304 | 302 | ||
305 | struct btf *btf__new(uint8_t *data, uint32_t size, | 303 | struct btf *btf__new(__u8 *data, __u32 size, btf_print_fn_t err_log) |
306 | btf_print_fn_t err_log) | ||
307 | { | 304 | { |
308 | uint32_t log_buf_size = 0; | 305 | __u32 log_buf_size = 0; |
309 | char *log_buf = NULL; | 306 | char *log_buf = NULL; |
310 | struct btf *btf; | 307 | struct btf *btf; |
311 | int err; | 308 | int err; |
diff --git a/tools/lib/bpf/btf.h b/tools/lib/bpf/btf.h index 74bb344035bb..e2a09a155f84 100644 --- a/tools/lib/bpf/btf.h +++ b/tools/lib/bpf/btf.h | |||
@@ -4,19 +4,21 @@ | |||
4 | #ifndef __BPF_BTF_H | 4 | #ifndef __BPF_BTF_H |
5 | #define __BPF_BTF_H | 5 | #define __BPF_BTF_H |
6 | 6 | ||
7 | #include <stdint.h> | 7 | #include <linux/types.h> |
8 | 8 | ||
9 | #define BTF_ELF_SEC ".BTF" | 9 | #define BTF_ELF_SEC ".BTF" |
10 | 10 | ||
11 | struct btf; | 11 | struct btf; |
12 | struct btf_type; | ||
12 | 13 | ||
13 | typedef int (*btf_print_fn_t)(const char *, ...) | 14 | typedef int (*btf_print_fn_t)(const char *, ...) |
14 | __attribute__((format(printf, 1, 2))); | 15 | __attribute__((format(printf, 1, 2))); |
15 | 16 | ||
16 | void btf__free(struct btf *btf); | 17 | void btf__free(struct btf *btf); |
17 | struct btf *btf__new(uint8_t *data, uint32_t size, btf_print_fn_t err_log); | 18 | struct btf *btf__new(__u8 *data, __u32 size, btf_print_fn_t err_log); |
18 | int32_t btf__find_by_name(const struct btf *btf, const char *type_name); | 19 | __s32 btf__find_by_name(const struct btf *btf, const char *type_name); |
19 | int64_t btf__resolve_size(const struct btf *btf, uint32_t type_id); | 20 | const struct btf_type *btf__type_by_id(const struct btf *btf, __u32 id); |
21 | __s64 btf__resolve_size(const struct btf *btf, __u32 type_id); | ||
20 | int btf__fd(const struct btf *btf); | 22 | int btf__fd(const struct btf *btf); |
21 | 23 | ||
22 | #endif | 24 | #endif |
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index a1e96b5de5ff..1aafdbe827fe 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/err.h> | 36 | #include <linux/err.h> |
37 | #include <linux/kernel.h> | 37 | #include <linux/kernel.h> |
38 | #include <linux/bpf.h> | 38 | #include <linux/bpf.h> |
39 | #include <linux/btf.h> | ||
39 | #include <linux/list.h> | 40 | #include <linux/list.h> |
40 | #include <linux/limits.h> | 41 | #include <linux/limits.h> |
41 | #include <sys/stat.h> | 42 | #include <sys/stat.h> |
@@ -216,8 +217,8 @@ struct bpf_map { | |||
216 | size_t offset; | 217 | size_t offset; |
217 | int map_ifindex; | 218 | int map_ifindex; |
218 | struct bpf_map_def def; | 219 | struct bpf_map_def def; |
219 | uint32_t btf_key_type_id; | 220 | __u32 btf_key_type_id; |
220 | uint32_t btf_value_type_id; | 221 | __u32 btf_value_type_id; |
221 | void *priv; | 222 | void *priv; |
222 | bpf_map_clear_priv_t clear_priv; | 223 | bpf_map_clear_priv_t clear_priv; |
223 | }; | 224 | }; |
@@ -1014,68 +1015,72 @@ bpf_program__collect_reloc(struct bpf_program *prog, GElf_Shdr *shdr, | |||
1014 | 1015 | ||
1015 | static int bpf_map_find_btf_info(struct bpf_map *map, const struct btf *btf) | 1016 | static int bpf_map_find_btf_info(struct bpf_map *map, const struct btf *btf) |
1016 | { | 1017 | { |
1018 | const struct btf_type *container_type; | ||
1019 | const struct btf_member *key, *value; | ||
1017 | struct bpf_map_def *def = &map->def; | 1020 | struct bpf_map_def *def = &map->def; |
1018 | const size_t max_name = 256; | 1021 | const size_t max_name = 256; |
1019 | int64_t key_size, value_size; | 1022 | char container_name[max_name]; |
1020 | int32_t key_id, value_id; | 1023 | __s64 key_size, value_size; |
1021 | char name[max_name]; | 1024 | __s32 container_id; |
1022 | 1025 | ||
1023 | /* Find key type by name from BTF */ | 1026 | if (snprintf(container_name, max_name, "____btf_map_%s", map->name) == |
1024 | if (snprintf(name, max_name, "%s_key", map->name) == max_name) { | 1027 | max_name) { |
1025 | pr_warning("map:%s length of BTF key_type:%s_key is too long\n", | 1028 | pr_warning("map:%s length of '____btf_map_%s' is too long\n", |
1026 | map->name, map->name); | 1029 | map->name, map->name); |
1027 | return -EINVAL; | 1030 | return -EINVAL; |
1028 | } | 1031 | } |
1029 | 1032 | ||
1030 | key_id = btf__find_by_name(btf, name); | 1033 | container_id = btf__find_by_name(btf, container_name); |
1031 | if (key_id < 0) { | 1034 | if (container_id < 0) { |
1032 | pr_debug("map:%s key_type:%s cannot be found in BTF\n", | 1035 | pr_debug("map:%s container_name:%s cannot be found in BTF. Missing BPF_ANNOTATE_KV_PAIR?\n", |
1033 | map->name, name); | 1036 | map->name, container_name); |
1034 | return key_id; | 1037 | return container_id; |
1035 | } | 1038 | } |
1036 | 1039 | ||
1037 | key_size = btf__resolve_size(btf, key_id); | 1040 | container_type = btf__type_by_id(btf, container_id); |
1038 | if (key_size < 0) { | 1041 | if (!container_type) { |
1039 | pr_warning("map:%s key_type:%s cannot get the BTF type_size\n", | 1042 | pr_warning("map:%s cannot find BTF type for container_id:%u\n", |
1040 | map->name, name); | 1043 | map->name, container_id); |
1041 | return key_size; | 1044 | return -EINVAL; |
1042 | } | 1045 | } |
1043 | 1046 | ||
1044 | if (def->key_size != key_size) { | 1047 | if (BTF_INFO_KIND(container_type->info) != BTF_KIND_STRUCT || |
1045 | pr_warning("map:%s key_type:%s has BTF type_size:%u != key_size:%u\n", | 1048 | BTF_INFO_VLEN(container_type->info) < 2) { |
1046 | map->name, name, (unsigned int)key_size, def->key_size); | 1049 | pr_warning("map:%s container_name:%s is an invalid container struct\n", |
1050 | map->name, container_name); | ||
1047 | return -EINVAL; | 1051 | return -EINVAL; |
1048 | } | 1052 | } |
1049 | 1053 | ||
1050 | /* Find value type from BTF */ | 1054 | key = (struct btf_member *)(container_type + 1); |
1051 | if (snprintf(name, max_name, "%s_value", map->name) == max_name) { | 1055 | value = key + 1; |
1052 | pr_warning("map:%s length of BTF value_type:%s_value is too long\n", | 1056 | |
1053 | map->name, map->name); | 1057 | key_size = btf__resolve_size(btf, key->type); |
1054 | return -EINVAL; | 1058 | if (key_size < 0) { |
1059 | pr_warning("map:%s invalid BTF key_type_size\n", | ||
1060 | map->name); | ||
1061 | return key_size; | ||
1055 | } | 1062 | } |
1056 | 1063 | ||
1057 | value_id = btf__find_by_name(btf, name); | 1064 | if (def->key_size != key_size) { |
1058 | if (value_id < 0) { | 1065 | pr_warning("map:%s btf_key_type_size:%u != map_def_key_size:%u\n", |
1059 | pr_debug("map:%s value_type:%s cannot be found in BTF\n", | 1066 | map->name, (__u32)key_size, def->key_size); |
1060 | map->name, name); | 1067 | return -EINVAL; |
1061 | return value_id; | ||
1062 | } | 1068 | } |
1063 | 1069 | ||
1064 | value_size = btf__resolve_size(btf, value_id); | 1070 | value_size = btf__resolve_size(btf, value->type); |
1065 | if (value_size < 0) { | 1071 | if (value_size < 0) { |
1066 | pr_warning("map:%s value_type:%s cannot get the BTF type_size\n", | 1072 | pr_warning("map:%s invalid BTF value_type_size\n", map->name); |
1067 | map->name, name); | ||
1068 | return value_size; | 1073 | return value_size; |
1069 | } | 1074 | } |
1070 | 1075 | ||
1071 | if (def->value_size != value_size) { | 1076 | if (def->value_size != value_size) { |
1072 | pr_warning("map:%s value_type:%s has BTF type_size:%u != value_size:%u\n", | 1077 | pr_warning("map:%s btf_value_type_size:%u != map_def_value_size:%u\n", |
1073 | map->name, name, (unsigned int)value_size, def->value_size); | 1078 | map->name, (__u32)value_size, def->value_size); |
1074 | return -EINVAL; | 1079 | return -EINVAL; |
1075 | } | 1080 | } |
1076 | 1081 | ||
1077 | map->btf_key_type_id = key_id; | 1082 | map->btf_key_type_id = key->type; |
1078 | map->btf_value_type_id = value_id; | 1083 | map->btf_value_type_id = value->type; |
1079 | 1084 | ||
1080 | return 0; | 1085 | return 0; |
1081 | } | 1086 | } |
@@ -2089,12 +2094,12 @@ const char *bpf_map__name(struct bpf_map *map) | |||
2089 | return map ? map->name : NULL; | 2094 | return map ? map->name : NULL; |
2090 | } | 2095 | } |
2091 | 2096 | ||
2092 | uint32_t bpf_map__btf_key_type_id(const struct bpf_map *map) | 2097 | __u32 bpf_map__btf_key_type_id(const struct bpf_map *map) |
2093 | { | 2098 | { |
2094 | return map ? map->btf_key_type_id : 0; | 2099 | return map ? map->btf_key_type_id : 0; |
2095 | } | 2100 | } |
2096 | 2101 | ||
2097 | uint32_t bpf_map__btf_value_type_id(const struct bpf_map *map) | 2102 | __u32 bpf_map__btf_value_type_id(const struct bpf_map *map) |
2098 | { | 2103 | { |
2099 | return map ? map->btf_value_type_id : 0; | 2104 | return map ? map->btf_value_type_id : 0; |
2100 | } | 2105 | } |
@@ -2268,8 +2273,8 @@ bpf_perf_event_read_simple(void *mem, unsigned long size, | |||
2268 | volatile struct perf_event_mmap_page *header = mem; | 2273 | volatile struct perf_event_mmap_page *header = mem; |
2269 | __u64 data_tail = header->data_tail; | 2274 | __u64 data_tail = header->data_tail; |
2270 | __u64 data_head = header->data_head; | 2275 | __u64 data_head = header->data_head; |
2276 | int ret = LIBBPF_PERF_EVENT_ERROR; | ||
2271 | void *base, *begin, *end; | 2277 | void *base, *begin, *end; |
2272 | int ret; | ||
2273 | 2278 | ||
2274 | asm volatile("" ::: "memory"); /* in real code it should be smp_rmb() */ | 2279 | asm volatile("" ::: "memory"); /* in real code it should be smp_rmb() */ |
2275 | if (data_head == data_tail) | 2280 | if (data_head == data_tail) |
diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h index 09976531aa74..b33ae02f7d0e 100644 --- a/tools/lib/bpf/libbpf.h +++ b/tools/lib/bpf/libbpf.h | |||
@@ -244,8 +244,8 @@ bpf_map__next(struct bpf_map *map, struct bpf_object *obj); | |||
244 | int bpf_map__fd(struct bpf_map *map); | 244 | int bpf_map__fd(struct bpf_map *map); |
245 | const struct bpf_map_def *bpf_map__def(struct bpf_map *map); | 245 | const struct bpf_map_def *bpf_map__def(struct bpf_map *map); |
246 | const char *bpf_map__name(struct bpf_map *map); | 246 | const char *bpf_map__name(struct bpf_map *map); |
247 | uint32_t bpf_map__btf_key_type_id(const struct bpf_map *map); | 247 | __u32 bpf_map__btf_key_type_id(const struct bpf_map *map); |
248 | uint32_t bpf_map__btf_value_type_id(const struct bpf_map *map); | 248 | __u32 bpf_map__btf_value_type_id(const struct bpf_map *map); |
249 | 249 | ||
250 | typedef void (*bpf_map_clear_priv_t)(struct bpf_map *, void *); | 250 | typedef void (*bpf_map_clear_priv_t)(struct bpf_map *, void *); |
251 | int bpf_map__set_priv(struct bpf_map *map, void *priv, | 251 | int bpf_map__set_priv(struct bpf_map *map, void *priv, |
diff --git a/tools/testing/selftests/bpf/bpf_helpers.h b/tools/testing/selftests/bpf/bpf_helpers.h index f2f28b6c8915..810de20e8e26 100644 --- a/tools/testing/selftests/bpf/bpf_helpers.h +++ b/tools/testing/selftests/bpf/bpf_helpers.h | |||
@@ -158,6 +158,15 @@ struct bpf_map_def { | |||
158 | unsigned int numa_node; | 158 | unsigned int numa_node; |
159 | }; | 159 | }; |
160 | 160 | ||
161 | #define BPF_ANNOTATE_KV_PAIR(name, type_key, type_val) \ | ||
162 | struct ____btf_map_##name { \ | ||
163 | type_key key; \ | ||
164 | type_val value; \ | ||
165 | }; \ | ||
166 | struct ____btf_map_##name \ | ||
167 | __attribute__ ((section(".maps." #name), used)) \ | ||
168 | ____btf_map_##name = { } | ||
169 | |||
161 | static int (*bpf_skb_load_bytes)(void *ctx, int off, void *to, int len) = | 170 | static int (*bpf_skb_load_bytes)(void *ctx, int off, void *to, int len) = |
162 | (void *) BPF_FUNC_skb_load_bytes; | 171 | (void *) BPF_FUNC_skb_load_bytes; |
163 | static int (*bpf_skb_store_bytes)(void *ctx, int off, void *from, int len, int flags) = | 172 | static int (*bpf_skb_store_bytes)(void *ctx, int off, void *from, int len, int flags) = |
diff --git a/tools/testing/selftests/bpf/test_btf.c b/tools/testing/selftests/bpf/test_btf.c index 3619f3023088..ffdd27737c9e 100644 --- a/tools/testing/selftests/bpf/test_btf.c +++ b/tools/testing/selftests/bpf/test_btf.c | |||
@@ -247,6 +247,34 @@ static struct btf_raw_test raw_tests[] = { | |||
247 | .max_entries = 4, | 247 | .max_entries = 4, |
248 | }, | 248 | }, |
249 | 249 | ||
250 | { | ||
251 | .descr = "struct test #3 Invalid member offset", | ||
252 | .raw_types = { | ||
253 | /* int */ /* [1] */ | ||
254 | BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), | ||
255 | /* int64 */ /* [2] */ | ||
256 | BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 64, 8), | ||
257 | |||
258 | /* struct A { */ /* [3] */ | ||
259 | BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 2), 16), | ||
260 | BTF_MEMBER_ENC(NAME_TBD, 1, 64), /* int m; */ | ||
261 | BTF_MEMBER_ENC(NAME_TBD, 2, 0), /* int64 n; */ | ||
262 | /* } */ | ||
263 | BTF_END_RAW, | ||
264 | }, | ||
265 | .str_sec = "\0A\0m\0n\0", | ||
266 | .str_sec_size = sizeof("\0A\0m\0n\0"), | ||
267 | .map_type = BPF_MAP_TYPE_ARRAY, | ||
268 | .map_name = "struct_test3_map", | ||
269 | .key_size = sizeof(int), | ||
270 | .value_size = 16, | ||
271 | .key_type_id = 1, | ||
272 | .value_type_id = 3, | ||
273 | .max_entries = 4, | ||
274 | .btf_load_err = true, | ||
275 | .err_str = "Invalid member bits_offset", | ||
276 | }, | ||
277 | |||
250 | /* Test member exceeds the size of struct. | 278 | /* Test member exceeds the size of struct. |
251 | * | 279 | * |
252 | * struct A { | 280 | * struct A { |
@@ -479,7 +507,7 @@ static struct btf_raw_test raw_tests[] = { | |||
479 | .key_size = sizeof(int), | 507 | .key_size = sizeof(int), |
480 | .value_size = sizeof(void *) * 4, | 508 | .value_size = sizeof(void *) * 4, |
481 | .key_type_id = 1, | 509 | .key_type_id = 1, |
482 | .value_type_id = 4, | 510 | .value_type_id = 5, |
483 | .max_entries = 4, | 511 | .max_entries = 4, |
484 | }, | 512 | }, |
485 | 513 | ||
@@ -1264,6 +1292,88 @@ static struct btf_raw_test raw_tests[] = { | |||
1264 | .err_str = "type != 0", | 1292 | .err_str = "type != 0", |
1265 | }, | 1293 | }, |
1266 | 1294 | ||
1295 | { | ||
1296 | .descr = "arraymap invalid btf key (a bit field)", | ||
1297 | .raw_types = { | ||
1298 | /* int */ /* [1] */ | ||
1299 | BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), | ||
1300 | /* 32 bit int with 32 bit offset */ /* [2] */ | ||
1301 | BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 32, 32, 8), | ||
1302 | BTF_END_RAW, | ||
1303 | }, | ||
1304 | .str_sec = "", | ||
1305 | .str_sec_size = sizeof(""), | ||
1306 | .map_type = BPF_MAP_TYPE_ARRAY, | ||
1307 | .map_name = "array_map_check_btf", | ||
1308 | .key_size = sizeof(int), | ||
1309 | .value_size = sizeof(int), | ||
1310 | .key_type_id = 2, | ||
1311 | .value_type_id = 1, | ||
1312 | .max_entries = 4, | ||
1313 | .map_create_err = true, | ||
1314 | }, | ||
1315 | |||
1316 | { | ||
1317 | .descr = "arraymap invalid btf key (!= 32 bits)", | ||
1318 | .raw_types = { | ||
1319 | /* int */ /* [1] */ | ||
1320 | BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), | ||
1321 | /* 16 bit int with 0 bit offset */ /* [2] */ | ||
1322 | BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 16, 2), | ||
1323 | BTF_END_RAW, | ||
1324 | }, | ||
1325 | .str_sec = "", | ||
1326 | .str_sec_size = sizeof(""), | ||
1327 | .map_type = BPF_MAP_TYPE_ARRAY, | ||
1328 | .map_name = "array_map_check_btf", | ||
1329 | .key_size = sizeof(int), | ||
1330 | .value_size = sizeof(int), | ||
1331 | .key_type_id = 2, | ||
1332 | .value_type_id = 1, | ||
1333 | .max_entries = 4, | ||
1334 | .map_create_err = true, | ||
1335 | }, | ||
1336 | |||
1337 | { | ||
1338 | .descr = "arraymap invalid btf value (too small)", | ||
1339 | .raw_types = { | ||
1340 | /* int */ /* [1] */ | ||
1341 | BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), | ||
1342 | BTF_END_RAW, | ||
1343 | }, | ||
1344 | .str_sec = "", | ||
1345 | .str_sec_size = sizeof(""), | ||
1346 | .map_type = BPF_MAP_TYPE_ARRAY, | ||
1347 | .map_name = "array_map_check_btf", | ||
1348 | .key_size = sizeof(int), | ||
1349 | /* btf_value_size < map->value_size */ | ||
1350 | .value_size = sizeof(__u64), | ||
1351 | .key_type_id = 1, | ||
1352 | .value_type_id = 1, | ||
1353 | .max_entries = 4, | ||
1354 | .map_create_err = true, | ||
1355 | }, | ||
1356 | |||
1357 | { | ||
1358 | .descr = "arraymap invalid btf value (too big)", | ||
1359 | .raw_types = { | ||
1360 | /* int */ /* [1] */ | ||
1361 | BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), | ||
1362 | BTF_END_RAW, | ||
1363 | }, | ||
1364 | .str_sec = "", | ||
1365 | .str_sec_size = sizeof(""), | ||
1366 | .map_type = BPF_MAP_TYPE_ARRAY, | ||
1367 | .map_name = "array_map_check_btf", | ||
1368 | .key_size = sizeof(int), | ||
1369 | /* btf_value_size > map->value_size */ | ||
1370 | .value_size = sizeof(__u16), | ||
1371 | .key_type_id = 1, | ||
1372 | .value_type_id = 1, | ||
1373 | .max_entries = 4, | ||
1374 | .map_create_err = true, | ||
1375 | }, | ||
1376 | |||
1267 | }; /* struct btf_raw_test raw_tests[] */ | 1377 | }; /* struct btf_raw_test raw_tests[] */ |
1268 | 1378 | ||
1269 | static const char *get_next_str(const char *start, const char *end) | 1379 | static const char *get_next_str(const char *start, const char *end) |
@@ -2023,7 +2133,7 @@ static struct btf_raw_test pprint_test = { | |||
2023 | BTF_ENUM_ENC(NAME_TBD, 2), | 2133 | BTF_ENUM_ENC(NAME_TBD, 2), |
2024 | BTF_ENUM_ENC(NAME_TBD, 3), | 2134 | BTF_ENUM_ENC(NAME_TBD, 3), |
2025 | /* struct pprint_mapv */ /* [16] */ | 2135 | /* struct pprint_mapv */ /* [16] */ |
2026 | BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 8), 28), | 2136 | BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 0, 8), 32), |
2027 | BTF_MEMBER_ENC(NAME_TBD, 11, 0), /* uint32_t ui32 */ | 2137 | BTF_MEMBER_ENC(NAME_TBD, 11, 0), /* uint32_t ui32 */ |
2028 | BTF_MEMBER_ENC(NAME_TBD, 10, 32), /* uint16_t ui16 */ | 2138 | BTF_MEMBER_ENC(NAME_TBD, 10, 32), /* uint16_t ui16 */ |
2029 | BTF_MEMBER_ENC(NAME_TBD, 12, 64), /* int32_t si32 */ | 2139 | BTF_MEMBER_ENC(NAME_TBD, 12, 64), /* int32_t si32 */ |
diff --git a/tools/testing/selftests/bpf/test_btf_haskv.c b/tools/testing/selftests/bpf/test_btf_haskv.c index 8c7ca096ecf2..b21b876f475d 100644 --- a/tools/testing/selftests/bpf/test_btf_haskv.c +++ b/tools/testing/selftests/bpf/test_btf_haskv.c | |||
@@ -10,11 +10,6 @@ struct ipv_counts { | |||
10 | unsigned int v6; | 10 | unsigned int v6; |
11 | }; | 11 | }; |
12 | 12 | ||
13 | typedef int btf_map_key; | ||
14 | typedef struct ipv_counts btf_map_value; | ||
15 | btf_map_key dumm_key; | ||
16 | btf_map_value dummy_value; | ||
17 | |||
18 | struct bpf_map_def SEC("maps") btf_map = { | 13 | struct bpf_map_def SEC("maps") btf_map = { |
19 | .type = BPF_MAP_TYPE_ARRAY, | 14 | .type = BPF_MAP_TYPE_ARRAY, |
20 | .key_size = sizeof(int), | 15 | .key_size = sizeof(int), |
@@ -22,6 +17,8 @@ struct bpf_map_def SEC("maps") btf_map = { | |||
22 | .max_entries = 4, | 17 | .max_entries = 4, |
23 | }; | 18 | }; |
24 | 19 | ||
20 | BPF_ANNOTATE_KV_PAIR(btf_map, int, struct ipv_counts); | ||
21 | |||
25 | struct dummy_tracepoint_args { | 22 | struct dummy_tracepoint_args { |
26 | unsigned long long pad; | 23 | unsigned long long pad; |
27 | struct sock *sock; | 24 | struct sock *sock; |