Skip to content

Commit 6850a33

Browse files
author
Martin KaFai Lau
committed
Merge branch 'add-a-dynptr-type-for-skb-metadata-for-tc-bpf'
Jakub Sitnicki says: ==================== Add a dynptr type for skb metadata for TC BPF TL;DR ----- This is the first step in an effort which aims to enable skb metadata access for all BPF programs which operate on an skb context. By skb metadata we mean the custom metadata area which can be allocated from an XDP program with the bpf_xdp_adjust_meta helper [1]. Network stack code accesses it using the skb_metadata_* helpers. Changelog --------- Changes in v7: - Make dynptr read-only for cloned skbs for now. (Martin) - Extend tests for skb clones to cover writes to metadata. - Drop Jesse's review stamp for patch 2 due to an update. - Link to v6: https://lore.kernel.org/r/20250804-skb-metadata-thru-dynptr-v6-0-05da400bfa4b@cloudflare.com Changes in v6: - Enable CONFIG_NET_ACT_MIRRED for bpf selftests to fix CI failure - Switch from u32 to matchall classifier, which bpf selftests already use - Link to v5: https://lore.kernel.org/r/20250731-skb-metadata-thru-dynptr-v5-0-f02f6b5688dc@cloudflare.com Changes in v5: - Invalidate skb payload and metadata slices on write to metadata. (Martin) - Drop redundant bounds check in bpf_skb_meta_*(). (Martin) - Check for unexpected flags in __bpf_dynptr_write(). (Martin) - Fold bpf_skb_meta_{load,store}_bytes() into callers. - Add a test for metadata access when an skb clone has been modified. - Drop Eduard's Ack for patch 3. Patch updated. - Keep Eduard's Ack for patches 4-8. - Add Jesse's stamp from an internal review. - Link to v4: https://lore.kernel.org/r/20250723-skb-metadata-thru-dynptr-v4-0-a0fed48bcd37@cloudflare.com Changes in v4: - Kill bpf_dynptr_from_skb_meta_rdonly. Not needed for now. (Marin) - Add a test to cover passing OOB offsets to dynptr ops. (Eduard) - Factor out bounds checks from bpf_dynptr_{read,write,slice}. (Eduard) - Squash patches: bpf: Enable read access to skb metadata with bpf_dynptr_read bpf: Enable write access to skb metadata with bpf_dynptr_write bpf: Enable read-write access to skb metadata with dynptr slice - Kept Eduard's Acks for v3 on unchanged patches. - Link to v3: https://lore.kernel.org/r/20250721-skb-metadata-thru-dynptr-v3-0-e92be5534174@cloudflare.com Changes in v3: - Add a kfunc set for skb metadata access. Limited to TC BPF. (Martin) - Drop patches related to skb metadata access outside of TC BPF: net: Clear skb metadata on handover from device to protocol selftests/bpf: Cover lack of access to skb metadata at ip layer selftests/bpf: Count successful bpf program runs - Link to v2: https://lore.kernel.org/r/20250716-skb-metadata-thru-dynptr-v2-0-5f580447e1df@cloudflare.com Changes in v2: - Switch to a dedicated dynptr type for skb metadata (Andrii) - Add verifier test coverage since we now touch its code - Add missing test coverage for bpf_dynptr_adjust and access at an offset - Link to v1: https://lore.kernel.org/r/20250630-skb-metadata-thru-dynptr-v1-0-f17da13625d8@cloudflare.com Overview -------- Today, the skb metadata is accessible only by the BPF TC ingress programs through the __sk_buff->data_meta pointer. We propose a three step plan to make skb metadata available to all other BPF programs which operate on skb objects: 1) Add a dynptr type for skb metadata (this patch set) This is a preparatory step, but it also stands on its own. Here we enable access to the skb metadata through a bpf_dynptr, the same way we can already access the skb payload today. As the next step (2), we want to relocate the metadata as skb travels through the network stack in order to persist it. That will require a safe way to access the metadata area irrespective of its location. This is where the dynptr [2] comes into play. It solves exactly that problem. A dynptr to skb metadata can be backed by a memory area that resides in a different location depending on the code path. 2) Persist skb metadata past the TC hook (future) Having the metadata in front of the packet headers as the skb travels through the network stack is problematic - see the discussion of alternative approaches below. Hence, we plan to relocate it as necessary past the TC hook. Where to relocate it? We don't know yet. There are a couple of options: (i) move it to the top of skb headroom, or (ii) allocate dedicated memory for it. They are not mutually exclusive. The right solution might be a mix. When to relocate it? That is also an open question. It could be done during device to protocol handover or lazily when headers get pushed or headroom gets resized. 3) skb dynptr for sockops, sk_lookup, etc. (future) There are BPF program types don't operate on __sk_buff context, but either have, or could have, access to the skb itself. As a final touch, we want to provide a way to create an skb metadata dynptr for these program types. TIMTOWDI -------- Alternative approaches which we considered: * Keep the metadata always in front of skb->data We think it is a bad idea for two reasons, outlined below. Nevertheless we are open to it, if necessary. 1) Performance concerns It would require the network stack to move the metadata on each header pull/push - see skb_reorder_vlan_header() [3] for an example. While doable, there is an expected performance overhead. 2) Potential for bugs In addition to updating skb_push/pull and pskp_expand_head, we would need to audit any code paths which operate on skb->data pointer directly without going through the helpers. This creates a "known unknown" risk. * Design a new custom metadata area from scratch We have tried that in Arthur's patch set [4]. One of the outcomes of the discussion there was that we don't want to have two places to store custom metadata. Hence the change of approach to make the existing custom metadata area work. -jkbs [1] https://docs.ebpf.io/linux/helper-function/bpf_xdp_adjust_meta/ [2] https://docs.ebpf.io/linux/concepts/dynptrs/ [3] https://elixir.bootlin.com/linux/v6.16-rc6/source/net/core/skbuff.c#L6211 [4] https://lore.kernel.org/all/20250422-afabre-traits-010-rfc2-v2-0-92bcc6b146c9@arthurfabre.com/ ==================== Link: https://patch.msgid.link/20250814-skb-metadata-thru-dynptr-v7-0-8a39e636e0fb@cloudflare.com Signed-off-by: Martin KaFai Lau <[email protected]>
2 parents dbe99ea + 403fae5 commit 6850a33

