aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2008-03-25 20:08:37 -0700
committerDavid S. Miller <davem@davemloft.net>2008-03-25 20:08:37 -0700
commit359b9ab614aba71c2c3bc047efbd6d12dd4a2b9e (patch)
tree3399b1bf65d5d1faff0c4231f7a716c445c19d2a
parent4bb119eab7b724109d8eeb0f8d86ed1e4953d338 (diff)
[NETFILTER]: nf_conntrack_expect: support inactive expectations
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>
-rw-r--r--include/net/netfilter/nf_conntrack_expect.h3
-rw-r--r--net/netfilter/nf_conntrack_expect.c25
2 files changed, 23 insertions, 5 deletions
diff --git a/include/net/netfilter/nf_conntrack_expect.h b/include/net/netfilter/nf_conntrack_expect.h
index f1bdcb4f3f2..47c28dd0789 100644
--- a/include/net/netfilter/nf_conntrack_expect.h
+++ b/include/net/netfilter/nf_conntrack_expect.h
@@ -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);
diff --git a/net/netfilter/nf_conntrack_expect.c b/net/netfilter/nf_conntrack_expect.c
index 4c05a588116..882602f1c0e 100644
--- a/net/netfilter/nf_conntrack_expect.c
+++ b/net/netfilter/nf_conntrack_expect.c
@@ -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');
}