xdp: Add VLAN tag hint
authorLarysa Zaremba <larysa.zaremba@intel.com>
Tue, 5 Dec 2023 21:08:38 +0000 (22:08 +0100)
committerAlexei Starovoitov <ast@kernel.org>
Thu, 14 Dec 2023 00:16:40 +0000 (16:16 -0800)
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>
Documentation/netlink/specs/netdev.yaml
Documentation/networking/xdp-rx-metadata.rst
include/net/xdp.h
include/uapi/linux/netdev.h
net/core/xdp.c
tools/include/uapi/linux/netdev.h
tools/net/ynl/generated/netdev-user.c

index eef6358ec587da04f3195e550e853fc712f29b5a..aeec090e1387c4f0cba8d40efb44c54c03768273 100644 (file)
@@ -54,6 +54,10 @@ definitions:
         name: hash
         doc:
           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
     name: xsk-flags
index e3e9420fd817421fa6db8eac04e20ab8c6e819e8..a6e0ece18be54b4e6cd6fdd00878185877b66904 100644 (file)
@@ -20,7 +20,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
index b7d6fe61381f7ac47e47ca2126c9edb2fdcb2ae0..8cd04a74dba509db5bede3646716a36d1080deaa 100644 (file)
@@ -404,6 +404,10 @@ void xdp_attachment_setup(struct xdp_attachment_info *info,
                           NETDEV_XDP_RX_METADATA_HASH, \
                           bpf_xdp_metadata_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 {
 #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_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, __be16 *vlan_proto,
+                                  u16 *vlan_tci);
 };
 
 #ifdef CONFIG_NET
index 6244c0164976a28f7e31577a54d97aebaaf45c30..966638b08ccfe1c3fb4f82a32705c5f0450350d6 100644 (file)
@@ -44,10 +44,13 @@ enum netdev_xdp_act {
  *   timestamp via bpf_xdp_metadata_rx_timestamp().
  * @NETDEV_XDP_RX_METADATA_HASH: Device is capable of exposing receive packet
  *   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 {
        NETDEV_XDP_RX_METADATA_TIMESTAMP = 1,
        NETDEV_XDP_RX_METADATA_HASH = 2,
+       NETDEV_XDP_RX_METADATA_VLAN_TAG = 4,
 };
 
 /**
index b6f1d6dab3f2e3c2e8515ad1293fb284cfc42218..4869c1c2d8f3d9ca7e33a1d7d56f450a49f37096 100644 (file)
@@ -736,6 +736,39 @@ __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_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();
 
 BTF_SET8_START(xdp_metadata_kfunc_ids)
index 6244c0164976a28f7e31577a54d97aebaaf45c30..966638b08ccfe1c3fb4f82a32705c5f0450350d6 100644 (file)
@@ -44,10 +44,13 @@ enum netdev_xdp_act {
  *   timestamp via bpf_xdp_metadata_rx_timestamp().
  * @NETDEV_XDP_RX_METADATA_HASH: Device is capable of exposing receive packet
  *   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 {
        NETDEV_XDP_RX_METADATA_TIMESTAMP = 1,
        NETDEV_XDP_RX_METADATA_HASH = 2,
+       NETDEV_XDP_RX_METADATA_VLAN_TAG = 4,
 };
 
 /**
index 3b9dee94d4ce48d4d76d70d9f94e2cdab9a6d092..e3fe748086bd50f7785d573dad3a538fbbf6a428 100644 (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[] = {
        [0] = "timestamp",
        [1] = "hash",
+       [2] = "vlan-tag",
 };
 
 const char *netdev_xdp_rx_metadata_str(enum netdev_xdp_rx_metadata value)