Skip to content

Commit

Permalink
netfilter: connlimit: factor hlist search into new function
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Florian Westphal authored and Pablo Neira Ayuso committed Mar 12, 2014
1 parent a4c2e8b commit 15cfd52
Showing 1 changed file with 33 additions and 16 deletions.
49 changes: 33 additions & 16 deletions net/netfilter/xt_connlimit.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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 */
Expand Down

0 comments on commit 15cfd52

Please sign in to comment.