Commit 5c42715e authored by Martin KaFai Lau's avatar Martin KaFai Lau
Browse files

Merge branch 'bpf-next/skb-meta-dynptr' into 'bpf-next/master'



Merge 'skb-meta-dynptr' branch into 'master' branch. No conflict.

Signed-off-by: default avatarMartin KaFai Lau <martin.lau@kernel.org>
parents dbe99ea5 7f7a958a
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -767,12 +767,15 @@ enum bpf_type_flag {
	 */
	MEM_WRITE		= BIT(18 + BPF_BASE_TYPE_BITS),

	/* DYNPTR points to skb_metadata_end()-skb_metadata_len() */
	DYNPTR_TYPE_SKB_META	= BIT(19 + BPF_BASE_TYPE_BITS),

	__BPF_TYPE_FLAG_MAX,
	__BPF_TYPE_LAST_FLAG	= __BPF_TYPE_FLAG_MAX - 1,
};

#define DYNPTR_TYPE_FLAG_MASK	(DYNPTR_TYPE_LOCAL | DYNPTR_TYPE_RINGBUF | DYNPTR_TYPE_SKB \
				 | DYNPTR_TYPE_XDP)
				 | DYNPTR_TYPE_XDP | DYNPTR_TYPE_SKB_META)

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

int bpf_dynptr_check_size(u32 size);
+6 −0
Original line number Diff line number Diff line
@@ -1784,6 +1784,7 @@ int __bpf_xdp_store_bytes(struct xdp_buff *xdp, u32 offset, void *buf, u32 len);
void *bpf_xdp_pointer(struct xdp_buff *xdp, u32 offset, u32 len);
void bpf_xdp_copy_buf(struct xdp_buff *xdp, unsigned long off,
		      void *buf, unsigned long len, bool flush);
void *bpf_skb_meta_pointer(struct sk_buff *skb, u32 offset);
#else /* CONFIG_NET */
static inline int __bpf_skb_load_bytes(const struct sk_buff *skb, u32 offset,
				       void *to, u32 len)
@@ -1818,6 +1819,11 @@ static inline void bpf_xdp_copy_buf(struct xdp_buff *xdp, unsigned long off, voi
				    unsigned long len, bool flush)
{
}

static inline void *bpf_skb_meta_pointer(struct sk_buff *skb, u32 offset)
{
	return NULL;
}
#endif /* CONFIG_NET */

