aboutsummaryrefslogtreecommitdiffstats
path: root/net/netfilter
diff options
context:
space:
mode:
authorEric Dumazet <eric.dumazet@gmail.com>2010-06-08 10:09:52 -0400
committerPatrick McHardy <kaber@trash.net>2010-06-08 10:09:52 -0400
commit5bfddbd46a95c978f4d3c992339cbdf4f4b790a3 (patch)
tree9291ba4e1e3c7bf7ae8b5dfa8271e7127a6a6958 /net/netfilter
parent339bb99e4a8ba1f8960eed21d50be808b35ad22a (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.c11
-rw-r--r--net/netfilter/nf_conntrack_netlink.c2
-rw-r--r--net/netfilter/xt_CT.c4
-rw-r--r--net/netfilter/xt_NOTRACK.c2
-rw-r--r--net/netfilter/xt_TEE.c4
-rw-r--r--net/netfilter/xt_cluster.c2
-rw-r--r--net/netfilter/xt_conntrack.c11
-rw-r--r--net/netfilter/xt_socket.c2
-rw-r--r--net/netfilter/xt_state.c14
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);
62unsigned int nf_conntrack_max __read_mostly; 62unsigned int nf_conntrack_max __read_mostly;
63EXPORT_SYMBOL_GPL(nf_conntrack_max); 63EXPORT_SYMBOL_GPL(nf_conntrack_max);
64 64
65struct nf_conn nf_conntrack_untracked __read_mostly; 65struct nf_conn nf_conntrack_untracked;
66EXPORT_SYMBOL_GPL(nf_conntrack_untracked); 66EXPORT_SYMBOL_GPL(nf_conntrack_untracked);
67 67
68static int nf_conntrack_hash_rnd_initted; 68static int nf_conntrack_hash_rnd_initted;
@@ -1321,6 +1321,12 @@ EXPORT_SYMBOL_GPL(nf_conntrack_set_hashsize);
1321module_param_call(hashsize, nf_conntrack_set_hashsize, param_get_uint, 1321module_param_call(hashsize, nf_conntrack_set_hashsize, param_get_uint,
1322 &nf_conntrack_htable_size, 0600); 1322 &nf_conntrack_htable_size, 0600);
1323 1323
1324void nf_ct_untracked_status_or(unsigned long bits)
1325{
1326 nf_conntrack_untracked.status |= bits;
1327}
1328EXPORT_SYMBOL_GPL(nf_ct_untracked_status_or);
1329
1324static int nf_conntrack_init_init_net(void) 1330static 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