diff options
author | Florian Westphal <fw@strlen.de> | 2014-03-07 08:37:09 -0500 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2014-03-12 08:55:01 -0400 |
commit | 15cfd52895751e8f36b48b8ad33f1d68b59611e2 (patch) | |
tree | 312c48932d059e660667a28d5cd37aaef7e5c09c /net/netfilter | |
parent | a4c2e8beba843206cf6447a85b0580a1ae5d50a0 (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.c | 49 |
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 | ||
95 | static int count_them(struct net *net, | 95 | static 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 | ||
170 | static 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 | |||
176 | static bool | 195 | static bool |
177 | connlimit_mt(const struct sk_buff *skb, struct xt_action_param *par) | 196 | connlimit_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 */ |