On 07/19, Larysa Zaremba wrote: > Implement functionality that enables drivers to expose VLAN tag > to XDP code. > > Signed-off-by: Larysa Zaremba <larysa.zaremba@xxxxxxxxx> Acked-by: Stanislav Fomichev <sdf@xxxxxxxxxx> Thank you for a super detailed kfunc kdoc! > --- > Documentation/networking/xdp-rx-metadata.rst | 8 ++++- > include/linux/netdevice.h | 2 ++ > include/net/xdp.h | 2 ++ > kernel/bpf/offload.c | 2 ++ > net/core/xdp.c | 34 ++++++++++++++++++++ > 5 files changed, 47 insertions(+), 1 deletion(-) > > diff --git a/Documentation/networking/xdp-rx-metadata.rst b/Documentation/networking/xdp-rx-metadata.rst > index 25ce72af81c2..ea6dd79a21d3 100644 > --- a/Documentation/networking/xdp-rx-metadata.rst > +++ b/Documentation/networking/xdp-rx-metadata.rst > @@ -18,7 +18,13 @@ Currently, the following kfuncs are supported. In the future, as more > metadata is supported, this set will grow: > > .. kernel-doc:: net/core/xdp.c > - :identifiers: bpf_xdp_metadata_rx_timestamp bpf_xdp_metadata_rx_hash > + :identifiers: bpf_xdp_metadata_rx_timestamp > + > +.. kernel-doc:: net/core/xdp.c > + :identifiers: bpf_xdp_metadata_rx_hash > + > +.. kernel-doc:: net/core/xdp.c > + :identifiers: bpf_xdp_metadata_rx_vlan_tag > > An XDP program can use these kfuncs to read the metadata into stack > variables for its own consumption. Or, to pass the metadata on to other > diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h > index b828c7a75be2..1749f4f75c64 100644 > --- a/include/linux/netdevice.h > +++ b/include/linux/netdevice.h > @@ -1658,6 +1658,8 @@ struct xdp_metadata_ops { > int (*xmo_rx_timestamp)(const struct xdp_md *ctx, u64 *timestamp); > int (*xmo_rx_hash)(const struct xdp_md *ctx, u32 *hash, > enum xdp_rss_hash_type *rss_type); > + int (*xmo_rx_vlan_tag)(const struct xdp_md *ctx, u16 *vlan_tci, > + __be16 *vlan_proto); > }; > > /** > diff --git a/include/net/xdp.h b/include/net/xdp.h > index 6381560efae2..89c58f56ffc6 100644 > --- a/include/net/xdp.h > +++ b/include/net/xdp.h > @@ -389,6 +389,8 @@ void xdp_attachment_setup(struct xdp_attachment_info *info, > bpf_xdp_metadata_rx_timestamp) \ > XDP_METADATA_KFUNC(XDP_METADATA_KFUNC_RX_HASH, \ > bpf_xdp_metadata_rx_hash) \ > + XDP_METADATA_KFUNC(XDP_METADATA_KFUNC_RX_VLAN_TAG, \ > + bpf_xdp_metadata_rx_vlan_tag) \ > > enum { > #define XDP_METADATA_KFUNC(name, _) name, > diff --git a/kernel/bpf/offload.c b/kernel/bpf/offload.c > index 8a26cd8814c1..986e7becfd42 100644 > --- a/kernel/bpf/offload.c > +++ b/kernel/bpf/offload.c > @@ -848,6 +848,8 @@ void *bpf_dev_bound_resolve_kfunc(struct bpf_prog *prog, u32 func_id) > p = ops->xmo_rx_timestamp; > else if (func_id == bpf_xdp_metadata_kfunc_id(XDP_METADATA_KFUNC_RX_HASH)) > p = ops->xmo_rx_hash; > + else if (func_id == bpf_xdp_metadata_kfunc_id(XDP_METADATA_KFUNC_RX_VLAN_TAG)) > + p = ops->xmo_rx_vlan_tag; > out: > up_read(&bpf_devs_lock); > > diff --git a/net/core/xdp.c b/net/core/xdp.c > index 8362130bf085..8b55419d332e 100644 > --- a/net/core/xdp.c > +++ b/net/core/xdp.c > @@ -738,6 +738,40 @@ __bpf_kfunc int bpf_xdp_metadata_rx_hash(const struct xdp_md *ctx, u32 *hash, > return -EOPNOTSUPP; > } > > +/** > + * bpf_xdp_metadata_rx_vlan_tag - Get XDP packet outermost VLAN tag > + * @ctx: XDP context pointer. > + * @vlan_tci: Destination pointer for VLAN TCI (VID + DEI + PCP) > + * @vlan_proto: Destination pointer for VLAN Tag protocol identifier (TPID). > + * > + * In case of success, ``vlan_proto`` contains *Tag protocol identifier (TPID)*, > + * usually ``ETH_P_8021Q`` or ``ETH_P_8021AD``, but some networks can use > + * custom TPIDs. ``vlan_proto`` is stored in **network byte order (BE)** > + * and should be used as follows: > + * ``if (vlan_proto == bpf_htons(ETH_P_8021Q)) do_something();`` > + * > + * ``vlan_tci`` contains the remaining 16 bits of a VLAN tag. > + * Driver is expected to provide those in **host byte order (usually LE)**, > + * so the bpf program should not perform byte conversion. > + * According to 802.1Q standard, *VLAN TCI (Tag control information)* > + * is a bit field that contains: > + * *VLAN identifier (VID)* that can be read with ``vlan_tci & 0xfff``, > + * *Drop eligible indicator (DEI)* - 1 bit, > + * *Priority code point (PCP)* - 3 bits. > + * For detailed meaning of DEI and PCP, please refer to other sources. > + * > + * Return: > + * * Returns 0 on success or ``-errno`` on error. > + * * ``-EOPNOTSUPP`` : device driver doesn't implement kfunc > + * * ``-ENODATA`` : VLAN tag was not stripped or is not available > + */ > +__bpf_kfunc int bpf_xdp_metadata_rx_vlan_tag(const struct xdp_md *ctx, > + u16 *vlan_tci, > + __be16 *vlan_proto) > +{ > + return -EOPNOTSUPP; > +} > + > __diag_pop(); > > BTF_SET8_START(xdp_metadata_kfunc_ids) > -- > 2.41.0 >