#endif /* __LINUX_FILTER_H__ */
+11 −0
Original line number Diff line number Diff line
@@ -1780,6 +1780,9 @@ static int __bpf_dynptr_read(void *dst, u32 len, const struct bpf_dynptr_kern *s
		return __bpf_skb_load_bytes(src->data, src->offset + offset, dst, len);
	case BPF_DYNPTR_TYPE_XDP:
		return __bpf_xdp_load_bytes(src->data, src->offset + offset, dst, len);
	case BPF_DYNPTR_TYPE_SKB_META:
		memmove(dst, bpf_skb_meta_pointer(src->data, src->offset + offset), len);
		return 0;
	default:
		WARN_ONCE(true, "bpf_dynptr_read: unknown dynptr type %d\n", type);
		return -EFAULT;
@@ -1836,6 +1839,11 @@ int __bpf_dynptr_write(const struct bpf_dynptr_kern *dst, u32 offset, void *src,
		if (flags)
			return -EINVAL;
		return __bpf_xdp_store_bytes(dst->data, dst->offset + offset, src, len);
	case BPF_DYNPTR_TYPE_SKB_META:
		if (flags)
			return -EINVAL;
		memmove(bpf_skb_meta_pointer(dst->data, dst->offset + offset), src, len);
		return 0;
	default:
		WARN_ONCE(true, "bpf_dynptr_write: unknown dynptr type %d\n", type);
		return -EFAULT;
@@ -1882,6 +1890,7 @@ BPF_CALL_3(bpf_dynptr_data, const struct bpf_dynptr_kern *, ptr, u32, offset, u3
		return (unsigned long)(ptr->data + ptr->offset + offset);
	case BPF_DYNPTR_TYPE_SKB:
	case BPF_DYNPTR_TYPE_XDP:
	case BPF_DYNPTR_TYPE_SKB_META:
		/* skb and xdp dynptrs should use bpf_dynptr_slice / bpf_dynptr_slice_rdwr */
		return 0;
	default:
@@ -2710,6 +2719,8 @@ __bpf_kfunc void *bpf_dynptr_slice(const struct bpf_dynptr *p, u32 offset,
		bpf_xdp_copy_buf(ptr->data, ptr->offset + offset, buffer__opt, len, false);
		return buffer__opt;
	}
	case BPF_DYNPTR_TYPE_SKB_META:
		return bpf_skb_meta_pointer(ptr->data, ptr->offset + offset);
	default:
		WARN_ONCE(true, "unknown dynptr type %d\n", type);
		return NULL;
+2 −0
Original line number Diff line number Diff line
@@ -498,6 +498,8 @@ const char *dynptr_type_str(enum bpf_dynptr_type type)
		return "skb";
	case BPF_DYNPTR_TYPE_XDP:
		return "xdp";
	case BPF_DYNPTR_TYPE_SKB_META:
		return "skb_meta";
	case BPF_DYNPTR_TYPE_INVALID:
		return "<invalid>";
	default:
+13 −2
Original line number Diff line number Diff line
@@ -674,6 +674,8 @@ static enum bpf_dynptr_type arg_to_dynptr_type(enum bpf_arg_type arg_type)
		return BPF_DYNPTR_TYPE_SKB;
	case DYNPTR_TYPE_XDP:
		return BPF_DYNPTR_TYPE_XDP;
	case DYNPTR_TYPE_SKB_META:
		return BPF_DYNPTR_TYPE_SKB_META;
	default:
		return BPF_DYNPTR_TYPE_INVALID;
	}
@@ -690,6 +692,8 @@ static enum bpf_type_flag get_dynptr_type_flag(enum bpf_dynptr_type type)
		return DYNPTR_TYPE_SKB;
	case BPF_DYNPTR_TYPE_XDP:
		return DYNPTR_TYPE_XDP;
	case BPF_DYNPTR_TYPE_SKB_META:
		return DYNPTR_TYPE_SKB_META;
	default:
		return 0;
	}
@@ -2274,7 +2278,8 @@ static bool reg_is_pkt_pointer_any(const struct bpf_reg_state *reg)
static bool reg_is_dynptr_slice_pkt(const struct bpf_reg_state *reg)
{
	return base_type(reg->type) == PTR_TO_MEM &&
		(reg->type & DYNPTR_TYPE_SKB || reg->type & DYNPTR_TYPE_XDP);
	       (reg->type &
		(DYNPTR_TYPE_SKB | DYNPTR_TYPE_XDP | DYNPTR_TYPE_SKB_META));
}
/* 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
		if (dynptr_type == BPF_DYNPTR_TYPE_INVALID)
			return -EFAULT;
		if (dynptr_type == BPF_DYNPTR_TYPE_SKB)
		if (dynptr_type == BPF_DYNPTR_TYPE_SKB ||
		    dynptr_type == BPF_DYNPTR_TYPE_SKB_META)
			/* this will trigger clear_all_pkt_pointers(), which will
			 * invalidate all dynptr slices associated with the skb
			 */
@@ -12228,6 +12234,7 @@ enum special_kfunc_type {
	KF_bpf_rbtree_right,
	KF_bpf_dynptr_from_skb,
	KF_bpf_dynptr_from_xdp,
	KF_bpf_dynptr_from_skb_meta,
	KF_bpf_dynptr_slice,
	KF_bpf_dynptr_slice_rdwr,
	KF_bpf_dynptr_clone,
@@ -12277,9 +12284,11 @@ BTF_ID(func, bpf_rbtree_right)
#ifdef CONFIG_NET
BTF_ID(func, bpf_dynptr_from_skb)
BTF_ID(func, bpf_dynptr_from_xdp)
BTF_ID(func, bpf_dynptr_from_skb_meta)
#else
BTF_ID_UNUSED
BTF_ID_UNUSED
BTF_ID_UNUSED
#endif
BTF_ID(func, bpf_dynptr_slice)
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_
				dynptr_arg_type |= DYNPTR_TYPE_SKB;
			} else if (meta->func_id == special_kfunc_list[KF_bpf_dynptr_from_xdp]) {
				dynptr_arg_type |= DYNPTR_TYPE_XDP;
			} else if (meta->func_id == special_kfunc_list[KF_bpf_dynptr_from_skb_meta]) {
				dynptr_arg_type |= DYNPTR_TYPE_SKB_META;
			} else if (meta->func_id == special_kfunc_list[KF_bpf_dynptr_clone] &&
				   (dynptr_arg_type & MEM_UNINIT)) {
				enum bpf_dynptr_type parent_type = meta->initialized_dynptr.type;
Loading