bpf: Add attach_type field to bpf_link

Attach_type will be set when a link is created by user. It is better to
record attach_type in bpf_link generically and have it available
universally for all link types. So add the attach_type field in bpf_link
and move the sleepable field to avoid unnecessary gap padding.

Signed-off-by: Tao Chen <chen.dylane@linux.dev>
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Acked-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Jiri Olsa <jolsa@kernel.org>
Link: https://lore.kernel.org/bpf/20250710032038.888700-2-chen.dylane@linux.dev
This commit is contained in:
Tao Chen 2025-07-10 11:20:32 +08:00 committed by Andrii Nakryiko
parent d81526a6eb
commit b725441f02
14 changed files with 66 additions and 42 deletions

View file

@ -775,7 +775,7 @@ static int netkit_link_init(struct netkit_link *nkl,
struct bpf_prog *prog) struct bpf_prog *prog)
{ {
bpf_link_init(&nkl->link, BPF_LINK_TYPE_NETKIT, bpf_link_init(&nkl->link, BPF_LINK_TYPE_NETKIT,
&netkit_link_lops, prog); &netkit_link_lops, prog, attr->link_create.attach_type);
nkl->location = attr->link_create.attach_type; nkl->location = attr->link_create.attach_type;
nkl->dev = dev; nkl->dev = dev;
return bpf_link_prime(&nkl->link, link_primer); return bpf_link_prime(&nkl->link, link_primer);

View file

@ -1729,12 +1729,10 @@ struct bpf_link {
enum bpf_link_type type; enum bpf_link_type type;
const struct bpf_link_ops *ops; const struct bpf_link_ops *ops;
struct bpf_prog *prog; struct bpf_prog *prog;
/* whether BPF link itself has "sleepable" semantics, which can differ
* from underlying BPF program having a "sleepable" semantics, as BPF
* link's semantics is determined by target attach hook
*/
bool sleepable;
u32 flags; u32 flags;
enum bpf_attach_type attach_type;
/* rcu is used before freeing, work can be used to schedule that /* rcu is used before freeing, work can be used to schedule that
* RCU-based freeing before that, so they never overlap * RCU-based freeing before that, so they never overlap
*/ */
@ -1742,6 +1740,11 @@ struct bpf_link {
struct rcu_head rcu; struct rcu_head rcu;
struct work_struct work; struct work_struct work;
}; };
/* whether BPF link itself has "sleepable" semantics, which can differ
* from underlying BPF program having a "sleepable" semantics, as BPF
* link's semantics is determined by target attach hook
*/
bool sleepable;
}; };
struct bpf_link_ops { struct bpf_link_ops {
@ -2034,11 +2037,13 @@ int bpf_prog_ctx_arg_info_init(struct bpf_prog *prog,
#if defined(CONFIG_CGROUP_BPF) && defined(CONFIG_BPF_LSM) #if defined(CONFIG_CGROUP_BPF) && defined(CONFIG_BPF_LSM)
int bpf_trampoline_link_cgroup_shim(struct bpf_prog *prog, int bpf_trampoline_link_cgroup_shim(struct bpf_prog *prog,
int cgroup_atype); int cgroup_atype,
enum bpf_attach_type attach_type);
void bpf_trampoline_unlink_cgroup_shim(struct bpf_prog *prog); void bpf_trampoline_unlink_cgroup_shim(struct bpf_prog *prog);
#else #else
static inline int bpf_trampoline_link_cgroup_shim(struct bpf_prog *prog, static inline int bpf_trampoline_link_cgroup_shim(struct bpf_prog *prog,
int cgroup_atype) int cgroup_atype,
enum bpf_attach_type attach_type)
{ {
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
@ -2528,10 +2533,11 @@ int bpf_map_new_fd(struct bpf_map *map, int flags);
int bpf_prog_new_fd(struct bpf_prog *prog); int bpf_prog_new_fd(struct bpf_prog *prog);
void bpf_link_init(struct bpf_link *link, enum bpf_link_type type, void bpf_link_init(struct bpf_link *link, enum bpf_link_type type,
const struct bpf_link_ops *ops, struct bpf_prog *prog); const struct bpf_link_ops *ops, struct bpf_prog *prog,
enum bpf_attach_type attach_type);
void bpf_link_init_sleepable(struct bpf_link *link, enum bpf_link_type type, void bpf_link_init_sleepable(struct bpf_link *link, enum bpf_link_type type,
const struct bpf_link_ops *ops, struct bpf_prog *prog, const struct bpf_link_ops *ops, struct bpf_prog *prog,
bool sleepable); enum bpf_attach_type attach_type, bool sleepable);
int bpf_link_prime(struct bpf_link *link, struct bpf_link_primer *primer); int bpf_link_prime(struct bpf_link *link, struct bpf_link_primer *primer);
int bpf_link_settle(struct bpf_link_primer *primer); int bpf_link_settle(struct bpf_link_primer *primer);
void bpf_link_cleanup(struct bpf_link_primer *primer); void bpf_link_cleanup(struct bpf_link_primer *primer);
@ -2883,13 +2889,13 @@ bpf_prog_inc_not_zero(struct bpf_prog *prog)
static inline void bpf_link_init(struct bpf_link *link, enum bpf_link_type type, static inline void bpf_link_init(struct bpf_link *link, enum bpf_link_type type,
const struct bpf_link_ops *ops, const struct bpf_link_ops *ops,
struct bpf_prog *prog) struct bpf_prog *prog, enum bpf_attach_type attach_type)
{ {
} }
static inline void bpf_link_init_sleepable(struct bpf_link *link, enum bpf_link_type type, static inline void bpf_link_init_sleepable(struct bpf_link *link, enum bpf_link_type type,
const struct bpf_link_ops *ops, struct bpf_prog *prog, const struct bpf_link_ops *ops, struct bpf_prog *prog,
bool sleepable) enum bpf_attach_type attach_type, bool sleepable)
{ {
} }

View file

@ -552,7 +552,8 @@ int bpf_iter_link_attach(const union bpf_attr *attr, bpfptr_t uattr,
if (!link) if (!link)
return -ENOMEM; return -ENOMEM;
bpf_link_init(&link->link, BPF_LINK_TYPE_ITER, &bpf_iter_link_lops, prog); bpf_link_init(&link->link, BPF_LINK_TYPE_ITER, &bpf_iter_link_lops, prog,
attr->link_create.attach_type);
link->tinfo = tinfo; link->tinfo = tinfo;
err = bpf_link_prime(&link->link, &link_primer); err = bpf_link_prime(&link->link, &link_primer);

View file

@ -808,7 +808,7 @@ static long bpf_struct_ops_map_update_elem(struct bpf_map *map, void *key,
goto reset_unlock; goto reset_unlock;
} }
bpf_link_init(&link->link, BPF_LINK_TYPE_STRUCT_OPS, bpf_link_init(&link->link, BPF_LINK_TYPE_STRUCT_OPS,
&bpf_struct_ops_link_lops, prog); &bpf_struct_ops_link_lops, prog, prog->expected_attach_type);
*plink++ = &link->link; *plink++ = &link->link;
ksym = kzalloc(sizeof(*ksym), GFP_USER); ksym = kzalloc(sizeof(*ksym), GFP_USER);
@ -1351,7 +1351,8 @@ int bpf_struct_ops_link_create(union bpf_attr *attr)
err = -ENOMEM; err = -ENOMEM;
goto err_out; goto err_out;
} }
bpf_link_init(&link->link, BPF_LINK_TYPE_STRUCT_OPS, &bpf_struct_ops_map_lops, NULL); bpf_link_init(&link->link, BPF_LINK_TYPE_STRUCT_OPS, &bpf_struct_ops_map_lops, NULL,
attr->link_create.attach_type);
err = bpf_link_prime(&link->link, &link_primer); err = bpf_link_prime(&link->link, &link_primer);
if (err) if (err)

View file

@ -867,7 +867,7 @@ static int __cgroup_bpf_attach(struct cgroup *cgrp,
cgrp->bpf.flags[atype] = saved_flags; cgrp->bpf.flags[atype] = saved_flags;
if (type == BPF_LSM_CGROUP) { if (type == BPF_LSM_CGROUP) {
err = bpf_trampoline_link_cgroup_shim(new_prog, atype); err = bpf_trampoline_link_cgroup_shim(new_prog, atype, type);
if (err) if (err)
goto cleanup; goto cleanup;
} }
@ -1495,7 +1495,7 @@ int cgroup_bpf_link_attach(const union bpf_attr *attr, struct bpf_prog *prog)
goto out_put_cgroup; goto out_put_cgroup;
} }
bpf_link_init(&link->link, BPF_LINK_TYPE_CGROUP, &bpf_cgroup_link_lops, bpf_link_init(&link->link, BPF_LINK_TYPE_CGROUP, &bpf_cgroup_link_lops,
prog); prog, attr->link_create.attach_type);
link->cgroup = cgrp; link->cgroup = cgrp;
link->type = attr->link_create.attach_type; link->type = attr->link_create.attach_type;

View file

@ -501,7 +501,7 @@ int netns_bpf_link_create(const union bpf_attr *attr, struct bpf_prog *prog)
goto out_put_net; goto out_put_net;
} }
bpf_link_init(&net_link->link, BPF_LINK_TYPE_NETNS, bpf_link_init(&net_link->link, BPF_LINK_TYPE_NETNS,
&bpf_netns_link_ops, prog); &bpf_netns_link_ops, prog, type);
net_link->net = net; net_link->net = net;
net_link->type = type; net_link->type = type;
net_link->netns_type = netns_type; net_link->netns_type = netns_type;

