Blame view
net/netfilter/nf_conntrack_extend.c
2.79 KB
2874c5fd2 treewide: Replace... |
1 |
// SPDX-License-Identifier: GPL-2.0-or-later |
ecfab2c9f [NETFILTER]: nf_c... |
2 3 4 5 |
/* Structure dynamic extension infrastructure * Copyright (C) 2004 Rusty Russell IBM Corporation * Copyright (C) 2007 Netfilter Core Team <coreteam@netfilter.org> * Copyright (C) 2007 USAGI/WIDE Project <http://www.linux-ipv6.org> |
ecfab2c9f [NETFILTER]: nf_c... |
6 7 |
*/ #include <linux/kernel.h> |
765cca91b netfilter: conntr... |
8 |
#include <linux/kmemleak.h> |
ecfab2c9f [NETFILTER]: nf_c... |
9 10 11 12 13 14 |
#include <linux/module.h> #include <linux/mutex.h> #include <linux/rcupdate.h> #include <linux/slab.h> #include <linux/skbuff.h> #include <net/netfilter/nf_conntrack_extend.h> |
0906a372f net/netfilter: __... |
15 |
static struct nf_ct_ext_type __rcu *nf_ct_ext_types[NF_CT_EXT_NUM]; |
ecfab2c9f [NETFILTER]: nf_c... |
16 |
static DEFINE_MUTEX(nf_ct_ext_type_mutex); |
54044b1f0 netfilter: conntr... |
17 |
#define NF_CT_EXT_PREALLOC 128u /* conntrack events are on by default */ |
ecfab2c9f [NETFILTER]: nf_c... |
18 |
|
8eeef2350 netfilter: nf_ct_... |
19 |
void nf_ct_ext_destroy(struct nf_conn *ct) |
ecfab2c9f [NETFILTER]: nf_c... |
20 21 22 23 24 |
{ unsigned int i; struct nf_ct_ext_type *t; for (i = 0; i < NF_CT_EXT_NUM; i++) { |
ecfab2c9f [NETFILTER]: nf_c... |
25 26 27 28 29 30 31 32 33 34 35 |
rcu_read_lock(); t = rcu_dereference(nf_ct_ext_types[i]); /* Here the nf_ct_ext_type might have been unregisterd. * I.e., it has responsible to cleanup private * area in all conntracks when it is unregisterd. */ if (t && t->destroy) t->destroy(ct); rcu_read_unlock(); } |
2ad9d7747 netfilter: conntr... |
36 37 |
kfree(ct->ext); |
ecfab2c9f [NETFILTER]: nf_c... |
38 |
} |
8eeef2350 netfilter: nf_ct_... |
39 |
EXPORT_SYMBOL(nf_ct_ext_destroy); |
ecfab2c9f [NETFILTER]: nf_c... |
40 |
|
faec865db netfilter: remove... |
41 |
void *nf_ct_ext_add(struct nf_conn *ct, enum nf_ct_ext_id id, gfp_t gfp) |
ecfab2c9f [NETFILTER]: nf_c... |
42 |
{ |
22d4536d2 netfilter: conntr... |
43 |
unsigned int newlen, newoff, oldlen, alloc; |
ecfab2c9f [NETFILTER]: nf_c... |
44 |
struct nf_ct_ext_type *t; |
2ad9d7747 netfilter: conntr... |
45 |
struct nf_ct_ext *new; |
ecfab2c9f [NETFILTER]: nf_c... |
46 |
|
55871d047 [NETFILTER]: nf_c... |
47 |
/* Conntrack must not be confirmed to avoid races on reallocation. */ |
44d6e2f27 net: Replace NF_C... |
48 |
WARN_ON(nf_ct_is_confirmed(ct)); |
55871d047 [NETFILTER]: nf_c... |
49 |
|
ecfab2c9f [NETFILTER]: nf_c... |
50 |
|
2ad9d7747 netfilter: conntr... |
51 52 |
if (ct->ext) { const struct nf_ct_ext *old = ct->ext; |
22d4536d2 netfilter: conntr... |
53 54 55 56 57 58 |
if (__nf_ct_ext_exist(old, id)) return NULL; oldlen = old->len; } else { oldlen = sizeof(*new); } |
ecfab2c9f [NETFILTER]: nf_c... |
59 60 61 |
rcu_read_lock(); t = rcu_dereference(nf_ct_ext_types[id]); |
9c3f37949 netfilter: nf_ct_... |
62 63 64 65 |
if (!t) { rcu_read_unlock(); return NULL; } |
ecfab2c9f [NETFILTER]: nf_c... |
66 |
|
22d4536d2 netfilter: conntr... |
67 |
newoff = ALIGN(oldlen, t->align); |
faec865db netfilter: remove... |
68 |
newlen = newoff + t->len; |
ecfab2c9f [NETFILTER]: nf_c... |
69 |
rcu_read_unlock(); |
22d4536d2 netfilter: conntr... |
70 |
alloc = max(newlen, NF_CT_EXT_PREALLOC); |
2ad9d7747 netfilter: conntr... |
71 |
new = krealloc(ct->ext, alloc, gfp); |
31d8519c9 netfilter: nf_con... |
72 73 |
if (!new) return NULL; |
ecfab2c9f [NETFILTER]: nf_c... |
74 |
|
2ad9d7747 netfilter: conntr... |
75 |
if (!ct->ext) |
22d4536d2 netfilter: conntr... |
76 |
memset(new->offset, 0, sizeof(new->offset)); |
ecfab2c9f [NETFILTER]: nf_c... |
77 |
|
6c64825bf netfilter: nf_con... |
78 79 80 |
new->offset[id] = newoff; new->len = newlen; memset((void *)new + newoff, 0, newlen - newoff); |
2ad9d7747 netfilter: conntr... |
81 82 |
ct->ext = new; |
6c64825bf netfilter: nf_con... |
83 |
return (void *)new + newoff; |
ecfab2c9f [NETFILTER]: nf_c... |
84 |
} |
faec865db netfilter: remove... |
85 |
EXPORT_SYMBOL(nf_ct_ext_add); |
ecfab2c9f [NETFILTER]: nf_c... |
86 |
|
ecfab2c9f [NETFILTER]: nf_c... |
87 |
/* This MUST be called in process context. */ |
23f671a1b netfilter: conntr... |
88 |
int nf_ct_extend_register(const struct nf_ct_ext_type *type) |
ecfab2c9f [NETFILTER]: nf_c... |
89 90 91 92 93 94 95 96 |
{ int ret = 0; mutex_lock(&nf_ct_ext_type_mutex); if (nf_ct_ext_types[type->id]) { ret = -EBUSY; goto out; } |
cf778b00e net: reintroduce ... |
97 |
rcu_assign_pointer(nf_ct_ext_types[type->id], type); |
ecfab2c9f [NETFILTER]: nf_c... |
98 99 100 101 102 103 104 |
out: mutex_unlock(&nf_ct_ext_type_mutex); return ret; } EXPORT_SYMBOL_GPL(nf_ct_extend_register); /* This MUST be called in process context. */ |
23f671a1b netfilter: conntr... |
105 |
void nf_ct_extend_unregister(const struct nf_ct_ext_type *type) |
ecfab2c9f [NETFILTER]: nf_c... |
106 107 |
{ mutex_lock(&nf_ct_ext_type_mutex); |
a9b3cd7f3 rcu: convert uses... |
108 |
RCU_INIT_POINTER(nf_ct_ext_types[type->id], NULL); |
ecfab2c9f [NETFILTER]: nf_c... |
109 |
mutex_unlock(&nf_ct_ext_type_mutex); |
9c3f37949 netfilter: nf_ct_... |
110 |
synchronize_rcu(); |
ecfab2c9f [NETFILTER]: nf_c... |
111 112 |
} EXPORT_SYMBOL_GPL(nf_ct_extend_unregister); |