diff options
author | Eric Dumazet <eric.dumazet@gmail.com> | 2010-06-08 10:09:52 -0400 |
---|---|---|
committer | Patrick McHardy <kaber@trash.net> | 2010-06-08 10:09:52 -0400 |
commit | 5bfddbd46a95c978f4d3c992339cbdf4f4b790a3 (patch) | |
tree | 9291ba4e1e3c7bf7ae8b5dfa8271e7127a6a6958 /net/netfilter | |
parent | 339bb99e4a8ba1f8960eed21d50be808b35ad22a (diff) |
netfilter: nf_conntrack: IPS_UNTRACKED bit
NOTRACK makes all cpus share a cache line on nf_conntrack_untracked
twice per packet. This is bad for performance.
__read_mostly annotation is also a bad choice.
This patch introduces IPS_UNTRACKED bit so that we can use later a
per_cpu untrack structure more easily.
A new helper, nf_ct_untracked_get() returns a pointer to
nf_conntrack_untracked.
Another one, nf_ct_untracked_status_or() is used by nf_nat_init() to add
IPS_NAT_DONE_MASK bits to untracked status.
nf_ct_is_untracked() prototype is changed to work on a nf_conn pointer.
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: Patrick McHardy <kaber@trash.net>
Diffstat (limited to 'net/netfilter')
-rw-r--r-- | net/netfilter/nf_conntrack_core.c | 11 | ||||
-rw-r--r-- | net/netfilter/nf_conntrack_netlink.c | 2 | ||||
-rw-r--r-- | net/netfilter/xt_CT.c | 4 | ||||
-rw-r--r-- | net/netfilter/xt_NOTRACK.c | 2 | ||||
-rw-r--r-- | net/netfilter/xt_TEE.c | 4 | ||||
-rw-r--r-- | net/netfilter/xt_cluster.c | 2 | ||||
-rw-r--r-- | net/netfilter/xt_conntrack.c | 11 | ||||
-rw-r--r-- | net/netfilter/xt_socket.c | 2 | ||||
-rw-r--r-- | net/netfilter/xt_state.c | 14 |
9 files changed, 30 insertions, 22 deletions
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index eeeb8bc73982..6c1da212380d 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c | |||
@@ -62,7 +62,7 @@ EXPORT_SYMBOL_GPL(nf_conntrack_htable_size); | |||
62 | unsigned int nf_conntrack_max __read_mostly; | 62 | unsigned int nf_conntrack_max __read_mostly; |
63 | EXPORT_SYMBOL_GPL(nf_conntrack_max); | 63 | EXPORT_SYMBOL_GPL(nf_conntrack_max); |
64 | 64 | ||
65 | struct nf_conn nf_conntrack_untracked __read_mostly; | 65 | struct nf_conn nf_conntrack_untracked; |
66 | EXPORT_SYMBOL_GPL(nf_conntrack_untracked); | 66 | EXPORT_SYMBOL_GPL(nf_conntrack_untracked); |
67 | 67 | ||
68 | static int nf_conntrack_hash_rnd_initted; | 68 | static int nf_conntrack_hash_rnd_initted; |
@@ -1321,6 +1321,12 @@ EXPORT_SYMBOL_GPL(nf_conntrack_set_hashsize); | |||
1321 | module_param_call(hashsize, nf_conntrack_set_hashsize, param_get_uint, | 1321 | module_param_call(hashsize, nf_conntrack_set_hashsize, param_get_uint, |
1322 | &nf_conntrack_htable_size, 0600); | 1322 | &nf_conntrack_htable_size, 0600); |
1323 | 1323 | ||
1324 | void nf_ct_untracked_status_or(unsigned long bits) | ||
1325 | { | ||
1326 | nf_conntrack_untracked.status |= bits; | ||
1327 | } | ||
1328 | EXPORT_SYMBOL_GPL(nf_ct_untracked_status_or); | ||
1329 | |||
1324 | static int nf_conntrack_init_init_net(void) | 1330 | static int nf_conntrack_init_init_net(void) |
1325 | { | 1331 | { |
1326 | int max_factor = 8; | 1332 | int max_factor = 8; |
@@ -1368,8 +1374,7 @@ static int nf_conntrack_init_init_net(void) | |||
1368 | #endif | 1374 | #endif |
1369 | atomic_set(&nf_conntrack_untracked.ct_general.use, 1); | 1375 | atomic_set(&nf_conntrack_untracked.ct_general.use, 1); |
1370 | /* - and look it like as a confirmed connection */ | 1376 | /* - and look it like as a confirmed connection */ |
1371 | set_bit(IPS_CONFIRMED_BIT, &nf_conntrack_untracked.status); | 1377 | nf_ct_untracked_status_or(IPS_CONFIRMED | IPS_UNTRACKED); |
1372 | |||
1373 | return 0; | 1378 | return 0; |
1374 | 1379 | ||
1375 | #ifdef CONFIG_NF_CONNTRACK_ZONES | 1380 | #ifdef CONFIG_NF_CONNTRACK_ZONES |
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index c42ff6aa441d..5bae1cd15eea 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c | |||
@@ -480,7 +480,7 @@ ctnetlink_conntrack_event(unsigned int events, struct nf_ct_event *item) | |||
480 | int err; | 480 | int err; |
481 | 481 | ||
482 | /* ignore our fake conntrack entry */ | 482 | /* ignore our fake conntrack entry */ |
483 | if (ct == &nf_conntrack_untracked) | 483 | if (nf_ct_is_untracked(ct)) |
484 | return 0; | 484 | return 0; |
485 | 485 | ||
486 | if (events & (1 << IPCT_DESTROY)) { | 486 | if (events & (1 << IPCT_DESTROY)) { |
diff --git a/net/netfilter/xt_CT.c b/net/netfilter/xt_CT.c index 562bf3266e04..0cb6053f02fd 100644 --- a/net/netfilter/xt_CT.c +++ b/net/netfilter/xt_CT.c | |||
@@ -67,7 +67,7 @@ static int xt_ct_tg_check(const struct xt_tgchk_param *par) | |||
67 | return -EINVAL; | 67 | return -EINVAL; |
68 | 68 | ||
69 | if (info->flags & XT_CT_NOTRACK) { | 69 | if (info->flags & XT_CT_NOTRACK) { |
70 | ct = &nf_conntrack_untracked; | 70 | ct = nf_ct_untracked_get(); |
71 | atomic_inc(&ct->ct_general.use); | 71 | atomic_inc(&ct->ct_general.use); |
72 | goto out; | 72 | goto out; |
73 | } | 73 | } |
@@ -132,7 +132,7 @@ static void xt_ct_tg_destroy(const struct xt_tgdtor_param *par) | |||
132 | struct nf_conn *ct = info->ct; | 132 | struct nf_conn *ct = info->ct; |
133 | struct nf_conn_help *help; | 133 | struct nf_conn_help *help; |
134 | 134 | ||
135 | if (ct != &nf_conntrack_untracked) { | 135 | if (!nf_ct_is_untracked(ct)) { |
136 | help = nfct_help(ct); | 136 | help = nfct_help(ct); |
137 | if (help) | 137 | if (help) |
138 | module_put(help->helper->me); | 138 | module_put(help->helper->me); |
diff --git a/net/netfilter/xt_NOTRACK.c b/net/netfilter/xt_NOTRACK.c index 512b9123252f..9d782181b6c8 100644 --- a/net/netfilter/xt_NOTRACK.c +++ b/net/netfilter/xt_NOTRACK.c | |||
@@ -23,7 +23,7 @@ notrack_tg(struct sk_buff *skb, const struct xt_action_param *par) | |||
23 | If there is a real ct entry correspondig to this packet, | 23 | If there is a real ct entry correspondig to this packet, |
24 | it'll hang aroun till timing out. We don't deal with it | 24 | it'll hang aroun till timing out. We don't deal with it |
25 | for performance reasons. JK */ | 25 | for performance reasons. JK */ |
26 | skb->nfct = &nf_conntrack_untracked.ct_general; | 26 | skb->nfct = &nf_ct_untracked_get()->ct_general; |
27 | skb->nfctinfo = IP_CT_NEW; | 27 | skb->nfctinfo = IP_CT_NEW; |
28 | nf_conntrack_get(skb->nfct); | 28 | nf_conntrack_get(skb->nfct); |
29 | 29 | ||
diff --git a/net/netfilter/xt_TEE.c b/net/netfilter/xt_TEE.c index 859d9fd429c8..7a118267c4c4 100644 --- a/net/netfilter/xt_TEE.c +++ b/net/netfilter/xt_TEE.c | |||
@@ -104,7 +104,7 @@ tee_tg4(struct sk_buff *skb, const struct xt_action_param *par) | |||
104 | #ifdef WITH_CONNTRACK | 104 | #ifdef WITH_CONNTRACK |
105 | /* Avoid counting cloned packets towards the original connection. */ | 105 | /* Avoid counting cloned packets towards the original connection. */ |
106 | nf_conntrack_put(skb->nfct); | 106 | nf_conntrack_put(skb->nfct); |
107 | skb->nfct = &nf_conntrack_untracked.ct_general; | 107 | skb->nfct = &nf_ct_untracked_get()->ct_general; |
108 | skb->nfctinfo = IP_CT_NEW; | 108 | skb->nfctinfo = IP_CT_NEW; |
109 | nf_conntrack_get(skb->nfct); | 109 | nf_conntrack_get(skb->nfct); |
110 | #endif | 110 | #endif |
@@ -177,7 +177,7 @@ tee_tg6(struct sk_buff *skb, const struct xt_action_param *par) | |||
177 | 177 | ||
178 | #ifdef WITH_CONNTRACK | 178 | #ifdef WITH_CONNTRACK |
179 | nf_conntrack_put(skb->nfct); | 179 | nf_conntrack_put(skb->nfct); |
180 | skb->nfct = &nf_conntrack_untracked.ct_general; | 180 | skb->nfct = &nf_ct_untracked_get()->ct_general; |
181 | skb->nfctinfo = IP_CT_NEW; | 181 | skb->nfctinfo = IP_CT_NEW; |
182 | nf_conntrack_get(skb->nfct); | 182 | nf_conntrack_get(skb->nfct); |
183 | #endif | 183 | #endif |
diff --git a/net/netfilter/xt_cluster.c b/net/netfilter/xt_cluster.c index 30b95a1c1c89..f4af1bfafb1c 100644 --- a/net/netfilter/xt_cluster.c +++ b/net/netfilter/xt_cluster.c | |||
@@ -120,7 +120,7 @@ xt_cluster_mt(const struct sk_buff *skb, struct xt_action_param *par) | |||
120 | if (ct == NULL) | 120 | if (ct == NULL) |
121 | return false; | 121 | return false; |
122 | 122 | ||
123 | if (ct == &nf_conntrack_untracked) | 123 | if (nf_ct_is_untracked(ct)) |
124 | return false; | 124 | return false; |
125 | 125 | ||
126 | if (ct->master) | 126 | if (ct->master) |
diff --git a/net/netfilter/xt_conntrack.c b/net/netfilter/xt_conntrack.c index 39681f10291c..e536710ad916 100644 --- a/net/netfilter/xt_conntrack.c +++ b/net/netfilter/xt_conntrack.c | |||
@@ -123,11 +123,12 @@ conntrack_mt(const struct sk_buff *skb, struct xt_action_param *par, | |||
123 | 123 | ||
124 | ct = nf_ct_get(skb, &ctinfo); | 124 | ct = nf_ct_get(skb, &ctinfo); |
125 | 125 | ||
126 | if (ct == &nf_conntrack_untracked) | 126 | if (ct) { |
127 | statebit = XT_CONNTRACK_STATE_UNTRACKED; | 127 | if (nf_ct_is_untracked(ct)) |
128 | else if (ct != NULL) | 128 | statebit = XT_CONNTRACK_STATE_UNTRACKED; |
129 | statebit = XT_CONNTRACK_STATE_BIT(ctinfo); | 129 | else |
130 | else | 130 | statebit = XT_CONNTRACK_STATE_BIT(ctinfo); |
131 | } else | ||
131 | statebit = XT_CONNTRACK_STATE_INVALID; | 132 | statebit = XT_CONNTRACK_STATE_INVALID; |
132 | 133 | ||
133 | if (info->match_flags & XT_CONNTRACK_STATE) { | 134 | if (info->match_flags & XT_CONNTRACK_STATE) { |
diff --git a/net/netfilter/xt_socket.c b/net/netfilter/xt_socket.c index 3d54c236a1ba..1ca89908cbad 100644 --- a/net/netfilter/xt_socket.c +++ b/net/netfilter/xt_socket.c | |||
@@ -127,7 +127,7 @@ socket_match(const struct sk_buff *skb, struct xt_action_param *par, | |||
127 | * reply packet of an established SNAT-ted connection. */ | 127 | * reply packet of an established SNAT-ted connection. */ |
128 | 128 | ||
129 | ct = nf_ct_get(skb, &ctinfo); | 129 | ct = nf_ct_get(skb, &ctinfo); |
130 | if (ct && (ct != &nf_conntrack_untracked) && | 130 | if (ct && !nf_ct_is_untracked(ct) && |
131 | ((iph->protocol != IPPROTO_ICMP && | 131 | ((iph->protocol != IPPROTO_ICMP && |
132 | ctinfo == IP_CT_IS_REPLY + IP_CT_ESTABLISHED) || | 132 | ctinfo == IP_CT_IS_REPLY + IP_CT_ESTABLISHED) || |
133 | (iph->protocol == IPPROTO_ICMP && | 133 | (iph->protocol == IPPROTO_ICMP && |
diff --git a/net/netfilter/xt_state.c b/net/netfilter/xt_state.c index e12e053d3782..a507922d80cd 100644 --- a/net/netfilter/xt_state.c +++ b/net/netfilter/xt_state.c | |||
@@ -26,14 +26,16 @@ state_mt(const struct sk_buff *skb, struct xt_action_param *par) | |||
26 | const struct xt_state_info *sinfo = par->matchinfo; | 26 | const struct xt_state_info *sinfo = par->matchinfo; |
27 | enum ip_conntrack_info ctinfo; | 27 | enum ip_conntrack_info ctinfo; |
28 | unsigned int statebit; | 28 | unsigned int statebit; |
29 | struct nf_conn *ct = nf_ct_get(skb, &ctinfo); | ||
29 | 30 | ||
30 | if (nf_ct_is_untracked(skb)) | 31 | if (!ct) |
31 | statebit = XT_STATE_UNTRACKED; | ||
32 | else if (!nf_ct_get(skb, &ctinfo)) | ||
33 | statebit = XT_STATE_INVALID; | 32 | statebit = XT_STATE_INVALID; |
34 | else | 33 | else { |
35 | statebit = XT_STATE_BIT(ctinfo); | 34 | if (nf_ct_is_untracked(ct)) |
36 | 35 | statebit = XT_STATE_UNTRACKED; | |
36 | else | ||
37 | statebit = XT_STATE_BIT(ctinfo); | ||
38 | } | ||
37 | return (sinfo->statemask & statebit); | 39 | return (sinfo->statemask & statebit); |
38 | } | 40 | } |
39 | 41 | ||