diff options
Diffstat (limited to 'tools')
30 files changed, 1037 insertions, 143 deletions
diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h index 3c38ac9a92a7..929c8e537a14 100644 --- a/tools/include/uapi/linux/bpf.h +++ b/tools/include/uapi/linux/bpf.h | |||
@@ -502,16 +502,6 @@ union bpf_attr { | |||
502 | * Return | 502 | * Return |
503 | * 0 on success, or a negative error in case of failure. | 503 | * 0 on success, or a negative error in case of failure. |
504 | * | 504 | * |
505 | * int bpf_map_push_elem(struct bpf_map *map, const void *value, u64 flags) | ||
506 | * Description | ||
507 | * Push an element *value* in *map*. *flags* is one of: | ||
508 | * | ||
509 | * **BPF_EXIST** | ||
510 | * If the queue/stack is full, the oldest element is removed to | ||
511 | * make room for this. | ||
512 | * Return | ||
513 | * 0 on success, or a negative error in case of failure. | ||
514 | * | ||
515 | * int bpf_probe_read(void *dst, u32 size, const void *src) | 505 | * int bpf_probe_read(void *dst, u32 size, const void *src) |
516 | * Description | 506 | * Description |
517 | * For tracing programs, safely attempt to read *size* bytes from | 507 | * For tracing programs, safely attempt to read *size* bytes from |
@@ -1435,14 +1425,14 @@ union bpf_attr { | |||
1435 | * u64 bpf_get_socket_cookie(struct bpf_sock_addr *ctx) | 1425 | * u64 bpf_get_socket_cookie(struct bpf_sock_addr *ctx) |
1436 | * Description | 1426 | * Description |
1437 | * Equivalent to bpf_get_socket_cookie() helper that accepts | 1427 | * Equivalent to bpf_get_socket_cookie() helper that accepts |
1438 | * *skb*, but gets socket from **struct bpf_sock_addr** contex. | 1428 | * *skb*, but gets socket from **struct bpf_sock_addr** context. |
1439 | * Return | 1429 | * Return |
1440 | * A 8-byte long non-decreasing number. | 1430 | * A 8-byte long non-decreasing number. |
1441 | * | 1431 | * |
1442 | * u64 bpf_get_socket_cookie(struct bpf_sock_ops *ctx) | 1432 | * u64 bpf_get_socket_cookie(struct bpf_sock_ops *ctx) |
1443 | * Description | 1433 | * Description |
1444 | * Equivalent to bpf_get_socket_cookie() helper that accepts | 1434 | * Equivalent to bpf_get_socket_cookie() helper that accepts |
1445 | * *skb*, but gets socket from **struct bpf_sock_ops** contex. | 1435 | * *skb*, but gets socket from **struct bpf_sock_ops** context. |
1446 | * Return | 1436 | * Return |
1447 | * A 8-byte long non-decreasing number. | 1437 | * A 8-byte long non-decreasing number. |
1448 | * | 1438 | * |
@@ -2098,52 +2088,52 @@ union bpf_attr { | |||
2098 | * Return | 2088 | * Return |
2099 | * 0 on success, or a negative error in case of failure. | 2089 | * 0 on success, or a negative error in case of failure. |
2100 | * | 2090 | * |
2101 | * int bpf_rc_keydown(void *ctx, u32 protocol, u64 scancode, u32 toggle) | 2091 | * int bpf_rc_repeat(void *ctx) |
2102 | * Description | 2092 | * Description |
2103 | * This helper is used in programs implementing IR decoding, to | 2093 | * This helper is used in programs implementing IR decoding, to |
2104 | * report a successfully decoded key press with *scancode*, | 2094 | * report a successfully decoded repeat key message. This delays |
2105 | * *toggle* value in the given *protocol*. The scancode will be | 2095 | * the generation of a key up event for previously generated |
2106 | * translated to a keycode using the rc keymap, and reported as | 2096 | * key down event. |
2107 | * an input key down event. After a period a key up event is | ||
2108 | * generated. This period can be extended by calling either | ||
2109 | * **bpf_rc_keydown**\ () again with the same values, or calling | ||
2110 | * **bpf_rc_repeat**\ (). | ||
2111 | * | 2097 | * |
2112 | * Some protocols include a toggle bit, in case the button was | 2098 | * Some IR protocols like NEC have a special IR message for |
2113 | * released and pressed again between consecutive scancodes. | 2099 | * repeating last button, for when a button is held down. |
2114 | * | 2100 | * |
2115 | * The *ctx* should point to the lirc sample as passed into | 2101 | * The *ctx* should point to the lirc sample as passed into |
2116 | * the program. | 2102 | * the program. |
2117 | * | 2103 | * |
2118 | * The *protocol* is the decoded protocol number (see | ||
2119 | * **enum rc_proto** for some predefined values). | ||
2120 | * | ||
2121 | * This helper is only available is the kernel was compiled with | 2104 | * This helper is only available is the kernel was compiled with |
2122 | * the **CONFIG_BPF_LIRC_MODE2** configuration option set to | 2105 | * the **CONFIG_BPF_LIRC_MODE2** configuration option set to |
2123 | * "**y**". | 2106 | * "**y**". |
2124 | * Return | 2107 | * Return |
2125 | * 0 | 2108 | * 0 |
2126 | * | 2109 | * |
2127 | * int bpf_rc_repeat(void *ctx) | 2110 | * int bpf_rc_keydown(void *ctx, u32 protocol, u64 scancode, u32 toggle) |
2128 | * Description | 2111 | * Description |
2129 | * This helper is used in programs implementing IR decoding, to | 2112 | * This helper is used in programs implementing IR decoding, to |
2130 | * report a successfully decoded repeat key message. This delays | 2113 | * report a successfully decoded key press with *scancode*, |
2131 | * the generation of a key up event for previously generated | 2114 | * *toggle* value in the given *protocol*. The scancode will be |
2132 | * key down event. | 2115 | * translated to a keycode using the rc keymap, and reported as |
2116 | * an input key down event. After a period a key up event is | ||
2117 | * generated. This period can be extended by calling either | ||
2118 | * **bpf_rc_keydown**\ () again with the same values, or calling | ||
2119 | * **bpf_rc_repeat**\ (). | ||
2133 | * | 2120 | * |
2134 | * Some IR protocols like NEC have a special IR message for | 2121 | * Some protocols include a toggle bit, in case the button was |
2135 | * repeating last button, for when a button is held down. | 2122 | * released and pressed again between consecutive scancodes. |
2136 | * | 2123 | * |
2137 | * The *ctx* should point to the lirc sample as passed into | 2124 | * The *ctx* should point to the lirc sample as passed into |
2138 | * the program. | 2125 | * the program. |
2139 | * | 2126 | * |
2127 | * The *protocol* is the decoded protocol number (see | ||
2128 | * **enum rc_proto** for some predefined values). | ||
2129 | * | ||
2140 | * This helper is only available is the kernel was compiled with | 2130 | * This helper is only available is the kernel was compiled with |
2141 | * the **CONFIG_BPF_LIRC_MODE2** configuration option set to | 2131 | * the **CONFIG_BPF_LIRC_MODE2** configuration option set to |
2142 | * "**y**". | 2132 | * "**y**". |
2143 | * Return | 2133 | * Return |
2144 | * 0 | 2134 | * 0 |
2145 | * | 2135 | * |
2146 | * uint64_t bpf_skb_cgroup_id(struct sk_buff *skb) | 2136 | * u64 bpf_skb_cgroup_id(struct sk_buff *skb) |
2147 | * Description | 2137 | * Description |
2148 | * Return the cgroup v2 id of the socket associated with the *skb*. | 2138 | * Return the cgroup v2 id of the socket associated with the *skb*. |
2149 | * This is roughly similar to the **bpf_get_cgroup_classid**\ () | 2139 | * This is roughly similar to the **bpf_get_cgroup_classid**\ () |
@@ -2159,30 +2149,12 @@ union bpf_attr { | |||
2159 | * Return | 2149 | * Return |
2160 | * The id is returned or 0 in case the id could not be retrieved. | 2150 | * The id is returned or 0 in case the id could not be retrieved. |
2161 | * | 2151 | * |
2162 | * u64 bpf_skb_ancestor_cgroup_id(struct sk_buff *skb, int ancestor_level) | ||
2163 | * Description | ||
2164 | * Return id of cgroup v2 that is ancestor of cgroup associated | ||
2165 | * with the *skb* at the *ancestor_level*. The root cgroup is at | ||
2166 | * *ancestor_level* zero and each step down the hierarchy | ||
2167 | * increments the level. If *ancestor_level* == level of cgroup | ||
2168 | * associated with *skb*, then return value will be same as that | ||
2169 | * of **bpf_skb_cgroup_id**\ (). | ||
2170 | * | ||
2171 | * The helper is useful to implement policies based on cgroups | ||
2172 | * that are upper in hierarchy than immediate cgroup associated | ||
2173 | * with *skb*. | ||
2174 | * | ||
2175 | * The format of returned id and helper limitations are same as in | ||
2176 | * **bpf_skb_cgroup_id**\ (). | ||
2177 | * Return | ||
2178 | * The id is returned or 0 in case the id could not be retrieved. | ||
2179 | * | ||
2180 | * u64 bpf_get_current_cgroup_id(void) | 2152 | * u64 bpf_get_current_cgroup_id(void) |
2181 | * Return | 2153 | * Return |
2182 | * A 64-bit integer containing the current cgroup id based | 2154 | * A 64-bit integer containing the current cgroup id based |
2183 | * on the cgroup within which the current task is running. | 2155 | * on the cgroup within which the current task is running. |
2184 | * | 2156 | * |
2185 | * void* get_local_storage(void *map, u64 flags) | 2157 | * void *bpf_get_local_storage(void *map, u64 flags) |
2186 | * Description | 2158 | * Description |
2187 | * Get the pointer to the local storage area. | 2159 | * Get the pointer to the local storage area. |
2188 | * The type and the size of the local storage is defined | 2160 | * The type and the size of the local storage is defined |
@@ -2209,6 +2181,24 @@ union bpf_attr { | |||
2209 | * Return | 2181 | * Return |
2210 | * 0 on success, or a negative error in case of failure. | 2182 | * 0 on success, or a negative error in case of failure. |
2211 | * | 2183 | * |
2184 | * u64 bpf_skb_ancestor_cgroup_id(struct sk_buff *skb, int ancestor_level) | ||
2185 | * Description | ||
2186 | * Return id of cgroup v2 that is ancestor of cgroup associated | ||
2187 | * with the *skb* at the *ancestor_level*. The root cgroup is at | ||
2188 | * *ancestor_level* zero and each step down the hierarchy | ||
2189 | * increments the level. If *ancestor_level* == level of cgroup | ||
2190 | * associated with *skb*, then return value will be same as that | ||
2191 | * of **bpf_skb_cgroup_id**\ (). | ||
2192 | * | ||
2193 | * The helper is useful to implement policies based on cgroups | ||
2194 | * that are upper in hierarchy than immediate cgroup associated | ||
2195 | * with *skb*. | ||
2196 | * | ||
2197 | * The format of returned id and helper limitations are same as in | ||
2198 | * **bpf_skb_cgroup_id**\ (). | ||
2199 | * Return | ||
2200 | * The id is returned or 0 in case the id could not be retrieved. | ||
2201 | * | ||
2212 | * struct bpf_sock *bpf_sk_lookup_tcp(void *ctx, struct bpf_sock_tuple *tuple, u32 tuple_size, u64 netns, u64 flags) | 2202 | * struct bpf_sock *bpf_sk_lookup_tcp(void *ctx, struct bpf_sock_tuple *tuple, u32 tuple_size, u64 netns, u64 flags) |
2213 | * Description | 2203 | * Description |
2214 | * Look for TCP socket matching *tuple*, optionally in a child | 2204 | * Look for TCP socket matching *tuple*, optionally in a child |
@@ -2289,6 +2279,16 @@ union bpf_attr { | |||
2289 | * Return | 2279 | * Return |
2290 | * 0 on success, or a negative error in case of failure. | 2280 | * 0 on success, or a negative error in case of failure. |
2291 | * | 2281 | * |
2282 | * int bpf_map_push_elem(struct bpf_map *map, const void *value, u64 flags) | ||
2283 | * Description | ||
2284 | * Push an element *value* in *map*. *flags* is one of: | ||
2285 | * | ||
2286 | * **BPF_EXIST** | ||
2287 | * If the queue/stack is full, the oldest element is | ||
2288 | * removed to make room for this. | ||
2289 | * Return | ||
2290 | * 0 on success, or a negative error in case of failure. | ||
2291 | * | ||
2292 | * int bpf_map_pop_elem(struct bpf_map *map, void *value) | 2292 | * int bpf_map_pop_elem(struct bpf_map *map, void *value) |
2293 | * Description | 2293 | * Description |
2294 | * Pop an element from *map*. | 2294 | * Pop an element from *map*. |
@@ -2343,29 +2343,94 @@ union bpf_attr { | |||
2343 | * Return | 2343 | * Return |
2344 | * 0 | 2344 | * 0 |
2345 | * | 2345 | * |
2346 | * int bpf_spin_lock(struct bpf_spin_lock *lock) | ||
2347 | * Description | ||
2348 | * Acquire a spinlock represented by the pointer *lock*, which is | ||
2349 | * stored as part of a value of a map. Taking the lock allows to | ||
2350 | * safely update the rest of the fields in that value. The | ||
2351 | * spinlock can (and must) later be released with a call to | ||
2352 | * **bpf_spin_unlock**\ (\ *lock*\ ). | ||
2353 | * | ||
2354 | * Spinlocks in BPF programs come with a number of restrictions | ||
2355 | * and constraints: | ||
2356 | * | ||
2357 | * * **bpf_spin_lock** objects are only allowed inside maps of | ||
2358 | * types **BPF_MAP_TYPE_HASH** and **BPF_MAP_TYPE_ARRAY** (this | ||
2359 | * list could be extended in the future). | ||
2360 | * * BTF description of the map is mandatory. | ||
2361 | * * The BPF program can take ONE lock at a time, since taking two | ||
2362 | * or more could cause dead locks. | ||
2363 | * * Only one **struct bpf_spin_lock** is allowed per map element. | ||
2364 | * * When the lock is taken, calls (either BPF to BPF or helpers) | ||
2365 | * are not allowed. | ||
2366 | * * The **BPF_LD_ABS** and **BPF_LD_IND** instructions are not | ||
2367 | * allowed inside a spinlock-ed region. | ||
2368 | * * The BPF program MUST call **bpf_spin_unlock**\ () to release | ||
2369 | * the lock, on all execution paths, before it returns. | ||
2370 | * * The BPF program can access **struct bpf_spin_lock** only via | ||
2371 | * the **bpf_spin_lock**\ () and **bpf_spin_unlock**\ () | ||
2372 | * helpers. Loading or storing data into the **struct | ||
2373 | * bpf_spin_lock** *lock*\ **;** field of a map is not allowed. | ||
2374 | * * To use the **bpf_spin_lock**\ () helper, the BTF description | ||
2375 | * of the map value must be a struct and have **struct | ||
2376 | * bpf_spin_lock** *anyname*\ **;** field at the top level. | ||
2377 | * Nested lock inside another struct is not allowed. | ||
2378 | * * The **struct bpf_spin_lock** *lock* field in a map value must | ||
2379 | * be aligned on a multiple of 4 bytes in that value. | ||
2380 | * * Syscall with command **BPF_MAP_LOOKUP_ELEM** does not copy | ||
2381 | * the **bpf_spin_lock** field to user space. | ||
2382 | * * Syscall with command **BPF_MAP_UPDATE_ELEM**, or update from | ||
2383 | * a BPF program, do not update the **bpf_spin_lock** field. | ||
2384 | * * **bpf_spin_lock** cannot be on the stack or inside a | ||
2385 | * networking packet (it can only be inside of a map values). | ||
2386 | * * **bpf_spin_lock** is available to root only. | ||
2387 | * * Tracing programs and socket filter programs cannot use | ||
2388 | * **bpf_spin_lock**\ () due to insufficient preemption checks | ||
2389 | * (but this may change in the future). | ||
2390 | * * **bpf_spin_lock** is not allowed in inner maps of map-in-map. | ||
2391 | * Return | ||
2392 | * 0 | ||
2393 | * | ||
2394 | * int bpf_spin_unlock(struct bpf_spin_lock *lock) | ||
2395 | * Description | ||
2396 | * Release the *lock* previously locked by a call to | ||
2397 | * **bpf_spin_lock**\ (\ *lock*\ ). | ||
2398 | * Return | ||
2399 | * 0 | ||
2400 | * | ||
2346 | * struct bpf_sock *bpf_sk_fullsock(struct bpf_sock *sk) | 2401 | * struct bpf_sock *bpf_sk_fullsock(struct bpf_sock *sk) |
2347 | * Description | 2402 | * Description |
2348 | * This helper gets a **struct bpf_sock** pointer such | 2403 | * This helper gets a **struct bpf_sock** pointer such |
2349 | * that all the fields in bpf_sock can be accessed. | 2404 | * that all the fields in this **bpf_sock** can be accessed. |
2350 | * Return | 2405 | * Return |
2351 | * A **struct bpf_sock** pointer on success, or NULL in | 2406 | * A **struct bpf_sock** pointer on success, or **NULL** in |
2352 | * case of failure. | 2407 | * case of failure. |
2353 | * | 2408 | * |
2354 | * struct bpf_tcp_sock *bpf_tcp_sock(struct bpf_sock *sk) | 2409 | * struct bpf_tcp_sock *bpf_tcp_sock(struct bpf_sock *sk) |
2355 | * Description | 2410 | * Description |
2356 | * This helper gets a **struct bpf_tcp_sock** pointer from a | 2411 | * This helper gets a **struct bpf_tcp_sock** pointer from a |
2357 | * **struct bpf_sock** pointer. | 2412 | * **struct bpf_sock** pointer. |
2358 | * | ||
2359 | * Return | 2413 | * Return |
2360 | * A **struct bpf_tcp_sock** pointer on success, or NULL in | 2414 | * A **struct bpf_tcp_sock** pointer on success, or **NULL** in |
2361 | * case of failure. | 2415 | * case of failure. |
2362 | * | 2416 | * |
2363 | * int bpf_skb_ecn_set_ce(struct sk_buf *skb) | 2417 | * int bpf_skb_ecn_set_ce(struct sk_buf *skb) |
2364 | * Description | 2418 | * Description |
2365 | * Sets ECN of IP header to ce (congestion encountered) if | 2419 | * Set ECN (Explicit Congestion Notification) field of IP header |
2366 | * current value is ect (ECN capable). Works with IPv6 and IPv4. | 2420 | * to **CE** (Congestion Encountered) if current value is **ECT** |
2367 | * Return | 2421 | * (ECN Capable Transport). Otherwise, do nothing. Works with IPv6 |
2368 | * 1 if set, 0 if not set. | 2422 | * and IPv4. |
2423 | * Return | ||
2424 | * 1 if the **CE** flag is set (either by the current helper call | ||
2425 | * or because it was already present), 0 if it is not set. | ||
2426 | * | ||
2427 | * struct bpf_sock *bpf_get_listener_sock(struct bpf_sock *sk) | ||
2428 | * Description | ||
2429 | * Return a **struct bpf_sock** pointer in **TCP_LISTEN** state. | ||
2430 | * **bpf_sk_release**\ () is unnecessary and not allowed. | ||
2431 | * Return | ||
2432 | * A **struct bpf_sock** pointer on success, or **NULL** in | ||
2433 | * case of failure. | ||
2369 | */ | 2434 | */ |
2370 | #define __BPF_FUNC_MAPPER(FN) \ | 2435 | #define __BPF_FUNC_MAPPER(FN) \ |
2371 | FN(unspec), \ | 2436 | FN(unspec), \ |
@@ -2465,7 +2530,8 @@ union bpf_attr { | |||
2465 | FN(spin_unlock), \ | 2530 | FN(spin_unlock), \ |
2466 | FN(sk_fullsock), \ | 2531 | FN(sk_fullsock), \ |
2467 | FN(tcp_sock), \ | 2532 | FN(tcp_sock), \ |
2468 | FN(skb_ecn_set_ce), | 2533 | FN(skb_ecn_set_ce), \ |
2534 | FN(get_listener_sock), | ||
2469 | 2535 | ||
2470 | /* integer value in 'imm' field of BPF_CALL instruction selects which helper | 2536 | /* integer value in 'imm' field of BPF_CALL instruction selects which helper |
2471 | * function eBPF program intends to call | 2537 | * function eBPF program intends to call |
diff --git a/tools/lib/bpf/Makefile b/tools/lib/bpf/Makefile index 61aaacf0cfa1..5bf8e52c41fc 100644 --- a/tools/lib/bpf/Makefile +++ b/tools/lib/bpf/Makefile | |||
@@ -3,7 +3,7 @@ | |||
3 | 3 | ||
4 | BPF_VERSION = 0 | 4 | BPF_VERSION = 0 |
5 | BPF_PATCHLEVEL = 0 | 5 | BPF_PATCHLEVEL = 0 |
6 | BPF_EXTRAVERSION = 1 | 6 | BPF_EXTRAVERSION = 2 |
7 | 7 | ||
8 | MAKEFLAGS += --no-print-directory | 8 | MAKEFLAGS += --no-print-directory |
9 | 9 | ||
@@ -79,8 +79,6 @@ export prefix libdir src obj | |||
79 | libdir_SQ = $(subst ','\'',$(libdir)) | 79 | libdir_SQ = $(subst ','\'',$(libdir)) |
80 | libdir_relative_SQ = $(subst ','\'',$(libdir_relative)) | 80 | libdir_relative_SQ = $(subst ','\'',$(libdir_relative)) |
81 | 81 | ||
82 | LIB_FILE = libbpf.a libbpf.so | ||
83 | |||
84 | VERSION = $(BPF_VERSION) | 82 | VERSION = $(BPF_VERSION) |
85 | PATCHLEVEL = $(BPF_PATCHLEVEL) | 83 | PATCHLEVEL = $(BPF_PATCHLEVEL) |
86 | EXTRAVERSION = $(BPF_EXTRAVERSION) | 84 | EXTRAVERSION = $(BPF_EXTRAVERSION) |
@@ -88,7 +86,10 @@ EXTRAVERSION = $(BPF_EXTRAVERSION) | |||
88 | OBJ = $@ | 86 | OBJ = $@ |
89 | N = | 87 | N = |
90 | 88 | ||
91 | LIBBPF_VERSION = $(BPF_VERSION).$(BPF_PATCHLEVEL).$(BPF_EXTRAVERSION) | 89 | LIBBPF_VERSION = $(BPF_VERSION).$(BPF_PATCHLEVEL).$(BPF_EXTRAVERSION) |
90 | |||
91 | LIB_TARGET = libbpf.a libbpf.so.$(LIBBPF_VERSION) | ||
92 | LIB_FILE = libbpf.a libbpf.so* | ||
92 | 93 | ||
93 | # Set compile option CFLAGS | 94 | # Set compile option CFLAGS |
94 | ifdef EXTRA_CFLAGS | 95 | ifdef EXTRA_CFLAGS |
@@ -128,16 +129,18 @@ all: | |||
128 | export srctree OUTPUT CC LD CFLAGS V | 129 | export srctree OUTPUT CC LD CFLAGS V |
129 | include $(srctree)/tools/build/Makefile.include | 130 | include $(srctree)/tools/build/Makefile.include |
130 | 131 | ||
131 | BPF_IN := $(OUTPUT)libbpf-in.o | 132 | BPF_IN := $(OUTPUT)libbpf-in.o |
132 | LIB_FILE := $(addprefix $(OUTPUT),$(LIB_FILE)) | 133 | VERSION_SCRIPT := libbpf.map |
133 | VERSION_SCRIPT := libbpf.map | 134 | |
135 | LIB_TARGET := $(addprefix $(OUTPUT),$(LIB_TARGET)) | ||
136 | LIB_FILE := $(addprefix $(OUTPUT),$(LIB_FILE)) | ||
134 | 137 | ||
135 | GLOBAL_SYM_COUNT = $(shell readelf -s --wide $(BPF_IN) | \ | 138 | GLOBAL_SYM_COUNT = $(shell readelf -s --wide $(BPF_IN) | \ |
136 | awk '/GLOBAL/ && /DEFAULT/ && !/UND/ {s++} END{print s}') | 139 | awk '/GLOBAL/ && /DEFAULT/ && !/UND/ {s++} END{print s}') |
137 | VERSIONED_SYM_COUNT = $(shell readelf -s --wide $(OUTPUT)libbpf.so | \ | 140 | VERSIONED_SYM_COUNT = $(shell readelf -s --wide $(OUTPUT)libbpf.so | \ |
138 | grep -Eo '[^ ]+@LIBBPF_' | cut -d@ -f1 | sort -u | wc -l) | 141 | grep -Eo '[^ ]+@LIBBPF_' | cut -d@ -f1 | sort -u | wc -l) |
139 | 142 | ||
140 | CMD_TARGETS = $(LIB_FILE) | 143 | CMD_TARGETS = $(LIB_TARGET) |
141 | 144 | ||
142 | CXX_TEST_TARGET = $(OUTPUT)test_libbpf | 145 | CXX_TEST_TARGET = $(OUTPUT)test_libbpf |
143 | 146 | ||
@@ -170,9 +173,13 @@ $(BPF_IN): force elfdep bpfdep | |||
170 | echo "Warning: Kernel ABI header at 'tools/include/uapi/linux/if_xdp.h' differs from latest version at 'include/uapi/linux/if_xdp.h'" >&2 )) || true | 173 | echo "Warning: Kernel ABI header at 'tools/include/uapi/linux/if_xdp.h' differs from latest version at 'include/uapi/linux/if_xdp.h'" >&2 )) || true |
171 | $(Q)$(MAKE) $(build)=libbpf | 174 | $(Q)$(MAKE) $(build)=libbpf |
172 | 175 | ||
173 | $(OUTPUT)libbpf.so: $(BPF_IN) | 176 | $(OUTPUT)libbpf.so: $(OUTPUT)libbpf.so.$(LIBBPF_VERSION) |
174 | $(QUIET_LINK)$(CC) --shared -Wl,--version-script=$(VERSION_SCRIPT) \ | 177 | |
175 | $^ -o $@ | 178 | $(OUTPUT)libbpf.so.$(LIBBPF_VERSION): $(BPF_IN) |
179 | $(QUIET_LINK)$(CC) --shared -Wl,-soname,libbpf.so.$(VERSION) \ | ||
180 | -Wl,--version-script=$(VERSION_SCRIPT) $^ -o $@ | ||
181 | @ln -sf $(@F) $(OUTPUT)libbpf.so | ||
182 | @ln -sf $(@F) $(OUTPUT)libbpf.so.$(VERSION) | ||
176 | 183 | ||
177 | $(OUTPUT)libbpf.a: $(BPF_IN) | 184 | $(OUTPUT)libbpf.a: $(BPF_IN) |
178 | $(QUIET_LINK)$(RM) $@; $(AR) rcs $@ $^ | 185 | $(QUIET_LINK)$(RM) $@; $(AR) rcs $@ $^ |
@@ -192,6 +199,12 @@ check_abi: $(OUTPUT)libbpf.so | |||
192 | exit 1; \ | 199 | exit 1; \ |
193 | fi | 200 | fi |
194 | 201 | ||
202 | define do_install_mkdir | ||
203 | if [ ! -d '$(DESTDIR_SQ)$1' ]; then \ | ||
204 | $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$1'; \ | ||
205 | fi | ||
206 | endef | ||
207 | |||
195 | define do_install | 208 | define do_install |
196 | if [ ! -d '$(DESTDIR_SQ)$2' ]; then \ | 209 | if [ ! -d '$(DESTDIR_SQ)$2' ]; then \ |
197 | $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$2'; \ | 210 | $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$2'; \ |
@@ -200,8 +213,9 @@ define do_install | |||
200 | endef | 213 | endef |
201 | 214 | ||
202 | install_lib: all_cmd | 215 | install_lib: all_cmd |
203 | $(call QUIET_INSTALL, $(LIB_FILE)) \ | 216 | $(call QUIET_INSTALL, $(LIB_TARGET)) \ |
204 | $(call do_install,$(LIB_FILE),$(libdir_SQ)) | 217 | $(call do_install_mkdir,$(libdir_SQ)); \ |
218 | cp -fpR $(LIB_FILE) $(DESTDIR)$(libdir_SQ) | ||
205 | 219 | ||
206 | install_headers: | 220 | install_headers: |
207 | $(call QUIET_INSTALL, headers) \ | 221 | $(call QUIET_INSTALL, headers) \ |
@@ -219,7 +233,7 @@ config-clean: | |||
219 | 233 | ||
220 | clean: | 234 | clean: |
221 | $(call QUIET_CLEAN, libbpf) $(RM) $(TARGETS) $(CXX_TEST_TARGET) \ | 235 | $(call QUIET_CLEAN, libbpf) $(RM) $(TARGETS) $(CXX_TEST_TARGET) \ |
222 | *.o *~ *.a *.so .*.d .*.cmd LIBBPF-CFLAGS | 236 | *.o *~ *.a *.so *.so.$(VERSION) .*.d .*.cmd LIBBPF-CFLAGS |
223 | $(call QUIET_CLEAN, core-gen) $(RM) $(OUTPUT)FEATURE-DUMP.libbpf | 237 | $(call QUIET_CLEAN, core-gen) $(RM) $(OUTPUT)FEATURE-DUMP.libbpf |
224 | 238 | ||
225 | 239 | ||
diff --git a/tools/lib/bpf/README.rst b/tools/lib/bpf/README.rst index 5788479384ca..cef7b77eab69 100644 --- a/tools/lib/bpf/README.rst +++ b/tools/lib/bpf/README.rst | |||
@@ -111,6 +111,7 @@ starting from ``0.0.1``. | |||
111 | 111 | ||
112 | Every time ABI is being changed, e.g. because a new symbol is added or | 112 | Every time ABI is being changed, e.g. because a new symbol is added or |
113 | semantic of existing symbol is changed, ABI version should be bumped. | 113 | semantic of existing symbol is changed, ABI version should be bumped. |
114 | This bump in ABI version is at most once per kernel development cycle. | ||
114 | 115 | ||
115 | For example, if current state of ``libbpf.map`` is: | 116 | For example, if current state of ``libbpf.map`` is: |
116 | 117 | ||
diff --git a/tools/lib/bpf/btf.c b/tools/lib/bpf/btf.c index 1b8d8cdd3575..87e3020ac1bc 100644 --- a/tools/lib/bpf/btf.c +++ b/tools/lib/bpf/btf.c | |||
@@ -1602,16 +1602,12 @@ static bool btf_equal_int(struct btf_type *t1, struct btf_type *t2) | |||
1602 | /* Calculate type signature hash of ENUM. */ | 1602 | /* Calculate type signature hash of ENUM. */ |
1603 | static __u32 btf_hash_enum(struct btf_type *t) | 1603 | static __u32 btf_hash_enum(struct btf_type *t) |
1604 | { | 1604 | { |
1605 | struct btf_enum *member = (struct btf_enum *)(t + 1); | 1605 | __u32 h; |
1606 | __u32 vlen = BTF_INFO_VLEN(t->info); | ||
1607 | __u32 h = btf_hash_common(t); | ||
1608 | int i; | ||
1609 | 1606 | ||
1610 | for (i = 0; i < vlen; i++) { | 1607 | /* don't hash vlen and enum members to support enum fwd resolving */ |
1611 | h = hash_combine(h, member->name_off); | 1608 | h = hash_combine(0, t->name_off); |
1612 | h = hash_combine(h, member->val); | 1609 | h = hash_combine(h, t->info & ~0xffff); |
1613 | member++; | 1610 | h = hash_combine(h, t->size); |
1614 | } | ||
1615 | return h; | 1611 | return h; |
1616 | } | 1612 | } |
1617 | 1613 | ||
@@ -1637,6 +1633,22 @@ static bool btf_equal_enum(struct btf_type *t1, struct btf_type *t2) | |||
1637 | return true; | 1633 | return true; |
1638 | } | 1634 | } |
1639 | 1635 | ||
1636 | static inline bool btf_is_enum_fwd(struct btf_type *t) | ||
1637 | { | ||
1638 | return BTF_INFO_KIND(t->info) == BTF_KIND_ENUM && | ||
1639 | BTF_INFO_VLEN(t->info) == 0; | ||
1640 | } | ||
1641 | |||
1642 | static bool btf_compat_enum(struct btf_type *t1, struct btf_type *t2) | ||
1643 | { | ||
1644 | if (!btf_is_enum_fwd(t1) && !btf_is_enum_fwd(t2)) | ||
1645 | return btf_equal_enum(t1, t2); | ||
1646 | /* ignore vlen when comparing */ | ||
1647 | return t1->name_off == t2->name_off && | ||
1648 | (t1->info & ~0xffff) == (t2->info & ~0xffff) && | ||
1649 | t1->size == t2->size; | ||
1650 | } | ||
1651 | |||
1640 | /* | 1652 | /* |
1641 | * Calculate type signature hash of STRUCT/UNION, ignoring referenced type IDs, | 1653 | * Calculate type signature hash of STRUCT/UNION, ignoring referenced type IDs, |
1642 | * as referenced type IDs equivalence is established separately during type | 1654 | * as referenced type IDs equivalence is established separately during type |
@@ -1860,6 +1872,17 @@ static int btf_dedup_prim_type(struct btf_dedup *d, __u32 type_id) | |||
1860 | new_id = cand_node->type_id; | 1872 | new_id = cand_node->type_id; |
1861 | break; | 1873 | break; |
1862 | } | 1874 | } |
1875 | if (d->opts.dont_resolve_fwds) | ||
1876 | continue; | ||
1877 | if (btf_compat_enum(t, cand)) { | ||
1878 | if (btf_is_enum_fwd(t)) { | ||
1879 | /* resolve fwd to full enum */ | ||
1880 | new_id = cand_node->type_id; | ||
1881 | break; | ||
1882 | } | ||
1883 | /* resolve canonical enum fwd to full enum */ | ||
1884 | d->map[cand_node->type_id] = type_id; | ||
1885 | } | ||
1863 | } | 1886 | } |
1864 | break; | 1887 | break; |
1865 | 1888 | ||
@@ -2084,15 +2107,15 @@ static int btf_dedup_is_equiv(struct btf_dedup *d, __u32 cand_id, | |||
2084 | return fwd_kind == real_kind; | 2107 | return fwd_kind == real_kind; |
2085 | } | 2108 | } |
2086 | 2109 | ||
2087 | if (cand_type->info != canon_type->info) | ||
2088 | return 0; | ||
2089 | |||
2090 | switch (cand_kind) { | 2110 | switch (cand_kind) { |
2091 | case BTF_KIND_INT: | 2111 | case BTF_KIND_INT: |
2092 | return btf_equal_int(cand_type, canon_type); | 2112 | return btf_equal_int(cand_type, canon_type); |
2093 | 2113 | ||
2094 | case BTF_KIND_ENUM: | 2114 | case BTF_KIND_ENUM: |
2095 | return btf_equal_enum(cand_type, canon_type); | 2115 | if (d->opts.dont_resolve_fwds) |
2116 | return btf_equal_enum(cand_type, canon_type); | ||
2117 | else | ||
2118 | return btf_compat_enum(cand_type, canon_type); | ||
2096 | 2119 | ||
2097 | case BTF_KIND_FWD: | 2120 | case BTF_KIND_FWD: |
2098 | return btf_equal_common(cand_type, canon_type); | 2121 | return btf_equal_common(cand_type, canon_type); |
@@ -2103,6 +2126,8 @@ static int btf_dedup_is_equiv(struct btf_dedup *d, __u32 cand_id, | |||
2103 | case BTF_KIND_PTR: | 2126 | case BTF_KIND_PTR: |
2104 | case BTF_KIND_TYPEDEF: | 2127 | case BTF_KIND_TYPEDEF: |
2105 | case BTF_KIND_FUNC: | 2128 | case BTF_KIND_FUNC: |
2129 | if (cand_type->info != canon_type->info) | ||
2130 | return 0; | ||
2106 | return btf_dedup_is_equiv(d, cand_type->type, canon_type->type); | 2131 | return btf_dedup_is_equiv(d, cand_type->type, canon_type->type); |
2107 | 2132 | ||
2108 | case BTF_KIND_ARRAY: { | 2133 | case BTF_KIND_ARRAY: { |
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index e6ad87512519..11c25d9ea431 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c | |||
@@ -840,12 +840,19 @@ static int bpf_object__elf_collect(struct bpf_object *obj, int flags) | |||
840 | obj->efile.maps_shndx = idx; | 840 | obj->efile.maps_shndx = idx; |
841 | else if (strcmp(name, BTF_ELF_SEC) == 0) { | 841 | else if (strcmp(name, BTF_ELF_SEC) == 0) { |
842 | obj->btf = btf__new(data->d_buf, data->d_size); | 842 | obj->btf = btf__new(data->d_buf, data->d_size); |
843 | if (IS_ERR(obj->btf) || btf__load(obj->btf)) { | 843 | if (IS_ERR(obj->btf)) { |
844 | pr_warning("Error loading ELF section %s: %ld. Ignored and continue.\n", | 844 | pr_warning("Error loading ELF section %s: %ld. Ignored and continue.\n", |
845 | BTF_ELF_SEC, PTR_ERR(obj->btf)); | 845 | BTF_ELF_SEC, PTR_ERR(obj->btf)); |
846 | if (!IS_ERR(obj->btf)) | ||
847 | btf__free(obj->btf); | ||
848 | obj->btf = NULL; | 846 | obj->btf = NULL; |
847 | continue; | ||
848 | } | ||
849 | err = btf__load(obj->btf); | ||
850 | if (err) { | ||
851 | pr_warning("Error loading %s into kernel: %d. Ignored and continue.\n", | ||
852 | BTF_ELF_SEC, err); | ||
853 | btf__free(obj->btf); | ||
854 | obj->btf = NULL; | ||
855 | err = 0; | ||
849 | } | 856 | } |
850 | } else if (strcmp(name, BTF_EXT_ELF_SEC) == 0) { | 857 | } else if (strcmp(name, BTF_EXT_ELF_SEC) == 0) { |
851 | btf_ext_data = data; | 858 | btf_ext_data = data; |
diff --git a/tools/lib/bpf/xsk.c b/tools/lib/bpf/xsk.c index f98ac82c9aea..8d0078b65486 100644 --- a/tools/lib/bpf/xsk.c +++ b/tools/lib/bpf/xsk.c | |||
@@ -126,8 +126,8 @@ static void xsk_set_umem_config(struct xsk_umem_config *cfg, | |||
126 | cfg->frame_headroom = usr_cfg->frame_headroom; | 126 | cfg->frame_headroom = usr_cfg->frame_headroom; |
127 | } | 127 | } |
128 | 128 | ||
129 | static void xsk_set_xdp_socket_config(struct xsk_socket_config *cfg, | 129 | static int xsk_set_xdp_socket_config(struct xsk_socket_config *cfg, |
130 | const struct xsk_socket_config *usr_cfg) | 130 | const struct xsk_socket_config *usr_cfg) |
131 | { | 131 | { |
132 | if (!usr_cfg) { | 132 | if (!usr_cfg) { |
133 | cfg->rx_size = XSK_RING_CONS__DEFAULT_NUM_DESCS; | 133 | cfg->rx_size = XSK_RING_CONS__DEFAULT_NUM_DESCS; |
@@ -135,14 +135,19 @@ static void xsk_set_xdp_socket_config(struct xsk_socket_config *cfg, | |||
135 | cfg->libbpf_flags = 0; | 135 | cfg->libbpf_flags = 0; |
136 | cfg->xdp_flags = 0; | 136 | cfg->xdp_flags = 0; |
137 | cfg->bind_flags = 0; | 137 | cfg->bind_flags = 0; |
138 | return; | 138 | return 0; |
139 | } | 139 | } |
140 | 140 | ||
141 | if (usr_cfg->libbpf_flags & ~XSK_LIBBPF_FLAGS__INHIBIT_PROG_LOAD) | ||
142 | return -EINVAL; | ||
143 | |||
141 | cfg->rx_size = usr_cfg->rx_size; | 144 | cfg->rx_size = usr_cfg->rx_size; |
142 | cfg->tx_size = usr_cfg->tx_size; | 145 | cfg->tx_size = usr_cfg->tx_size; |
143 | cfg->libbpf_flags = usr_cfg->libbpf_flags; | 146 | cfg->libbpf_flags = usr_cfg->libbpf_flags; |
144 | cfg->xdp_flags = usr_cfg->xdp_flags; | 147 | cfg->xdp_flags = usr_cfg->xdp_flags; |
145 | cfg->bind_flags = usr_cfg->bind_flags; | 148 | cfg->bind_flags = usr_cfg->bind_flags; |
149 | |||
150 | return 0; | ||
146 | } | 151 | } |
147 | 152 | ||
148 | int xsk_umem__create(struct xsk_umem **umem_ptr, void *umem_area, __u64 size, | 153 | int xsk_umem__create(struct xsk_umem **umem_ptr, void *umem_area, __u64 size, |
@@ -557,7 +562,9 @@ int xsk_socket__create(struct xsk_socket **xsk_ptr, const char *ifname, | |||
557 | } | 562 | } |
558 | strncpy(xsk->ifname, ifname, IFNAMSIZ); | 563 | strncpy(xsk->ifname, ifname, IFNAMSIZ); |
559 | 564 | ||
560 | xsk_set_xdp_socket_config(&xsk->config, usr_config); | 565 | err = xsk_set_xdp_socket_config(&xsk->config, usr_config); |
566 | if (err) | ||
567 | goto out_socket; | ||
561 | 568 | ||
562 | if (rx) { | 569 | if (rx) { |
563 | err = setsockopt(xsk->fd, SOL_XDP, XDP_RX_RING, | 570 | err = setsockopt(xsk->fd, SOL_XDP, XDP_RX_RING, |
diff --git a/tools/testing/selftests/bpf/bpf_helpers.h b/tools/testing/selftests/bpf/bpf_helpers.h index c9433a496d54..c81fc350f7ad 100644 --- a/tools/testing/selftests/bpf/bpf_helpers.h +++ b/tools/testing/selftests/bpf/bpf_helpers.h | |||
@@ -180,6 +180,8 @@ static struct bpf_sock *(*bpf_sk_fullsock)(struct bpf_sock *sk) = | |||
180 | (void *) BPF_FUNC_sk_fullsock; | 180 | (void *) BPF_FUNC_sk_fullsock; |
181 | static struct bpf_tcp_sock *(*bpf_tcp_sock)(struct bpf_sock *sk) = | 181 | static struct bpf_tcp_sock *(*bpf_tcp_sock)(struct bpf_sock *sk) = |
182 | (void *) BPF_FUNC_tcp_sock; | 182 | (void *) BPF_FUNC_tcp_sock; |
183 | static struct bpf_sock *(*bpf_get_listener_sock)(struct bpf_sock *sk) = | ||
184 | (void *) BPF_FUNC_get_listener_sock; | ||
183 | static int (*bpf_skb_ecn_set_ce)(void *ctx) = | 185 | static int (*bpf_skb_ecn_set_ce)(void *ctx) = |
184 | (void *) BPF_FUNC_skb_ecn_set_ce; | 186 | (void *) BPF_FUNC_skb_ecn_set_ce; |
185 | 187 | ||
diff --git a/tools/testing/selftests/bpf/prog_tests/map_lock.c b/tools/testing/selftests/bpf/prog_tests/map_lock.c index 90f8a206340a..ee99368c595c 100644 --- a/tools/testing/selftests/bpf/prog_tests/map_lock.c +++ b/tools/testing/selftests/bpf/prog_tests/map_lock.c | |||
@@ -37,7 +37,7 @@ void test_map_lock(void) | |||
37 | const char *file = "./test_map_lock.o"; | 37 | const char *file = "./test_map_lock.o"; |
38 | int prog_fd, map_fd[2], vars[17] = {}; | 38 | int prog_fd, map_fd[2], vars[17] = {}; |
39 | pthread_t thread_id[6]; | 39 | pthread_t thread_id[6]; |
40 | struct bpf_object *obj; | 40 | struct bpf_object *obj = NULL; |
41 | int err = 0, key = 0, i; | 41 | int err = 0, key = 0, i; |
42 | void *ret; | 42 | void *ret; |
43 | 43 | ||
diff --git a/tools/testing/selftests/bpf/prog_tests/spinlock.c b/tools/testing/selftests/bpf/prog_tests/spinlock.c index 9a573a9675d7..114ebe6a438e 100644 --- a/tools/testing/selftests/bpf/prog_tests/spinlock.c +++ b/tools/testing/selftests/bpf/prog_tests/spinlock.c | |||
@@ -5,7 +5,7 @@ void test_spinlock(void) | |||
5 | { | 5 | { |
6 | const char *file = "./test_spin_lock.o"; | 6 | const char *file = "./test_spin_lock.o"; |
7 | pthread_t thread_id[4]; | 7 | pthread_t thread_id[4]; |
8 | struct bpf_object *obj; | 8 | struct bpf_object *obj = NULL; |
9 | int prog_fd; | 9 | int prog_fd; |
10 | int err = 0, i; | 10 | int err = 0, i; |
11 | void *ret; | 11 | void *ret; |
diff --git a/tools/testing/selftests/bpf/progs/test_sock_fields_kern.c b/tools/testing/selftests/bpf/progs/test_sock_fields_kern.c index de1a43e8f610..37328f148538 100644 --- a/tools/testing/selftests/bpf/progs/test_sock_fields_kern.c +++ b/tools/testing/selftests/bpf/progs/test_sock_fields_kern.c | |||
@@ -8,38 +8,51 @@ | |||
8 | #include "bpf_helpers.h" | 8 | #include "bpf_helpers.h" |
9 | #include "bpf_endian.h" | 9 | #include "bpf_endian.h" |
10 | 10 | ||
11 | enum bpf_array_idx { | 11 | enum bpf_addr_array_idx { |
12 | SRV_IDX, | 12 | ADDR_SRV_IDX, |
13 | CLI_IDX, | 13 | ADDR_CLI_IDX, |
14 | __NR_BPF_ARRAY_IDX, | 14 | __NR_BPF_ADDR_ARRAY_IDX, |
15 | }; | ||
16 | |||
17 | enum bpf_result_array_idx { | ||
18 | EGRESS_SRV_IDX, | ||
19 | EGRESS_CLI_IDX, | ||
20 | INGRESS_LISTEN_IDX, | ||
21 | __NR_BPF_RESULT_ARRAY_IDX, | ||
22 | }; | ||
23 | |||
24 | enum bpf_linum_array_idx { | ||
25 | EGRESS_LINUM_IDX, | ||
26 | INGRESS_LINUM_IDX, | ||
27 | __NR_BPF_LINUM_ARRAY_IDX, | ||
15 | }; | 28 | }; |
16 | 29 | ||
17 | struct bpf_map_def SEC("maps") addr_map = { | 30 | struct bpf_map_def SEC("maps") addr_map = { |
18 | .type = BPF_MAP_TYPE_ARRAY, | 31 | .type = BPF_MAP_TYPE_ARRAY, |
19 | .key_size = sizeof(__u32), | 32 | .key_size = sizeof(__u32), |
20 | .value_size = sizeof(struct sockaddr_in6), | 33 | .value_size = sizeof(struct sockaddr_in6), |
21 | .max_entries = __NR_BPF_ARRAY_IDX, | 34 | .max_entries = __NR_BPF_ADDR_ARRAY_IDX, |
22 | }; | 35 | }; |
23 | 36 | ||
24 | struct bpf_map_def SEC("maps") sock_result_map = { | 37 | struct bpf_map_def SEC("maps") sock_result_map = { |
25 | .type = BPF_MAP_TYPE_ARRAY, | 38 | .type = BPF_MAP_TYPE_ARRAY, |
26 | .key_size = sizeof(__u32), | 39 | .key_size = sizeof(__u32), |
27 | .value_size = sizeof(struct bpf_sock), | 40 | .value_size = sizeof(struct bpf_sock), |
28 | .max_entries = __NR_BPF_ARRAY_IDX, | 41 | .max_entries = __NR_BPF_RESULT_ARRAY_IDX, |
29 | }; | 42 | }; |
30 | 43 | ||
31 | struct bpf_map_def SEC("maps") tcp_sock_result_map = { | 44 | struct bpf_map_def SEC("maps") tcp_sock_result_map = { |
32 | .type = BPF_MAP_TYPE_ARRAY, | 45 | .type = BPF_MAP_TYPE_ARRAY, |
33 | .key_size = sizeof(__u32), | 46 | .key_size = sizeof(__u32), |
34 | .value_size = sizeof(struct bpf_tcp_sock), | 47 | .value_size = sizeof(struct bpf_tcp_sock), |
35 | .max_entries = __NR_BPF_ARRAY_IDX, | 48 | .max_entries = __NR_BPF_RESULT_ARRAY_IDX, |
36 | }; | 49 | }; |
37 | 50 | ||
38 | struct bpf_map_def SEC("maps") linum_map = { | 51 | struct bpf_map_def SEC("maps") linum_map = { |
39 | .type = BPF_MAP_TYPE_ARRAY, | 52 | .type = BPF_MAP_TYPE_ARRAY, |
40 | .key_size = sizeof(__u32), | 53 | .key_size = sizeof(__u32), |
41 | .value_size = sizeof(__u32), | 54 | .value_size = sizeof(__u32), |
42 | .max_entries = 1, | 55 | .max_entries = __NR_BPF_LINUM_ARRAY_IDX, |
43 | }; | 56 | }; |
44 | 57 | ||
45 | static bool is_loopback6(__u32 *a6) | 58 | static bool is_loopback6(__u32 *a6) |
@@ -100,18 +113,20 @@ static void tpcpy(struct bpf_tcp_sock *dst, | |||
100 | 113 | ||
101 | #define RETURN { \ | 114 | #define RETURN { \ |
102 | linum = __LINE__; \ | 115 | linum = __LINE__; \ |
103 | bpf_map_update_elem(&linum_map, &idx0, &linum, 0); \ | 116 | bpf_map_update_elem(&linum_map, &linum_idx, &linum, 0); \ |
104 | return 1; \ | 117 | return 1; \ |
105 | } | 118 | } |
106 | 119 | ||
107 | SEC("cgroup_skb/egress") | 120 | SEC("cgroup_skb/egress") |
108 | int read_sock_fields(struct __sk_buff *skb) | 121 | int egress_read_sock_fields(struct __sk_buff *skb) |
109 | { | 122 | { |
110 | __u32 srv_idx = SRV_IDX, cli_idx = CLI_IDX, idx; | 123 | __u32 srv_idx = ADDR_SRV_IDX, cli_idx = ADDR_CLI_IDX, result_idx; |
111 | struct sockaddr_in6 *srv_sa6, *cli_sa6; | 124 | struct sockaddr_in6 *srv_sa6, *cli_sa6; |
112 | struct bpf_tcp_sock *tp, *tp_ret; | 125 | struct bpf_tcp_sock *tp, *tp_ret; |
113 | struct bpf_sock *sk, *sk_ret; | 126 | struct bpf_sock *sk, *sk_ret; |
114 | __u32 linum, idx0 = 0; | 127 | __u32 linum, linum_idx; |
128 | |||
129 | linum_idx = EGRESS_LINUM_IDX; | ||
115 | 130 | ||
116 | sk = skb->sk; | 131 | sk = skb->sk; |
117 | if (!sk || sk->state == 10) | 132 | if (!sk || sk->state == 10) |
@@ -132,14 +147,55 @@ int read_sock_fields(struct __sk_buff *skb) | |||
132 | RETURN; | 147 | RETURN; |
133 | 148 | ||
134 | if (sk->src_port == bpf_ntohs(srv_sa6->sin6_port)) | 149 | if (sk->src_port == bpf_ntohs(srv_sa6->sin6_port)) |
135 | idx = srv_idx; | 150 | result_idx = EGRESS_SRV_IDX; |
136 | else if (sk->src_port == bpf_ntohs(cli_sa6->sin6_port)) | 151 | else if (sk->src_port == bpf_ntohs(cli_sa6->sin6_port)) |
137 | idx = cli_idx; | 152 | result_idx = EGRESS_CLI_IDX; |
138 | else | 153 | else |
139 | RETURN; | 154 | RETURN; |
140 | 155 | ||
141 | sk_ret = bpf_map_lookup_elem(&sock_result_map, &idx); | 156 | sk_ret = bpf_map_lookup_elem(&sock_result_map, &result_idx); |
142 | tp_ret = bpf_map_lookup_elem(&tcp_sock_result_map, &idx); | 157 | tp_ret = bpf_map_lookup_elem(&tcp_sock_result_map, &result_idx); |
158 | if (!sk_ret || !tp_ret) | ||
159 | RETURN; | ||
160 | |||
161 | skcpy(sk_ret, sk); | ||
162 | tpcpy(tp_ret, tp); | ||
163 | |||
164 | RETURN; | ||
165 | } | ||
166 | |||
167 | SEC("cgroup_skb/ingress") | ||
168 | int ingress_read_sock_fields(struct __sk_buff *skb) | ||
169 | { | ||
170 | __u32 srv_idx = ADDR_SRV_IDX, result_idx = INGRESS_LISTEN_IDX; | ||
171 | struct bpf_tcp_sock *tp, *tp_ret; | ||
172 | struct bpf_sock *sk, *sk_ret; | ||
173 | struct sockaddr_in6 *srv_sa6; | ||
174 | __u32 linum, linum_idx; | ||
175 | |||
176 | linum_idx = INGRESS_LINUM_IDX; | ||
177 | |||
178 | sk = skb->sk; | ||
179 | if (!sk || sk->family != AF_INET6 || !is_loopback6(sk->src_ip6)) | ||
180 | RETURN; | ||
181 | |||
182 | srv_sa6 = bpf_map_lookup_elem(&addr_map, &srv_idx); | ||
183 | if (!srv_sa6 || sk->src_port != bpf_ntohs(srv_sa6->sin6_port)) | ||
184 | RETURN; | ||
185 | |||
186 | if (sk->state != 10 && sk->state != 12) | ||
187 | RETURN; | ||
188 | |||
189 | sk = bpf_get_listener_sock(sk); | ||
190 | if (!sk) | ||
191 | RETURN; | ||
192 | |||
193 | tp = bpf_tcp_sock(sk); | ||
194 | if (!tp) | ||
195 | RETURN; | ||
196 | |||
197 | sk_ret = bpf_map_lookup_elem(&sock_result_map, &result_idx); | ||
198 | tp_ret = bpf_map_lookup_elem(&tcp_sock_result_map, &result_idx); | ||
143 | if (!sk_ret || !tp_ret) | 199 | if (!sk_ret || !tp_ret) |
144 | RETURN; | 200 | RETURN; |
145 | 201 | ||
diff --git a/tools/testing/selftests/bpf/test_btf.c b/tools/testing/selftests/bpf/test_btf.c index 38797aa627a7..23e3b314ca60 100644 --- a/tools/testing/selftests/bpf/test_btf.c +++ b/tools/testing/selftests/bpf/test_btf.c | |||
@@ -5874,6 +5874,50 @@ const struct btf_dedup_test dedup_tests[] = { | |||
5874 | .dont_resolve_fwds = false, | 5874 | .dont_resolve_fwds = false, |
5875 | }, | 5875 | }, |
5876 | }, | 5876 | }, |
5877 | { | ||
5878 | .descr = "dedup: enum fwd resolution", | ||
5879 | .input = { | ||
5880 | .raw_types = { | ||
5881 | /* [1] fwd enum 'e1' before full enum */ | ||
5882 | BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 0), 4), | ||
5883 | /* [2] full enum 'e1' after fwd */ | ||
5884 | BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4), | ||
5885 | BTF_ENUM_ENC(NAME_NTH(2), 123), | ||
5886 | /* [3] full enum 'e2' before fwd */ | ||
5887 | BTF_TYPE_ENC(NAME_NTH(3), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4), | ||
5888 | BTF_ENUM_ENC(NAME_NTH(4), 456), | ||
5889 | /* [4] fwd enum 'e2' after full enum */ | ||
5890 | BTF_TYPE_ENC(NAME_NTH(3), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 0), 4), | ||
5891 | /* [5] incompatible fwd enum with different size */ | ||
5892 | BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 0), 1), | ||
5893 | /* [6] incompatible full enum with different value */ | ||
5894 | BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4), | ||
5895 | BTF_ENUM_ENC(NAME_NTH(2), 321), | ||
5896 | BTF_END_RAW, | ||
5897 | }, | ||
5898 | BTF_STR_SEC("\0e1\0e1_val\0e2\0e2_val"), | ||
5899 | }, | ||
5900 | .expect = { | ||
5901 | .raw_types = { | ||
5902 | /* [1] full enum 'e1' */ | ||
5903 | BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4), | ||
5904 | BTF_ENUM_ENC(NAME_NTH(2), 123), | ||
5905 | /* [2] full enum 'e2' */ | ||
5906 | BTF_TYPE_ENC(NAME_NTH(3), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4), | ||
5907 | BTF_ENUM_ENC(NAME_NTH(4), 456), | ||
5908 | /* [3] incompatible fwd enum with different size */ | ||
5909 | BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 0), 1), | ||
5910 | /* [4] incompatible full enum with different value */ | ||
5911 | BTF_TYPE_ENC(NAME_NTH(1), BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4), | ||
5912 | BTF_ENUM_ENC(NAME_NTH(2), 321), | ||
5913 | BTF_END_RAW, | ||
5914 | }, | ||
5915 | BTF_STR_SEC("\0e1\0e1_val\0e2\0e2_val"), | ||
5916 | }, | ||
5917 | .opts = { | ||
5918 | .dont_resolve_fwds = false, | ||
5919 | }, | ||
5920 | }, | ||
5877 | 5921 | ||
5878 | }; | 5922 | }; |
5879 | 5923 | ||
diff --git a/tools/testing/selftests/bpf/test_sock_fields.c b/tools/testing/selftests/bpf/test_sock_fields.c index bc8943938bf5..dcae7f664dce 100644 --- a/tools/testing/selftests/bpf/test_sock_fields.c +++ b/tools/testing/selftests/bpf/test_sock_fields.c | |||
@@ -16,10 +16,23 @@ | |||
16 | #include "cgroup_helpers.h" | 16 | #include "cgroup_helpers.h" |
17 | #include "bpf_rlimit.h" | 17 | #include "bpf_rlimit.h" |
18 | 18 | ||
19 | enum bpf_array_idx { | 19 | enum bpf_addr_array_idx { |
20 | SRV_IDX, | 20 | ADDR_SRV_IDX, |
21 | CLI_IDX, | 21 | ADDR_CLI_IDX, |
22 | __NR_BPF_ARRAY_IDX, | 22 | __NR_BPF_ADDR_ARRAY_IDX, |
23 | }; | ||
24 | |||
25 | enum bpf_result_array_idx { | ||
26 | EGRESS_SRV_IDX, | ||
27 | EGRESS_CLI_IDX, | ||
28 | INGRESS_LISTEN_IDX, | ||
29 | __NR_BPF_RESULT_ARRAY_IDX, | ||
30 | }; | ||
31 | |||
32 | enum bpf_linum_array_idx { | ||
33 | EGRESS_LINUM_IDX, | ||
34 | INGRESS_LINUM_IDX, | ||
35 | __NR_BPF_LINUM_ARRAY_IDX, | ||
23 | }; | 36 | }; |
24 | 37 | ||
25 | #define CHECK(condition, tag, format...) ({ \ | 38 | #define CHECK(condition, tag, format...) ({ \ |
@@ -41,8 +54,16 @@ static int linum_map_fd; | |||
41 | static int addr_map_fd; | 54 | static int addr_map_fd; |
42 | static int tp_map_fd; | 55 | static int tp_map_fd; |
43 | static int sk_map_fd; | 56 | static int sk_map_fd; |
44 | static __u32 srv_idx = SRV_IDX; | 57 | |
45 | static __u32 cli_idx = CLI_IDX; | 58 | static __u32 addr_srv_idx = ADDR_SRV_IDX; |
59 | static __u32 addr_cli_idx = ADDR_CLI_IDX; | ||
60 | |||
61 | static __u32 egress_srv_idx = EGRESS_SRV_IDX; | ||
62 | static __u32 egress_cli_idx = EGRESS_CLI_IDX; | ||
63 | static __u32 ingress_listen_idx = INGRESS_LISTEN_IDX; | ||
64 | |||
65 | static __u32 egress_linum_idx = EGRESS_LINUM_IDX; | ||
66 | static __u32 ingress_linum_idx = INGRESS_LINUM_IDX; | ||
46 | 67 | ||
47 | static void init_loopback6(struct sockaddr_in6 *sa6) | 68 | static void init_loopback6(struct sockaddr_in6 *sa6) |
48 | { | 69 | { |
@@ -93,29 +114,46 @@ static void print_tp(const struct bpf_tcp_sock *tp) | |||
93 | 114 | ||
94 | static void check_result(void) | 115 | static void check_result(void) |
95 | { | 116 | { |
96 | struct bpf_tcp_sock srv_tp, cli_tp; | 117 | struct bpf_tcp_sock srv_tp, cli_tp, listen_tp; |
97 | struct bpf_sock srv_sk, cli_sk; | 118 | struct bpf_sock srv_sk, cli_sk, listen_sk; |
98 | __u32 linum, idx0 = 0; | 119 | __u32 ingress_linum, egress_linum; |
99 | int err; | 120 | int err; |
100 | 121 | ||
101 | err = bpf_map_lookup_elem(linum_map_fd, &idx0, &linum); | 122 | err = bpf_map_lookup_elem(linum_map_fd, &egress_linum_idx, |
123 | &egress_linum); | ||
102 | CHECK(err == -1, "bpf_map_lookup_elem(linum_map_fd)", | 124 | CHECK(err == -1, "bpf_map_lookup_elem(linum_map_fd)", |
103 | "err:%d errno:%d", err, errno); | 125 | "err:%d errno:%d", err, errno); |
104 | 126 | ||
105 | err = bpf_map_lookup_elem(sk_map_fd, &srv_idx, &srv_sk); | 127 | err = bpf_map_lookup_elem(linum_map_fd, &ingress_linum_idx, |
106 | CHECK(err == -1, "bpf_map_lookup_elem(sk_map_fd, &srv_idx)", | 128 | &ingress_linum); |
129 | CHECK(err == -1, "bpf_map_lookup_elem(linum_map_fd)", | ||
130 | "err:%d errno:%d", err, errno); | ||
131 | |||
132 | err = bpf_map_lookup_elem(sk_map_fd, &egress_srv_idx, &srv_sk); | ||
133 | CHECK(err == -1, "bpf_map_lookup_elem(sk_map_fd, &egress_srv_idx)", | ||
134 | "err:%d errno:%d", err, errno); | ||
135 | err = bpf_map_lookup_elem(tp_map_fd, &egress_srv_idx, &srv_tp); | ||
136 | CHECK(err == -1, "bpf_map_lookup_elem(tp_map_fd, &egress_srv_idx)", | ||
137 | "err:%d errno:%d", err, errno); | ||
138 | |||
139 | err = bpf_map_lookup_elem(sk_map_fd, &egress_cli_idx, &cli_sk); | ||
140 | CHECK(err == -1, "bpf_map_lookup_elem(sk_map_fd, &egress_cli_idx)", | ||
107 | "err:%d errno:%d", err, errno); | 141 | "err:%d errno:%d", err, errno); |
108 | err = bpf_map_lookup_elem(tp_map_fd, &srv_idx, &srv_tp); | 142 | err = bpf_map_lookup_elem(tp_map_fd, &egress_cli_idx, &cli_tp); |
109 | CHECK(err == -1, "bpf_map_lookup_elem(tp_map_fd, &srv_idx)", | 143 | CHECK(err == -1, "bpf_map_lookup_elem(tp_map_fd, &egress_cli_idx)", |
110 | "err:%d errno:%d", err, errno); | 144 | "err:%d errno:%d", err, errno); |
111 | 145 | ||
112 | err = bpf_map_lookup_elem(sk_map_fd, &cli_idx, &cli_sk); | 146 | err = bpf_map_lookup_elem(sk_map_fd, &ingress_listen_idx, &listen_sk); |
113 | CHECK(err == -1, "bpf_map_lookup_elem(sk_map_fd, &cli_idx)", | 147 | CHECK(err == -1, "bpf_map_lookup_elem(sk_map_fd, &ingress_listen_idx)", |
114 | "err:%d errno:%d", err, errno); | 148 | "err:%d errno:%d", err, errno); |
115 | err = bpf_map_lookup_elem(tp_map_fd, &cli_idx, &cli_tp); | 149 | err = bpf_map_lookup_elem(tp_map_fd, &ingress_listen_idx, &listen_tp); |
116 | CHECK(err == -1, "bpf_map_lookup_elem(tp_map_fd, &cli_idx)", | 150 | CHECK(err == -1, "bpf_map_lookup_elem(tp_map_fd, &ingress_listen_idx)", |
117 | "err:%d errno:%d", err, errno); | 151 | "err:%d errno:%d", err, errno); |
118 | 152 | ||
153 | printf("listen_sk: "); | ||
154 | print_sk(&listen_sk); | ||
155 | printf("\n"); | ||
156 | |||
119 | printf("srv_sk: "); | 157 | printf("srv_sk: "); |
120 | print_sk(&srv_sk); | 158 | print_sk(&srv_sk); |
121 | printf("\n"); | 159 | printf("\n"); |
@@ -124,6 +162,10 @@ static void check_result(void) | |||
124 | print_sk(&cli_sk); | 162 | print_sk(&cli_sk); |
125 | printf("\n"); | 163 | printf("\n"); |
126 | 164 | ||
165 | printf("listen_tp: "); | ||
166 | print_tp(&listen_tp); | ||
167 | printf("\n"); | ||
168 | |||
127 | printf("srv_tp: "); | 169 | printf("srv_tp: "); |
128 | print_tp(&srv_tp); | 170 | print_tp(&srv_tp); |
129 | printf("\n"); | 171 | printf("\n"); |
@@ -132,6 +174,19 @@ static void check_result(void) | |||
132 | print_tp(&cli_tp); | 174 | print_tp(&cli_tp); |
133 | printf("\n"); | 175 | printf("\n"); |
134 | 176 | ||
177 | CHECK(listen_sk.state != 10 || | ||
178 | listen_sk.family != AF_INET6 || | ||
179 | listen_sk.protocol != IPPROTO_TCP || | ||
180 | memcmp(listen_sk.src_ip6, &in6addr_loopback, | ||
181 | sizeof(listen_sk.src_ip6)) || | ||
182 | listen_sk.dst_ip6[0] || listen_sk.dst_ip6[1] || | ||
183 | listen_sk.dst_ip6[2] || listen_sk.dst_ip6[3] || | ||
184 | listen_sk.src_port != ntohs(srv_sa6.sin6_port) || | ||
185 | listen_sk.dst_port, | ||
186 | "Unexpected listen_sk", | ||
187 | "Check listen_sk output. ingress_linum:%u", | ||
188 | ingress_linum); | ||
189 | |||
135 | CHECK(srv_sk.state == 10 || | 190 | CHECK(srv_sk.state == 10 || |
136 | !srv_sk.state || | 191 | !srv_sk.state || |
137 | srv_sk.family != AF_INET6 || | 192 | srv_sk.family != AF_INET6 || |
@@ -142,7 +197,8 @@ static void check_result(void) | |||
142 | sizeof(srv_sk.dst_ip6)) || | 197 | sizeof(srv_sk.dst_ip6)) || |
143 | srv_sk.src_port != ntohs(srv_sa6.sin6_port) || | 198 | srv_sk.src_port != ntohs(srv_sa6.sin6_port) || |
144 | srv_sk.dst_port != cli_sa6.sin6_port, | 199 | srv_sk.dst_port != cli_sa6.sin6_port, |
145 | "Unexpected srv_sk", "Check srv_sk output. linum:%u", linum); | 200 | "Unexpected srv_sk", "Check srv_sk output. egress_linum:%u", |
201 | egress_linum); | ||
146 | 202 | ||
147 | CHECK(cli_sk.state == 10 || | 203 | CHECK(cli_sk.state == 10 || |
148 | !cli_sk.state || | 204 | !cli_sk.state || |
@@ -154,21 +210,31 @@ static void check_result(void) | |||
154 | sizeof(cli_sk.dst_ip6)) || | 210 | sizeof(cli_sk.dst_ip6)) || |
155 | cli_sk.src_port != ntohs(cli_sa6.sin6_port) || | 211 | cli_sk.src_port != ntohs(cli_sa6.sin6_port) || |
156 | cli_sk.dst_port != srv_sa6.sin6_port, | 212 | cli_sk.dst_port != srv_sa6.sin6_port, |
157 | "Unexpected cli_sk", "Check cli_sk output. linum:%u", linum); | 213 | "Unexpected cli_sk", "Check cli_sk output. egress_linum:%u", |
214 | egress_linum); | ||
215 | |||
216 | CHECK(listen_tp.data_segs_out || | ||
217 | listen_tp.data_segs_in || | ||
218 | listen_tp.total_retrans || | ||
219 | listen_tp.bytes_acked, | ||
220 | "Unexpected listen_tp", "Check listen_tp output. ingress_linum:%u", | ||
221 | ingress_linum); | ||
158 | 222 | ||
159 | CHECK(srv_tp.data_segs_out != 1 || | 223 | CHECK(srv_tp.data_segs_out != 1 || |
160 | srv_tp.data_segs_in || | 224 | srv_tp.data_segs_in || |
161 | srv_tp.snd_cwnd != 10 || | 225 | srv_tp.snd_cwnd != 10 || |
162 | srv_tp.total_retrans || | 226 | srv_tp.total_retrans || |
163 | srv_tp.bytes_acked != DATA_LEN, | 227 | srv_tp.bytes_acked != DATA_LEN, |
164 | "Unexpected srv_tp", "Check srv_tp output. linum:%u", linum); | 228 | "Unexpected srv_tp", "Check srv_tp output. egress_linum:%u", |
229 | egress_linum); | ||
165 | 230 | ||
166 | CHECK(cli_tp.data_segs_out || | 231 | CHECK(cli_tp.data_segs_out || |
167 | cli_tp.data_segs_in != 1 || | 232 | cli_tp.data_segs_in != 1 || |
168 | cli_tp.snd_cwnd != 10 || | 233 | cli_tp.snd_cwnd != 10 || |
169 | cli_tp.total_retrans || | 234 | cli_tp.total_retrans || |
170 | cli_tp.bytes_received != DATA_LEN, | 235 | cli_tp.bytes_received != DATA_LEN, |
171 | "Unexpected cli_tp", "Check cli_tp output. linum:%u", linum); | 236 | "Unexpected cli_tp", "Check cli_tp output. egress_linum:%u", |
237 | egress_linum); | ||
172 | } | 238 | } |
173 | 239 | ||
174 | static void test(void) | 240 | static void test(void) |
@@ -211,10 +277,10 @@ static void test(void) | |||
211 | err, errno); | 277 | err, errno); |
212 | 278 | ||
213 | /* Update addr_map with srv_sa6 and cli_sa6 */ | 279 | /* Update addr_map with srv_sa6 and cli_sa6 */ |
214 | err = bpf_map_update_elem(addr_map_fd, &srv_idx, &srv_sa6, 0); | 280 | err = bpf_map_update_elem(addr_map_fd, &addr_srv_idx, &srv_sa6, 0); |
215 | CHECK(err, "map_update", "err:%d errno:%d", err, errno); | 281 | CHECK(err, "map_update", "err:%d errno:%d", err, errno); |
216 | 282 | ||
217 | err = bpf_map_update_elem(addr_map_fd, &cli_idx, &cli_sa6, 0); | 283 | err = bpf_map_update_elem(addr_map_fd, &addr_cli_idx, &cli_sa6, 0); |
218 | CHECK(err, "map_update", "err:%d errno:%d", err, errno); | 284 | CHECK(err, "map_update", "err:%d errno:%d", err, errno); |
219 | 285 | ||
220 | /* Connect from cli_sa6 to srv_sa6 */ | 286 | /* Connect from cli_sa6 to srv_sa6 */ |
@@ -273,9 +339,9 @@ int main(int argc, char **argv) | |||
273 | struct bpf_prog_load_attr attr = { | 339 | struct bpf_prog_load_attr attr = { |
274 | .file = "test_sock_fields_kern.o", | 340 | .file = "test_sock_fields_kern.o", |
275 | .prog_type = BPF_PROG_TYPE_CGROUP_SKB, | 341 | .prog_type = BPF_PROG_TYPE_CGROUP_SKB, |
276 | .expected_attach_type = BPF_CGROUP_INET_EGRESS, | ||
277 | }; | 342 | }; |
278 | int cgroup_fd, prog_fd, err; | 343 | int cgroup_fd, egress_fd, ingress_fd, err; |
344 | struct bpf_program *ingress_prog; | ||
279 | struct bpf_object *obj; | 345 | struct bpf_object *obj; |
280 | struct bpf_map *map; | 346 | struct bpf_map *map; |
281 | 347 | ||
@@ -293,12 +359,24 @@ int main(int argc, char **argv) | |||
293 | err = join_cgroup(TEST_CGROUP); | 359 | err = join_cgroup(TEST_CGROUP); |
294 | CHECK(err, "join_cgroup", "err:%d errno:%d", err, errno); | 360 | CHECK(err, "join_cgroup", "err:%d errno:%d", err, errno); |
295 | 361 | ||
296 | err = bpf_prog_load_xattr(&attr, &obj, &prog_fd); | 362 | err = bpf_prog_load_xattr(&attr, &obj, &egress_fd); |
297 | CHECK(err, "bpf_prog_load_xattr()", "err:%d", err); | 363 | CHECK(err, "bpf_prog_load_xattr()", "err:%d", err); |
298 | 364 | ||
299 | err = bpf_prog_attach(prog_fd, cgroup_fd, BPF_CGROUP_INET_EGRESS, 0); | 365 | ingress_prog = bpf_object__find_program_by_title(obj, |
366 | "cgroup_skb/ingress"); | ||
367 | CHECK(!ingress_prog, | ||
368 | "bpf_object__find_program_by_title(cgroup_skb/ingress)", | ||
369 | "not found"); | ||
370 | ingress_fd = bpf_program__fd(ingress_prog); | ||
371 | |||
372 | err = bpf_prog_attach(egress_fd, cgroup_fd, BPF_CGROUP_INET_EGRESS, 0); | ||
300 | CHECK(err == -1, "bpf_prog_attach(CPF_CGROUP_INET_EGRESS)", | 373 | CHECK(err == -1, "bpf_prog_attach(CPF_CGROUP_INET_EGRESS)", |
301 | "err:%d errno%d", err, errno); | 374 | "err:%d errno%d", err, errno); |
375 | |||
376 | err = bpf_prog_attach(ingress_fd, cgroup_fd, | ||
377 | BPF_CGROUP_INET_INGRESS, 0); | ||
378 | CHECK(err == -1, "bpf_prog_attach(CPF_CGROUP_INET_INGRESS)", | ||
379 | "err:%d errno%d", err, errno); | ||
302 | close(cgroup_fd); | 380 | close(cgroup_fd); |
303 | 381 | ||
304 | map = bpf_object__find_map_by_name(obj, "addr_map"); | 382 | map = bpf_object__find_map_by_name(obj, "addr_map"); |
diff --git a/tools/testing/selftests/bpf/verifier/calls.c b/tools/testing/selftests/bpf/verifier/calls.c index 4004891afa9c..f2ccae39ee66 100644 --- a/tools/testing/selftests/bpf/verifier/calls.c +++ b/tools/testing/selftests/bpf/verifier/calls.c | |||
@@ -1940,3 +1940,28 @@ | |||
1940 | .errstr = "!read_ok", | 1940 | .errstr = "!read_ok", |
1941 | .result = REJECT, | 1941 | .result = REJECT, |
1942 | }, | 1942 | }, |
1943 | { | ||
1944 | "calls: cross frame pruning - liveness propagation", | ||
1945 | .insns = { | ||
1946 | BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_get_prandom_u32), | ||
1947 | BPF_MOV64_IMM(BPF_REG_8, 0), | ||
1948 | BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1), | ||
1949 | BPF_MOV64_IMM(BPF_REG_8, 1), | ||
1950 | BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_get_prandom_u32), | ||
1951 | BPF_MOV64_IMM(BPF_REG_9, 0), | ||
1952 | BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1), | ||
1953 | BPF_MOV64_IMM(BPF_REG_9, 1), | ||
1954 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_0), | ||
1955 | BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4), | ||
1956 | BPF_JMP_IMM(BPF_JEQ, BPF_REG_8, 1, 1), | ||
1957 | BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_2, 0), | ||
1958 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
1959 | BPF_EXIT_INSN(), | ||
1960 | BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 0), | ||
1961 | BPF_EXIT_INSN(), | ||
1962 | }, | ||
1963 | .prog_type = BPF_PROG_TYPE_SOCKET_FILTER, | ||
1964 | .errstr_unpriv = "function calls to other bpf functions are allowed for root only", | ||
1965 | .errstr = "!read_ok", | ||
1966 | .result = REJECT, | ||
1967 | }, | ||
diff --git a/tools/testing/selftests/bpf/verifier/ref_tracking.c b/tools/testing/selftests/bpf/verifier/ref_tracking.c index 3ed3593bd8b6..923f2110072d 100644 --- a/tools/testing/selftests/bpf/verifier/ref_tracking.c +++ b/tools/testing/selftests/bpf/verifier/ref_tracking.c | |||
@@ -605,3 +605,171 @@ | |||
605 | .prog_type = BPF_PROG_TYPE_SCHED_CLS, | 605 | .prog_type = BPF_PROG_TYPE_SCHED_CLS, |
606 | .result = ACCEPT, | 606 | .result = ACCEPT, |
607 | }, | 607 | }, |
608 | { | ||
609 | "reference tracking: use ptr from bpf_tcp_sock() after release", | ||
610 | .insns = { | ||
611 | BPF_SK_LOOKUP, | ||
612 | BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1), | ||
613 | BPF_EXIT_INSN(), | ||
614 | BPF_MOV64_REG(BPF_REG_6, BPF_REG_0), | ||
615 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_0), | ||
616 | BPF_EMIT_CALL(BPF_FUNC_tcp_sock), | ||
617 | BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 3), | ||
618 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), | ||
619 | BPF_EMIT_CALL(BPF_FUNC_sk_release), | ||
620 | BPF_EXIT_INSN(), | ||
621 | BPF_MOV64_REG(BPF_REG_7, BPF_REG_0), | ||
622 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), | ||
623 | BPF_EMIT_CALL(BPF_FUNC_sk_release), | ||
624 | BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_7, offsetof(struct bpf_tcp_sock, snd_cwnd)), | ||
625 | BPF_EXIT_INSN(), | ||
626 | }, | ||
627 | .prog_type = BPF_PROG_TYPE_SCHED_CLS, | ||
628 | .result = REJECT, | ||
629 | .errstr = "invalid mem access", | ||
630 | }, | ||
631 | { | ||
632 | "reference tracking: use ptr from bpf_sk_fullsock() after release", | ||
633 | .insns = { | ||
634 | BPF_SK_LOOKUP, | ||
635 | BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1), | ||
636 | BPF_EXIT_INSN(), | ||
637 | BPF_MOV64_REG(BPF_REG_6, BPF_REG_0), | ||
638 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_0), | ||
639 | BPF_EMIT_CALL(BPF_FUNC_sk_fullsock), | ||
640 | BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 3), | ||
641 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), | ||
642 | BPF_EMIT_CALL(BPF_FUNC_sk_release), | ||
643 | BPF_EXIT_INSN(), | ||
644 | BPF_MOV64_REG(BPF_REG_7, BPF_REG_0), | ||
645 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), | ||
646 | BPF_EMIT_CALL(BPF_FUNC_sk_release), | ||
647 | BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_7, offsetof(struct bpf_sock, type)), | ||
648 | BPF_EXIT_INSN(), | ||
649 | }, | ||
650 | .prog_type = BPF_PROG_TYPE_SCHED_CLS, | ||
651 | .result = REJECT, | ||
652 | .errstr = "invalid mem access", | ||
653 | }, | ||
654 | { | ||
655 | "reference tracking: use ptr from bpf_sk_fullsock(tp) after release", | ||
656 | .insns = { | ||
657 | BPF_SK_LOOKUP, | ||
658 | BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1), | ||
659 | BPF_EXIT_INSN(), | ||
660 | BPF_MOV64_REG(BPF_REG_6, BPF_REG_0), | ||
661 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_0), | ||
662 | BPF_EMIT_CALL(BPF_FUNC_tcp_sock), | ||
663 | BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 3), | ||
664 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), | ||
665 | BPF_EMIT_CALL(BPF_FUNC_sk_release), | ||
666 | BPF_EXIT_INSN(), | ||
667 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_0), | ||
668 | BPF_EMIT_CALL(BPF_FUNC_sk_fullsock), | ||
669 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), | ||
670 | BPF_MOV64_REG(BPF_REG_6, BPF_REG_0), | ||
671 | BPF_EMIT_CALL(BPF_FUNC_sk_release), | ||
672 | BPF_JMP_IMM(BPF_JNE, BPF_REG_6, 0, 1), | ||
673 | BPF_EXIT_INSN(), | ||
674 | BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_6, offsetof(struct bpf_sock, type)), | ||
675 | BPF_EXIT_INSN(), | ||
676 | }, | ||
677 | .prog_type = BPF_PROG_TYPE_SCHED_CLS, | ||
678 | .result = REJECT, | ||
679 | .errstr = "invalid mem access", | ||
680 | }, | ||
681 | { | ||
682 | "reference tracking: use sk after bpf_sk_release(tp)", | ||
683 | .insns = { | ||
684 | BPF_SK_LOOKUP, | ||
685 | BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1), | ||
686 | BPF_EXIT_INSN(), | ||
687 | BPF_MOV64_REG(BPF_REG_6, BPF_REG_0), | ||
688 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_0), | ||
689 | BPF_EMIT_CALL(BPF_FUNC_tcp_sock), | ||
690 | BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 3), | ||
691 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), | ||
692 | BPF_EMIT_CALL(BPF_FUNC_sk_release), | ||
693 | BPF_EXIT_INSN(), | ||
694 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_0), | ||
695 | BPF_EMIT_CALL(BPF_FUNC_sk_release), | ||
696 | BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_6, offsetof(struct bpf_sock, type)), | ||
697 | BPF_EXIT_INSN(), | ||
698 | }, | ||
699 | .prog_type = BPF_PROG_TYPE_SCHED_CLS, | ||
700 | .result = REJECT, | ||
701 | .errstr = "invalid mem access", | ||
702 | }, | ||
703 | { | ||
704 | "reference tracking: use ptr from bpf_get_listener_sock() after bpf_sk_release(sk)", | ||
705 | .insns = { | ||
706 | BPF_SK_LOOKUP, | ||
707 | BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1), | ||
708 | BPF_EXIT_INSN(), | ||
709 | BPF_MOV64_REG(BPF_REG_6, BPF_REG_0), | ||
710 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_0), | ||
711 | BPF_EMIT_CALL(BPF_FUNC_get_listener_sock), | ||
712 | BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 3), | ||
713 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), | ||
714 | BPF_EMIT_CALL(BPF_FUNC_sk_release), | ||
715 | BPF_EXIT_INSN(), | ||
716 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), | ||
717 | BPF_MOV64_REG(BPF_REG_6, BPF_REG_0), | ||
718 | BPF_EMIT_CALL(BPF_FUNC_sk_release), | ||
719 | BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_6, offsetof(struct bpf_sock, src_port)), | ||
720 | BPF_EXIT_INSN(), | ||
721 | }, | ||
722 | .prog_type = BPF_PROG_TYPE_SCHED_CLS, | ||
723 | .result = ACCEPT, | ||
724 | }, | ||
725 | { | ||
726 | "reference tracking: bpf_sk_release(listen_sk)", | ||
727 | .insns = { | ||
728 | BPF_SK_LOOKUP, | ||
729 | BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1), | ||
730 | BPF_EXIT_INSN(), | ||
731 | BPF_MOV64_REG(BPF_REG_6, BPF_REG_0), | ||
732 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_0), | ||
733 | BPF_EMIT_CALL(BPF_FUNC_get_listener_sock), | ||
734 | BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 3), | ||
735 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), | ||
736 | BPF_EMIT_CALL(BPF_FUNC_sk_release), | ||
737 | BPF_EXIT_INSN(), | ||
738 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_0), | ||
739 | BPF_EMIT_CALL(BPF_FUNC_sk_release), | ||
740 | BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_6, offsetof(struct bpf_sock, type)), | ||
741 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), | ||
742 | BPF_EMIT_CALL(BPF_FUNC_sk_release), | ||
743 | BPF_EXIT_INSN(), | ||
744 | }, | ||
745 | .prog_type = BPF_PROG_TYPE_SCHED_CLS, | ||
746 | .result = REJECT, | ||
747 | .errstr = "reference has not been acquired before", | ||
748 | }, | ||
749 | { | ||
750 | /* !bpf_sk_fullsock(sk) is checked but !bpf_tcp_sock(sk) is not checked */ | ||
751 | "reference tracking: tp->snd_cwnd after bpf_sk_fullsock(sk) and bpf_tcp_sock(sk)", | ||
752 | .insns = { | ||
753 | BPF_SK_LOOKUP, | ||
754 | BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1), | ||
755 | BPF_EXIT_INSN(), | ||
756 | BPF_MOV64_REG(BPF_REG_6, BPF_REG_0), | ||
757 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_0), | ||
758 | BPF_EMIT_CALL(BPF_FUNC_sk_fullsock), | ||
759 | BPF_MOV64_REG(BPF_REG_7, BPF_REG_0), | ||
760 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), | ||
761 | BPF_EMIT_CALL(BPF_FUNC_tcp_sock), | ||
762 | BPF_MOV64_REG(BPF_REG_8, BPF_REG_0), | ||
763 | BPF_JMP_IMM(BPF_JNE, BPF_REG_7, 0, 3), | ||
764 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), | ||
765 | BPF_EMIT_CALL(BPF_FUNC_sk_release), | ||
766 | BPF_EXIT_INSN(), | ||
767 | BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_8, offsetof(struct bpf_tcp_sock, snd_cwnd)), | ||
768 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), | ||
769 | BPF_EMIT_CALL(BPF_FUNC_sk_release), | ||
770 | BPF_EXIT_INSN(), | ||
771 | }, | ||
772 | .prog_type = BPF_PROG_TYPE_SCHED_CLS, | ||
773 | .result = REJECT, | ||
774 | .errstr = "invalid mem access", | ||
775 | }, | ||
diff --git a/tools/testing/selftests/bpf/verifier/sock.c b/tools/testing/selftests/bpf/verifier/sock.c index 0ddfdf76aba5..416436231fab 100644 --- a/tools/testing/selftests/bpf/verifier/sock.c +++ b/tools/testing/selftests/bpf/verifier/sock.c | |||
@@ -342,7 +342,7 @@ | |||
342 | }, | 342 | }, |
343 | .prog_type = BPF_PROG_TYPE_SCHED_CLS, | 343 | .prog_type = BPF_PROG_TYPE_SCHED_CLS, |
344 | .result = REJECT, | 344 | .result = REJECT, |
345 | .errstr = "type=sock_common expected=sock", | 345 | .errstr = "reference has not been acquired before", |
346 | }, | 346 | }, |
347 | { | 347 | { |
348 | "bpf_sk_release(bpf_sk_fullsock(skb->sk))", | 348 | "bpf_sk_release(bpf_sk_fullsock(skb->sk))", |
@@ -380,5 +380,5 @@ | |||
380 | }, | 380 | }, |
381 | .prog_type = BPF_PROG_TYPE_SCHED_CLS, | 381 | .prog_type = BPF_PROG_TYPE_SCHED_CLS, |
382 | .result = REJECT, | 382 | .result = REJECT, |
383 | .errstr = "type=tcp_sock expected=sock", | 383 | .errstr = "reference has not been acquired before", |
384 | }, | 384 | }, |
diff --git a/tools/testing/selftests/tc-testing/tc-tests/actions/bpf.json b/tools/testing/selftests/tc-testing/tc-tests/actions/bpf.json index 5970cee6d05f..b074ea9b6fe8 100644 --- a/tools/testing/selftests/tc-testing/tc-tests/actions/bpf.json +++ b/tools/testing/selftests/tc-testing/tc-tests/actions/bpf.json | |||
@@ -286,5 +286,30 @@ | |||
286 | "teardown": [ | 286 | "teardown": [ |
287 | "$TC action flush action bpf" | 287 | "$TC action flush action bpf" |
288 | ] | 288 | ] |
289 | }, | ||
290 | { | ||
291 | "id": "b8a1", | ||
292 | "name": "Replace bpf action with invalid goto_chain control", | ||
293 | "category": [ | ||
294 | "actions", | ||
295 | "bpf" | ||
296 | ], | ||
297 | "setup": [ | ||
298 | [ | ||
299 | "$TC actions flush action bpf", | ||
300 | 0, | ||
301 | 1, | ||
302 | 255 | ||
303 | ], | ||
304 | "$TC action add action bpf bytecode '1,6 0 0 4294967295' pass index 90" | ||
305 | ], | ||
306 | "cmdUnderTest": "$TC action replace action bpf bytecode '1,6 0 0 4294967295' goto chain 42 index 90 cookie c1a0c1a0", | ||
307 | "expExitCode": "255", | ||
308 | "verifyCmd": "$TC action list action bpf", | ||
309 | "matchPattern": "action order [0-9]*: bpf.* default-action pass.*index 90", | ||
310 | "matchCount": "1", | ||
311 | "teardown": [ | ||
312 | "$TC action flush action bpf" | ||
313 | ] | ||
289 | } | 314 | } |
290 | ] | 315 | ] |
diff --git a/tools/testing/selftests/tc-testing/tc-tests/actions/connmark.json b/tools/testing/selftests/tc-testing/tc-tests/actions/connmark.json index 13147a1f5731..cadde8f41fcd 100644 --- a/tools/testing/selftests/tc-testing/tc-tests/actions/connmark.json +++ b/tools/testing/selftests/tc-testing/tc-tests/actions/connmark.json | |||
@@ -287,5 +287,30 @@ | |||
287 | "teardown": [ | 287 | "teardown": [ |
288 | "$TC actions flush action connmark" | 288 | "$TC actions flush action connmark" |
289 | ] | 289 | ] |
290 | }, | ||
291 | { | ||
292 | "id": "c506", | ||
293 | "name": "Replace connmark with invalid goto chain control", | ||
294 | "category": [ | ||
295 | "actions", | ||
296 | "connmark" | ||
297 | ], | ||
298 | "setup": [ | ||
299 | [ | ||
300 | "$TC actions flush action connmark", | ||
301 | 0, | ||
302 | 1, | ||
303 | 255 | ||
304 | ], | ||
305 | "$TC actions add action connmark pass index 90" | ||
306 | ], | ||
307 | "cmdUnderTest": "$TC actions replace action connmark goto chain 42 index 90 cookie c1a0c1a0", | ||
308 | "expExitCode": "255", | ||
309 | "verifyCmd": "$TC actions get action connmark index 90", | ||
310 | "matchPattern": "action order [0-9]+: connmark zone 0 pass.*index 90 ref", | ||
311 | "matchCount": "1", | ||
312 | "teardown": [ | ||
313 | "$TC actions flush action connmark" | ||
314 | ] | ||
290 | } | 315 | } |
291 | ] | 316 | ] |
diff --git a/tools/testing/selftests/tc-testing/tc-tests/actions/csum.json b/tools/testing/selftests/tc-testing/tc-tests/actions/csum.json index a022792d392a..ddabb2fbb7c7 100644 --- a/tools/testing/selftests/tc-testing/tc-tests/actions/csum.json +++ b/tools/testing/selftests/tc-testing/tc-tests/actions/csum.json | |||
@@ -500,5 +500,30 @@ | |||
500 | "matchPattern": "^[ \t]+index [0-9]+ ref", | 500 | "matchPattern": "^[ \t]+index [0-9]+ ref", |
501 | "matchCount": "0", | 501 | "matchCount": "0", |
502 | "teardown": [] | 502 | "teardown": [] |
503 | }, | ||
504 | { | ||
505 | "id": "d128", | ||
506 | "name": "Replace csum action with invalid goto chain control", | ||
507 | "category": [ | ||
508 | "actions", | ||
509 | "csum" | ||
510 | ], | ||
511 | "setup": [ | ||
512 | [ | ||
513 | "$TC actions flush action csum", | ||
514 | 0, | ||
515 | 1, | ||
516 | 255 | ||
517 | ], | ||
518 | "$TC actions add action csum iph index 90" | ||
519 | ], | ||
520 | "cmdUnderTest": "$TC actions replace action csum iph goto chain 42 index 90 cookie c1a0c1a0", | ||
521 | "expExitCode": "255", | ||
522 | "verifyCmd": "$TC actions get action csum index 90", | ||
523 | "matchPattern": "action order [0-9]*: csum \\(iph\\) action pass.*index 90 ref", | ||
524 | "matchCount": "1", | ||
525 | "teardown": [ | ||
526 | "$TC actions flush action csum" | ||
527 | ] | ||
503 | } | 528 | } |
504 | ] | 529 | ] |
diff --git a/tools/testing/selftests/tc-testing/tc-tests/actions/gact.json b/tools/testing/selftests/tc-testing/tc-tests/actions/gact.json index 89189a03ce3d..814b7a8a478b 100644 --- a/tools/testing/selftests/tc-testing/tc-tests/actions/gact.json +++ b/tools/testing/selftests/tc-testing/tc-tests/actions/gact.json | |||
@@ -560,5 +560,30 @@ | |||
560 | "teardown": [ | 560 | "teardown": [ |
561 | "$TC actions flush action gact" | 561 | "$TC actions flush action gact" |
562 | ] | 562 | ] |
563 | }, | ||
564 | { | ||
565 | "id": "ca89", | ||
566 | "name": "Replace gact action with invalid goto chain control", | ||
567 | "category": [ | ||
568 | "actions", | ||
569 | "gact" | ||
570 | ], | ||
571 | "setup": [ | ||
572 | [ | ||
573 | "$TC actions flush action gact", | ||
574 | 0, | ||
575 | 1, | ||
576 | 255 | ||
577 | ], | ||
578 | "$TC actions add action pass random determ drop 2 index 90" | ||
579 | ], | ||
580 | "cmdUnderTest": "$TC actions replace action goto chain 42 random determ drop 5 index 90 cookie c1a0c1a0", | ||
581 | "expExitCode": "255", | ||
582 | "verifyCmd": "$TC actions list action gact", | ||
583 | "matchPattern": "action order [0-9]*: gact action pass.*random type determ drop val 2.*index 90 ref", | ||
584 | "matchCount": "1", | ||
585 | "teardown": [ | ||
586 | "$TC actions flush action gact" | ||
587 | ] | ||
563 | } | 588 | } |
564 | ] | 589 | ] |
diff --git a/tools/testing/selftests/tc-testing/tc-tests/actions/ife.json b/tools/testing/selftests/tc-testing/tc-tests/actions/ife.json index 0da3545cabdb..c13a68b98fc7 100644 --- a/tools/testing/selftests/tc-testing/tc-tests/actions/ife.json +++ b/tools/testing/selftests/tc-testing/tc-tests/actions/ife.json | |||
@@ -1060,5 +1060,30 @@ | |||
1060 | "matchPattern": "action order [0-9]*: ife encode action pipe.*allow prio.*index 4", | 1060 | "matchPattern": "action order [0-9]*: ife encode action pipe.*allow prio.*index 4", |
1061 | "matchCount": "0", | 1061 | "matchCount": "0", |
1062 | "teardown": [] | 1062 | "teardown": [] |
1063 | }, | ||
1064 | { | ||
1065 | "id": "a0e2", | ||
1066 | "name": "Replace ife encode action with invalid goto chain control", | ||
1067 | "category": [ | ||
1068 | "actions", | ||
1069 | "ife" | ||
1070 | ], | ||
1071 | "setup": [ | ||
1072 | [ | ||
1073 | "$TC actions flush action ife", | ||
1074 | 0, | ||
1075 | 1, | ||
1076 | 255 | ||
1077 | ], | ||
1078 | "$TC actions add action ife encode allow mark pass index 90" | ||
1079 | ], | ||
1080 | "cmdUnderTest": "$TC actions replace action ife encode allow mark goto chain 42 index 90 cookie c1a0c1a0", | ||
1081 | "expExitCode": "255", | ||
1082 | "verifyCmd": "$TC actions get action ife index 90", | ||
1083 | "matchPattern": "action order [0-9]*: ife encode action pass.*type 0[xX]ED3E .*allow mark.*index 90 ref", | ||
1084 | "matchCount": "1", | ||
1085 | "teardown": [ | ||
1086 | "$TC actions flush action ife" | ||
1087 | ] | ||
1063 | } | 1088 | } |
1064 | ] | 1089 | ] |
diff --git a/tools/testing/selftests/tc-testing/tc-tests/actions/mirred.json b/tools/testing/selftests/tc-testing/tc-tests/actions/mirred.json index db49fd0f8445..6e5fb3d25681 100644 --- a/tools/testing/selftests/tc-testing/tc-tests/actions/mirred.json +++ b/tools/testing/selftests/tc-testing/tc-tests/actions/mirred.json | |||
@@ -434,5 +434,30 @@ | |||
434 | "teardown": [ | 434 | "teardown": [ |
435 | "$TC actions flush action mirred" | 435 | "$TC actions flush action mirred" |
436 | ] | 436 | ] |
437 | }, | ||
438 | { | ||
439 | "id": "2a9a", | ||
440 | "name": "Replace mirred action with invalid goto chain control", | ||
441 | "category": [ | ||
442 | "actions", | ||
443 | "mirred" | ||
444 | ], | ||
445 | "setup": [ | ||
446 | [ | ||
447 | "$TC actions flush action mirred", | ||
448 | 0, | ||
449 | 1, | ||
450 | 255 | ||
451 | ], | ||
452 | "$TC actions add action mirred ingress mirror dev lo drop index 90" | ||
453 | ], | ||
454 | "cmdUnderTest": "$TC actions replace action mirred ingress mirror dev lo goto chain 42 index 90 cookie c1a0c1a0", | ||
455 | "expExitCode": "255", | ||
456 | "verifyCmd": "$TC actions get action mirred index 90", | ||
457 | "matchPattern": "action order [0-9]*: mirred \\(Ingress Mirror to device lo\\) drop.*index 90 ref", | ||
458 | "matchCount": "1", | ||
459 | "teardown": [ | ||
460 | "$TC actions flush action mirred" | ||
461 | ] | ||
437 | } | 462 | } |
438 | ] | 463 | ] |
diff --git a/tools/testing/selftests/tc-testing/tc-tests/actions/nat.json b/tools/testing/selftests/tc-testing/tc-tests/actions/nat.json index 0080dc2fd41c..bc12c1ccad30 100644 --- a/tools/testing/selftests/tc-testing/tc-tests/actions/nat.json +++ b/tools/testing/selftests/tc-testing/tc-tests/actions/nat.json | |||
@@ -589,5 +589,30 @@ | |||
589 | "teardown": [ | 589 | "teardown": [ |
590 | "$TC actions flush action nat" | 590 | "$TC actions flush action nat" |
591 | ] | 591 | ] |
592 | }, | ||
593 | { | ||
594 | "id": "4b12", | ||
595 | "name": "Replace nat action with invalid goto chain control", | ||
596 | "category": [ | ||
597 | "actions", | ||
598 | "nat" | ||
599 | ], | ||
600 | "setup": [ | ||
601 | [ | ||
602 | "$TC actions flush action nat", | ||
603 | 0, | ||
604 | 1, | ||
605 | 255 | ||
606 | ], | ||
607 | "$TC actions add action nat ingress 1.18.1.1 1.18.2.2 drop index 90" | ||
608 | ], | ||
609 | "cmdUnderTest": "$TC actions replace action nat ingress 1.18.1.1 1.18.2.2 goto chain 42 index 90 cookie c1a0c1a0", | ||
610 | "expExitCode": "255", | ||
611 | "verifyCmd": "$TC actions get action nat index 90", | ||
612 | "matchPattern": "action order [0-9]+: nat ingress 1.18.1.1/32 1.18.2.2 drop.*index 90 ref", | ||
613 | "matchCount": "1", | ||
614 | "teardown": [ | ||
615 | "$TC actions flush action nat" | ||
616 | ] | ||
592 | } | 617 | } |
593 | ] | 618 | ] |
diff --git a/tools/testing/selftests/tc-testing/tc-tests/actions/pedit.json b/tools/testing/selftests/tc-testing/tc-tests/actions/pedit.json new file mode 100644 index 000000000000..b73ceb9e28b1 --- /dev/null +++ b/tools/testing/selftests/tc-testing/tc-tests/actions/pedit.json | |||
@@ -0,0 +1,51 @@ | |||
1 | [ | ||
2 | { | ||
3 | "id": "319a", | ||
4 | "name": "Add pedit action that mangles IP TTL", | ||
5 | "category": [ | ||
6 | "actions", | ||
7 | "pedit" | ||
8 | ], | ||
9 | "setup": [ | ||
10 | [ | ||
11 | "$TC actions flush action pedit", | ||
12 | 0, | ||
13 | 1, | ||
14 | 255 | ||
15 | ] | ||
16 | ], | ||
17 | "cmdUnderTest": "$TC actions add action pedit ex munge ip ttl set 10", | ||
18 | "expExitCode": "0", | ||
19 | "verifyCmd": "$TC actions ls action pedit", | ||
20 | "matchPattern": "action order [0-9]+: pedit action pass keys 1.*index 1 ref.*key #0 at ipv4\\+8: val 0a000000 mask 00ffffff", | ||
21 | "matchCount": "1", | ||
22 | "teardown": [ | ||
23 | "$TC actions flush action pedit" | ||
24 | ] | ||
25 | }, | ||
26 | { | ||
27 | "id": "7e67", | ||
28 | "name": "Replace pedit action with invalid goto chain", | ||
29 | "category": [ | ||
30 | "actions", | ||
31 | "pedit" | ||
32 | ], | ||
33 | "setup": [ | ||
34 | [ | ||
35 | "$TC actions flush action pedit", | ||
36 | 0, | ||
37 | 1, | ||
38 | 255 | ||
39 | ], | ||
40 | "$TC actions add action pedit ex munge ip ttl set 10 pass index 90" | ||
41 | ], | ||
42 | "cmdUnderTest": "$TC actions replace action pedit ex munge ip ttl set 10 goto chain 42 index 90 cookie c1a0c1a0", | ||
43 | "expExitCode": "255", | ||
44 | "verifyCmd": "$TC actions ls action pedit", | ||
45 | "matchPattern": "action order [0-9]+: pedit action pass keys 1.*index 90 ref.*key #0 at ipv4\\+8: val 0a000000 mask 00ffffff", | ||
46 | "matchCount": "1", | ||
47 | "teardown": [ | ||
48 | "$TC actions flush action pedit" | ||
49 | ] | ||
50 | } | ||
51 | ] | ||
diff --git a/tools/testing/selftests/tc-testing/tc-tests/actions/police.json b/tools/testing/selftests/tc-testing/tc-tests/actions/police.json index 4086a50a670e..b8268da5adaa 100644 --- a/tools/testing/selftests/tc-testing/tc-tests/actions/police.json +++ b/tools/testing/selftests/tc-testing/tc-tests/actions/police.json | |||
@@ -739,5 +739,30 @@ | |||
739 | "teardown": [ | 739 | "teardown": [ |
740 | "$TC actions flush action police" | 740 | "$TC actions flush action police" |
741 | ] | 741 | ] |
742 | }, | ||
743 | { | ||
744 | "id": "689e", | ||
745 | "name": "Replace police action with invalid goto chain control", | ||
746 | "category": [ | ||
747 | "actions", | ||
748 | "police" | ||
749 | ], | ||
750 | "setup": [ | ||
751 | [ | ||
752 | "$TC actions flush action police", | ||
753 | 0, | ||
754 | 1, | ||
755 | 255 | ||
756 | ], | ||
757 | "$TC actions add action police rate 3mbit burst 250k drop index 90" | ||
758 | ], | ||
759 | "cmdUnderTest": "$TC actions replace action police rate 3mbit burst 250k goto chain 42 index 90 cookie c1a0c1a0", | ||
760 | "expExitCode": "255", | ||
761 | "verifyCmd": "$TC actions get action police index 90", | ||
762 | "matchPattern": "action order [0-9]*: police 0x5a rate 3Mbit burst 250Kb mtu 2Kb action drop", | ||
763 | "matchCount": "1", | ||
764 | "teardown": [ | ||
765 | "$TC actions flush action police" | ||
766 | ] | ||
742 | } | 767 | } |
743 | ] | 768 | ] |
diff --git a/tools/testing/selftests/tc-testing/tc-tests/actions/sample.json b/tools/testing/selftests/tc-testing/tc-tests/actions/sample.json index 3aca33c00039..27f0acaed880 100644 --- a/tools/testing/selftests/tc-testing/tc-tests/actions/sample.json +++ b/tools/testing/selftests/tc-testing/tc-tests/actions/sample.json | |||
@@ -584,5 +584,30 @@ | |||
584 | "teardown": [ | 584 | "teardown": [ |
585 | "$TC actions flush action sample" | 585 | "$TC actions flush action sample" |
586 | ] | 586 | ] |
587 | }, | ||
588 | { | ||
589 | "id": "0a6e", | ||
590 | "name": "Replace sample action with invalid goto chain control", | ||
591 | "category": [ | ||
592 | "actions", | ||
593 | "sample" | ||
594 | ], | ||
595 | "setup": [ | ||
596 | [ | ||
597 | "$TC actions flush action sample", | ||
598 | 0, | ||
599 | 1, | ||
600 | 255 | ||
601 | ], | ||
602 | "$TC actions add action sample rate 1024 group 4 pass index 90" | ||
603 | ], | ||
604 | "cmdUnderTest": "$TC actions replace action sample rate 1024 group 7 goto chain 42 index 90 cookie c1a0c1a0", | ||
605 | "expExitCode": "255", | ||
606 | "verifyCmd": "$TC actions list action sample", | ||
607 | "matchPattern": "action order [0-9]+: sample rate 1/1024 group 4 pass.*index 90", | ||
608 | "matchCount": "1", | ||
609 | "teardown": [ | ||
610 | "$TC actions flush action sample" | ||
611 | ] | ||
587 | } | 612 | } |
588 | ] | 613 | ] |
diff --git a/tools/testing/selftests/tc-testing/tc-tests/actions/simple.json b/tools/testing/selftests/tc-testing/tc-tests/actions/simple.json index e89a7aa4012d..8e8c1ae12260 100644 --- a/tools/testing/selftests/tc-testing/tc-tests/actions/simple.json +++ b/tools/testing/selftests/tc-testing/tc-tests/actions/simple.json | |||
@@ -126,5 +126,30 @@ | |||
126 | "teardown": [ | 126 | "teardown": [ |
127 | "" | 127 | "" |
128 | ] | 128 | ] |
129 | }, | ||
130 | { | ||
131 | "id": "b776", | ||
132 | "name": "Replace simple action with invalid goto chain control", | ||
133 | "category": [ | ||
134 | "actions", | ||
135 | "simple" | ||
136 | ], | ||
137 | "setup": [ | ||
138 | [ | ||
139 | "$TC actions flush action simple", | ||
140 | 0, | ||
141 | 1, | ||
142 | 255 | ||
143 | ], | ||
144 | "$TC actions add action simple sdata \"hello\" pass index 90" | ||
145 | ], | ||
146 | "cmdUnderTest": "$TC actions replace action simple sdata \"world\" goto chain 42 index 90 cookie c1a0c1a0", | ||
147 | "expExitCode": "255", | ||
148 | "verifyCmd": "$TC actions list action simple", | ||
149 | "matchPattern": "action order [0-9]*: Simple <hello>.*index 90 ref", | ||
150 | "matchCount": "1", | ||
151 | "teardown": [ | ||
152 | "$TC actions flush action simple" | ||
153 | ] | ||
129 | } | 154 | } |
130 | ] | 155 | ] |
diff --git a/tools/testing/selftests/tc-testing/tc-tests/actions/skbedit.json b/tools/testing/selftests/tc-testing/tc-tests/actions/skbedit.json index 5aaf593b914a..ecd96eda7f6a 100644 --- a/tools/testing/selftests/tc-testing/tc-tests/actions/skbedit.json +++ b/tools/testing/selftests/tc-testing/tc-tests/actions/skbedit.json | |||
@@ -484,5 +484,30 @@ | |||
484 | "teardown": [ | 484 | "teardown": [ |
485 | "$TC actions flush action skbedit" | 485 | "$TC actions flush action skbedit" |
486 | ] | 486 | ] |
487 | }, | ||
488 | { | ||
489 | "id": "1b2b", | ||
490 | "name": "Replace skbedit action with invalid goto_chain control", | ||
491 | "category": [ | ||
492 | "actions", | ||
493 | "skbedit" | ||
494 | ], | ||
495 | "setup": [ | ||
496 | [ | ||
497 | "$TC actions flush action skbedit", | ||
498 | 0, | ||
499 | 1, | ||
500 | 255 | ||
501 | ], | ||
502 | "$TC actions add action skbedit ptype host pass index 90" | ||
503 | ], | ||
504 | "cmdUnderTest": "$TC actions replace action skbedit ptype host goto chain 42 index 90 cookie c1a0c1a0", | ||
505 | "expExitCode": "255", | ||
506 | "verifyCmd": "$TC actions list action skbedit", | ||
507 | "matchPattern": "action order [0-9]*: skbedit ptype host pass.*index 90 ref", | ||
508 | "matchCount": "1", | ||
509 | "teardown": [ | ||
510 | "$TC actions flush action skbedit" | ||
511 | ] | ||
487 | } | 512 | } |
488 | ] | 513 | ] |
diff --git a/tools/testing/selftests/tc-testing/tc-tests/actions/skbmod.json b/tools/testing/selftests/tc-testing/tc-tests/actions/skbmod.json index fe3326e939c1..6eb4c4f97060 100644 --- a/tools/testing/selftests/tc-testing/tc-tests/actions/skbmod.json +++ b/tools/testing/selftests/tc-testing/tc-tests/actions/skbmod.json | |||
@@ -392,5 +392,30 @@ | |||
392 | "teardown": [ | 392 | "teardown": [ |
393 | "$TC actions flush action skbmod" | 393 | "$TC actions flush action skbmod" |
394 | ] | 394 | ] |
395 | }, | ||
396 | { | ||
397 | "id": "b651", | ||
398 | "name": "Replace skbmod action with invalid goto_chain control", | ||
399 | "category": [ | ||
400 | "actions", | ||
401 | "skbmod" | ||
402 | ], | ||
403 | "setup": [ | ||
404 | [ | ||
405 | "$TC actions flush action skbmod", | ||
406 | 0, | ||
407 | 1, | ||
408 | 255 | ||
409 | ], | ||
410 | "$TC actions add action skbmod set etype 0x1111 pass index 90" | ||
411 | ], | ||
412 | "cmdUnderTest": "$TC actions replace action skbmod set etype 0x1111 goto chain 42 index 90 cookie c1a0c1a0", | ||
413 | "expExitCode": "255", | ||
414 | "verifyCmd": "$TC actions ls action skbmod", | ||
415 | "matchPattern": "action order [0-9]*: skbmod pass set etype 0x1111\\s+index 90 ref", | ||
416 | "matchCount": "1", | ||
417 | "teardown": [ | ||
418 | "$TC actions flush action skbmod" | ||
419 | ] | ||
395 | } | 420 | } |
396 | ] | 421 | ] |
diff --git a/tools/testing/selftests/tc-testing/tc-tests/actions/tunnel_key.json b/tools/testing/selftests/tc-testing/tc-tests/actions/tunnel_key.json index e7e15a7336b6..28453a445fdb 100644 --- a/tools/testing/selftests/tc-testing/tc-tests/actions/tunnel_key.json +++ b/tools/testing/selftests/tc-testing/tc-tests/actions/tunnel_key.json | |||
@@ -884,5 +884,30 @@ | |||
884 | "teardown": [ | 884 | "teardown": [ |
885 | "$TC actions flush action tunnel_key" | 885 | "$TC actions flush action tunnel_key" |
886 | ] | 886 | ] |
887 | }, | ||
888 | { | ||
889 | "id": "8242", | ||
890 | "name": "Replace tunnel_key set action with invalid goto chain", | ||
891 | "category": [ | ||
892 | "actions", | ||
893 | "tunnel_key" | ||
894 | ], | ||
895 | "setup": [ | ||
896 | [ | ||
897 | "$TC actions flush action tunnel_key", | ||
898 | 0, | ||
899 | 1, | ||
900 | 255 | ||
901 | ], | ||
902 | "$TC actions add action tunnel_key set src_ip 10.10.10.1 dst_ip 20.20.20.2 dst_port 3128 nocsum id 1 pass index 90" | ||
903 | ], | ||
904 | "cmdUnderTest": "$TC actions replace action tunnel_key set src_ip 10.10.10.2 dst_ip 20.20.20.1 dst_port 3129 id 2 csum goto chain 42 index 90 cookie c1a0c1a0", | ||
905 | "expExitCode": "255", | ||
906 | "verifyCmd": "$TC actions get action tunnel_key index 90", | ||
907 | "matchPattern": "action order [0-9]+: tunnel_key.*set.*src_ip 10.10.10.1.*dst_ip 20.20.20.2.*key_id 1.*dst_port 3128.*csum pass.*index 90 ref", | ||
908 | "matchCount": "1", | ||
909 | "teardown": [ | ||
910 | "$TC actions flush action tunnel_key" | ||
911 | ] | ||
887 | } | 912 | } |
888 | ] | 913 | ] |
diff --git a/tools/testing/selftests/tc-testing/tc-tests/actions/vlan.json b/tools/testing/selftests/tc-testing/tc-tests/actions/vlan.json index 69ea09eefffc..cc7c7d758008 100644 --- a/tools/testing/selftests/tc-testing/tc-tests/actions/vlan.json +++ b/tools/testing/selftests/tc-testing/tc-tests/actions/vlan.json | |||
@@ -688,5 +688,30 @@ | |||
688 | "teardown": [ | 688 | "teardown": [ |
689 | "$TC actions flush action vlan" | 689 | "$TC actions flush action vlan" |
690 | ] | 690 | ] |
691 | }, | ||
692 | { | ||
693 | "id": "e394", | ||
694 | "name": "Replace vlan push action with invalid goto chain control", | ||
695 | "category": [ | ||
696 | "actions", | ||
697 | "vlan" | ||
698 | ], | ||
699 | "setup": [ | ||
700 | [ | ||
701 | "$TC actions flush action vlan", | ||
702 | 0, | ||
703 | 1, | ||
704 | 255 | ||
705 | ], | ||
706 | "$TC actions add action vlan push id 500 pass index 90" | ||
707 | ], | ||
708 | "cmdUnderTest": "$TC actions replace action vlan push id 500 goto chain 42 index 90 cookie c1a0c1a0", | ||
709 | "expExitCode": "255", | ||
710 | "verifyCmd": "$TC actions get action vlan index 90", | ||
711 | "matchPattern": "action order [0-9]+: vlan.*push id 500 protocol 802.1Q priority 0 pass.*index 90 ref", | ||
712 | "matchCount": "1", | ||
713 | "teardown": [ | ||
714 | "$TC actions flush action vlan" | ||
715 | ] | ||
691 | } | 716 | } |
692 | ] | 717 | ] |