Skip to content

Commit ea7da1d

Browse files
author
Alexei Starovoitov
committed
Merge branch 'Various BPF helper improvements'
Daniel Borkmann says: ==================== This series adds two BPF helpers, that is, one for retrieving the classid of an skb and another one to redirect via the neigh subsystem, and improves also the cookie helpers by removing the atomic counter. I've also added the bpf_tail_call_static() helper to the libbpf API that we've been using in Cilium for a while now, and last but not least the series adds a few selftests. For details, please check individual patches, thanks! v3 -> v4: - Removed out_rec error path (Martin) - Integrate BPF_F_NEIGH flag into rejecting invalid flags (Martin) - I think this way it's better to avoid bit overlaps given it's right in the place that would need to be extended on new flags v2 -> v3: - Removed double skb->dev = dev assignment (David) - Added headroom check for v6 path (David) - Set set flowi4_proto for ip_route_output_flow (David) - Rebased onto latest bpf-next v1 -> v2: - Rework cookie generator to support nested contexts (Eric) - Use ip_neigh_gw6() and container_of() (David) - Rename __throw_build_bug() and improve comments (Andrii) - Use bpf_tail_call_static() also in BPF samples (Maciej) ==================== Signed-off-by: Alexei Starovoitov <[email protected]>
2 parents 963ec27 + eef4a01 commit ea7da1d

File tree

23 files changed

+830
-82
lines changed

23 files changed

+830
-82
lines changed

include/linux/cookie.h

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/* SPDX-License-Identifier: GPL-2.0 */
2+
#ifndef __LINUX_COOKIE_H
3+
#define __LINUX_COOKIE_H
4+
5+
#include <linux/atomic.h>
6+
#include <linux/percpu.h>
7+
#include <asm/local.h>
8+
9+
struct pcpu_gen_cookie {
10+
local_t nesting;
11+
u64 last;
12+
} __aligned(16);
13+
14+
struct gen_cookie {
15+
struct pcpu_gen_cookie __percpu *local;
16+
atomic64_t forward_last ____cacheline_aligned_in_smp;
17+
atomic64_t reverse_last;
18+
};
19+
20+
#define COOKIE_LOCAL_BATCH 4096
21+
22+
#define DEFINE_COOKIE(name) \
23+
static DEFINE_PER_CPU(struct pcpu_gen_cookie, __##name); \
24+
static struct gen_cookie name = { \
25+
.local = &__##name, \
26+
.forward_last = ATOMIC64_INIT(0), \
27+
.reverse_last = ATOMIC64_INIT(0), \
28+
}
29+
30+
static __always_inline u64 gen_cookie_next(struct gen_cookie *gc)
31+
{
32+
struct pcpu_gen_cookie *local = this_cpu_ptr(gc->local);
33+
u64 val;
34+
35+
if (likely(local_inc_return(&local->nesting) == 1)) {
36+
val = local->last;
37+
if (__is_defined(CONFIG_SMP) &&
38+
unlikely((val & (COOKIE_LOCAL_BATCH - 1)) == 0)) {
39+
s64 next = atomic64_add_return(COOKIE_LOCAL_BATCH,
40+
&gc->forward_last);
41+
val = next - COOKIE_LOCAL_BATCH;
42+
}
43+
local->last = ++val;
44+
} else {
45+
val = atomic64_dec_return(&gc->reverse_last);
46+
}
47+
local_dec(&local->nesting);
48+
return val;
49+
}
50+
51+
#endif /* __LINUX_COOKIE_H */

include/linux/skbuff.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2548,6 +2548,11 @@ static inline int skb_mac_header_was_set(const struct sk_buff *skb)
25482548
return skb->mac_header != (typeof(skb->mac_header))~0U;
25492549
}
25502550

