Skip to content

Commit 0529662

Browse files
Jakub Kicinskiborkmann
authored andcommitted
xdp: factor out common program/flags handling from drivers
Basic operations drivers perform during xdp setup and query can be moved to helpers in the core. Encapsulate program and flags into a structure and add helpers. Note that the structure is intended as the "main" program information source in the driver. Most drivers will additionally place the program pointer in their fast path or ring structures. The helpers don't have a huge impact now, but they will decrease the code duplication when programs can be installed in HW and driver at the same time. Encapsulating the basic operations in helpers will hopefully also reduce the number of changes to drivers which adopt them. Helpers could really be static inline, but they depend on definition of struct netdev_bpf which means they'd have to be placed in netdevice.h, an already 4500 line header. Signed-off-by: Jakub Kicinski <[email protected]> Reviewed-by: Quentin Monnet <[email protected]> Signed-off-by: Daniel Borkmann <[email protected]>
1 parent 6b86758 commit 0529662

File tree

7 files changed

+67
-38
lines changed

7 files changed

+67
-38
lines changed

drivers/net/ethernet/netronome/nfp/nfp_net.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -553,8 +553,7 @@ struct nfp_net_dp {
553553
* @rss_cfg: RSS configuration
554554
* @rss_key: RSS secret key
555555
* @rss_itbl: RSS indirection table
556-
* @xdp_flags: Flags with which XDP prog was loaded
557-
* @xdp_prog: XDP prog (for ctrl path, both DRV and HW modes)
556+
* @xdp: Information about the attached XDP program
558557
* @max_r_vecs: Number of allocated interrupt vectors for RX/TX
559558
* @max_tx_rings: Maximum number of TX rings supported by the Firmware
560559
* @max_rx_rings: Maximum number of RX rings supported by the Firmware
@@ -610,8 +609,7 @@ struct nfp_net {
610609
u8 rss_key[NFP_NET_CFG_RSS_KEY_SZ];
611610
u8 rss_itbl[NFP_NET_CFG_RSS_ITBL_SZ];
612611

613-
u32 xdp_flags;
614-
struct bpf_prog *xdp_prog;
612+
struct xdp_attachment_info xdp;
615613

616614
unsigned int max_tx_rings;
617615
unsigned int max_rx_rings;

drivers/net/ethernet/netronome/nfp/nfp_net_common.c

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3417,34 +3417,29 @@ nfp_net_xdp_setup_drv(struct nfp_net *nn, struct bpf_prog *prog,
34173417
return nfp_net_ring_reconfig(nn, dp, extack);
34183418
}
34193419

3420-
static int
3421-
nfp_net_xdp_setup(struct nfp_net *nn, struct bpf_prog *prog, u32 flags,
3422-
struct netlink_ext_ack *extack)
3420+
static int nfp_net_xdp_setup(struct nfp_net *nn, struct netdev_bpf *bpf)
34233421
{
34243422
struct bpf_prog *drv_prog, *offload_prog;
34253423
int err;
34263424

3427-
if (nn->xdp_prog && (flags ^ nn->xdp_flags) & XDP_FLAGS_MODES)
3425+
if (!xdp_attachment_flags_ok(&nn->xdp, bpf))
34283426
return -EBUSY;
34293427

34303428
/* Load both when no flags set to allow easy activation of driver path
34313429
* when program is replaced by one which can't be offloaded.
34323430
*/
3433-
drv_prog = flags & XDP_FLAGS_HW_MODE ? NULL : prog;
3434-
offload_prog = flags & XDP_FLAGS_DRV_MODE ? NULL : prog;
3431+
drv_prog = bpf->flags & XDP_FLAGS_HW_MODE ? NULL : bpf->prog;
3432+
offload_prog = bpf->flags & XDP_FLAGS_DRV_MODE ? NULL : bpf->prog;
34353433

3436-
err = nfp_net_xdp_setup_drv(nn, drv_prog, extack);
3434+
err = nfp_net_xdp_setup_drv(nn, drv_prog, bpf->extack);
34373435
if (err)
34383436
return err;
34393437

3440-
err = nfp_app_xdp_offload(nn->app, nn, offload_prog, extack);
3441-
if (err && flags & XDP_FLAGS_HW_MODE)
3438+
err = nfp_app_xdp_offload(nn->app, nn, offload_prog, bpf->extack);
3439+
if (err && bpf->flags & XDP_FLAGS_HW_MODE)
34423440
return err;
34433441

3444-
if (nn->xdp_prog)
3445-
bpf_prog_put(nn->xdp_prog);
3446-
nn->xdp_prog = prog;
3447-
nn->xdp_flags = flags;
3442+
xdp_attachment_setup(&nn->xdp, bpf);
34483443

34493444
return 0;
34503445
}
@@ -3456,12 +3451,9 @@ static int nfp_net_xdp(struct net_device *netdev, struct netdev_bpf *xdp)
34563451
switch (xdp->command) {
34573452
case XDP_SETUP_PROG:
34583453
case XDP_SETUP_PROG_HW:
3459-
return nfp_net_xdp_setup(nn, xdp->prog, xdp->flags,
3460-
xdp->extack);
3454+
return nfp_net_xdp_setup(nn, xdp);
34613455
case XDP_QUERY_PROG:
3462-
xdp->prog_id = nn->xdp_prog ? nn->xdp_prog->aux->id : 0;
3463-
xdp->prog_flags = nn->xdp_prog ? nn->xdp_flags : 0;
3464-
return 0;
3456+
return xdp_attachment_query(&nn->xdp, xdp);
34653457
default:
34663458
return nfp_app_bpf(nn->app, nn, xdp);
34673459
}

drivers/net/netdevsim/bpf.c

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -199,10 +199,8 @@ static int nsim_xdp_set_prog(struct netdevsim *ns, struct netdev_bpf *bpf)
199199
{
200200
int err;
201201

202-
if (ns->xdp_prog && (bpf->flags ^ ns->xdp_flags) & XDP_FLAGS_MODES) {
203-
NSIM_EA(bpf->extack, "program loaded with different flags");
202+
if (!xdp_attachment_flags_ok(&ns->xdp, bpf))
204203
return -EBUSY;
205-
}
206204

207205
if (bpf->command == XDP_SETUP_PROG && !ns->bpf_xdpdrv_accept) {
208206
NSIM_EA(bpf->extack, "driver XDP disabled in DebugFS");
@@ -219,11 +217,7 @@ static int nsim_xdp_set_prog(struct netdevsim *ns, struct netdev_bpf *bpf)
219217
return err;
220218
}
221219

222-
if (ns->xdp_prog)
223-
bpf_prog_put(ns->xdp_prog);
224-
225-
ns->xdp_prog = bpf->prog;
226-
ns->xdp_flags = bpf->flags;
220+
xdp_attachment_setup(&ns->xdp, bpf);
227221

228222
if (!bpf->prog)
229223
ns->xdp_prog_mode = XDP_ATTACHED_NONE;
@@ -567,9 +561,7 @@ int nsim_bpf(struct net_device *dev, struct netdev_bpf *bpf)
567561
nsim_bpf_destroy_prog(bpf->offload.prog);
568562
return 0;
569563
case XDP_QUERY_PROG:
570-
bpf->prog_id = ns->xdp_prog ? ns->xdp_prog->aux->id : 0;
571-
bpf->prog_flags = ns->xdp_prog ? ns->xdp_flags : 0;
572-
return 0;
564+
return xdp_attachment_query(&ns->xdp, bpf);
573565
case XDP_SETUP_PROG:
574566
err = nsim_setup_prog_checks(ns, bpf);
575567
if (err)
@@ -636,6 +628,6 @@ void nsim_bpf_uninit(struct netdevsim *ns)
636628
{
637629
WARN_ON(!list_empty(&ns->bpf_bound_progs));
638630
WARN_ON(!list_empty(&ns->bpf_bound_maps));
639-
WARN_ON(ns->xdp_prog);
631+
WARN_ON(ns->xdp.prog);
640632
WARN_ON(ns->bpf_offloaded);
641633
}

drivers/net/netdevsim/netdevsim.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <linux/list.h>
1919
#include <linux/netdevice.h>
2020
#include <linux/u64_stats_sync.h>
21+
#include <net/xdp.h>
2122

2223
#define DRV_NAME "netdevsim"
2324

@@ -67,9 +68,8 @@ struct netdevsim {
6768
struct bpf_prog *bpf_offloaded;
6869
u32 bpf_offloaded_id;
6970

70-
u32 xdp_flags;
71+
struct xdp_attachment_info xdp;
7172
int xdp_prog_mode;
72-
struct bpf_prog *xdp_prog;
7373

7474
u32 prog_id_gen;
7575

include/net/xdp.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,4 +144,17 @@ xdp_data_meta_unsupported(const struct xdp_buff *xdp)
144144
return unlikely(xdp->data_meta > xdp->data);
145145
}
146146

147+
struct xdp_attachment_info {
148+
struct bpf_prog *prog;
149+
u32 flags;
150+
};
151+
152+
struct netdev_bpf;
153+
int xdp_attachment_query(struct xdp_attachment_info *info,
154+
struct netdev_bpf *bpf);
155+
bool xdp_attachment_flags_ok(struct xdp_attachment_info *info,
156+
struct netdev_bpf *bpf);
157+
void xdp_attachment_setup(struct xdp_attachment_info *info,
158+
struct netdev_bpf *bpf);
159+
147160
#endif /* __LINUX_NET_XDP_H__ */

net/core/xdp.c

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,11 @@
33
* Copyright (c) 2017 Jesper Dangaard Brouer, Red Hat Inc.
44
* Released under terms in GPL version 2. See COPYING.
55
*/
6+
#include <linux/bpf.h>
7+
#include <linux/filter.h>
68
#include <linux/types.h>
79
#include <linux/mm.h>
10+
#include <linux/netdevice.h>
811
#include <linux/slab.h>
912
#include <linux/idr.h>
1013
#include <linux/rhashtable.h>
@@ -370,3 +373,34 @@ void xdp_return_buff(struct xdp_buff *xdp)
370373
__xdp_return(xdp->data, &xdp->rxq->mem, true, xdp->handle);
371374
}
372375
EXPORT_SYMBOL_GPL(xdp_return_buff);
376+
377+
int xdp_attachment_query(struct xdp_attachment_info *info,
378+
struct netdev_bpf *bpf)
379+
{
380+
bpf->prog_id = info->prog ? info->prog->aux->id : 0;
381+
bpf->prog_flags = info->prog ? info->flags : 0;
382+
return 0;
383+
}
384+
EXPORT_SYMBOL_GPL(xdp_attachment_query);
385+
386+
bool xdp_attachment_flags_ok(struct xdp_attachment_info *info,
387+
struct netdev_bpf *bpf)
388+
{
389+
if (info->prog && (bpf->flags ^ info->flags) & XDP_FLAGS_MODES) {
390+
NL_SET_ERR_MSG(bpf->extack,
391+
"program loaded with different flags");
392+
return false;
393+
}
394+
return true;
395+
}
396+
EXPORT_SYMBOL_GPL(xdp_attachment_flags_ok);
397+
398+
void xdp_attachment_setup(struct xdp_attachment_info *info,
399+
struct netdev_bpf *bpf)
400+
{
401+
if (info->prog)
402+
bpf_prog_put(info->prog);
403+
info->prog = bpf->prog;
404+
info->flags = bpf->flags;
405+
}
406+
EXPORT_SYMBOL_GPL(xdp_attachment_setup);

tools/testing/selftests/bpf/test_offload.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -821,7 +821,7 @@ def test_spurios_extack(sim, obj, skip_hw, needle):
821821
ret, _, err = sim.set_xdp(obj, "", force=True,
822822
fail=False, include_stderr=True)
823823
fail(ret == 0, "Replaced XDP program with a program in different mode")
824-
check_extack_nsim(err, "program loaded with different flags.", args)
824+
check_extack(err, "program loaded with different flags.", args)
825825

826826
start_test("Test XDP prog remove with bad flags...")
827827
ret, _, err = sim.unset_xdp("offload", force=True,
@@ -831,7 +831,7 @@ def test_spurios_extack(sim, obj, skip_hw, needle):
831831
ret, _, err = sim.unset_xdp("", force=True,
832832
fail=False, include_stderr=True)
833833
fail(ret == 0, "Removed program with a bad mode")
834-
check_extack_nsim(err, "program loaded with different flags.", args)
834+
check_extack(err, "program loaded with different flags.", args)
835835

836836
start_test("Test MTU restrictions...")
837837
ret, _ = sim.set_mtu(9000, fail=False)

0 commit comments

Comments
 (0)