xdp: Add VLAN tag hint

Implement functionality that enables drivers to expose VLAN tag
to XDP code.

VLAN tag is represented by 2 variables:
- protocol ID, which is passed to bpf code in BE
- VLAN TCI, in host byte order

Acked-by: Stanislav Fomichev <sdf@google.com>
Signed-off-by: Larysa Zaremba <larysa.zaremba@intel.com>
Acked-by: Jesper Dangaard Brouer <hawk@kernel.org>
Link: https://lore.kernel.org/r/20231205210847.28460-10-larysa.zaremba@intel.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
Larysa Zaremba 2023-12-05 22:08:38 +01:00 committed by Alexei Starovoitov
parent d68d707dcb
commit e6795330f8
7 changed files with 57 additions and 1 deletions

View File

@ -54,6 +54,10 @@ definitions:
name: hash name: hash
doc: doc:
Device is capable of exposing receive packet hash via bpf_xdp_metadata_rx_hash(). Device is capable of exposing receive packet hash via bpf_xdp_metadata_rx_hash().
-
name: vlan-tag
doc:
Device is capable of exposing receive packet VLAN tag via bpf_xdp_metadata_rx_vlan_tag().
- -
type: flags type: flags
name: xsk-flags name: xsk-flags

View File

@ -20,7 +20,13 @@ Currently, the following kfuncs are supported. In the future, as more
metadata is supported, this set will grow: metadata is supported, this set will grow:
.. kernel-doc:: net/core/xdp.c .. 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 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 variables for its own consumption. Or, to pass the metadata on to other

View File

@ -404,6 +404,10 @@ void xdp_attachment_setup(struct xdp_attachment_info *info,
NETDEV_XDP_RX_METADATA_HASH, \ NETDEV_XDP_RX_METADATA_HASH, \
bpf_xdp_metadata_rx_hash, \ bpf_xdp_metadata_rx_hash, \
xmo_rx_hash) \ xmo_rx_hash) \
XDP_METADATA_KFUNC(XDP_METADATA_KFUNC_RX_VLAN_TAG, \
NETDEV_XDP_RX_METADATA_VLAN_TAG, \
bpf_xdp_metadata_rx_vlan_tag, \
xmo_rx_vlan_tag) \
enum xdp_rx_metadata { enum xdp_rx_metadata {
#define XDP_METADATA_KFUNC(name, _, __, ___) name, #define XDP_METADATA_KFUNC(name, _, __, ___) name,
@ -465,6 +469,8 @@ struct xdp_metadata_ops {
int (*xmo_rx_timestamp)(const struct xdp_md *ctx, u64 *timestamp); int (*xmo_rx_timestamp)(const struct xdp_md *ctx, u64 *timestamp);
int (*xmo_rx_hash)(const struct xdp_md *ctx, u32 *hash, int (*xmo_rx_hash)(const struct xdp_md *ctx, u32 *hash,
enum xdp_rss_hash_type *rss_type); enum xdp_rss_hash_type *rss_type);
int (*xmo_rx_vlan_tag)(const struct xdp_md *ctx, __be16 *vlan_proto,
u16 *vlan_tci);
}; };
#ifdef CONFIG_NET #ifdef CONFIG_NET

View File

@ -44,10 +44,13 @@ enum netdev_xdp_act {
* timestamp via bpf_xdp_metadata_rx_timestamp(). * timestamp via bpf_xdp_metadata_rx_timestamp().
* @NETDEV_XDP_RX_METADATA_HASH: Device is capable of exposing receive packet * @NETDEV_XDP_RX_METADATA_HASH: Device is capable of exposing receive packet
* hash via bpf_xdp_metadata_rx_hash(). * hash via bpf_xdp_metadata_rx_hash().
* @NETDEV_XDP_RX_METADATA_VLAN_TAG: Device is capable of exposing receive
* packet VLAN tag via bpf_xdp_metadata_rx_vlan_tag().
*/ */
enum netdev_xdp_rx_metadata { enum netdev_xdp_rx_metadata {
NETDEV_XDP_RX_METADATA_TIMESTAMP = 1, NETDEV_XDP_RX_METADATA_TIMESTAMP = 1,
NETDEV_XDP_RX_METADATA_HASH = 2, NETDEV_XDP_RX_METADATA_HASH = 2,
NETDEV_XDP_RX_METADATA_VLAN_TAG = 4,
}; };
/** /**

View File

@ -736,6 +736,39 @@ __bpf_kfunc int bpf_xdp_metadata_rx_hash(const struct xdp_md *ctx, u32 *hash,
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
/**
* bpf_xdp_metadata_rx_vlan_tag - Get XDP packet outermost VLAN tag
* @ctx: XDP context pointer.
* @vlan_proto: Destination pointer for VLAN Tag protocol identifier (TPID).
* @vlan_tci: Destination pointer for VLAN TCI (VID + DEI + PCP)
*
* 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,
__be16 *vlan_proto, u16 *vlan_tci)
{
return -EOPNOTSUPP;
}
__bpf_kfunc_end_defs(); __bpf_kfunc_end_defs();
BTF_SET8_START(xdp_metadata_kfunc_ids) BTF_SET8_START(xdp_metadata_kfunc_ids)

View File

@ -44,10 +44,13 @@ enum netdev_xdp_act {
* timestamp via bpf_xdp_metadata_rx_timestamp(). * timestamp via bpf_xdp_metadata_rx_timestamp().
* @NETDEV_XDP_RX_METADATA_HASH: Device is capable of exposing receive packet * @NETDEV_XDP_RX_METADATA_HASH: Device is capable of exposing receive packet
* hash via bpf_xdp_metadata_rx_hash(). * hash via bpf_xdp_metadata_rx_hash().
* @NETDEV_XDP_RX_METADATA_VLAN_TAG: Device is capable of exposing receive
* packet VLAN tag via bpf_xdp_metadata_rx_vlan_tag().
*/ */
enum netdev_xdp_rx_metadata { enum netdev_xdp_rx_metadata {
NETDEV_XDP_RX_METADATA_TIMESTAMP = 1, NETDEV_XDP_RX_METADATA_TIMESTAMP = 1,
NETDEV_XDP_RX_METADATA_HASH = 2, NETDEV_XDP_RX_METADATA_HASH = 2,
NETDEV_XDP_RX_METADATA_VLAN_TAG = 4,
}; };
/** /**

View File

@ -53,6 +53,7 @@ const char *netdev_xdp_act_str(enum netdev_xdp_act value)
static const char * const netdev_xdp_rx_metadata_strmap[] = { static const char * const netdev_xdp_rx_metadata_strmap[] = {
[0] = "timestamp", [0] = "timestamp",
[1] = "hash", [1] = "hash",
[2] = "vlan-tag",
}; };
const char *netdev_xdp_rx_metadata_str(enum netdev_xdp_rx_metadata value) const char *netdev_xdp_rx_metadata_str(enum netdev_xdp_rx_metadata value)