[NETFILTER]: nf_conntrack_expect: support inactive expectations
authorPatrick McHardy <kaber@trash.net>
Wed, 26 Mar 2008 03:08:37 +0000 (20:08 -0700)
committerDavid S. Miller <davem@davemloft.net>
Wed, 26 Mar 2008 03:08:37 +0000 (20:08 -0700)
This is useful for the SIP helper and signalling expectations.
We don't want to create a full-blown expectation with a wildcard
as source based on a single UDP packet, but need to know the
final port anyways. With inactive expectations we can register
the expectation and reserve the tuple, but wait for confirmation
from the registrar before activating it.

Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/net/netfilter/nf_conntrack_expect.h
net/netfilter/nf_conntrack_expect.c

index f1bdcb4f3f2ad1edc71b436a1789ba7dbc0fb672..47c28dd07896054d081f91dce55cfcdb55ef0710 100644 (file)
@@ -53,7 +53,8 @@ struct nf_conntrack_expect
        struct rcu_head rcu;
 };
 
-#define NF_CT_EXPECT_PERMANENT 0x1
+#define NF_CT_EXPECT_PERMANENT 0x1
+#define NF_CT_EXPECT_INACTIVE  0x2
 
 int nf_conntrack_expect_init(void);
 void nf_conntrack_expect_fini(void);
index 4c05a588116f86632809f147da8aafec7e3948a6..882602f1c0ef9ac062dc5c54550aaffb16feebfa 100644 (file)
@@ -126,9 +126,21 @@ EXPORT_SYMBOL_GPL(nf_ct_expect_find_get);
 struct nf_conntrack_expect *
 nf_ct_find_expectation(const struct nf_conntrack_tuple *tuple)
 {
-       struct nf_conntrack_expect *exp;
+       struct nf_conntrack_expect *i, *exp = NULL;
+       struct hlist_node *n;
+       unsigned int h;
+
+       if (!nf_ct_expect_count)
+               return NULL;
 
-       exp = __nf_ct_expect_find(tuple);
+       h = nf_ct_expect_dst_hash(tuple);
+       hlist_for_each_entry(i, n, &nf_ct_expect_hash[h], hnode) {
+               if (!(i->flags & NF_CT_EXPECT_INACTIVE) &&
+                   nf_ct_tuple_mask_cmp(tuple, &i->tuple, &i->mask)) {
+                       exp = i;
+                       break;
+               }
+       }
        if (!exp)
                return NULL;
 
@@ -460,6 +472,7 @@ static int exp_seq_show(struct seq_file *s, void *v)
 {
        struct nf_conntrack_expect *expect;
        struct hlist_node *n = v;
+       char *delim = "";
 
        expect = hlist_entry(n, struct nf_conntrack_expect, hnode);
 
@@ -476,8 +489,12 @@ static int exp_seq_show(struct seq_file *s, void *v)
                    __nf_ct_l4proto_find(expect->tuple.src.l3num,
                                       expect->tuple.dst.protonum));
 
-       if (expect->flags & NF_CT_EXPECT_PERMANENT)
-               seq_printf(s, "PERMANENT ");
+       if (expect->flags & NF_CT_EXPECT_PERMANENT) {
+               seq_printf(s, "PERMANENT");
+               delim = ",";
+       }
+       if (expect->flags & NF_CT_EXPECT_INACTIVE)
+               seq_printf(s, "%sINACTIVE", delim);
 
        return seq_putc(s, '\n');
 }