aboutsummaryrefslogtreecommitdiffstats
path: root/net/netfilter
diff options
context:
space:
mode:
authorFlorian Westphal <fw@strlen.de>2014-03-07 08:37:09 -0500
committerPablo Neira Ayuso <pablo@netfilter.org>2014-03-12 08:55:01 -0400
commit15cfd52895751e8f36b48b8ad33f1d68b59611e2 (patch)
tree312c48932d059e660667a28d5cd37aaef7e5c09c /net/netfilter
parenta4c2e8beba843206cf6447a85b0580a1ae5d50a0 (diff)
netfilter: connlimit: factor hlist search into new function
Simplifies followup patch that introduces separate locks for each of the hash slots. Reviewed-by: Jesper Dangaard Brouer <brouer@redhat.com> Signed-off-by: Florian Westphal <fw@strlen.de> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'net/netfilter')
-rw-r--r--net/netfilter/xt_connlimit.c49
1 files changed, 33 insertions, 16 deletions
diff --git a/net/netfilter/xt_connlimit.c b/net/netfilter/xt_connlimit.c
index c40b2695633b..6988818acf88 100644
--- a/net/netfilter/xt_connlimit.c
+++ b/net/netfilter/xt_connlimit.c
@@ -92,30 +92,24 @@ same_source_net(const union nf_inet_addr *addr,
92 } 92 }
93} 93}
94 94
95static int count_them(struct net *net, 95static int count_hlist(struct net *net,
96 struct xt_connlimit_data *data, 96 struct hlist_head *head,
97 const struct nf_conntrack_tuple *tuple, 97 const struct nf_conntrack_tuple *tuple,
98 const union nf_inet_addr *addr, 98 const union nf_inet_addr *addr,
99 const union nf_inet_addr *mask, 99 const union nf_inet_addr *mask,
100 u_int8_t family) 100 u_int8_t family)
101{ 101{
102 const struct nf_conntrack_tuple_hash *found; 102 const struct nf_conntrack_tuple_hash *found;
103 struct xt_connlimit_conn *conn; 103 struct xt_connlimit_conn *conn;
104 struct hlist_node *n; 104 struct hlist_node *n;
105 struct nf_conn *found_ct; 105 struct nf_conn *found_ct;
106 struct hlist_head *hash;
107 bool addit = true; 106 bool addit = true;
108 int matches = 0; 107 int matches = 0;
109 108
110 if (family == NFPROTO_IPV6)
111 hash = &data->iphash[connlimit_iphash6(addr, mask)];
112 else
113 hash = &data->iphash[connlimit_iphash(addr->ip & mask->ip)];
114
115 rcu_read_lock(); 109 rcu_read_lock();
116 110
117 /* check the saved connections */ 111 /* check the saved connections */
118 hlist_for_each_entry_safe(conn, n, hash, node) { 112 hlist_for_each_entry_safe(conn, n, head, node) {
119 found = nf_conntrack_find_get(net, NF_CT_DEFAULT_ZONE, 113 found = nf_conntrack_find_get(net, NF_CT_DEFAULT_ZONE,
120 &conn->tuple); 114 &conn->tuple);
121 found_ct = NULL; 115 found_ct = NULL;
@@ -166,13 +160,38 @@ static int count_them(struct net *net,
166 return -ENOMEM; 160 return -ENOMEM;
167 conn->tuple = *tuple; 161 conn->tuple = *tuple;
168 conn->addr = *addr; 162 conn->addr = *addr;
169 hlist_add_head(&conn->node, hash); 163 hlist_add_head(&conn->node, head);
170 ++matches; 164 ++matches;
171 } 165 }
172 166
173 return matches; 167 return matches;
174} 168}
175 169
170static int count_them(struct net *net,
171 struct xt_connlimit_data *data,
172 const struct nf_conntrack_tuple *tuple,
173 const union nf_inet_addr *addr,
174 const union nf_inet_addr *mask,
175 u_int8_t family)
176{
177 struct hlist_head *hhead;
178 int count;
179 u32 hash;
180
181 if (family == NFPROTO_IPV6)
182 hash = connlimit_iphash6(addr, mask);
183 else
184 hash = connlimit_iphash(addr->ip & mask->ip);
185
186 hhead = &data->iphash[hash];
187
188 spin_lock_bh(&data->lock);
189 count = count_hlist(net, hhead, tuple, addr, mask, family);
190 spin_unlock_bh(&data->lock);
191
192 return count;
193}
194
176static bool 195static bool
177connlimit_mt(const struct sk_buff *skb, struct xt_action_param *par) 196connlimit_mt(const struct sk_buff *skb, struct xt_action_param *par)
178{ 197{
@@ -202,10 +221,8 @@ connlimit_mt(const struct sk_buff *skb, struct xt_action_param *par)
202 iph->daddr : iph->saddr; 221 iph->daddr : iph->saddr;
203 } 222 }
204 223
205 spin_lock_bh(&info->data->lock);
206 connections = count_them(net, info->data, tuple_ptr, &addr, 224 connections = count_them(net, info->data, tuple_ptr, &addr,
207 &info->mask, par->family); 225 &info->mask, par->family);
208 spin_unlock_bh(&info->data->lock);
209 226
210 if (connections < 0) 227 if (connections < 0)
211 /* kmalloc failed, drop it entirely */ 228 /* kmalloc failed, drop it entirely */