static int timeout_ct_or_exp(const struct ip_conntrack_tuple *t) { struct ip_conntrack_tuple_hash *h; struct ip_conntrack_expect *exp; DEBUGP("trying to timeout ct or exp for tuple "); DUMP_TUPLE(t); h = __ip_conntrack_find(t, NULL); if (h) { struct ip_conntrack *sibling = tuplehash_to_ctrack(h); DEBUGP("setting timeout of conntrack %p to 0\n", sibling); sibling->proto.gre.timeout = 0; sibling->proto.gre.stream_timeout = 0; /* refresh_acct will not modify counters if skb == NULL */ ip_ct_refresh_acct(sibling, 0, NULL, 0); return 1; } else { exp = __ip_conntrack_exp_find(t); if (exp) { DEBUGP("unexpect_related of expect %p\n", exp); ip_conntrack_unexpect_related(exp); return 1; } } return 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; }