Skip to content

Commit a7ba455

Browse files
Cong WangAlexei Starovoitov
authored andcommitted
sock_map: Introduce BPF_SK_SKB_VERDICT
Reusing BPF_SK_SKB_STREAM_VERDICT is possible but its name is confusing and more importantly we still want to distinguish them from user-space. So we can just reuse the stream verdict code but introduce a new type of eBPF program, skb_verdict. Users are not allowed to attach stream_verdict and skb_verdict programs to the same map. Signed-off-by: Cong Wang <[email protected]> Signed-off-by: Alexei Starovoitov <[email protected]> Acked-by: John Fastabend <[email protected]> Link: https://lore.kernel.org/bpf/[email protected]
1 parent b017055 commit a7ba455

File tree

8 files changed

+38
-1
lines changed

8 files changed

+38
-1
lines changed

include/linux/skmsg.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ struct sk_psock_progs {
5858
struct bpf_prog *msg_parser;
5959
struct bpf_prog *stream_parser;
6060
struct bpf_prog *stream_verdict;
61+
struct bpf_prog *skb_verdict;
6162
};
6263

6364
enum sk_psock_state_bits {
@@ -487,6 +488,7 @@ static inline void psock_progs_drop(struct sk_psock_progs *progs)
487488
psock_set_prog(&progs->msg_parser, NULL);
488489
psock_set_prog(&progs->stream_parser, NULL);
489490
psock_set_prog(&progs->stream_verdict, NULL);
491+
psock_set_prog(&progs->skb_verdict, NULL);
490492
}
491493

492494
int sk_psock_tls_strp_read(struct sk_psock *psock, struct sk_buff *skb);

include/uapi/linux/bpf.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -957,6 +957,7 @@ enum bpf_attach_type {
957957
BPF_XDP_CPUMAP,
958958
BPF_SK_LOOKUP,
959959
BPF_XDP,
960+
BPF_SK_SKB_VERDICT,
960961
__MAX_BPF_ATTACH_TYPE
961962
};
962963

kernel/bpf/syscall.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2948,6 +2948,7 @@ attach_type_to_prog_type(enum bpf_attach_type attach_type)
29482948
return BPF_PROG_TYPE_SK_MSG;
29492949
case BPF_SK_SKB_STREAM_PARSER:
29502950
case BPF_SK_SKB_STREAM_VERDICT:
2951+
case BPF_SK_SKB_VERDICT:
29512952
return BPF_PROG_TYPE_SK_SKB;
29522953
case BPF_LIRC_MODE2:
29532954
return BPF_PROG_TYPE_LIRC_MODE2;

net/core/skmsg.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -697,7 +697,7 @@ void sk_psock_drop(struct sock *sk, struct sk_psock *psock)
697697
rcu_assign_sk_user_data(sk, NULL);
698698
if (psock->progs.stream_parser)
699699
sk_psock_stop_strp(sk, psock);
700-
else if (psock->progs.stream_verdict)
700+
else if (psock->progs.stream_verdict || psock->progs.skb_verdict)
701701
sk_psock_stop_verdict(sk, psock);
702702
write_unlock_bh(&sk->sk_callback_lock);
703703

@@ -1024,6 +1024,8 @@ static int sk_psock_verdict_recv(read_descriptor_t *desc, struct sk_buff *skb,
10241024
}
10251025
skb_set_owner_r(skb, sk);
10261026
prog = READ_ONCE(psock->progs.stream_verdict);
1027+
if (!prog)
1028+
prog = READ_ONCE(psock->progs.skb_verdict);
10271029
if (likely(prog)) {
10281030
skb_dst_drop(skb);
10291031
skb_bpf_redirect_clear(skb);

net/core/sock_map.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,8 @@ static void sock_map_del_link(struct sock *sk,
156156
strp_stop = true;
157157
if (psock->saved_data_ready && stab->progs.stream_verdict)
158158
verdict_stop = true;
159+
if (psock->saved_data_ready && stab->progs.skb_verdict)
160+
verdict_stop = true;
159161
list_del(&link->list);
160162
sk_psock_free_link(link);
161163
}
@@ -232,6 +234,7 @@ static int sock_map_link(struct bpf_map *map, struct sock *sk)
232234
struct sk_psock_progs *progs = sock_map_progs(map);
233235
struct bpf_prog *stream_verdict = NULL;
234236
struct bpf_prog *stream_parser = NULL;
237+
struct bpf_prog *skb_verdict = NULL;
235238
struct bpf_prog *msg_parser = NULL;
236239
struct sk_psock *psock;
237240
int ret;
@@ -268,6 +271,15 @@ static int sock_map_link(struct bpf_map *map, struct sock *sk)
268271
}
269272
}
270273

