static int count_them(struct xt_connlimit_data *data, const struct ip_conntrack_tuple *tuple, const __be32 addr, const __be32 mask, const struct xt_match *match) { struct ip_conntrack_tuple_hash *found; struct xt_connlimit_conn *conn; struct xt_connlimit_conn *tmp; struct ip_conntrack *found_ct; struct list_head *hash; bool addit = true; int matches = 0; hash = &data->iphash[connlimit_iphash(addr & mask)]; read_lock_bh(&ip_conntrack_lock); /* check the saved connections */ list_for_each_entry_safe(conn, tmp, hash, list) { found = __ip_conntrack_find(&conn->tuple, NULL); found_ct = NULL; if (found != NULL) found_ct = tuplehash_to_ctrack(found); if (found_ct != NULL && ip_ct_tuple_equal(&conn->tuple, tuple) && !already_closed(found_ct)) /* * Just to be sure we have it only once in the list. * We should not see tuples twice unless someone hooks * this into a table without "-p tcp --syn". */ addit = false; if (found == NULL) { /* this one is gone */ list_del(&conn->list); kfree(conn); continue; } if (already_closed(found_ct)) { /* * we do not care about connections which are * closed already -> ditch it */ list_del(&conn->list); kfree(conn); continue; } if (same_source_net(addr, mask, conn->tuple.src.ip, match->family)) /* same source network -> be counted! */ ++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) { const struct nf_conntrack_tuple_hash *found; struct xt_connlimit_conn *conn; struct xt_connlimit_conn *tmp; struct nf_conn *found_ct; struct list_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 */ list_for_each_entry_safe(conn, tmp, hash, list) { found = nf_conntrack_find_get(net, NF_CT_DEFAULT_ZONE, &conn->tuple); found_ct = NULL; if (found != NULL) found_ct = nf_ct_tuplehash_to_ctrack(found); if (found_ct != NULL && nf_ct_tuple_equal(&conn->tuple, tuple) && !already_closed(found_ct)) /* * Just to be sure we have it only once in the list. * We should not see tuples twice unless someone hooks * this into a table without "-p tcp --syn". */ addit = false; if (found == NULL) { /* this one is gone */ list_del(&conn->list); kfree(conn); continue; } if (already_closed(found_ct)) { /* * we do not care about connections which are * closed already -> ditch it */ nf_ct_put(found_ct); list_del(&conn->list); kfree(conn); continue; } if (same_source_net(addr, mask, &conn->tuple.src.u3, family)) /* same source network -> be counted! */ ++matches; nf_ct_put(found_ct); }