Skip to content

Commit

Permalink
libbpf: search for metadata casting in create link
Browse files Browse the repository at this point in the history
This is third approach to implement informing driver about metadata used
in XDP program. The same as in first one, searching for casting looks
silly and probably decision about using metadata should be move to user
application (second approach).

Instead of searching for cast in program loading path do it in link
creating path. From this context new field can be sent via ndo_bpf call
to driver.

Intorduce new metadata field in attributes structure. Instead of that we
probably can reuse XDP flags, but as header with definition of flags
isn't included in libbpf I decided to create new field. We also can
include this header in libbpf (I think).

This code assume that user uses bpf_program__attach_xdp to attach XDP
program. It is used only in selftest code, so I haven't tested it yet.
This is only idea, and also I think it will be better to move decision
about using metadata to user. Because of that I will write sample used
this function and test it when we decide that this approach is correct.

Signed-off-by: Michal Swiatkowski <michal.swiatkowski@intel.com>
  • Loading branch information
mswiatko committed Jul 21, 2021
1 parent 8ac91e6 commit 92de1e0
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 5 deletions.
1 change: 1 addition & 0 deletions include/linux/netdevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -968,6 +968,7 @@ struct netdev_bpf {
/* XDP_SETUP_PROG */
struct {
u32 flags;
bool metadata;
struct bpf_prog *prog;
struct netlink_ext_ack *extack;
};
Expand Down
1 change: 1 addition & 0 deletions include/uapi/linux/bpf.h
Original file line number Diff line number Diff line change
Expand Up @@ -1420,6 +1420,7 @@ union bpf_attr {
};
__u32 attach_type; /* attach type */
__u32 flags; /* extra flags */
__u32 metadata;
union {
__u32 target_btf_id; /* btf_id of target to attach to */
struct {
Expand Down
13 changes: 8 additions & 5 deletions net/core/dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -9239,6 +9239,7 @@ struct bpf_xdp_link {
struct bpf_link link;
struct net_device *dev; /* protected by rtnl_lock, no refcnt held */
int flags;
bool metadata;
};

static enum bpf_xdp_mode dev_xdp_mode(struct net_device *dev, u32 flags)
Expand Down Expand Up @@ -9315,7 +9316,7 @@ static void dev_xdp_set_prog(struct net_device *dev, enum bpf_xdp_mode mode,

static int dev_xdp_install(struct net_device *dev, enum bpf_xdp_mode mode,
bpf_op_t bpf_op, struct netlink_ext_ack *extack,
u32 flags, struct bpf_prog *prog)
u32 flags, bool metadata, struct bpf_prog *prog)
{
struct netdev_bpf xdp;
int err;
Expand All @@ -9325,6 +9326,7 @@ static int dev_xdp_install(struct net_device *dev, enum bpf_xdp_mode mode,
xdp.extack = extack;
xdp.flags = flags;
xdp.prog = prog;
xdp.metadata = metadata;

/* Drivers assume refcnt is already incremented (i.e, prog pointer is
* "moved" into driver), so they don't increment it on their own, but
Expand Down Expand Up @@ -9365,7 +9367,7 @@ static void dev_xdp_uninstall(struct net_device *dev)
if (!bpf_op)
continue;

WARN_ON(dev_xdp_install(dev, mode, bpf_op, NULL, 0, NULL));
WARN_ON(dev_xdp_install(dev, mode, bpf_op, NULL, 0, false, NULL));

/* auto-detach link from net device */
link = dev_xdp_link(dev, mode);
Expand Down Expand Up @@ -9472,7 +9474,7 @@ static int dev_xdp_attach(struct net_device *dev, struct netlink_ext_ack *extack
return -EOPNOTSUPP;
}

err = dev_xdp_install(dev, mode, bpf_op, extack, flags, new_prog);
err = dev_xdp_install(dev, mode, bpf_op, extack, flags, link->metadata, new_prog);
if (err)
return err;
}
Expand Down Expand Up @@ -9508,7 +9510,7 @@ static int dev_xdp_detach_link(struct net_device *dev,
return -EINVAL;

bpf_op = dev_xdp_bpf_op(dev, mode);
WARN_ON(dev_xdp_install(dev, mode, bpf_op, NULL, 0, NULL));
WARN_ON(dev_xdp_install(dev, mode, bpf_op, NULL, 0, false, NULL));
dev_xdp_set_link(dev, mode, NULL);
return 0;
}
Expand Down Expand Up @@ -9602,7 +9604,7 @@ static int bpf_xdp_link_update(struct bpf_link *link, struct bpf_prog *new_prog,
mode = dev_xdp_mode(xdp_link->dev, xdp_link->flags);
bpf_op = dev_xdp_bpf_op(xdp_link->dev, mode);
err = dev_xdp_install(xdp_link->dev, mode, bpf_op, NULL,
xdp_link->flags, new_prog);
xdp_link->flags, xdp_link->metadata, new_prog);
if (err)
goto out_unlock;

Expand Down Expand Up @@ -9644,6 +9646,7 @@ int bpf_xdp_link_attach(const union bpf_attr *attr, struct bpf_prog *prog)
bpf_link_init(&link->link, BPF_LINK_TYPE_XDP, &bpf_xdp_link_lops, prog);
link->dev = dev;
link->flags = attr->link_create.flags;
link->metadata = attr->link_create.metadata;

err = bpf_link_prime(&link->link, &link_primer);
if (err) {
Expand Down
1 change: 1 addition & 0 deletions tools/lib/bpf/bpf.h
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ struct bpf_link_create_opts {
union bpf_iter_link_info *iter_info;
__u32 iter_info_len;
__u32 target_btf_id;
bool metadata;
};
#define bpf_link_create_opts__last_field target_btf_id

Expand Down
25 changes: 25 additions & 0 deletions tools/lib/bpf/libbpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -10265,6 +10265,28 @@ static struct bpf_link *attach_iter(const struct bpf_sec_def *sec,
return bpf_program__attach_iter(prog, NULL);
}

/* Assume that if line have (struct xdp_meta_generic *) program for
* sure uses hints. This automatic search doesn't look good, maybe better
* solution is to allow user to decide if hints offload should be use.
* This can be done by exposing attr load bpf program flag.
* */
static bool
libbpf_is_metadata_used(struct bpf_program *prog, int btf_fd)
{
struct bpf_line_info *linfo = (struct bpf_line_info *)prog->line_info;
struct btf *btf = btf_get_from_fd(btf_fd, NULL);
const char meta_marker[] = "(struct xdp_meta_generic *)";
int i;

for (i = 0; i < prog->line_info_cnt; i++) {
if (strstr(btf__name_by_offset(btf, linfo[i].line_off),
meta_marker))
return true;
}

return false;
}

static struct bpf_link *
bpf_program__attach_fd(struct bpf_program *prog, int target_fd, int btf_id,
const char *target_name)
Expand All @@ -10288,6 +10310,9 @@ bpf_program__attach_fd(struct bpf_program *prog, int target_fd, int btf_id,
link->detach = &bpf_link__detach_fd;

attach_type = bpf_program__get_expected_attach_type(prog);
opts.metadata = attach_type == BPF_XDP &&
libbpf_is_metadata_used(prog, bpf_object__btf_fd(prog->obj));

link_fd = bpf_link_create(prog_fd, target_fd, attach_type, &opts);
if (link_fd < 0) {
link_fd = -errno;
Expand Down

0 comments on commit 92de1e0

Please sign in to comment.