diff options
author | Florian Westphal <fw@strlen.de> | 2014-03-07 14:37:09 +0100 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2014-03-12 13:55:01 +0100 |
commit | 15cfd52895751e8f36b48b8ad33f1d68b59611e2 (patch) | |
tree | 312c48932d059e660667a28d5cd37aaef7e5c09c /net/netfilter/xt_connlimit.c | |
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/xt_connlimit.c')
-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, } } -static int count_them(struct net *net, - struct xt_connlimit_data *data, - const struct nf_conntrack_tuple *tuple, - const union nf_inet_addr *addr, - const union nf_inet_addr *mask, - u_int8_t family) +static int count_hlist(struct net *net, + struct hlist_head *head, + const struct nf_conntrack_tuple *tuple, + const union nf_inet_addr *addr, + const union nf_inet_addr *mask, + u_int8_t family) { const struct nf_conntrack_tuple_hash *found; struct xt_connlimit_conn *conn; struct hlist_node *n; struct nf_conn *found_ct; - struct hlist_head *hash; bool addit = true; int matches = 0; - if (family == NFPROTO_IPV6) - hash = &data->iphash[connlimit_iphash6(addr, mask)]; - else - hash = &data->iphash[connlimit_iphash(addr->ip & mask->ip)]; - rcu_read_lock(); /* check the saved connections */ - hlist_for_each_entry_safe(conn, n, hash, node) { + hlist_for_each_entry_safe(conn, n, head, node) { found = nf_conntrack_find_get(net, NF_CT_DEFAULT_ZONE, &conn->tuple); found_ct = NULL; @@ -166,13 +160,38 @@ static int count_them(struct net *net, return -ENOMEM; conn->tuple = *tuple; conn->addr = *addr; - hlist_add_head(&conn->node, hash); + hlist_add_head(&conn->node, head); ++matches; } return matches; } +static int count_them(struct net *net, + struct xt_connlimit_data *data, + const struct nf_conntrack_tuple *tuple, + const union nf_inet_addr *addr, + const union nf_inet_addr *mask, + u_int8_t family) +{ + struct hlist_head *hhead; + int count; + u32 hash; + + if (family == NFPROTO_IPV6) + hash = connlimit_iphash6(addr, mask); + else + hash = connlimit_iphash(addr->ip & mask->ip); + + hhead = &data->iphash[hash]; + + spin_lock_bh(&data->lock); + count = count_hlist(net, hhead, tuple, addr, mask, family); + spin_unlock_bh(&data->lock); + + return count; +} + static bool connlimit_mt(const struct sk_buff *skb, struct xt_action_param *par) { @@ -202,10 +221,8 @@ connlimit_mt(const struct sk_buff *skb, struct xt_action_param *par) iph->daddr : iph->saddr; } - spin_lock_bh(&info->data->lock); connections = count_them(net, info->data, tuple_ptr, &addr, &info->mask, par->family); - spin_unlock_bh(&info->data->lock); if (connections < 0) /* kmalloc failed, drop it entirely */ |