2551+
static inline void skb_unset_mac_header(struct sk_buff *skb)
2552+
{
2553+
skb->mac_header = (typeof(skb->mac_header))~0U;
2554+
}
2555+
25512556
static inline void skb_reset_mac_header(struct sk_buff *skb)
25522557
{
25532558
skb->mac_header = skb->data - skb->head;

include/linux/sock_diag.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,19 @@ void sock_diag_unregister(const struct sock_diag_handler *h);
2525
void sock_diag_register_inet_compat(int (*fn)(struct sk_buff *skb, struct nlmsghdr *nlh));
2626
void sock_diag_unregister_inet_compat(int (*fn)(struct sk_buff *skb, struct nlmsghdr *nlh));
2727

28-
u64 sock_gen_cookie(struct sock *sk);
28+
u64 __sock_gen_cookie(struct sock *sk);
29+
30+
static inline u64 sock_gen_cookie(struct sock *sk)
31+
{
32+
u64 cookie;
33+
34+
preempt_disable();
35+
cookie = __sock_gen_cookie(sk);
36+
preempt_enable();
37+
38+
return cookie;
39+
}
40+
2941
int sock_diag_check_cookie(struct sock *sk, const __u32 *cookie);
3042
void sock_diag_save_cookie(struct sock *sk, __u32 *cookie);
3143

include/net/net_namespace.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ extern struct list_head net_namespace_list;
230230
struct net *get_net_ns_by_pid(pid_t pid);
231231
struct net *get_net_ns_by_fd(int fd);
232232

233-
u64 net_gen_cookie(struct net *net);
233+
u64 __net_gen_cookie(struct net *net);
234234

235235
#ifdef CONFIG_SYSCTL
236236
void ipx_register_sysctl(void);

include/uapi/linux/bpf.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3643,6 +3643,28 @@ union bpf_attr {
36433643
* *flags* are identical to those used for bpf_snprintf_btf.
36443644
* Return
36453645
* 0 on success or a negative error in case of failure.
3646+
*
3647+
* u64 bpf_skb_cgroup_classid(struct sk_buff *skb)
3648+
* Description
3649+
* See **bpf_get_cgroup_classid**\ () for the main description.
3650+
* This helper differs from **bpf_get_cgroup_classid**\ () in that
3651+
* the cgroup v1 net_cls class is retrieved only from the *skb*'s
3652+
* associated socket instead of the current process.
3653+
* Return
3654+
* The id is returned or 0 in case the id could not be retrieved.
3655+
*
3656+
* long bpf_redirect_neigh(u32 ifindex, u64 flags)
3657+
* Description
3658+
* Redirect the packet to another net device of index *ifindex*
3659+
* and fill in L2 addresses from neighboring subsystem. This helper
3660+
* is somewhat similar to **bpf_redirect**\ (), except that it
3661+
* fills in e.g. MAC addresses based on the L3 information from
3662+
* the packet. This helper is supported for IPv4 and IPv6 protocols.
3663+
* The *flags* argument is reserved and must be 0. The helper is
3664+
* currently only supported for tc BPF program types.
3665+
* Return
3666+
* The helper returns **TC_ACT_REDIRECT** on success or
3667+
* **TC_ACT_SHOT** on error.
36463668
*/
36473669
#define __BPF_FUNC_MAPPER(FN) \
36483670
FN(unspec), \
@@ -3796,6 +3818,8 @@ union bpf_attr {
37963818
FN(copy_from_user), \
37973819
FN(snprintf_btf), \
37983820
FN(seq_printf_btf), \
3821+
FN(skb_cgroup_classid), \
3822+
FN(redirect_neigh), \
37993823
/* */
38003824

38013825
/* integer value in 'imm' field of BPF_CALL instruction selects which helper

kernel/bpf/reuseport_array.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ int bpf_fd_reuseport_array_lookup_elem(struct bpf_map *map, void *key,
191191
rcu_read_lock();
192192
sk = reuseport_array_lookup_elem(map, key);
193193
if (sk) {
194-
*(u64 *)value = sock_gen_cookie(sk);
194+
*(u64 *)value = __sock_gen_cookie(sk);
195195
err = 0;
196196
} else {
197197
err = -ENOENT;

0 commit comments

Comments
 (0)