Skip to content

Commit ba50bf7

Browse files
JonKohlerNipaLocal
authored and
NipaLocal
committed
xdp: Add helpers for head length, headroom, and metadata length
Introduce new XDP helpers: - xdp_headlen: Similar to skb_headlen - xdp_headroom: Similar to skb_headroom - xdp_metadata_len: Similar to skb_metadata_len Integrate these helpers into tap, tun, and XDP implementation to start. No functional changes introduced. Reviewed-by: Jacob Keller <[email protected]> Signed-off-by: Jon Kohler <[email protected]> Acked-by: Stanislav Fomichev <[email protected]> Signed-off-by: NipaLocal <nipa@local>
1 parent 858df18 commit ba50bf7

File tree

4 files changed

+66
-19
lines changed

4 files changed

+66
-19
lines changed

drivers/net/tap.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1048,7 +1048,7 @@ static int tap_get_user_xdp(struct tap_queue *q, struct xdp_buff *xdp)
10481048
struct sk_buff *skb;
10491049
int err, depth;
10501050

1051-
if (unlikely(xdp->data_end - xdp->data < ETH_HLEN)) {
1051+
if (unlikely(xdp_headlen(xdp) < ETH_HLEN)) {
10521052
err = -EINVAL;
10531053
goto err;
10541054
}
@@ -1062,8 +1062,8 @@ static int tap_get_user_xdp(struct tap_queue *q, struct xdp_buff *xdp)
10621062
goto err;
10631063
}
10641064

1065-
skb_reserve(skb, xdp->data - xdp->data_hard_start);
1066-
skb_put(skb, xdp->data_end - xdp->data);
1065+
skb_reserve(skb, xdp_headroom(xdp));
1066+
skb_put(skb, xdp_headlen(xdp));
10671067

10681068
skb_set_network_header(skb, ETH_HLEN);
10691069
skb_reset_mac_header(skb);

drivers/net/tun.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1567,15 +1567,15 @@ static int tun_xdp_act(struct tun_struct *tun, struct bpf_prog *xdp_prog,
15671567
dev_core_stats_rx_dropped_inc(tun->dev);
15681568
return err;
15691569
}
1570-
dev_sw_netstats_rx_add(tun->dev, xdp->data_end - xdp->data);
1570+
dev_sw_netstats_rx_add(tun->dev, xdp_headlen(xdp));
15711571
break;
15721572
case XDP_TX:
15731573
err = tun_xdp_tx(tun->dev, xdp);
15741574
if (err < 0) {
15751575
dev_core_stats_rx_dropped_inc(tun->dev);
15761576
return err;
15771577
}
1578-
dev_sw_netstats_rx_add(tun->dev, xdp->data_end - xdp->data);
1578+
dev_sw_netstats_rx_add(tun->dev, xdp_headlen(xdp));
15791579
break;
15801580
case XDP_PASS:
15811581
break;
@@ -2355,7 +2355,7 @@ static int tun_xdp_one(struct tun_struct *tun,
23552355
struct xdp_buff *xdp, int *flush,
23562356
struct tun_page *tpage)
23572357
{
2358-
unsigned int datasize = xdp->data_end - xdp->data;
2358+
unsigned int datasize = xdp_headlen(xdp);
23592359
struct tun_xdp_hdr *hdr = xdp->data_hard_start;
23602360
struct virtio_net_hdr *gso = &hdr->gso;
23612361
struct bpf_prog *xdp_prog;
@@ -2415,14 +2415,14 @@ static int tun_xdp_one(struct tun_struct *tun,
24152415
goto out;
24162416
}
24172417

2418-
skb_reserve(skb, xdp->data - xdp->data_hard_start);
2419-
skb_put(skb, xdp->data_end - xdp->data);
2418+
skb_reserve(skb, xdp_headroom(xdp));
2419+
skb_put(skb, xdp_headlen(xdp));
24202420

24212421
/* The externally provided xdp_buff may have no metadata support, which
24222422
* is marked by xdp->data_meta being xdp->data + 1. This will lead to a
24232423
* metasize of -1 and is the reason why the condition checks for > 0.
24242424
*/
2425-
metasize = xdp->data - xdp->data_meta;
2425+
metasize = xdp_metadata_len(xdp);
24262426
if (metasize > 0)
24272427
skb_metadata_set(skb, metasize);
24282428

include/net/xdp.h

Lines changed: 51 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -151,10 +151,57 @@ xdp_get_shared_info_from_buff(const struct xdp_buff *xdp)
151151
return (struct skb_shared_info *)xdp_data_hard_end(xdp);
152152
}
153153

