.. | .. |
---|
13 | 13 | #include <linux/static_key.h> |
---|
14 | 14 | #include <linux/netfilter_defs.h> |
---|
15 | 15 | #include <linux/netdevice.h> |
---|
| 16 | +#include <linux/sockptr.h> |
---|
| 17 | +#include <linux/android_kabi.h> |
---|
16 | 18 | #include <net/net_namespace.h> |
---|
17 | 19 | |
---|
18 | | -#ifdef CONFIG_NETFILTER |
---|
19 | 20 | static inline int NF_DROP_GETERR(int verdict) |
---|
20 | 21 | { |
---|
21 | 22 | return -(verdict >> NF_VERDICT_QBITS); |
---|
.. | .. |
---|
24 | 25 | static inline int nf_inet_addr_cmp(const union nf_inet_addr *a1, |
---|
25 | 26 | const union nf_inet_addr *a2) |
---|
26 | 27 | { |
---|
| 28 | +#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64 |
---|
| 29 | + const unsigned long *ul1 = (const unsigned long *)a1; |
---|
| 30 | + const unsigned long *ul2 = (const unsigned long *)a2; |
---|
| 31 | + |
---|
| 32 | + return ((ul1[0] ^ ul2[0]) | (ul1[1] ^ ul2[1])) == 0UL; |
---|
| 33 | +#else |
---|
27 | 34 | return a1->all[0] == a2->all[0] && |
---|
28 | 35 | a1->all[1] == a2->all[1] && |
---|
29 | 36 | a1->all[2] == a2->all[2] && |
---|
30 | 37 | a1->all[3] == a2->all[3]; |
---|
| 38 | +#endif |
---|
31 | 39 | } |
---|
32 | 40 | |
---|
33 | 41 | static inline void nf_inet_addr_mask(const union nf_inet_addr *a1, |
---|
34 | 42 | union nf_inet_addr *result, |
---|
35 | 43 | const union nf_inet_addr *mask) |
---|
36 | 44 | { |
---|
| 45 | +#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64 |
---|
| 46 | + const unsigned long *ua = (const unsigned long *)a1; |
---|
| 47 | + unsigned long *ur = (unsigned long *)result; |
---|
| 48 | + const unsigned long *um = (const unsigned long *)mask; |
---|
| 49 | + |
---|
| 50 | + ur[0] = ua[0] & um[0]; |
---|
| 51 | + ur[1] = ua[1] & um[1]; |
---|
| 52 | +#else |
---|
37 | 53 | result->all[0] = a1->all[0] & mask->all[0]; |
---|
38 | 54 | result->all[1] = a1->all[1] & mask->all[1]; |
---|
39 | 55 | result->all[2] = a1->all[2] & mask->all[2]; |
---|
40 | 56 | result->all[3] = a1->all[3] & mask->all[3]; |
---|
| 57 | +#endif |
---|
41 | 58 | } |
---|
42 | 59 | |
---|
43 | 60 | int netfilter_init(void); |
---|
.. | .. |
---|
102 | 119 | */ |
---|
103 | 120 | }; |
---|
104 | 121 | |
---|
| 122 | +#ifdef CONFIG_NETFILTER |
---|
105 | 123 | static inline struct nf_hook_ops **nf_hook_entries_get_hook_ops(const struct nf_hook_entries *e) |
---|
106 | 124 | { |
---|
107 | 125 | unsigned int n = e->num_hook_entries; |
---|
.. | .. |
---|
147 | 165 | /* Non-inclusive ranges: use 0/0/NULL to never get called. */ |
---|
148 | 166 | int set_optmin; |
---|
149 | 167 | int set_optmax; |
---|
150 | | - int (*set)(struct sock *sk, int optval, void __user *user, unsigned int len); |
---|
151 | | -#ifdef CONFIG_COMPAT |
---|
152 | | - int (*compat_set)(struct sock *sk, int optval, |
---|
153 | | - void __user *user, unsigned int len); |
---|
154 | | -#endif |
---|
| 168 | + int (*set)(struct sock *sk, int optval, sockptr_t arg, |
---|
| 169 | + unsigned int len); |
---|
155 | 170 | int get_optmin; |
---|
156 | 171 | int get_optmax; |
---|
157 | 172 | int (*get)(struct sock *sk, int optval, void __user *user, int *len); |
---|
158 | | -#ifdef CONFIG_COMPAT |
---|
159 | | - int (*compat_get)(struct sock *sk, int optval, |
---|
160 | | - void __user *user, int *len); |
---|
161 | | -#endif |
---|
162 | 173 | /* Use the module struct to lock set/get code in place */ |
---|
163 | 174 | struct module *owner; |
---|
| 175 | + |
---|
| 176 | + ANDROID_KABI_RESERVE(1); |
---|
164 | 177 | }; |
---|
165 | 178 | |
---|
166 | 179 | /* Function to register/unregister hook points. */ |
---|
.. | .. |
---|
183 | 196 | int nf_hook_slow(struct sk_buff *skb, struct nf_hook_state *state, |
---|
184 | 197 | const struct nf_hook_entries *e, unsigned int i); |
---|
185 | 198 | |
---|
| 199 | +void nf_hook_slow_list(struct list_head *head, struct nf_hook_state *state, |
---|
| 200 | + const struct nf_hook_entries *e); |
---|
186 | 201 | /** |
---|
187 | 202 | * nf_hook - call a netfilter hook |
---|
188 | 203 | * |
---|
.. | .. |
---|
295 | 310 | struct list_head *head, struct net_device *in, struct net_device *out, |
---|
296 | 311 | int (*okfn)(struct net *, struct sock *, struct sk_buff *)) |
---|
297 | 312 | { |
---|
298 | | - struct sk_buff *skb, *next; |
---|
299 | | - struct list_head sublist; |
---|
| 313 | + struct nf_hook_entries *hook_head = NULL; |
---|
300 | 314 | |
---|
301 | | - INIT_LIST_HEAD(&sublist); |
---|
302 | | - list_for_each_entry_safe(skb, next, head, list) { |
---|
303 | | - skb_list_del_init(skb); |
---|
304 | | - if (nf_hook(pf, hook, net, sk, skb, in, out, okfn) == 1) |
---|
305 | | - list_add_tail(&skb->list, &sublist); |
---|
| 315 | +#ifdef CONFIG_JUMP_LABEL |
---|
| 316 | + if (__builtin_constant_p(pf) && |
---|
| 317 | + __builtin_constant_p(hook) && |
---|
| 318 | + !static_key_false(&nf_hooks_needed[pf][hook])) |
---|
| 319 | + return; |
---|
| 320 | +#endif |
---|
| 321 | + |
---|
| 322 | + rcu_read_lock(); |
---|
| 323 | + switch (pf) { |
---|
| 324 | + case NFPROTO_IPV4: |
---|
| 325 | + hook_head = rcu_dereference(net->nf.hooks_ipv4[hook]); |
---|
| 326 | + break; |
---|
| 327 | + case NFPROTO_IPV6: |
---|
| 328 | + hook_head = rcu_dereference(net->nf.hooks_ipv6[hook]); |
---|
| 329 | + break; |
---|
| 330 | + default: |
---|
| 331 | + WARN_ON_ONCE(1); |
---|
| 332 | + break; |
---|
306 | 333 | } |
---|
307 | | - /* Put passed packets back on main list */ |
---|
308 | | - list_splice(&sublist, head); |
---|
| 334 | + |
---|
| 335 | + if (hook_head) { |
---|
| 336 | + struct nf_hook_state state; |
---|
| 337 | + |
---|
| 338 | + nf_hook_state_init(&state, hook, pf, in, out, sk, net, okfn); |
---|
| 339 | + |
---|
| 340 | + nf_hook_slow_list(head, &state, hook_head); |
---|
| 341 | + } |
---|
| 342 | + rcu_read_unlock(); |
---|
309 | 343 | } |
---|
310 | 344 | |
---|
311 | 345 | /* Call setsockopt() */ |
---|
312 | | -int nf_setsockopt(struct sock *sk, u_int8_t pf, int optval, char __user *opt, |
---|
| 346 | +int nf_setsockopt(struct sock *sk, u_int8_t pf, int optval, sockptr_t opt, |
---|
313 | 347 | unsigned int len); |
---|
314 | 348 | int nf_getsockopt(struct sock *sk, u_int8_t pf, int optval, char __user *opt, |
---|
315 | 349 | int *len); |
---|
316 | | -#ifdef CONFIG_COMPAT |
---|
317 | | -int compat_nf_setsockopt(struct sock *sk, u_int8_t pf, int optval, |
---|
318 | | - char __user *opt, unsigned int len); |
---|
319 | | -int compat_nf_getsockopt(struct sock *sk, u_int8_t pf, int optval, |
---|
320 | | - char __user *opt, int *len); |
---|
321 | | -#endif |
---|
322 | | - |
---|
323 | | -/* Call this before modifying an existing packet: ensures it is |
---|
324 | | - modifiable and linear to the point you care about (writable_len). |
---|
325 | | - Returns true or false. */ |
---|
326 | | -int skb_make_writable(struct sk_buff *skb, unsigned int writable_len); |
---|
327 | 350 | |
---|
328 | 351 | struct flowi; |
---|
329 | 352 | struct nf_queue_entry; |
---|
.. | .. |
---|
353 | 376 | unsigned int (*manip_pkt)(struct sk_buff *skb, struct nf_conn *ct, |
---|
354 | 377 | enum nf_nat_manip_type mtype, |
---|
355 | 378 | enum ip_conntrack_dir dir); |
---|
| 379 | + |
---|
| 380 | + ANDROID_KABI_RESERVE(1); |
---|
356 | 381 | }; |
---|
357 | 382 | |
---|
358 | 383 | extern struct nf_nat_hook __rcu *nf_nat_hook; |
---|
.. | .. |
---|
360 | 385 | static inline void |
---|
361 | 386 | nf_nat_decode_session(struct sk_buff *skb, struct flowi *fl, u_int8_t family) |
---|
362 | 387 | { |
---|
363 | | -#ifdef CONFIG_NF_NAT_NEEDED |
---|
| 388 | +#if IS_ENABLED(CONFIG_NF_NAT) |
---|
364 | 389 | struct nf_nat_hook *nat_hook; |
---|
365 | 390 | |
---|
366 | 391 | rcu_read_lock(); |
---|
.. | .. |
---|
411 | 436 | } |
---|
412 | 437 | #endif /*CONFIG_NETFILTER*/ |
---|
413 | 438 | |
---|
414 | | -#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) |
---|
| 439 | +#if IS_ENABLED(CONFIG_NF_CONNTRACK) |
---|
415 | 440 | #include <linux/netfilter/nf_conntrack_zones_common.h> |
---|
416 | 441 | |
---|
417 | 442 | extern void (*ip_ct_attach)(struct sk_buff *, const struct sk_buff *) __rcu; |
---|
.. | .. |
---|
437 | 462 | void (*destroy)(struct nf_conntrack *); |
---|
438 | 463 | bool (*get_tuple_skb)(struct nf_conntrack_tuple *, |
---|
439 | 464 | const struct sk_buff *); |
---|
| 465 | + |
---|
| 466 | + ANDROID_KABI_RESERVE(1); |
---|
440 | 467 | }; |
---|
441 | 468 | extern struct nf_ct_hook __rcu *nf_ct_hook; |
---|
442 | 469 | |
---|
.. | .. |
---|
454 | 481 | u32 portid, u32 report); |
---|
455 | 482 | void (*seq_adjust)(struct sk_buff *skb, struct nf_conn *ct, |
---|
456 | 483 | enum ip_conntrack_info ctinfo, s32 off); |
---|
| 484 | + |
---|
| 485 | + ANDROID_KABI_RESERVE(1); |
---|
457 | 486 | }; |
---|
458 | 487 | extern struct nfnl_ct_hook __rcu *nfnl_ct_hook; |
---|
459 | 488 | |
---|