File tree

13 files changed

+1027
-27
lines changed

13 files changed

+1027
-27
lines changed

include/linux/bpf.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -767,12 +767,15 @@ enum bpf_type_flag {
767767
*/
768768
MEM_WRITE = BIT(18 + BPF_BASE_TYPE_BITS),
769769

770+
/* DYNPTR points to skb_metadata_end()-skb_metadata_len() */
771+
DYNPTR_TYPE_SKB_META = BIT(19 + BPF_BASE_TYPE_BITS),
772+
770773
__BPF_TYPE_FLAG_MAX,
771774
__BPF_TYPE_LAST_FLAG = __BPF_TYPE_FLAG_MAX - 1,
772775
};
773776

774777
#define DYNPTR_TYPE_FLAG_MASK (DYNPTR_TYPE_LOCAL | DYNPTR_TYPE_RINGBUF | DYNPTR_TYPE_SKB \
775-
| DYNPTR_TYPE_XDP)
778+
| DYNPTR_TYPE_XDP | DYNPTR_TYPE_SKB_META)
776779

777780
/* Max number of base types. */
778781
#define BPF_BASE_TYPE_LIMIT (1UL << BPF_BASE_TYPE_BITS)
@@ -1358,6 +1361,8 @@ enum bpf_dynptr_type {
13581361
BPF_DYNPTR_TYPE_SKB,
13591362
/* Underlying data is a xdp_buff */
13601363
BPF_DYNPTR_TYPE_XDP,
1364+
/* Points to skb_metadata_end()-skb_metadata_len() */
1365+
BPF_DYNPTR_TYPE_SKB_META,
13611366
};
13621367

13631368
int bpf_dynptr_check_size(u32 size);

