Skip to content

Commit 2a3757c

Browse files
committed
Merge: CNB95: xdp: Add VLAN tag hint
MR: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-9/-/merge_requests/4222 JIRA: https://issues.redhat.com/browse/RHEL-31890 Depends: !4111 Signed-off-by: Petr Oros <poros@redhat.com> Approved-by: Ivan Vecera <ivecera@redhat.com> Approved-by: Toke Høiland-Jørgensen <toke@redhat.com> Approved-by: CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com> Merged-by: Lucas Zampieri <lzampier@redhat.com>
2 parents c7c3dea + fab17b9 commit 2a3757c

File tree

19 files changed

+323
-44
lines changed

19 files changed

+323
-44
lines changed

Documentation/netlink/specs/netdev.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@ definitions:
5454
name: hash
5555
doc:
5656
Device is capable of exposing receive packet hash via bpf_xdp_metadata_rx_hash().
57+
-
58+
name: vlan-tag
59+
doc:
60+
Device is capable of exposing receive packet VLAN tag via bpf_xdp_metadata_rx_vlan_tag().
5761
-
5862
type: flags
5963
name: xsk-flags

Documentation/networking/xdp-rx-metadata.rst

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,13 @@ Currently, the following kfuncs are supported. In the future, as more
2020
metadata is supported, this set will grow:
2121

2222
.. kernel-doc:: net/core/xdp.c
23-
:identifiers: bpf_xdp_metadata_rx_timestamp bpf_xdp_metadata_rx_hash
23+
:identifiers: bpf_xdp_metadata_rx_timestamp
24+
25+
.. kernel-doc:: net/core/xdp.c
26+
:identifiers: bpf_xdp_metadata_rx_hash
27+
28+
.. kernel-doc:: net/core/xdp.c
29+
:identifiers: bpf_xdp_metadata_rx_vlan_tag
2430

2531
An XDP program can use these kfuncs to read the metadata into stack
2632
variables for its own consumption. Or, to pass the metadata on to other

drivers/net/veth.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1666,6 +1666,24 @@ static int veth_xdp_rx_hash(const struct xdp_md *ctx, u32 *hash,
16661666
return 0;
16671667
}
16681668

