xref: /linux-6.15/net/netfilter/nf_queue.c (revision ce628966)
1 /*
2  * Rusty Russell (C)2000 -- This code is GPL.
3  * Patrick McHardy (c) 2006-2012
4  */
5 
6 #include <linux/kernel.h>
7 #include <linux/slab.h>
8 #include <linux/init.h>
9 #include <linux/module.h>
10 #include <linux/proc_fs.h>
11 #include <linux/skbuff.h>
12 #include <linux/netfilter.h>
13 #include <linux/netfilter_ipv4.h>
14 #include <linux/netfilter_ipv6.h>
15 #include <linux/netfilter_bridge.h>
16 #include <linux/seq_file.h>
17 #include <linux/rcupdate.h>
18 #include <linux/netfilter_ipv4.h>
19 #include <linux/netfilter_ipv6.h>
20 #include <net/protocol.h>
21 #include <net/netfilter/nf_queue.h>
22 #include <net/dst.h>
23 
24 #include "nf_internals.h"
25 
26 /*
27  * Hook for nfnetlink_queue to register its queue handler.
28  * We do this so that most of the NFQUEUE code can be modular.
29  *
30  * Once the queue is registered it must reinject all packets it
31  * receives, no matter what.
32  */
33 
34 /* return EBUSY when somebody else is registered, return EEXIST if the
35  * same handler is registered, return 0 in case of success. */
36 void nf_register_queue_handler(struct net *net, const struct nf_queue_handler *qh)
37 {
38 	/* should never happen, we only have one queueing backend in kernel */
39 	WARN_ON(rcu_access_pointer(net->nf.queue_handler));
40 	rcu_assign_pointer(net->nf.queue_handler, qh);
41 }
42 EXPORT_SYMBOL(nf_register_queue_handler);
43 
44 /* The caller must flush their queue before this */
45 void nf_unregister_queue_handler(struct net *net)
46 {
47 	RCU_INIT_POINTER(net->nf.queue_handler, NULL);
48 }
49 EXPORT_SYMBOL(nf_unregister_queue_handler);
50 
51 void nf_queue_entry_release_refs(struct nf_queue_entry *entry)
52 {
53 	struct nf_hook_state *state = &entry->state;
54 
55 	/* Release those devices we held, or Alexey will kill me. */
56 	if (state->in)
57 		dev_put(state->in);
58 	if (state->out)
59 		dev_put(state->out);
60 	if (state->sk)
61 		sock_put(state->sk);
62 #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
63 	if (entry->skb->nf_bridge) {
64 		struct net_device *physdev;
65 
66 		physdev = nf_bridge_get_physindev(entry->skb);
67 		if (physdev)
68 			dev_put(physdev);
69 		physdev = nf_bridge_get_physoutdev(entry->skb);
70 		if (physdev)
71 			dev_put(physdev);
72 	}
73 #endif
74 }
75 EXPORT_SYMBOL_GPL(nf_queue_entry_release_refs);
76 
77 /* Bump dev refs so they don't vanish while packet is out */
78 void nf_queue_entry_get_refs(struct nf_queue_entry *entry)
79 {
80 	struct nf_hook_state *state = &entry->state;
81 
82 	if (state->in)
83 		dev_hold(state->in);
84 	if (state->out)
85 		dev_hold(state->out);
86 	if (state->sk)
87 		sock_hold(state->sk);
88 #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
89 	if (entry->skb->nf_bridge) {
90 		struct net_device *physdev;
91 
92 		physdev = nf_bridge_get_physindev(entry->skb);
93 		if (physdev)
94 			dev_hold(physdev);
95 		physdev = nf_bridge_get_physoutdev(entry->skb);
96 		if (physdev)
97 			dev_hold(physdev);
98 	}
99 #endif
100 }
101 EXPORT_SYMBOL_GPL(nf_queue_entry_get_refs);
102 
103 void nf_queue_nf_hook_drop(struct net *net)
104 {
105 	const struct nf_queue_handler *qh;
106 
107 	rcu_read_lock();
108 	qh = rcu_dereference(net->nf.queue_handler);
109 	if (qh)
110 		qh->nf_hook_drop(net);
111 	rcu_read_unlock();
112 }
113 EXPORT_SYMBOL_GPL(nf_queue_nf_hook_drop);
114 
115 static void nf_ip_saveroute(const struct sk_buff *skb,
116 			    struct nf_queue_entry *entry)
117 {
118 	struct ip_rt_info *rt_info = nf_queue_entry_reroute(entry);
119 
120 	if (entry->state.hook == NF_INET_LOCAL_OUT) {
121 		const struct iphdr *iph = ip_hdr(skb);
122 
123 		rt_info->tos = iph->tos;
124 		rt_info->daddr = iph->daddr;
125 		rt_info->saddr = iph->saddr;
126 		rt_info->mark = skb->mark;
127 	}
128 }
129 
130 static void nf_ip6_saveroute(const struct sk_buff *skb,
131 			     struct nf_queue_entry *entry)
132 {
133 	struct ip6_rt_info *rt_info = nf_queue_entry_reroute(entry);
134 
135 	if (entry->state.hook == NF_INET_LOCAL_OUT) {
136 		const struct ipv6hdr *iph = ipv6_hdr(skb);
137 
138 		rt_info->daddr = iph->daddr;
139 		rt_info->saddr = iph->saddr;
140 		rt_info->mark = skb->mark;
141 	}
142 }
143 
144 static int __nf_queue(struct sk_buff *skb, const struct nf_hook_state *state,
145 		      const struct nf_hook_entries *entries,
146 		      unsigned int index, unsigned int queuenum)
147 {
148 	int status = -ENOENT;
149 	struct nf_queue_entry *entry = NULL;
150 	const struct nf_queue_handler *qh;
151 	struct net *net = state->net;
152 	unsigned int route_key_size;
153 
154 	/* QUEUE == DROP if no one is waiting, to be safe. */
155 	qh = rcu_dereference(net->nf.queue_handler);
156 	if (!qh) {
157 		status = -ESRCH;
158 		goto err;
159 	}
160 
161 	switch (state->pf) {
162 	case AF_INET:
163 		route_key_size = sizeof(struct ip_rt_info);
164 		break;
165 	case AF_INET6:
166 		route_key_size = sizeof(struct ip6_rt_info);
167 		break;
168 	default:
169 		route_key_size = 0;
170 		break;
171 	}
172 
173 	entry = kmalloc(sizeof(*entry) + route_key_size, GFP_ATOMIC);
174 	if (!entry) {
175 		status = -ENOMEM;
176 		goto err;
177 	}
178 
179 	*entry = (struct nf_queue_entry) {
180 		.skb	= skb,
181 		.state	= *state,
182 		.hook_index = index,
183 		.size	= sizeof(*entry) + route_key_size,
184 	};
185 
186 	nf_queue_entry_get_refs(entry);
187 	skb_dst_force(skb);
188 
189 	switch (entry->state.pf) {
190 	case AF_INET:
191 		nf_ip_saveroute(skb, entry);
192 		break;
193 	case AF_INET6:
194 		nf_ip6_saveroute(skb, entry);
195 		break;
196 	}
197 
198 	status = qh->outfn(entry, queuenum);
199 
200 	if (status < 0) {
201 		nf_queue_entry_release_refs(entry);
202 		goto err;
203 	}
204 
205 	return 0;
206 
207 err:
208 	kfree(entry);
209 	return status;
210 }
211 
212 /* Packets leaving via this function must come back through nf_reinject(). */
213 int nf_queue(struct sk_buff *skb, struct nf_hook_state *state,
214 	     const struct nf_hook_entries *entries, unsigned int index,
215 	     unsigned int verdict)
216 {
217 	int ret;
218 
219 	ret = __nf_queue(skb, state, entries, index, verdict >> NF_VERDICT_QBITS);
220 	if (ret < 0) {
221 		if (ret == -ESRCH &&
222 		    (verdict & NF_VERDICT_FLAG_QUEUE_BYPASS))
223 			return 1;
224 		kfree_skb(skb);
225 	}
226 
227 	return 0;
228 }
229 
230 static unsigned int nf_iterate(struct sk_buff *skb,
231 			       struct nf_hook_state *state,
232 			       const struct nf_hook_entries *hooks,
233 			       unsigned int *index)
234 {
235 	const struct nf_hook_entry *hook;
236 	unsigned int verdict, i = *index;
237 
238 	while (i < hooks->num_hook_entries) {
239 		hook = &hooks->hooks[i];
240 repeat:
241 		verdict = nf_hook_entry_hookfn(hook, skb, state);
242 		if (verdict != NF_ACCEPT) {
243 			if (verdict != NF_REPEAT)
244 				return verdict;
245 			goto repeat;
246 		}
247 		i++;
248 	}
249 
250 	*index = i;
251 	return NF_ACCEPT;
252 }
253 
254 static struct nf_hook_entries *nf_hook_entries_head(const struct net *net, u8 pf, u8 hooknum)
255 {
256 	switch (pf) {
257 #ifdef CONFIG_NETFILTER_FAMILY_BRIDGE
258 	case NFPROTO_BRIDGE:
259 		return rcu_dereference(net->nf.hooks_bridge[hooknum]);
260 #endif
261 	case NFPROTO_IPV4:
262 		return rcu_dereference(net->nf.hooks_ipv4[hooknum]);
263 	case NFPROTO_IPV6:
264 		return rcu_dereference(net->nf.hooks_ipv6[hooknum]);
265 	default:
266 		WARN_ON_ONCE(1);
267 		return NULL;
268 	}
269 
270 	return NULL;
271 }
272 
273 /* Caller must hold rcu read-side lock */
274 void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict)
275 {
276 	const struct nf_hook_entry *hook_entry;
277 	const struct nf_hook_entries *hooks;
278 	struct sk_buff *skb = entry->skb;
279 	const struct net *net;
280 	unsigned int i;
281 	int err;
282 	u8 pf;
283 
284 	net = entry->state.net;
285 	pf = entry->state.pf;
286 
287 	hooks = nf_hook_entries_head(net, pf, entry->state.hook);
288 
289 	nf_queue_entry_release_refs(entry);
290 
291 	i = entry->hook_index;
292 	if (WARN_ON_ONCE(!hooks || i >= hooks->num_hook_entries)) {
293 		kfree_skb(skb);
294 		kfree(entry);
295 		return;
296 	}
297 
298 	hook_entry = &hooks->hooks[i];
299 
300 	/* Continue traversal iff userspace said ok... */
301 	if (verdict == NF_REPEAT)
302 		verdict = nf_hook_entry_hookfn(hook_entry, skb, &entry->state);
303 
304 	if (verdict == NF_ACCEPT) {
305 		if (nf_reroute(skb, entry) < 0)
306 			verdict = NF_DROP;
307 	}
308 
309 	if (verdict == NF_ACCEPT) {
310 next_hook:
311 		++i;
312 		verdict = nf_iterate(skb, &entry->state, hooks, &i);
313 	}
314 
315 	switch (verdict & NF_VERDICT_MASK) {
316 	case NF_ACCEPT:
317 	case NF_STOP:
318 		local_bh_disable();
319 		entry->state.okfn(entry->state.net, entry->state.sk, skb);
320 		local_bh_enable();
321 		break;
322 	case NF_QUEUE:
323 		err = nf_queue(skb, &entry->state, hooks, i, verdict);
324 		if (err == 1)
325 			goto next_hook;
326 		break;
327 	case NF_STOLEN:
328 		break;
329 	default:
330 		kfree_skb(skb);
331 	}
332 
333 	kfree(entry);
334 }
335 EXPORT_SYMBOL(nf_reinject);
336