include/linux/filter.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1784,6 +1784,7 @@ int __bpf_xdp_store_bytes(struct xdp_buff *xdp, u32 offset, void *buf, u32 len);
17841784
void *bpf_xdp_pointer(struct xdp_buff *xdp, u32 offset, u32 len);
17851785
void bpf_xdp_copy_buf(struct xdp_buff *xdp, unsigned long off,
17861786
void *buf, unsigned long len, bool flush);
1787+
void *bpf_skb_meta_pointer(struct sk_buff *skb, u32 offset);
17871788
#else /* CONFIG_NET */
17881789
static inline int __bpf_skb_load_bytes(const struct sk_buff *skb, u32 offset,
17891790
void *to, u32 len)
@@ -1818,6 +1819,11 @@ static inline void bpf_xdp_copy_buf(struct xdp_buff *xdp, unsigned long off, voi
18181819
unsigned long len, bool flush)
18191820
{
18201821
}
1822+
1823+
static inline void *bpf_skb_meta_pointer(struct sk_buff *skb, u32 offset)
1824+
{
1825+
return NULL;
1826+
}
18211827
#endif /* CONFIG_NET */
18221828

18231829
#endif /* __LINUX_FILTER_H__ */

kernel/bpf/helpers.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1780,6 +1780,9 @@ static int __bpf_dynptr_read(void *dst, u32 len, const struct bpf_dynptr_kern *s
17801780
return __bpf_skb_load_bytes(src->data, src->offset + offset, dst, len);
17811781
case BPF_DYNPTR_TYPE_XDP:
17821782
return __bpf_xdp_load_bytes(src->data, src->offset + offset, dst, len);
1783+
case BPF_DYNPTR_TYPE_SKB_META:
1784+
memmove(dst, bpf_skb_meta_pointer(src->data, src->offset + offset), len);
1785+
return 0;
17831786
default:
17841787
WARN_ONCE(true, "bpf_dynptr_read: unknown dynptr type %d\n", type);
17851788
return -EFAULT;
@@ -1836,6 +1839,11 @@ int __bpf_dynptr_write(const struct bpf_dynptr_kern *dst, u32 offset, void *src,
18361839
if (flags)
18371840
return -EINVAL;
18381841
return __bpf_xdp_store_bytes(dst->data, dst->offset + offset, src, len);
1842+
case BPF_DYNPTR_TYPE_SKB_META:
1843+
if (flags)
1844+
return -EINVAL;
1845+
memmove(bpf_skb_meta_pointer(dst->data, dst->offset + offset), src, len);
1846+
return 0;
18391847
default:
18401848
WARN_ONCE(true, "bpf_dynptr_write: unknown dynptr type %d\n", type);
18411849
return -EFAULT;
@@ -1882,6 +1890,7 @@ BPF_CALL_3(bpf_dynptr_data, const struct bpf_dynptr_kern *, ptr, u32, offset, u3
18821890
return (unsigned long)(ptr->data + ptr->offset + offset);
18831891
case BPF_DYNPTR_TYPE_SKB:
18841892
case BPF_DYNPTR_TYPE_XDP:
1893+
case BPF_DYNPTR_TYPE_SKB_META:
18851894
/* skb and xdp dynptrs should use bpf_dynptr_slice / bpf_dynptr_slice_rdwr */
18861895
return 0;
18871896
default:
@@ -2710,6 +2719,8 @@ __bpf_kfunc void *bpf_dynptr_slice(const struct bpf_dynptr *p, u32 offset,
27102719
bpf_xdp_copy_buf(ptr->data, ptr->offset + offset, buffer__opt, len, false);
27112720
return buffer__opt;
27122721
}
2722+
case BPF_DYNPTR_TYPE_SKB_META:
2723+
return bpf_skb_meta_pointer(ptr->data, ptr->offset + offset);
27132724
default:
27142725
WARN_ONCE(true, "unknown dynptr type %d\n", type);
27152726
return NULL;

kernel/bpf/log.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -498,6 +498,8 @@ const char *dynptr_type_str(enum bpf_dynptr_type type)
498498
return "skb";
499499
case BPF_DYNPTR_TYPE_XDP:
500500
return "xdp";
501+
case BPF_DYNPTR_TYPE_SKB_META:
502+
return "skb_meta";
501503
case BPF_DYNPTR_TYPE_INVALID:
502504
return "<invalid>";
503505
default:

kernel/bpf/verifier.c

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -674,6 +674,8 @@ static enum bpf_dynptr_type arg_to_dynptr_type(enum bpf_arg_type arg_type)
674674
return BPF_DYNPTR_TYPE_SKB;
675675
case DYNPTR_TYPE_XDP:
676676
return BPF_DYNPTR_TYPE_XDP;
677+
case DYNPTR_TYPE_SKB_META:
678+
return BPF_DYNPTR_TYPE_SKB_META;
677679
default:
678680
return BPF_DYNPTR_TYPE_INVALID;
679681
}
@@ -690,6 +692,8 @@ static enum bpf_type_flag get_dynptr_type_flag(enum bpf_dynptr_type type)
690692
return DYNPTR_TYPE_SKB;
691693
case BPF_DYNPTR_TYPE_XDP:
692694
return DYNPTR_TYPE_XDP;
695+
case BPF_DYNPTR_TYPE_SKB_META:
696+
return DYNPTR_TYPE_SKB_META;
693697
default:
694698
return 0;
695699
}
@@ -2274,7 +2278,8 @@ static bool reg_is_pkt_pointer_any(const struct bpf_reg_state *reg)
22742278
static bool reg_is_dynptr_slice_pkt(const struct bpf_reg_state *reg)
22752279
{
22762280
return base_type(reg->type) == PTR_TO_MEM &&
2277-
(reg->type & DYNPTR_TYPE_SKB || reg->type & DYNPTR_TYPE_XDP);
2281+
(reg->type &
2282+
(DYNPTR_TYPE_SKB | DYNPTR_TYPE_XDP | DYNPTR_TYPE_SKB_META));
22782283
}
22792284

22802285
/* Unmodified PTR_TO_PACKET[_META,_END] register from ctx access. */
@@ -11641,7 +11646,8 @@ static int check_helper_call(struct bpf_verifier_env *env, struct bpf_insn *insn
1164111646
if (dynptr_type == BPF_DYNPTR_TYPE_INVALID)
1164211647
return -EFAULT;
1164311648

11644-
if (dynptr_type == BPF_DYNPTR_TYPE_SKB)
11649+
if (dynptr_type == BPF_DYNPTR_TYPE_SKB ||
11650+
dynptr_type == BPF_DYNPTR_TYPE_SKB_META)
1164511651
/* this will trigger clear_all_pkt_pointers(), which will
1164611652
* invalidate all dynptr slices associated with the skb
1164711653
*/
@@ -12228,6 +12234,7 @@ enum special_kfunc_type {
1222812234
KF_bpf_rbtree_right,
1222912235
KF_bpf_dynptr_from_skb,
1223012236
KF_bpf_dynptr_from_xdp,
12237+
KF_bpf_dynptr_from_skb_meta,
1223112238
KF_bpf_dynptr_slice,
1223212239
KF_bpf_dynptr_slice_rdwr,
1223312240
KF_bpf_dynptr_clone,
@@ -12277,9 +12284,11 @@ BTF_ID(func, bpf_rbtree_right)
1227712284
#ifdef CONFIG_NET
1227812285
BTF_ID(func, bpf_dynptr_from_skb)
1227912286
BTF_ID(func, bpf_dynptr_from_xdp)
12287+
BTF_ID(func, bpf_dynptr_from_skb_meta)
1228012288
#else
1228112289
BTF_ID_UNUSED
1228212290
BTF_ID_UNUSED
12291+
BTF_ID_UNUSED
1228312292
#endif
1228412293
BTF_ID(func, bpf_dynptr_slice)
1228512294
BTF_ID(func, bpf_dynptr_slice_rdwr)
@@ -13253,6 +13262,8 @@ static int check_kfunc_args(struct bpf_verifier_env *env, struct bpf_kfunc_call_
1325313262
dynptr_arg_type |= DYNPTR_TYPE_SKB;
1325413263
} else if (meta->func_id == special_kfunc_list[KF_bpf_dynptr_from_xdp]) {
1325513264
dynptr_arg_type |= DYNPTR_TYPE_XDP;
13265+
} else if (meta->func_id == special_kfunc_list[KF_bpf_dynptr_from_skb_meta]) {
13266+
dynptr_arg_type |= DYNPTR_TYPE_SKB_META;
1325613267
} else if (meta->func_id == special_kfunc_list[KF_bpf_dynptr_clone] &&
1325713268
(dynptr_arg_type & MEM_UNINIT)) {
1325813269
enum bpf_dynptr_type parent_type = meta->initialized_dynptr.type;

net/core/filter.c

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11990,6 +11990,16 @@ bpf_sk_base_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
1199011990
return func;
1199111991
}
1199211992

11993+
/**
11994+
* bpf_skb_meta_pointer() - Gets a mutable pointer within the skb metadata area.
11995+
* @skb: socket buffer carrying the metadata
11996+
* @offset: offset into the metadata area, must be <= skb_metadata_len()
11997+
*/
11998+
void *bpf_skb_meta_pointer(struct sk_buff *skb, u32 offset)
11999+
{
12000+
return skb_metadata_end(skb) - skb_metadata_len(skb) + offset;
12001+
}
12002+
1199312003
__bpf_kfunc_start_defs();
1199412004
__bpf_kfunc int bpf_dynptr_from_skb(struct __sk_buff *s, u64 flags,
1199512005
struct bpf_dynptr *ptr__uninit)
@@ -12007,6 +12017,42 @@ __bpf_kfunc int bpf_dynptr_from_skb(struct __sk_buff *s, u64 flags,
1200712017
return 0;
1200812018
}
1200912019

12020+
/**
12021+
* bpf_dynptr_from_skb_meta() - Initialize a dynptr to the skb metadata area.
12022+
* @skb_: socket buffer carrying the metadata
12023+
* @flags: future use, must be zero
12024+
* @ptr__uninit: dynptr to initialize
12025+
*
12026+
* Set up a dynptr for access to the metadata area earlier allocated from the
12027+
* XDP context with bpf_xdp_adjust_meta(). Serves as an alternative to
12028+
* &__sk_buff->data_meta.
12029+
*
12030+
* If passed @skb_ is a clone which shares the data with the original, the
12031+
* dynptr will be read-only. This limitation may be lifted in the future.
12032+
*
12033+
* Return:
12034+
* * %0 - dynptr ready to use
12035+
* * %-EINVAL - invalid flags, dynptr set to null
12036+
*/
12037+
__bpf_kfunc int bpf_dynptr_from_skb_meta(struct __sk_buff *skb_, u64 flags,
12038+
struct bpf_dynptr *ptr__uninit)
12039+
{
12040+
struct bpf_dynptr_kern *ptr = (struct bpf_dynptr_kern *)ptr__uninit;
12041+
struct sk_buff *skb = (struct sk_buff *)skb_;
12042+
12043+
if (flags) {
12044+
bpf_dynptr_set_null(ptr);
12045+
return -EINVAL;
12046+
}
12047+
12048+
bpf_dynptr_init(ptr, skb, BPF_DYNPTR_TYPE_SKB_META, 0, skb_metadata_len(skb));
12049+
12050+
if (skb_cloned(skb))
12051+
bpf_dynptr_set_rdonly(ptr);
12052+
12053+
return 0;
12054+
}
12055+
1201012056
__bpf_kfunc int bpf_dynptr_from_xdp(struct xdp_md *x, u64 flags,
1201112057
struct bpf_dynptr *ptr__uninit)
1201212058
{
@@ -12181,6 +12227,10 @@ BTF_KFUNCS_START(bpf_kfunc_check_set_skb)
1218112227
BTF_ID_FLAGS(func, bpf_dynptr_from_skb, KF_TRUSTED_ARGS)
1218212228
BTF_KFUNCS_END(bpf_kfunc_check_set_skb)
1218312229

12230+
BTF_KFUNCS_START(bpf_kfunc_check_set_skb_meta)
12231+
BTF_ID_FLAGS(func, bpf_dynptr_from_skb_meta, KF_TRUSTED_ARGS)
12232+
BTF_KFUNCS_END(bpf_kfunc_check_set_skb_meta)
12233+
1218412234
BTF_KFUNCS_START(bpf_kfunc_check_set_xdp)
1218512235
BTF_ID_FLAGS(func, bpf_dynptr_from_xdp)
1218612236
BTF_KFUNCS_END(bpf_kfunc_check_set_xdp)
@@ -12202,6 +12252,11 @@ static const struct btf_kfunc_id_set bpf_kfunc_set_skb = {
1220212252
.set = &bpf_kfunc_check_set_skb,
1220312253
};
1220412254

12255+
static const struct btf_kfunc_id_set bpf_kfunc_set_skb_meta = {
12256+
.owner = THIS_MODULE,
12257+
.set = &bpf_kfunc_check_set_skb_meta,
12258+
};
12259+
1220512260
static const struct btf_kfunc_id_set bpf_kfunc_set_xdp = {
1220612261
.owner = THIS_MODULE,
1220712262
.set = &bpf_kfunc_check_set_xdp,
@@ -12237,6 +12292,8 @@ static int __init bpf_kfunc_init(void)
1223712292
ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_LWT_SEG6LOCAL, &bpf_kfunc_set_skb);
1223812293
ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_NETFILTER, &bpf_kfunc_set_skb);
1223912294
ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_TRACING, &bpf_kfunc_set_skb);
12295+
ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_SCHED_CLS, &bpf_kfunc_set_skb_meta);
12296+
ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_SCHED_ACT, &bpf_kfunc_set_skb_meta);
1224012297
ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_XDP, &bpf_kfunc_set_xdp);
1224112298
ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_CGROUP_SOCK_ADDR,
1224212299
&bpf_kfunc_set_sock_addr);

tools/testing/selftests/bpf/bpf_kfuncs.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ extern int bpf_dynptr_from_skb(struct __sk_buff *skb, __u64 flags,
1919
extern int bpf_dynptr_from_xdp(struct xdp_md *xdp, __u64 flags,
2020
struct bpf_dynptr *ptr__uninit) __ksym __weak;
2121

22+
extern int bpf_dynptr_from_skb_meta(struct __sk_buff *skb, __u64 flags,
23+
struct bpf_dynptr *ptr__uninit) __ksym __weak;
24+
2225
/* Description
2326
* Obtain a read-only pointer to the dynptr's data
2427
* Returns

tools/testing/selftests/bpf/config

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ CONFIG_MPLS_IPTUNNEL=y
6161
CONFIG_MPLS_ROUTING=y
6262
CONFIG_MPTCP=y
6363
CONFIG_NET_ACT_GACT=y
64+
CONFIG_NET_ACT_MIRRED=y
6465
CONFIG_NET_ACT_SKBMOD=y
6566
CONFIG_NET_CLS=y
6667
CONFIG_NET_CLS_ACT=y

tools/testing/selftests/bpf/prog_tests/dynptr.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ static struct {
3232
{"test_ringbuf", SETUP_SYSCALL_SLEEP},
3333
{"test_skb_readonly", SETUP_SKB_PROG},
3434
{"test_dynptr_skb_data", SETUP_SKB_PROG},
35+
{"test_dynptr_skb_meta_data", SETUP_SKB_PROG},
36+
{"test_dynptr_skb_meta_flags", SETUP_SKB_PROG},
3537
{"test_adjust", SETUP_SYSCALL_SLEEP},
3638
{"test_adjust_err", SETUP_SYSCALL_SLEEP},
3739
{"test_zero_size_dynptr", SETUP_SYSCALL_SLEEP},

0 commit comments

Comments
 (0)