aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2008-03-25 23:25:32 -0400
committerDavid S. Miller <davem@davemloft.net>2008-03-25 23:25:32 -0400
commitd901a9369e6e7d07a7eb4ddb315c6fcbaf8b24d3 (patch)
treee4ca6d7c02263b056bf73afc6f626a450e777acb
parent0f32a40fc91a9ebbbf66e826ac2a829ab37d9cf8 (diff)
[NETFILTER]: nf_conntrack_sip: allow media expectations with wildcard source address
Media streams can come from anywhere, add a module parameter which controls whether wildcard expectations or expectations between the two signalling endpoints are created. Since the same media description sent on multiple connections may results in multiple identical expections when using a wildcard source, we need to check whether a similar expectation already exists for a different connection before attempting to register it. Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--net/netfilter/nf_conntrack_sip.c45
1 files changed, 41 insertions, 4 deletions
diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c
index 043aa557e7a8..813aa8c67e4c 100644
--- a/net/netfilter/nf_conntrack_sip.c
+++ b/net/netfilter/nf_conntrack_sip.c
@@ -42,6 +42,11 @@ module_param(sip_direct_signalling, int, 0600);
42MODULE_PARM_DESC(sip_direct_signalling, "expect incoming calls from registrar " 42MODULE_PARM_DESC(sip_direct_signalling, "expect incoming calls from registrar "
43 "only (default 1)"); 43 "only (default 1)");
44 44
45static int sip_direct_media __read_mostly = 1;
46module_param(sip_direct_media, int, 0600);
47MODULE_PARM_DESC(sip_direct_media, "Expect Media streams between signalling "
48 "endpoints only (default 1)");
49
45unsigned int (*nf_nat_sip_hook)(struct sk_buff *skb, 50unsigned int (*nf_nat_sip_hook)(struct sk_buff *skb,
46 const char **dptr, 51 const char **dptr,
47 unsigned int *datalen) __read_mostly; 52 unsigned int *datalen) __read_mostly;
@@ -656,21 +661,53 @@ static void flush_expectations(struct nf_conn *ct, bool media)
656 661
657static int set_expected_rtp(struct sk_buff *skb, 662static int set_expected_rtp(struct sk_buff *skb,
658 const char **dptr, unsigned int *datalen, 663 const char **dptr, unsigned int *datalen,
659 union nf_inet_addr *addr, __be16 port) 664 union nf_inet_addr *daddr, __be16 port)
660{ 665{
661 struct nf_conntrack_expect *exp; 666 struct nf_conntrack_expect *exp;
662 enum ip_conntrack_info ctinfo; 667 enum ip_conntrack_info ctinfo;
663 struct nf_conn *ct = nf_ct_get(skb, &ctinfo); 668 struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
664 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo); 669 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
670 union nf_inet_addr *saddr;
671 struct nf_conntrack_tuple tuple;
665 int family = ct->tuplehash[!dir].tuple.src.l3num; 672 int family = ct->tuplehash[!dir].tuple.src.l3num;
666 int ret; 673 int skip_expect = 0, ret;
667 typeof(nf_nat_sdp_hook) nf_nat_sdp; 674 typeof(nf_nat_sdp_hook) nf_nat_sdp;
668 675
676 saddr = NULL;
677 if (sip_direct_media) {
678 if (!nf_inet_addr_cmp(daddr, &ct->tuplehash[dir].tuple.src.u3))
679 return NF_ACCEPT;
680 saddr = &ct->tuplehash[!dir].tuple.src.u3;
681 }
682
683 /* We need to check whether the registration exists before attempting
684 * to register it since we can see the same media description multiple
685 * times on different connections in case multiple endpoints receive
686 * the same call.
687 */
688 memset(&tuple, 0, sizeof(tuple));
689 if (saddr)
690 tuple.src.u3 = *saddr;
691 tuple.src.l3num = family;
692 tuple.dst.protonum = IPPROTO_UDP;
693 tuple.dst.u3 = *daddr;
694 tuple.dst.u.udp.port = port;
695
696 rcu_read_lock();
697 exp = __nf_ct_expect_find(&tuple);
698 if (exp && exp->master != ct &&
699 nfct_help(exp->master)->helper == nfct_help(ct)->helper &&
700 exp->class == SIP_EXPECT_AUDIO)
701 skip_expect = 1;
702 rcu_read_unlock();
703
704 if (skip_expect)
705 return NF_ACCEPT;
706
669 exp = nf_ct_expect_alloc(ct); 707 exp = nf_ct_expect_alloc(ct);
670 if (exp == NULL) 708 if (exp == NULL)
671 return NF_DROP; 709 return NF_DROP;
672 nf_ct_expect_init(exp, SIP_EXPECT_AUDIO, family, 710 nf_ct_expect_init(exp, SIP_EXPECT_AUDIO, family, saddr, daddr,
673 &ct->tuplehash[!dir].tuple.src.u3, addr,
674 IPPROTO_UDP, NULL, &port); 711 IPPROTO_UDP, NULL, &port);
675 712
676 nf_nat_sdp = rcu_dereference(nf_nat_sdp_hook); 713 nf_nat_sdp = rcu_dereference(nf_nat_sdp_hook);