154+
/**
155+
* xdp_headlen - Calculate the length of the data in an XDP buffer
156+
* @xdp: Pointer to the XDP buffer structure
157+
*
158+
* Compute the length of the data contained in the XDP buffer. Does not
159+
* include frags, use xdp_get_buff_len() for that instead.
160+
*
161+
* Analogous to skb_headlen().
162+
*
163+
* Return: The length of the data in the XDP buffer in bytes.
164+
*/
165+
static inline unsigned int xdp_headlen(const struct xdp_buff *xdp)
166+
{
167+
return xdp->data_end - xdp->data;
168+
}
169+
170+
/**
171+
* xdp_headroom - Calculate the headroom available in an XDP buffer
172+
* @xdp: Pointer to the XDP buffer structure
173+
*
174+
* Compute the headroom in an XDP buffer.
175+
*
176+
* Analogous to the skb_headroom().
177+
*
178+
* Return: The size of the headroom in bytes.
179+
*/
180+
static inline unsigned int xdp_headroom(const struct xdp_buff *xdp)
181+
{
182+
return xdp->data - xdp->data_hard_start;
183+
}
184+
185+
/**
186+
* xdp_metadata_len - Calculate the length of metadata in an XDP buffer
187+
* @xdp: Pointer to the XDP buffer structure
188+
*
189+
* Compute the length of the metadata region in an XDP buffer.
190+
*
191+
* Analogous to skb_metadata_len(), though using signed int as value
192+
* is allowed to be negative.
193+
*
194+
* Return: The length of the metadata in bytes.
195+
*/
196+
static inline int xdp_metadata_len(const struct xdp_buff *xdp)
197+
{
198+
return xdp->data - xdp->data_meta;
199+
}
200+
154201
static __always_inline unsigned int
155202
xdp_get_buff_len(const struct xdp_buff *xdp)
156203
{
157-
unsigned int len = xdp->data_end - xdp->data;
204+
unsigned int len = xdp_headlen(xdp);
158205
const struct skb_shared_info *sinfo;
159206

160207
if (likely(!xdp_buff_has_frags(xdp)))
@@ -364,8 +411,8 @@ int xdp_update_frame_from_buff(const struct xdp_buff *xdp,
364411
int metasize, headroom;
365412

366413
/* Assure headroom is available for storing info */
367-
headroom = xdp->data - xdp->data_hard_start;
368-
metasize = xdp->data - xdp->data_meta;
414+
headroom = xdp_headroom(xdp);
415+
metasize = xdp_metadata_len(xdp);
369416
metasize = metasize > 0 ? metasize : 0;
370417
if (unlikely((headroom - metasize) < sizeof(*xdp_frame)))
371418
return -ENOSPC;
@@ -377,7 +424,7 @@ int xdp_update_frame_from_buff(const struct xdp_buff *xdp,
377424
}
378425

379426
xdp_frame->data = xdp->data;
380-
xdp_frame->len = xdp->data_end - xdp->data;
427+
xdp_frame->len = xdp_headlen(xdp);
381428
xdp_frame->headroom = headroom - sizeof(*xdp_frame);
382429
xdp_frame->metasize = metasize;
383430
xdp_frame->frame_sz = xdp->frame_sz;

net/core/xdp.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -582,8 +582,8 @@ struct xdp_frame *xdp_convert_zc_to_xdp_frame(struct xdp_buff *xdp)
582582

583583
/* Clone into a MEM_TYPE_PAGE_ORDER0 xdp_frame. */
584584
metasize = xdp_data_meta_unsupported(xdp) ? 0 :
585-
xdp->data - xdp->data_meta;
586-
totsize = xdp->data_end - xdp->data + metasize;
585+
xdp_metadata_len(xdp);
586+
totsize = xdp_headlen(xdp) + metasize;
587587

588588
if (sizeof(*xdpf) + totsize > PAGE_SIZE)
589589
return NULL;
@@ -647,10 +647,10 @@ struct sk_buff *xdp_build_skb_from_buff(const struct xdp_buff *xdp)
647647
if (unlikely(!skb))
648648
return NULL;
649649

650-
skb_reserve(skb, xdp->data - xdp->data_hard_start);
651-
__skb_put(skb, xdp->data_end - xdp->data);
650+
skb_reserve(skb, xdp_headroom(xdp));
651+
__skb_put(skb, xdp_headlen(xdp));
652652

653-
metalen = xdp->data - xdp->data_meta;
653+
metalen = xdp_metadata_len(xdp);
654654
if (metalen > 0)
655655
skb_metadata_set(skb, metalen);
656656

@@ -765,7 +765,7 @@ struct sk_buff *xdp_build_skb_from_zc(struct xdp_buff *xdp)
765765

766766
memcpy(__skb_put(skb, len), xdp->data_meta, LARGEST_ALIGN(len));
767767

768-
metalen = xdp->data - xdp->data_meta;
768+
metalen = xdp_metadata_len(xdp);
769769
if (metalen > 0) {
770770
skb_metadata_set(skb, metalen);
771771
__skb_pull(skb, metalen);

0 commit comments

Comments
 (0)