コード例 #1
0
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;
	}
コード例 #2
0
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);
	}