1 // SPDX-License-Identifier: GPL-2.0
3 #include <linux/filter.h>
4 #include <linux/kmod.h>
5 #include <linux/module.h>
6 #include <linux/netfilter.h>
8 #include <net/netfilter/nf_bpf_link.h>
9 #include <uapi/linux/netfilter_ipv4.h>
11 static unsigned int nf_hook_run_bpf(void *bpf_prog
, struct sk_buff
*skb
,
12 const struct nf_hook_state
*s
)
14 const struct bpf_prog
*prog
= bpf_prog
;
15 struct bpf_nf_ctx ctx
= {
20 return bpf_prog_run(prog
, &ctx
);
25 struct nf_hook_ops hook_ops
;
28 const struct nf_defrag_hook
*defrag_hook
;
31 #if IS_ENABLED(CONFIG_NF_DEFRAG_IPV4) || IS_ENABLED(CONFIG_NF_DEFRAG_IPV6)
32 static const struct nf_defrag_hook
*
33 get_proto_defrag_hook(struct bpf_nf_link
*link
,
34 const struct nf_defrag_hook __rcu
**ptr_global_hook
,
37 const struct nf_defrag_hook
*hook
;
40 /* RCU protects us from races against module unloading */
42 hook
= rcu_dereference(*ptr_global_hook
);
45 err
= request_module(mod
);
47 return ERR_PTR(err
< 0 ? err
: -EINVAL
);
50 hook
= rcu_dereference(*ptr_global_hook
);
53 if (hook
&& try_module_get(hook
->owner
)) {
54 /* Once we have a refcnt on the module, we no longer need RCU */
55 hook
= rcu_pointer_handoff(hook
);
57 WARN_ONCE(!hook
, "%s has bad registration", mod
);
58 hook
= ERR_PTR(-ENOENT
);
63 err
= hook
->enable(link
->net
);
65 module_put(hook
->owner
);
74 static int bpf_nf_enable_defrag(struct bpf_nf_link
*link
)
76 const struct nf_defrag_hook __maybe_unused
*hook
;
78 switch (link
->hook_ops
.pf
) {
79 #if IS_ENABLED(CONFIG_NF_DEFRAG_IPV4)
81 hook
= get_proto_defrag_hook(link
, &nf_defrag_v4_hook
, "nf_defrag_ipv4");
85 link
->defrag_hook
= hook
;
88 #if IS_ENABLED(CONFIG_NF_DEFRAG_IPV6)
90 hook
= get_proto_defrag_hook(link
, &nf_defrag_v6_hook
, "nf_defrag_ipv6");
94 link
->defrag_hook
= hook
;
102 static void bpf_nf_disable_defrag(struct bpf_nf_link
*link
)
104 const struct nf_defrag_hook
*hook
= link
->defrag_hook
;
108 hook
->disable(link
->net
);
109 module_put(hook
->owner
);
112 static void bpf_nf_link_release(struct bpf_link
*link
)
114 struct bpf_nf_link
*nf_link
= container_of(link
, struct bpf_nf_link
, link
);
119 /* do not double release in case .detach was already called */
120 if (!cmpxchg(&nf_link
->dead
, 0, 1)) {
121 nf_unregister_net_hook(nf_link
->net
, &nf_link
->hook_ops
);
122 bpf_nf_disable_defrag(nf_link
);
126 static void bpf_nf_link_dealloc(struct bpf_link
*link
)
128 struct bpf_nf_link
*nf_link
= container_of(link
, struct bpf_nf_link
, link
);
133 static int bpf_nf_link_detach(struct bpf_link
*link
)
135 bpf_nf_link_release(link
);
139 static void bpf_nf_link_show_info(const struct bpf_link
*link
,
140 struct seq_file
*seq
)
142 struct bpf_nf_link
*nf_link
= container_of(link
, struct bpf_nf_link
, link
);
144 seq_printf(seq
, "pf:\t%u\thooknum:\t%u\tprio:\t%d\n",
145 nf_link
->hook_ops
.pf
, nf_link
->hook_ops
.hooknum
,
146 nf_link
->hook_ops
.priority
);
149 static int bpf_nf_link_fill_link_info(const struct bpf_link
*link
,
150 struct bpf_link_info
*info
)
152 struct bpf_nf_link
*nf_link
= container_of(link
, struct bpf_nf_link
, link
);
154 info
->netfilter
.pf
= nf_link
->hook_ops
.pf
;
155 info
->netfilter
.hooknum
= nf_link
->hook_ops
.hooknum
;
156 info
->netfilter
.priority
= nf_link
->hook_ops
.priority
;
157 info
->netfilter
.flags
= 0;
162 static int bpf_nf_link_update(struct bpf_link
*link
, struct bpf_prog
*new_prog
,
163 struct bpf_prog
*old_prog
)
168 static const struct bpf_link_ops bpf_nf_link_lops
= {
169 .release
= bpf_nf_link_release
,
170 .dealloc
= bpf_nf_link_dealloc
,
171 .detach
= bpf_nf_link_detach
,
172 .show_fdinfo
= bpf_nf_link_show_info
,
173 .fill_link_info
= bpf_nf_link_fill_link_info
,
174 .update_prog
= bpf_nf_link_update
,
177 static int bpf_nf_check_pf_and_hooks(const union bpf_attr
*attr
)
181 switch (attr
->link_create
.netfilter
.pf
) {
184 if (attr
->link_create
.netfilter
.hooknum
>= NF_INET_NUMHOOKS
)
188 return -EAFNOSUPPORT
;
191 if (attr
->link_create
.netfilter
.flags
& ~BPF_F_NETFILTER_IP_DEFRAG
)
194 /* make sure conntrack confirm is always last */
195 prio
= attr
->link_create
.netfilter
.priority
;
196 if (prio
== NF_IP_PRI_FIRST
)
197 return -ERANGE
; /* sabotage_in and other warts */
198 else if (prio
== NF_IP_PRI_LAST
)
199 return -ERANGE
; /* e.g. conntrack confirm */
200 else if ((attr
->link_create
.netfilter
.flags
& BPF_F_NETFILTER_IP_DEFRAG
) &&
201 prio
<= NF_IP_PRI_CONNTRACK_DEFRAG
)
202 return -ERANGE
; /* cannot use defrag if prog runs before nf_defrag */
207 int bpf_nf_link_attach(const union bpf_attr
*attr
, struct bpf_prog
*prog
)
209 struct net
*net
= current
->nsproxy
->net_ns
;
210 struct bpf_link_primer link_primer
;
211 struct bpf_nf_link
*link
;
214 if (attr
->link_create
.flags
)
217 err
= bpf_nf_check_pf_and_hooks(attr
);
221 link
= kzalloc(sizeof(*link
), GFP_USER
);
225 bpf_link_init(&link
->link
, BPF_LINK_TYPE_NETFILTER
, &bpf_nf_link_lops
, prog
);
227 link
->hook_ops
.hook
= nf_hook_run_bpf
;
228 link
->hook_ops
.hook_ops_type
= NF_HOOK_OP_BPF
;
229 link
->hook_ops
.priv
= prog
;
231 link
->hook_ops
.pf
= attr
->link_create
.netfilter
.pf
;
232 link
->hook_ops
.priority
= attr
->link_create
.netfilter
.priority
;
233 link
->hook_ops
.hooknum
= attr
->link_create
.netfilter
.hooknum
;
237 link
->defrag_hook
= NULL
;
239 err
= bpf_link_prime(&link
->link
, &link_primer
);
245 if (attr
->link_create
.netfilter
.flags
& BPF_F_NETFILTER_IP_DEFRAG
) {
246 err
= bpf_nf_enable_defrag(link
);
248 bpf_link_cleanup(&link_primer
);
253 err
= nf_register_net_hook(net
, &link
->hook_ops
);
255 bpf_nf_disable_defrag(link
);
256 bpf_link_cleanup(&link_primer
);
260 return bpf_link_settle(&link_primer
);
263 const struct bpf_prog_ops netfilter_prog_ops
= {
264 .test_run
= bpf_prog_test_run_nf
,
267 static bool nf_ptr_to_btf_id(struct bpf_insn_access_aux
*info
, const char *name
)
272 btf
= bpf_get_btf_vmlinux();
273 if (IS_ERR_OR_NULL(btf
))
276 type_id
= btf_find_by_name_kind(btf
, name
, BTF_KIND_STRUCT
);
277 if (WARN_ON_ONCE(type_id
< 0))
281 info
->btf_id
= type_id
;
282 info
->reg_type
= PTR_TO_BTF_ID
| PTR_TRUSTED
;
286 static bool nf_is_valid_access(int off
, int size
, enum bpf_access_type type
,
287 const struct bpf_prog
*prog
,
288 struct bpf_insn_access_aux
*info
)
290 if (off
< 0 || off
>= sizeof(struct bpf_nf_ctx
))
293 if (type
== BPF_WRITE
)
297 case bpf_ctx_range(struct bpf_nf_ctx
, skb
):
298 if (size
!= sizeof_field(struct bpf_nf_ctx
, skb
))
301 return nf_ptr_to_btf_id(info
, "sk_buff");
302 case bpf_ctx_range(struct bpf_nf_ctx
, state
):
303 if (size
!= sizeof_field(struct bpf_nf_ctx
, state
))
306 return nf_ptr_to_btf_id(info
, "nf_hook_state");
314 static const struct bpf_func_proto
*
315 bpf_nf_func_proto(enum bpf_func_id func_id
, const struct bpf_prog
*prog
)
317 return bpf_base_func_proto(func_id
);
320 const struct bpf_verifier_ops netfilter_verifier_ops
= {
321 .is_valid_access
= nf_is_valid_access
,
322 .get_func_proto
= bpf_nf_func_proto
,