View file

@ -3069,7 +3069,7 @@ static int bpf_obj_get(const union bpf_attr *attr)
*/ */
void bpf_link_init_sleepable(struct bpf_link *link, enum bpf_link_type type, void bpf_link_init_sleepable(struct bpf_link *link, enum bpf_link_type type,
const struct bpf_link_ops *ops, struct bpf_prog *prog, const struct bpf_link_ops *ops, struct bpf_prog *prog,
bool sleepable) enum bpf_attach_type attach_type, bool sleepable)
{ {
WARN_ON(ops->dealloc && ops->dealloc_deferred); WARN_ON(ops->dealloc && ops->dealloc_deferred);
atomic64_set(&link->refcnt, 1); atomic64_set(&link->refcnt, 1);
@ -3078,12 +3078,14 @@ void bpf_link_init_sleepable(struct bpf_link *link, enum bpf_link_type type,
link->id = 0; link->id = 0;
link->ops = ops; link->ops = ops;
link->prog = prog; link->prog = prog;
link->attach_type = attach_type;
} }
void bpf_link_init(struct bpf_link *link, enum bpf_link_type type, void bpf_link_init(struct bpf_link *link, enum bpf_link_type type,
const struct bpf_link_ops *ops, struct bpf_prog *prog) const struct bpf_link_ops *ops, struct bpf_prog *prog,
enum bpf_attach_type attach_type)
{ {
bpf_link_init_sleepable(link, type, ops, prog, false); bpf_link_init_sleepable(link, type, ops, prog, attach_type, false);
} }
static void bpf_link_free_id(int id) static void bpf_link_free_id(int id)
@ -3443,7 +3445,8 @@ static const struct bpf_link_ops bpf_tracing_link_lops = {
static int bpf_tracing_prog_attach(struct bpf_prog *prog, static int bpf_tracing_prog_attach(struct bpf_prog *prog,
int tgt_prog_fd, int tgt_prog_fd,
u32 btf_id, u32 btf_id,
u64 bpf_cookie) u64 bpf_cookie,
enum bpf_attach_type attach_type)
{ {
struct bpf_link_primer link_primer; struct bpf_link_primer link_primer;
struct bpf_prog *tgt_prog = NULL; struct bpf_prog *tgt_prog = NULL;
@ -3511,7 +3514,8 @@ static int bpf_tracing_prog_attach(struct bpf_prog *prog,
goto out_put_prog; goto out_put_prog;
} }
bpf_link_init(&link->link.link, BPF_LINK_TYPE_TRACING, bpf_link_init(&link->link.link, BPF_LINK_TYPE_TRACING,
&bpf_tracing_link_lops, prog); &bpf_tracing_link_lops, prog, attach_type);
link->attach_type = prog->expected_attach_type; link->attach_type = prog->expected_attach_type;
link->link.cookie = bpf_cookie; link->link.cookie = bpf_cookie;
@ -4049,7 +4053,8 @@ static int bpf_perf_link_attach(const union bpf_attr *attr, struct bpf_prog *pro
err = -ENOMEM; err = -ENOMEM;
goto out_put_file; goto out_put_file;
} }
bpf_link_init(&link->link, BPF_LINK_TYPE_PERF_EVENT, &bpf_perf_link_lops, prog); bpf_link_init(&link->link, BPF_LINK_TYPE_PERF_EVENT, &bpf_perf_link_lops, prog,
attr->link_create.attach_type);
link->perf_file = perf_file; link->perf_file = perf_file;
err = bpf_link_prime(&link->link, &link_primer); err = bpf_link_prime(&link->link, &link_primer);
@ -4081,7 +4086,8 @@ static int bpf_perf_link_attach(const union bpf_attr *attr, struct bpf_prog *pro
#endif /* CONFIG_PERF_EVENTS */ #endif /* CONFIG_PERF_EVENTS */
static int bpf_raw_tp_link_attach(struct bpf_prog *prog, static int bpf_raw_tp_link_attach(struct bpf_prog *prog,
const char __user *user_tp_name, u64 cookie) const char __user *user_tp_name, u64 cookie,
enum bpf_attach_type attach_type)
{ {
struct bpf_link_primer link_primer; struct bpf_link_primer link_primer;
struct bpf_raw_tp_link *link; struct bpf_raw_tp_link *link;
@ -4104,7 +4110,7 @@ static int bpf_raw_tp_link_attach(struct bpf_prog *prog,
tp_name = prog->aux->attach_func_name; tp_name = prog->aux->attach_func_name;
break; break;
} }
return bpf_tracing_prog_attach(prog, 0, 0, 0); return bpf_tracing_prog_attach(prog, 0, 0, 0, attach_type);
case BPF_PROG_TYPE_RAW_TRACEPOINT: case BPF_PROG_TYPE_RAW_TRACEPOINT:
case BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE: case BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE:
if (strncpy_from_user(buf, user_tp_name, sizeof(buf) - 1) < 0) if (strncpy_from_user(buf, user_tp_name, sizeof(buf) - 1) < 0)
@ -4126,7 +4132,7 @@ static int bpf_raw_tp_link_attach(struct bpf_prog *prog,
goto out_put_btp; goto out_put_btp;
} }
bpf_link_init_sleepable(&link->link, BPF_LINK_TYPE_RAW_TRACEPOINT, bpf_link_init_sleepable(&link->link, BPF_LINK_TYPE_RAW_TRACEPOINT,
&bpf_raw_tp_link_lops, prog, &bpf_raw_tp_link_lops, prog, attach_type,
tracepoint_is_faultable(btp->tp)); tracepoint_is_faultable(btp->tp));
link->btp = btp; link->btp = btp;
link->cookie = cookie; link->cookie = cookie;
@ -4168,7 +4174,7 @@ static int bpf_raw_tracepoint_open(const union bpf_attr *attr)
tp_name = u64_to_user_ptr(attr->raw_tracepoint.name); tp_name = u64_to_user_ptr(attr->raw_tracepoint.name);
cookie = attr->raw_tracepoint.cookie; cookie = attr->raw_tracepoint.cookie;
fd = bpf_raw_tp_link_attach(prog, tp_name, cookie); fd = bpf_raw_tp_link_attach(prog, tp_name, cookie, prog->expected_attach_type);
if (fd < 0) if (fd < 0)
bpf_prog_put(prog); bpf_prog_put(prog);
return fd; return fd;
@ -5525,7 +5531,8 @@ static int link_create(union bpf_attr *attr, bpfptr_t uattr)
ret = bpf_tracing_prog_attach(prog, ret = bpf_tracing_prog_attach(prog,
attr->link_create.target_fd, attr->link_create.target_fd,
attr->link_create.target_btf_id, attr->link_create.target_btf_id,
attr->link_create.tracing.cookie); attr->link_create.tracing.cookie,
attr->link_create.attach_type);
break; break;
case BPF_PROG_TYPE_LSM: case BPF_PROG_TYPE_LSM:
case BPF_PROG_TYPE_TRACING: case BPF_PROG_TYPE_TRACING:
@ -5534,7 +5541,8 @@ static int link_create(union bpf_attr *attr, bpfptr_t uattr)
goto out; goto out;
} }
if (prog->expected_attach_type == BPF_TRACE_RAW_TP) if (prog->expected_attach_type == BPF_TRACE_RAW_TP)
ret = bpf_raw_tp_link_attach(prog, NULL, attr->link_create.tracing.cookie); ret = bpf_raw_tp_link_attach(prog, NULL, attr->link_create.tracing.cookie,
attr->link_create.attach_type);
else if (prog->expected_attach_type == BPF_TRACE_ITER) else if (prog->expected_attach_type == BPF_TRACE_ITER)
ret = bpf_iter_link_attach(attr, uattr, prog); ret = bpf_iter_link_attach(attr, uattr, prog);
else if (prog->expected_attach_type == BPF_LSM_CGROUP) else if (prog->expected_attach_type == BPF_LSM_CGROUP)
@ -5543,7 +5551,8 @@ static int link_create(union bpf_attr *attr, bpfptr_t uattr)
ret = bpf_tracing_prog_attach(prog, ret = bpf_tracing_prog_attach(prog,
attr->link_create.target_fd, attr->link_create.target_fd,
attr->link_create.target_btf_id, attr->link_create.target_btf_id,
attr->link_create.tracing.cookie); attr->link_create.tracing.cookie,
attr->link_create.attach_type);
break; break;
case BPF_PROG_TYPE_FLOW_DISSECTOR: case BPF_PROG_TYPE_FLOW_DISSECTOR:
case BPF_PROG_TYPE_SK_LOOKUP: case BPF_PROG_TYPE_SK_LOOKUP:

View file

@ -301,7 +301,8 @@ static int tcx_link_init(struct tcx_link *tcx,
struct net_device *dev, struct net_device *dev,
struct bpf_prog *prog) struct bpf_prog *prog)
{ {
bpf_link_init(&tcx->link, BPF_LINK_TYPE_TCX, &tcx_link_lops, prog); bpf_link_init(&tcx->link, BPF_LINK_TYPE_TCX, &tcx_link_lops, prog,
attr->link_create.attach_type);
tcx->location = attr->link_create.attach_type; tcx->location = attr->link_create.attach_type;
tcx->dev = dev; tcx->dev = dev;
return bpf_link_prime(&tcx->link, link_primer); return bpf_link_prime(&tcx->link, link_primer);

View file

@ -674,7 +674,8 @@ static const struct bpf_link_ops bpf_shim_tramp_link_lops = {
static struct bpf_shim_tramp_link *cgroup_shim_alloc(const struct bpf_prog *prog, static struct bpf_shim_tramp_link *cgroup_shim_alloc(const struct bpf_prog *prog,
bpf_func_t bpf_func, bpf_func_t bpf_func,
int cgroup_atype) int cgroup_atype,
enum bpf_attach_type attach_type)
{ {
struct bpf_shim_tramp_link *shim_link = NULL; struct bpf_shim_tramp_link *shim_link = NULL;
struct bpf_prog *p; struct bpf_prog *p;
@ -701,7 +702,7 @@ static struct bpf_shim_tramp_link *cgroup_shim_alloc(const struct bpf_prog *prog
p->expected_attach_type = BPF_LSM_MAC; p->expected_attach_type = BPF_LSM_MAC;
bpf_prog_inc(p); bpf_prog_inc(p);
bpf_link_init(&shim_link->link.link, BPF_LINK_TYPE_UNSPEC, bpf_link_init(&shim_link->link.link, BPF_LINK_TYPE_UNSPEC,
&bpf_shim_tramp_link_lops, p); &bpf_shim_tramp_link_lops, p, attach_type);
bpf_cgroup_atype_get(p->aux->attach_btf_id, cgroup_atype); bpf_cgroup_atype_get(p->aux->attach_btf_id, cgroup_atype);
return shim_link; return shim_link;
@ -726,7 +727,8 @@ static struct bpf_shim_tramp_link *cgroup_shim_find(struct bpf_trampoline *tr,
} }
int bpf_trampoline_link_cgroup_shim(struct bpf_prog *prog, int bpf_trampoline_link_cgroup_shim(struct bpf_prog *prog,
int cgroup_atype) int cgroup_atype,
enum bpf_attach_type attach_type)
{ {
struct bpf_shim_tramp_link *shim_link = NULL; struct bpf_shim_tramp_link *shim_link = NULL;
struct bpf_attach_target_info tgt_info = {}; struct bpf_attach_target_info tgt_info = {};
@ -763,7 +765,7 @@ int bpf_trampoline_link_cgroup_shim(struct bpf_prog *prog,
/* Allocate and install new shim. */ /* Allocate and install new shim. */
shim_link = cgroup_shim_alloc(prog, bpf_func, cgroup_atype); shim_link = cgroup_shim_alloc(prog, bpf_func, cgroup_atype, attach_type);
if (!shim_link) { if (!shim_link) {
err = -ENOMEM; err = -ENOMEM;
goto err; goto err;

View file

@ -2986,7 +2986,7 @@ int bpf_kprobe_multi_link_attach(const union bpf_attr *attr, struct bpf_prog *pr
} }
bpf_link_init(&link->link, BPF_LINK_TYPE_KPROBE_MULTI, bpf_link_init(&link->link, BPF_LINK_TYPE_KPROBE_MULTI,
&bpf_kprobe_multi_link_lops, prog); &bpf_kprobe_multi_link_lops, prog, attr->link_create.attach_type);
err = bpf_link_prime(&link->link, &link_primer); err = bpf_link_prime(&link->link, &link_primer);
if (err) if (err)
@ -3441,7 +3441,7 @@ int bpf_uprobe_multi_link_attach(const union bpf_attr *attr, struct bpf_prog *pr
link->link.flags = flags; link->link.flags = flags;
bpf_link_init(&link->link, BPF_LINK_TYPE_UPROBE_MULTI, bpf_link_init(&link->link, BPF_LINK_TYPE_UPROBE_MULTI,
&bpf_uprobe_multi_link_lops, prog); &bpf_uprobe_multi_link_lops, prog, attr->link_create.attach_type);
for (i = 0; i < cnt; i++) { for (i = 0; i < cnt; i++) {
uprobes[i].uprobe = uprobe_register(d_real_inode(link->path.dentry), uprobes[i].uprobe = uprobe_register(d_real_inode(link->path.dentry),

View file

@ -171,7 +171,8 @@ int bpf_struct_ops_test_run(struct bpf_prog *prog, const union bpf_attr *kattr,
} }
/* prog doesn't take the ownership of the reference from caller */ /* prog doesn't take the ownership of the reference from caller */
bpf_prog_inc(prog); bpf_prog_inc(prog);
bpf_link_init(&link->link, BPF_LINK_TYPE_STRUCT_OPS, &bpf_struct_ops_link_lops, prog); bpf_link_init(&link->link, BPF_LINK_TYPE_STRUCT_OPS, &bpf_struct_ops_link_lops, prog,
prog->expected_attach_type);
op_idx = prog->expected_attach_type; op_idx = prog->expected_attach_type;
err = bpf_struct_ops_prepare_trampoline(tlinks, link, err = bpf_struct_ops_prepare_trampoline(tlinks, link,

View file

@ -10364,7 +10364,8 @@ int bpf_xdp_link_attach(const union bpf_attr *attr, struct bpf_prog *prog)
goto unlock; goto unlock;
} }
bpf_link_init(&link->link, BPF_LINK_TYPE_XDP, &bpf_xdp_link_lops, prog); bpf_link_init(&link->link, BPF_LINK_TYPE_XDP, &bpf_xdp_link_lops, prog,
attr->link_create.attach_type);
link->dev = dev; link->dev = dev;
link->flags = attr->link_create.flags; link->flags = attr->link_create.flags;

View file

@ -1866,7 +1866,8 @@ int sock_map_link_create(const union bpf_attr *attr, struct bpf_prog *prog)
} }
attach_type = attr->link_create.attach_type; attach_type = attr->link_create.attach_type;
bpf_link_init(&sockmap_link->link, BPF_LINK_TYPE_SOCKMAP, &sock_map_link_ops, prog); bpf_link_init(&sockmap_link->link, BPF_LINK_TYPE_SOCKMAP, &sock_map_link_ops, prog,
attach_type);
sockmap_link->map = map; sockmap_link->map = map;
sockmap_link->attach_type = attach_type; sockmap_link->attach_type = attach_type;

View file

@ -225,7 +225,8 @@ int bpf_nf_link_attach(const union bpf_attr *attr, struct bpf_prog *prog)
if (!link) if (!link)
return -ENOMEM; return -ENOMEM;
bpf_link_init(&link->link, BPF_LINK_TYPE_NETFILTER, &bpf_nf_link_lops, prog); bpf_link_init(&link->link, BPF_LINK_TYPE_NETFILTER, &bpf_nf_link_lops, prog,
attr->link_create.attach_type);
link->hook_ops.hook = nf_hook_run_bpf; link->hook_ops.hook = nf_hook_run_bpf;
link->hook_ops.hook_ops_type = NF_HOOK_OP_BPF; link->hook_ops.hook_ops_type = NF_HOOK_OP_BPF;