aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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);