274+
skb_verdict = READ_ONCE(progs->skb_verdict);
275+
if (skb_verdict) {
276+
skb_verdict = bpf_prog_inc_not_zero(skb_verdict);
277+
if (IS_ERR(skb_verdict)) {
278+
ret = PTR_ERR(skb_verdict);
279+
goto out_put_msg_parser;
280+
}
281+
}
282+
271283
no_progs:
272284
psock = sock_map_psock_get_checked(sk);
273285
if (IS_ERR(psock)) {
@@ -278,6 +290,9 @@ static int sock_map_link(struct bpf_map *map, struct sock *sk)
278290
if (psock) {
279291
if ((msg_parser && READ_ONCE(psock->progs.msg_parser)) ||
280292
(stream_parser && READ_ONCE(psock->progs.stream_parser)) ||
293+
(skb_verdict && READ_ONCE(psock->progs.skb_verdict)) ||
294+
(skb_verdict && READ_ONCE(psock->progs.stream_verdict)) ||
295+
(stream_verdict && READ_ONCE(psock->progs.skb_verdict)) ||
281296
(stream_verdict && READ_ONCE(psock->progs.stream_verdict))) {
282297
sk_psock_put(sk, psock);
283298
ret = -EBUSY;
@@ -309,6 +324,9 @@ static int sock_map_link(struct bpf_map *map, struct sock *sk)
309324
} else if (!stream_parser && stream_verdict && !psock->saved_data_ready) {
310325
psock_set_prog(&psock->progs.stream_verdict, stream_verdict);
311326
sk_psock_start_verdict(sk,psock);
327+
} else if (!stream_verdict && skb_verdict && !psock->saved_data_ready) {
328+
psock_set_prog(&psock->progs.skb_verdict, skb_verdict);
329+
sk_psock_start_verdict(sk, psock);
312330
}
313331
write_unlock_bh(&sk->sk_callback_lock);
314332
return 0;
@@ -317,6 +335,9 @@ static int sock_map_link(struct bpf_map *map, struct sock *sk)
317335
out_drop:
318336
sk_psock_put(sk, psock);
319337
out_progs:
338+
if (skb_verdict)
339+
bpf_prog_put(skb_verdict);
340+
out_put_msg_parser:
320341
if (msg_parser)
321342
bpf_prog_put(msg_parser);
322343
out_put_stream_parser:
@@ -1442,8 +1463,15 @@ static int sock_map_prog_update(struct bpf_map *map, struct bpf_prog *prog,
14421463
break;
14431464
#endif
14441465
case BPF_SK_SKB_STREAM_VERDICT:
1466+
if (progs->skb_verdict)
1467+
return -EBUSY;
14451468
pprog = &progs->stream_verdict;
14461469
break;
1470+
case BPF_SK_SKB_VERDICT:
1471+
if (progs->stream_verdict)
1472+
return -EBUSY;
1473+
pprog = &progs->skb_verdict;
1474+
break;
14471475
default:
14481476
return -EOPNOTSUPP;
14491477
}

tools/bpf/bpftool/common.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ const char * const attach_type_name[__MAX_BPF_ATTACH_TYPE] = {
5757

5858
[BPF_SK_SKB_STREAM_PARSER] = "sk_skb_stream_parser",
5959
[BPF_SK_SKB_STREAM_VERDICT] = "sk_skb_stream_verdict",
60+
[BPF_SK_SKB_VERDICT] = "sk_skb_verdict",
6061
[BPF_SK_MSG_VERDICT] = "sk_msg_verdict",
6162
[BPF_LIRC_MODE2] = "lirc_mode2",
6263
[BPF_FLOW_DISSECTOR] = "flow_dissector",

tools/bpf/bpftool/prog.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ enum dump_mode {
7676
static const char * const attach_type_strings[] = {
7777
[BPF_SK_SKB_STREAM_PARSER] = "stream_parser",
7878
[BPF_SK_SKB_STREAM_VERDICT] = "stream_verdict",
79+
[BPF_SK_SKB_VERDICT] = "skb_verdict",
7980
[BPF_SK_MSG_VERDICT] = "msg_verdict",
8081
[BPF_FLOW_DISSECTOR] = "flow_dissector",
8182
[__MAX_BPF_ATTACH_TYPE] = NULL,

tools/include/uapi/linux/bpf.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -957,6 +957,7 @@ enum bpf_attach_type {
957957
BPF_XDP_CPUMAP,
958958
BPF_SK_LOOKUP,
959959
BPF_XDP,
960+
BPF_SK_SKB_VERDICT,
960961
__MAX_BPF_ATTACH_TYPE
961962
};
962963

0 commit comments

Comments
 (0)