Commit 359b9ab6 authored by Patrick McHardy's avatar Patrick McHardy Committed by David S. Miller

[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: default avatarPatrick McHardy <kaber@trash.net>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 4bb119ea
...@@ -54,6 +54,7 @@ struct nf_conntrack_expect ...@@ -54,6 +54,7 @@ struct nf_conntrack_expect
}; };
#define NF_CT_EXPECT_PERMANENT 0x1 #define NF_CT_EXPECT_PERMANENT 0x1
#define NF_CT_EXPECT_INACTIVE 0x2
int nf_conntrack_expect_init(void); int nf_conntrack_expect_init(void);
void nf_conntrack_expect_fini(void); void nf_conntrack_expect_fini(void);
......
...@@ -126,9 +126,21 @@ EXPORT_SYMBOL_GPL(nf_ct_expect_find_get); ...@@ -126,9 +126,21 @@ EXPORT_SYMBOL_GPL(nf_ct_expect_find_get);
struct nf_conntrack_expect * struct nf_conntrack_expect *
nf_ct_find_expectation(const struct nf_conntrack_tuple *tuple) 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) if (!exp)
return NULL; return NULL;
...@@ -460,6 +472,7 @@ static int exp_seq_show(struct seq_file *s, void *v) ...@@ -460,6 +472,7 @@ static int exp_seq_show(struct seq_file *s, void *v)
{ {
struct nf_conntrack_expect *expect; struct nf_conntrack_expect *expect;
struct hlist_node *n = v; struct hlist_node *n = v;
char *delim = "";
expect = hlist_entry(n, struct nf_conntrack_expect, hnode); expect = hlist_entry(n, struct nf_conntrack_expect, hnode);
...@@ -476,8 +489,12 @@ static int exp_seq_show(struct seq_file *s, void *v) ...@@ -476,8 +489,12 @@ static int exp_seq_show(struct seq_file *s, void *v)
__nf_ct_l4proto_find(expect->tuple.src.l3num, __nf_ct_l4proto_find(expect->tuple.src.l3num,
expect->tuple.dst.protonum)); expect->tuple.dst.protonum));
if (expect->flags & NF_CT_EXPECT_PERMANENT) if (expect->flags & NF_CT_EXPECT_PERMANENT) {
seq_printf(s, "PERMANENT "); seq_printf(s, "PERMANENT");
delim = ",";
}
if (expect->flags & NF_CT_EXPECT_INACTIVE)
seq_printf(s, "%sINACTIVE", delim);
return seq_putc(s, '\n'); return seq_putc(s, '\n');
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment