···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);17831783+ case BPF_DYNPTR_TYPE_SKB_META:17841784+ memmove(dst, bpf_skb_meta_pointer(src->data, src->offset + offset), len);17851785+ return 0;17831786 default:17841787 WARN_ONCE(true, "bpf_dynptr_read: unknown dynptr type %d\n", type);17851788 return -EFAULT;···18391836 if (flags)18401837 return -EINVAL;18411838 return __bpf_xdp_store_bytes(dst->data, dst->offset + offset, src, len);18391839+ case BPF_DYNPTR_TYPE_SKB_META:18401840+ if (flags)18411841+ return -EINVAL;18421842+ memmove(bpf_skb_meta_pointer(dst->data, dst->offset + offset), src, len);18431843+ return 0;18421844 default:18431845 WARN_ONCE(true, "bpf_dynptr_write: unknown dynptr type %d\n", type);18441846 return -EFAULT;···18901882 return (unsigned long)(ptr->data + ptr->offset + offset);18911883 case BPF_DYNPTR_TYPE_SKB:18921884 case BPF_DYNPTR_TYPE_XDP:18851885+ case BPF_DYNPTR_TYPE_SKB_META:18931886 /* skb and xdp dynptrs should use bpf_dynptr_slice / bpf_dynptr_slice_rdwr */18941887 return 0;18951888 default:···27192710 bpf_xdp_copy_buf(ptr->data, ptr->offset + offset, buffer__opt, len, false);27202711 return buffer__opt;27212712 }27132713+ case BPF_DYNPTR_TYPE_SKB_META:27142714+ return bpf_skb_meta_pointer(ptr->data, ptr->offset + offset);27222715 default:27232716 WARN_ONCE(true, "unknown dynptr type %d\n", type);27242717 return NULL;
+2
kernel/bpf/log.c
···498498 return "skb";499499 case BPF_DYNPTR_TYPE_XDP:500500 return "xdp";501501+ case BPF_DYNPTR_TYPE_SKB_META:502502+ return "skb_meta";501503 case BPF_DYNPTR_TYPE_INVALID:502504 return "<invalid>";503505 default:
+13-2
kernel/bpf/verifier.c
···674674 return BPF_DYNPTR_TYPE_SKB;675675 case DYNPTR_TYPE_XDP:676676 return BPF_DYNPTR_TYPE_XDP;677677+ case DYNPTR_TYPE_SKB_META:678678+ return BPF_DYNPTR_TYPE_SKB_META;677679 default:678680 return BPF_DYNPTR_TYPE_INVALID;679681 }···692690 return DYNPTR_TYPE_SKB;693691 case BPF_DYNPTR_TYPE_XDP:694692 return DYNPTR_TYPE_XDP;693693+ case BPF_DYNPTR_TYPE_SKB_META:694694+ return DYNPTR_TYPE_SKB_META;695695 default:696696 return 0;697697 }···22782274static bool reg_is_dynptr_slice_pkt(const struct bpf_reg_state *reg)22792275{22802276 return base_type(reg->type) == PTR_TO_MEM &&22812281- (reg->type & DYNPTR_TYPE_SKB || reg->type & DYNPTR_TYPE_XDP);22772277+ (reg->type &22782278+ (DYNPTR_TYPE_SKB | DYNPTR_TYPE_XDP | DYNPTR_TYPE_SKB_META));22822279}2283228022842281/* Unmodified PTR_TO_PACKET[_META,_END] register from ctx access. */···1164611641 if (dynptr_type == BPF_DYNPTR_TYPE_INVALID)1164711642 return -EFAULT;11648116431164911649- if (dynptr_type == BPF_DYNPTR_TYPE_SKB)1164411644+ if (dynptr_type == BPF_DYNPTR_TYPE_SKB ||1164511645+ dynptr_type == BPF_DYNPTR_TYPE_SKB_META)1165011646 /* this will trigger clear_all_pkt_pointers(), which will1165111647 * invalidate all dynptr slices associated with the skb1165211648 */···1223412228 KF_bpf_rbtree_right,1223512229 KF_bpf_dynptr_from_skb,1223612230 KF_bpf_dynptr_from_xdp,1223112231+ KF_bpf_dynptr_from_skb_meta,1223712232 KF_bpf_dynptr_slice,1223812233 KF_bpf_dynptr_slice_rdwr,1223912234 KF_bpf_dynptr_clone,···1228412277#ifdef CONFIG_NET1228512278BTF_ID(func, bpf_dynptr_from_skb)1228612279BTF_ID(func, bpf_dynptr_from_xdp)1228012280+BTF_ID(func, bpf_dynptr_from_skb_meta)1228712281#else1228212282+BTF_ID_UNUSED1228812283BTF_ID_UNUSED1228912284BTF_ID_UNUSED1229012285#endif···1326213253 dynptr_arg_type |= DYNPTR_TYPE_SKB;1326313254 } else if (meta->func_id == special_kfunc_list[KF_bpf_dynptr_from_xdp]) {1326413255 dynptr_arg_type |= DYNPTR_TYPE_XDP;1325613256+ } else if (meta->func_id == special_kfunc_list[KF_bpf_dynptr_from_skb_meta]) {1325713257+ dynptr_arg_type |= DYNPTR_TYPE_SKB_META;1326513258 } else if (meta->func_id == special_kfunc_list[KF_bpf_dynptr_clone] &&1326613259 (dynptr_arg_type & MEM_UNINIT)) {1326713260 enum bpf_dynptr_type parent_type = meta->initialized_dynptr.type;
+57
net/core/filter.c
···1199011990 return func;1199111991}11992119921199311993+/**1199411994+ * bpf_skb_meta_pointer() - Gets a mutable pointer within the skb metadata area.1199511995+ * @skb: socket buffer carrying the metadata1199611996+ * @offset: offset into the metadata area, must be <= skb_metadata_len()1199711997+ */1199811998+void *bpf_skb_meta_pointer(struct sk_buff *skb, u32 offset)1199911999+{1200012000+ return skb_metadata_end(skb) - skb_metadata_len(skb) + offset;1200112001+}1200212002+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)···1201312003 }12014120041201512005 bpf_dynptr_init(ptr, skb, BPF_DYNPTR_TYPE_SKB, 0, skb->len);1200612006+1200712007+ return 0;1200812008+}1200912009+1201012010+/**1201112011+ * bpf_dynptr_from_skb_meta() - Initialize a dynptr to the skb metadata area.1201212012+ * @skb_: socket buffer carrying the metadata1201312013+ * @flags: future use, must be zero1201412014+ * @ptr__uninit: dynptr to initialize1201512015+ *1201612016+ * Set up a dynptr for access to the metadata area earlier allocated from the1201712017+ * XDP context with bpf_xdp_adjust_meta(). Serves as an alternative to1201812018+ * &__sk_buff->data_meta.1201912019+ *1202012020+ * If passed @skb_ is a clone which shares the data with the original, the1202112021+ * dynptr will be read-only. This limitation may be lifted in the future.1202212022+ *1202312023+ * Return:1202412024+ * * %0 - dynptr ready to use1202512025+ * * %-EINVAL - invalid flags, dynptr set to null1202612026+ */1202712027+__bpf_kfunc int bpf_dynptr_from_skb_meta(struct __sk_buff *skb_, u64 flags,1202812028+ struct bpf_dynptr *ptr__uninit)1202912029+{1203012030+ struct bpf_dynptr_kern *ptr = (struct bpf_dynptr_kern *)ptr__uninit;1203112031+ struct sk_buff *skb = (struct sk_buff *)skb_;1203212032+1203312033+ if (flags) {1203412034+ bpf_dynptr_set_null(ptr);1203512035+ return -EINVAL;1203612036+ }1203712037+1203812038+ bpf_dynptr_init(ptr, skb, BPF_DYNPTR_TYPE_SKB_META, 0, skb_metadata_len(skb));1203912039+1204012040+ if (skb_cloned(skb))1204112041+ bpf_dynptr_set_rdonly(ptr);12016120421201712043 return 0;1201812044}···1222712181BTF_ID_FLAGS(func, bpf_dynptr_from_skb, KF_TRUSTED_ARGS)1222812182BTF_KFUNCS_END(bpf_kfunc_check_set_skb)12229121831218412184+BTF_KFUNCS_START(bpf_kfunc_check_set_skb_meta)1218512185+BTF_ID_FLAGS(func, bpf_dynptr_from_skb_meta, KF_TRUSTED_ARGS)1218612186+BTF_KFUNCS_END(bpf_kfunc_check_set_skb_meta)1218712187+1223012188BTF_KFUNCS_START(bpf_kfunc_check_set_xdp)1223112189BTF_ID_FLAGS(func, bpf_dynptr_from_xdp)1223212190BTF_KFUNCS_END(bpf_kfunc_check_set_xdp)···1225012200static const struct btf_kfunc_id_set bpf_kfunc_set_skb = {1225112201 .owner = THIS_MODULE,1225212202 .set = &bpf_kfunc_check_set_skb,1220312203+};1220412204+1220512205+static const struct btf_kfunc_id_set bpf_kfunc_set_skb_meta = {1220612206+ .owner = THIS_MODULE,1220712207+ .set = &bpf_kfunc_check_set_skb_meta,1225312208};12254122091225512210static const struct btf_kfunc_id_set bpf_kfunc_set_xdp = {···1229212237 ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_LWT_SEG6LOCAL, &bpf_kfunc_set_skb);1229312238 ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_NETFILTER, &bpf_kfunc_set_skb);1229412239 ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_TRACING, &bpf_kfunc_set_skb);1224012240+ ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_SCHED_CLS, &bpf_kfunc_set_skb_meta);1224112241+ ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_SCHED_ACT, &bpf_kfunc_set_skb_meta);1229512242 ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_XDP, &bpf_kfunc_set_xdp);1229612243 ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_CGROUP_SOCK_ADDR,1229712244 &bpf_kfunc_set_sock_addr);
+3
tools/testing/selftests/bpf/bpf_kfuncs.h
···1919extern int bpf_dynptr_from_xdp(struct xdp_md *xdp, __u64 flags,2020 struct bpf_dynptr *ptr__uninit) __ksym __weak;21212222+extern int bpf_dynptr_from_skb_meta(struct __sk_buff *skb, __u64 flags,2323+ struct bpf_dynptr *ptr__uninit) __ksym __weak;2424+2225/* Description2326 * Obtain a read-only pointer to the dynptr's data2427 * Returns