1669+
static int veth_xdp_rx_vlan_tag(const struct xdp_md *ctx, __be16 *vlan_proto,
1670+
u16 *vlan_tci)
1671+
{
1672+
const struct veth_xdp_buff *_ctx = (void *)ctx;
1673+
const struct sk_buff *skb = _ctx->skb;
1674+
int err;
1675+
1676+
if (!skb)
1677+
return -ENODATA;
1678+
1679+
err = __vlan_hwaccel_get_tag(skb, vlan_tci);
1680+
if (err)
1681+
return err;
1682+
1683+
*vlan_proto = skb->vlan_proto;
1684+
return err;
1685+
}
1686+
16691687
static const struct net_device_ops veth_netdev_ops = {
16701688
.ndo_init = veth_dev_init,
16711689
.ndo_open = veth_open,
@@ -1690,6 +1708,7 @@ static const struct net_device_ops veth_netdev_ops = {
16901708
static const struct xdp_metadata_ops veth_xdp_metadata_ops = {
16911709
.xmo_rx_timestamp = veth_xdp_rx_timestamp,
16921710
.xmo_rx_hash = veth_xdp_rx_hash,
1711+
.xmo_rx_vlan_tag = veth_xdp_rx_vlan_tag,
16931712
};
16941713

16951714
#define VETH_FEATURES (NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HW_CSUM | \

include/linux/if_vlan.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -543,7 +543,7 @@ static inline int __vlan_get_tag(const struct sk_buff *skb, u16 *vlan_tci)
543543
struct vlan_ethhdr *veth = skb_vlan_eth_hdr(skb);
544544

545545
if (!eth_type_vlan(veth->h_vlan_proto))
546-
return -EINVAL;
546+
return -ENODATA;
547547

548548
*vlan_tci = ntohs(veth->h_vlan_TCI);
549549
return 0;
@@ -564,7 +564,7 @@ static inline int __vlan_hwaccel_get_tag(const struct sk_buff *skb,
564564
return 0;
565565
} else {
566566
*vlan_tci = 0;
567-
return -EINVAL;
567+
return -ENODATA;
568568
}
569569
}
570570

include/linux/netdevice.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1608,6 +1608,8 @@ struct xdp_metadata_ops {
16081608
int (*xmo_rx_timestamp)(const struct xdp_md *ctx, u64 *timestamp);
16091609
int (*xmo_rx_hash)(const struct xdp_md *ctx, u32 *hash,
16101610
enum xdp_rss_hash_type *rss_type);
1611+
int (*xmo_rx_vlan_tag)(const struct xdp_md *ctx, __be16 *vlan_proto,
1612+
u16 *vlan_tci);
16111613
};
16121614

16131615
/**

include/net/xdp.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,10 @@ void xdp_attachment_setup(struct xdp_attachment_info *info,
406406
NETDEV_XDP_RX_METADATA_HASH, \
407407
bpf_xdp_metadata_rx_hash, \
408408
xmo_rx_hash) \
409+
XDP_METADATA_KFUNC(XDP_METADATA_KFUNC_RX_VLAN_TAG, \
410+
NETDEV_XDP_RX_METADATA_VLAN_TAG, \
411+
bpf_xdp_metadata_rx_vlan_tag, \
412+
xmo_rx_vlan_tag) \
409413

410414
enum xdp_rx_metadata {
411415
#define XDP_METADATA_KFUNC(name, _, __, ___) name,

include/net/xdp_sock_drv.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,12 @@
1414

1515
#ifdef CONFIG_XDP_SOCKETS
1616

17+
struct xsk_cb_desc {
18+
void *src;
19+
u8 off;
20+
u8 bytes;
21+
};
22+
1723
void xsk_tx_completed(struct xsk_buff_pool *pool, u32 nb_entries);
1824
bool xsk_tx_peek_desc(struct xsk_buff_pool *pool, struct xdp_desc *desc);
1925
u32 xsk_tx_peek_release_desc_batch(struct xsk_buff_pool *pool, u32 max);
@@ -47,6 +53,12 @@ static inline void xsk_pool_set_rxq_info(struct xsk_buff_pool *pool,
4753
xp_set_rxq_info(pool, rxq);
4854
}
4955

56+
static inline void xsk_pool_fill_cb(struct xsk_buff_pool *pool,
57+
struct xsk_cb_desc *desc)
58+
{
59+
xp_fill_cb(pool, desc);
60+
}
61+
5062
static inline unsigned int xsk_pool_get_napi_id(struct xsk_buff_pool *pool)
5163
{
5264
#ifdef CONFIG_NET_RX_BUSY_POLL
@@ -292,6 +304,11 @@ static inline void xsk_pool_set_rxq_info(struct xsk_buff_pool *pool,
292304
{
293305
}
294306

307+
static inline void xsk_pool_fill_cb(struct xsk_buff_pool *pool,
308+
struct xsk_cb_desc *desc)
309+
{
310+
}
311+
295312
static inline unsigned int xsk_pool_get_napi_id(struct xsk_buff_pool *pool)
296313
{
297314
return 0;

include/net/xsk_buff_pool.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
struct xsk_buff_pool;
1414
struct xdp_rxq_info;
15+
struct xsk_cb_desc;
1516
struct xsk_queue;
1617
struct xdp_desc;
1718
struct xdp_umem;
@@ -135,6 +136,7 @@ static inline void xp_init_xskb_dma(struct xdp_buff_xsk *xskb, struct xsk_buff_p
135136

136137
/* AF_XDP ZC drivers, via xdp_sock_buff.h */
137138
void xp_set_rxq_info(struct xsk_buff_pool *pool, struct xdp_rxq_info *rxq);
139+
void xp_fill_cb(struct xsk_buff_pool *pool, struct xsk_cb_desc *desc);
138140
int xp_dma_map(struct xsk_buff_pool *pool, struct device *dev,
139141
unsigned long attrs, struct page **pages, u32 nr_pages);
140142
void xp_dma_unmap(struct xsk_buff_pool *pool, unsigned long attrs);

include/uapi/linux/netdev.h

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,13 @@ enum netdev_xdp_act {
4444
* timestamp via bpf_xdp_metadata_rx_timestamp().
4545
* @NETDEV_XDP_RX_METADATA_HASH: Device is capable of exposing receive packet
4646
* hash via bpf_xdp_metadata_rx_hash().
47+
* @NETDEV_XDP_RX_METADATA_VLAN_TAG: Device is capable of exposing receive
48+
* packet VLAN tag via bpf_xdp_metadata_rx_vlan_tag().
4749
*/
4850
enum netdev_xdp_rx_metadata {
4951
NETDEV_XDP_RX_METADATA_TIMESTAMP = 1,
5052
NETDEV_XDP_RX_METADATA_HASH = 2,
51-
52-
/* private: */
53-
NETDEV_XDP_RX_METADATA_MASK = 3,
53+
NETDEV_XDP_RX_METADATA_VLAN_TAG = 4,
5454
};
5555

5656
/**
@@ -63,9 +63,6 @@ enum netdev_xdp_rx_metadata {
6363
enum netdev_xsk_flags {
6464
NETDEV_XSK_FLAGS_TX_TIMESTAMP = 1,
6565
NETDEV_XSK_FLAGS_TX_CHECKSUM = 2,
66-
67-
/* private: */
68-
NETDEV_XSK_FLAGS_MASK = 3,
6966
};
7067

7168
enum {

net/core/xdp.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -737,6 +737,39 @@ __bpf_kfunc int bpf_xdp_metadata_rx_hash(const struct xdp_md *ctx, u32 *hash,
737737
return -EOPNOTSUPP;
738738
}
739739

740+
/**
741+
* bpf_xdp_metadata_rx_vlan_tag - Get XDP packet outermost VLAN tag
742+
* @ctx: XDP context pointer.
743+
* @vlan_proto: Destination pointer for VLAN Tag protocol identifier (TPID).
744+
* @vlan_tci: Destination pointer for VLAN TCI (VID + DEI + PCP)
745+
*
746+
* In case of success, ``vlan_proto`` contains *Tag protocol identifier (TPID)*,
747+
* usually ``ETH_P_8021Q`` or ``ETH_P_8021AD``, but some networks can use
748+
* custom TPIDs. ``vlan_proto`` is stored in **network byte order (BE)**
749+
* and should be used as follows:
750+
* ``if (vlan_proto == bpf_htons(ETH_P_8021Q)) do_something();``
751+
*
752+
* ``vlan_tci`` contains the remaining 16 bits of a VLAN tag.
753+
* Driver is expected to provide those in **host byte order (usually LE)**,
754+
* so the bpf program should not perform byte conversion.
755+
* According to 802.1Q standard, *VLAN TCI (Tag control information)*
756+
* is a bit field that contains:
757+
* *VLAN identifier (VID)* that can be read with ``vlan_tci & 0xfff``,
758+
* *Drop eligible indicator (DEI)* - 1 bit,
759+
* *Priority code point (PCP)* - 3 bits.
760+
* For detailed meaning of DEI and PCP, please refer to other sources.
761+
*
762+
* Return:
763+
* * Returns 0 on success or ``-errno`` on error.
764+
* * ``-EOPNOTSUPP`` : device driver doesn't implement kfunc
765+
* * ``-ENODATA`` : VLAN tag was not stripped or is not available
766+
*/
767+
__bpf_kfunc int bpf_xdp_metadata_rx_vlan_tag(const struct xdp_md *ctx,
768+
__be16 *vlan_proto, u16 *vlan_tci)
769+
{
770+
return -EOPNOTSUPP;
771+
}
772+
740773
__bpf_kfunc_end_defs();
741774

742775
BTF_SET8_START(xdp_metadata_kfunc_ids)

0 commit comments

Comments
 (0)