Commit 799e173d authored by Jakub Kicinski's avatar Jakub Kicinski Committed by Daniel Borkmann

netdevsim: add support for simultaneous driver and hw XDP

Allow netdevsim to accept driver and offload attachment of XDP
BPF programs at the same time.
Signed-off-by: default avatarJakub Kicinski <jakub.kicinski@netronome.com>
Reviewed-by: default avatarQuentin Monnet <quentin.monnet@netronome.com>
Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
parent a25717d2
...@@ -92,7 +92,7 @@ static const struct bpf_prog_offload_ops nsim_bpf_analyzer_ops = { ...@@ -92,7 +92,7 @@ static const struct bpf_prog_offload_ops nsim_bpf_analyzer_ops = {
static bool nsim_xdp_offload_active(struct netdevsim *ns) static bool nsim_xdp_offload_active(struct netdevsim *ns)
{ {
return ns->xdp_prog_mode == XDP_ATTACHED_HW; return ns->xdp_hw.prog;
} }
static void nsim_prog_set_loaded(struct bpf_prog *prog, bool loaded) static void nsim_prog_set_loaded(struct bpf_prog *prog, bool loaded)
...@@ -195,11 +195,13 @@ static int nsim_xdp_offload_prog(struct netdevsim *ns, struct netdev_bpf *bpf) ...@@ -195,11 +195,13 @@ static int nsim_xdp_offload_prog(struct netdevsim *ns, struct netdev_bpf *bpf)
return nsim_bpf_offload(ns, bpf->prog, nsim_xdp_offload_active(ns)); return nsim_bpf_offload(ns, bpf->prog, nsim_xdp_offload_active(ns));
} }
static int nsim_xdp_set_prog(struct netdevsim *ns, struct netdev_bpf *bpf) static int
nsim_xdp_set_prog(struct netdevsim *ns, struct netdev_bpf *bpf,
struct xdp_attachment_info *xdp)
{ {
int err; int err;
if (!xdp_attachment_flags_ok(&ns->xdp, bpf)) if (!xdp_attachment_flags_ok(xdp, bpf))
return -EBUSY; return -EBUSY;
if (bpf->command == XDP_SETUP_PROG && !ns->bpf_xdpdrv_accept) { if (bpf->command == XDP_SETUP_PROG && !ns->bpf_xdpdrv_accept) {
...@@ -217,14 +219,7 @@ static int nsim_xdp_set_prog(struct netdevsim *ns, struct netdev_bpf *bpf) ...@@ -217,14 +219,7 @@ static int nsim_xdp_set_prog(struct netdevsim *ns, struct netdev_bpf *bpf)
return err; return err;
} }
xdp_attachment_setup(&ns->xdp, bpf); xdp_attachment_setup(xdp, bpf);
if (!bpf->prog)
ns->xdp_prog_mode = XDP_ATTACHED_NONE;
else if (bpf->command == XDP_SETUP_PROG)
ns->xdp_prog_mode = XDP_ATTACHED_DRV;
else
ns->xdp_prog_mode = XDP_ATTACHED_HW;
return 0; return 0;
} }
...@@ -284,10 +279,6 @@ static int nsim_setup_prog_checks(struct netdevsim *ns, struct netdev_bpf *bpf) ...@@ -284,10 +279,6 @@ static int nsim_setup_prog_checks(struct netdevsim *ns, struct netdev_bpf *bpf)
NSIM_EA(bpf->extack, "MTU too large w/ XDP enabled"); NSIM_EA(bpf->extack, "MTU too large w/ XDP enabled");
return -EINVAL; return -EINVAL;
} }
if (nsim_xdp_offload_active(ns)) {
NSIM_EA(bpf->extack, "xdp offload active, can't load drv prog");
return -EBUSY;
}
return 0; return 0;
} }
...@@ -561,25 +552,21 @@ int nsim_bpf(struct net_device *dev, struct netdev_bpf *bpf) ...@@ -561,25 +552,21 @@ int nsim_bpf(struct net_device *dev, struct netdev_bpf *bpf)
nsim_bpf_destroy_prog(bpf->offload.prog); nsim_bpf_destroy_prog(bpf->offload.prog);
return 0; return 0;
case XDP_QUERY_PROG: case XDP_QUERY_PROG:
if (ns->xdp_prog_mode != XDP_ATTACHED_DRV)
return 0;
return xdp_attachment_query(&ns->xdp, bpf); return xdp_attachment_query(&ns->xdp, bpf);
case XDP_QUERY_PROG_HW: case XDP_QUERY_PROG_HW:
if (ns->xdp_prog_mode != XDP_ATTACHED_HW) return xdp_attachment_query(&ns->xdp_hw, bpf);
return 0;
return xdp_attachment_query(&ns->xdp, bpf);
case XDP_SETUP_PROG: case XDP_SETUP_PROG:
err = nsim_setup_prog_checks(ns, bpf); err = nsim_setup_prog_checks(ns, bpf);
if (err) if (err)
return err; return err;
return nsim_xdp_set_prog(ns, bpf); return nsim_xdp_set_prog(ns, bpf, &ns->xdp);
case XDP_SETUP_PROG_HW: case XDP_SETUP_PROG_HW:
err = nsim_setup_prog_hw_checks(ns, bpf); err = nsim_setup_prog_hw_checks(ns, bpf);
if (err) if (err)
return err; return err;
return nsim_xdp_set_prog(ns, bpf); return nsim_xdp_set_prog(ns, bpf, &ns->xdp_hw);
case BPF_OFFLOAD_MAP_ALLOC: case BPF_OFFLOAD_MAP_ALLOC:
if (!ns->bpf_map_accept) if (!ns->bpf_map_accept)
return -EOPNOTSUPP; return -EOPNOTSUPP;
...@@ -635,5 +622,6 @@ void nsim_bpf_uninit(struct netdevsim *ns) ...@@ -635,5 +622,6 @@ void nsim_bpf_uninit(struct netdevsim *ns)
WARN_ON(!list_empty(&ns->bpf_bound_progs)); WARN_ON(!list_empty(&ns->bpf_bound_progs));
WARN_ON(!list_empty(&ns->bpf_bound_maps)); WARN_ON(!list_empty(&ns->bpf_bound_maps));
WARN_ON(ns->xdp.prog); WARN_ON(ns->xdp.prog);
WARN_ON(ns->xdp_hw.prog);
WARN_ON(ns->bpf_offloaded); WARN_ON(ns->bpf_offloaded);
} }
...@@ -228,8 +228,7 @@ static int nsim_change_mtu(struct net_device *dev, int new_mtu) ...@@ -228,8 +228,7 @@ static int nsim_change_mtu(struct net_device *dev, int new_mtu)
{ {
struct netdevsim *ns = netdev_priv(dev); struct netdevsim *ns = netdev_priv(dev);
if (ns->xdp_prog_mode == XDP_ATTACHED_DRV && if (ns->xdp.prog && new_mtu > NSIM_XDP_MAX_MTU)
new_mtu > NSIM_XDP_MAX_MTU)
return -EBUSY; return -EBUSY;
dev->mtu = new_mtu; dev->mtu = new_mtu;
......
...@@ -69,7 +69,7 @@ struct netdevsim { ...@@ -69,7 +69,7 @@ struct netdevsim {
u32 bpf_offloaded_id; u32 bpf_offloaded_id;
struct xdp_attachment_info xdp; struct xdp_attachment_info xdp;
int xdp_prog_mode; struct xdp_attachment_info xdp_hw;
u32 prog_id_gen; u32 prog_id_gen;
......
...@@ -814,20 +814,12 @@ try: ...@@ -814,20 +814,12 @@ try:
"Device parameters reported for non-offloaded program") "Device parameters reported for non-offloaded program")
start_test("Test XDP prog replace with bad flags...") start_test("Test XDP prog replace with bad flags...")
ret, _, err = sim.set_xdp(obj, "offload", force=True,
fail=False, include_stderr=True)
fail(ret == 0, "Replaced XDP program with a program in different mode")
check_extack_nsim(err, "program loaded with different flags.", args)
ret, _, err = sim.set_xdp(obj, "", force=True, ret, _, err = sim.set_xdp(obj, "", force=True,
fail=False, include_stderr=True) fail=False, include_stderr=True)
fail(ret == 0, "Replaced XDP program with a program in different mode") fail(ret == 0, "Replaced XDP program with a program in different mode")
check_extack(err, "program loaded with different flags.", args) check_extack(err, "program loaded with different flags.", args)
start_test("Test XDP prog remove with bad flags...") start_test("Test XDP prog remove with bad flags...")
ret, _, err = sim.unset_xdp("offload", force=True,
fail=False, include_stderr=True)
fail(ret == 0, "Removed program with a bad mode mode")
check_extack_nsim(err, "program loaded with different flags.", args)
ret, _, err = sim.unset_xdp("", force=True, ret, _, err = sim.unset_xdp("", force=True,
fail=False, include_stderr=True) fail=False, include_stderr=True)
fail(ret == 0, "Removed program with a bad mode") fail(ret == 0, "Removed program with a bad mode")
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment