net: compat_mmsghdr must be used in sys_recvmmsg
[safe/jmp/linux-2.6] / net / netfilter / nf_conntrack_sip.c
index f3915f8..4b57216 100644 (file)
@@ -28,6 +28,7 @@ MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Christian Hentschel <chentschel@arnet.com.ar>");
 MODULE_DESCRIPTION("SIP connection tracking helper");
 MODULE_ALIAS("ip_conntrack_sip");
+MODULE_ALIAS_NFCT_HELPER("sip");
 
 #define MAX_PORTS      8
 static unsigned short ports[MAX_PORTS];
@@ -142,11 +143,10 @@ static int parse_addr(const struct nf_conn *ct, const char *cp,
                       const char *limit)
 {
        const char *end;
-       int family = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num;
        int ret = 0;
 
        memset(addr, 0, sizeof(*addr));
-       switch (family) {
+       switch (nf_ct_l3num(ct)) {
        case AF_INET:
                ret = in4_pton(cp, limit - cp, (u8 *)&addr->ip, -1, &end);
                break;
@@ -737,10 +737,10 @@ static int set_expected_rtp_rtcp(struct sk_buff *skb,
        struct nf_conntrack_expect *exp, *rtp_exp, *rtcp_exp;
        enum ip_conntrack_info ctinfo;
        struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
+       struct net *net = nf_ct_net(ct);
        enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
        union nf_inet_addr *saddr;
        struct nf_conntrack_tuple tuple;
-       int family = ct->tuplehash[!dir].tuple.src.l3num;
        int direct_rtp = 0, skip_expect = 0, ret = NF_DROP;
        u_int16_t base_port;
        __be16 rtp_port, rtcp_port;
@@ -770,20 +770,20 @@ static int set_expected_rtp_rtcp(struct sk_buff *skb,
        memset(&tuple, 0, sizeof(tuple));
        if (saddr)
                tuple.src.u3 = *saddr;
-       tuple.src.l3num         = family;
+       tuple.src.l3num         = nf_ct_l3num(ct);
        tuple.dst.protonum      = IPPROTO_UDP;
        tuple.dst.u3            = *daddr;
        tuple.dst.u.udp.port    = port;
 
        rcu_read_lock();
        do {
-               exp = __nf_ct_expect_find(&tuple);
+               exp = __nf_ct_expect_find(net, &tuple);
 
                if (!exp || exp->master == ct ||
                    nfct_help(exp->master)->helper != nfct_help(ct)->helper ||
                    exp->class != class)
                        break;
-
+#ifdef CONFIG_NF_NAT_NEEDED
                if (exp->tuple.src.l3num == AF_INET && !direct_rtp &&
                    (exp->saved_ip != exp->tuple.dst.u3.ip ||
                     exp->saved_proto.udp.port != exp->tuple.dst.u.udp.port) &&
@@ -793,6 +793,7 @@ static int set_expected_rtp_rtcp(struct sk_buff *skb,
                        tuple.dst.u.udp.port    = exp->saved_proto.udp.port;
                        direct_rtp = 1;
                } else
+#endif
                        skip_expect = 1;
        } while (!skip_expect);
        rcu_read_unlock();
@@ -815,13 +816,13 @@ static int set_expected_rtp_rtcp(struct sk_buff *skb,
        rtp_exp = nf_ct_expect_alloc(ct);
        if (rtp_exp == NULL)
                goto err1;
-       nf_ct_expect_init(rtp_exp, class, family, saddr, daddr,
+       nf_ct_expect_init(rtp_exp, class, nf_ct_l3num(ct), saddr, daddr,
                          IPPROTO_UDP, NULL, &rtp_port);
 
        rtcp_exp = nf_ct_expect_alloc(ct);
        if (rtcp_exp == NULL)
                goto err2;
-       nf_ct_expect_init(rtcp_exp, class, family, saddr, daddr,
+       nf_ct_expect_init(rtcp_exp, class, nf_ct_l3num(ct), saddr, daddr,
                          IPPROTO_UDP, NULL, &rtcp_port);
 
        nf_nat_sdp_media = rcu_dereference(nf_nat_sdp_media_hook);
@@ -871,7 +872,7 @@ static int process_sdp(struct sk_buff *skb,
 {
        enum ip_conntrack_info ctinfo;
        struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
-       int family = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num;
+       struct nf_conn_help *help = nfct_help(ct);
        unsigned int matchoff, matchlen;
        unsigned int mediaoff, medialen;
        unsigned int sdpoff;
@@ -886,8 +887,8 @@ static int process_sdp(struct sk_buff *skb,
        typeof(nf_nat_sdp_session_hook) nf_nat_sdp_session;
 
        nf_nat_sdp_addr = rcu_dereference(nf_nat_sdp_addr_hook);
-       c_hdr = family == AF_INET ? SDP_HDR_CONNECTION_IP4 :
-                                   SDP_HDR_CONNECTION_IP6;
+       c_hdr = nf_ct_l3num(ct) == AF_INET ? SDP_HDR_CONNECTION_IP4 :
+                                            SDP_HDR_CONNECTION_IP6;
 
        /* Find beginning of session description */
        if (ct_sip_get_sdp_header(ct, *dptr, 0, *datalen,
@@ -961,6 +962,9 @@ static int process_sdp(struct sk_buff *skb,
        if (nf_nat_sdp_session && ct->status & IPS_NAT_MASK)
                ret = nf_nat_sdp_session(skb, dptr, sdpoff, datalen, &rtp_addr);
 
+       if (ret == NF_ACCEPT && i > 0)
+               help->help.ct_sip_info.invite_cseq = cseq;
+
        return ret;
 }
 static int process_invite_response(struct sk_buff *skb,
@@ -969,14 +973,14 @@ static int process_invite_response(struct sk_buff *skb,
 {
        enum ip_conntrack_info ctinfo;
        struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
+       struct nf_conn_help *help = nfct_help(ct);
 
        if ((code >= 100 && code <= 199) ||
            (code >= 200 && code <= 299))
                return process_sdp(skb, dptr, datalen, cseq);
-       else {
+       else if (help->help.ct_sip_info.invite_cseq == cseq)
                flush_expectations(ct, true);
-               return NF_ACCEPT;
-       }
+       return NF_ACCEPT;
 }
 
 static int process_update_response(struct sk_buff *skb,
@@ -985,14 +989,14 @@ static int process_update_response(struct sk_buff *skb,
 {
        enum ip_conntrack_info ctinfo;
        struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
+       struct nf_conn_help *help = nfct_help(ct);
 
        if ((code >= 100 && code <= 199) ||
            (code >= 200 && code <= 299))
                return process_sdp(skb, dptr, datalen, cseq);
-       else {
+       else if (help->help.ct_sip_info.invite_cseq == cseq)
                flush_expectations(ct, true);
-               return NF_ACCEPT;
-       }
+       return NF_ACCEPT;
 }
 
 static int process_prack_response(struct sk_buff *skb,
@@ -1001,14 +1005,14 @@ static int process_prack_response(struct sk_buff *skb,
 {
        enum ip_conntrack_info ctinfo;
        struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
+       struct nf_conn_help *help = nfct_help(ct);
 
        if ((code >= 100 && code <= 199) ||
            (code >= 200 && code <= 299))
                return process_sdp(skb, dptr, datalen, cseq);
-       else {
+       else if (help->help.ct_sip_info.invite_cseq == cseq)
                flush_expectations(ct, true);
-               return NF_ACCEPT;
-       }
+       return NF_ACCEPT;
 }
 
 static int process_bye_request(struct sk_buff *skb,
@@ -1034,7 +1038,6 @@ static int process_register_request(struct sk_buff *skb,
        struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
        struct nf_conn_help *help = nfct_help(ct);
        enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
-       int family = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num;
        unsigned int matchoff, matchlen;
        struct nf_conntrack_expect *exp;
        union nf_inet_addr *saddr, daddr;
@@ -1089,8 +1092,8 @@ static int process_register_request(struct sk_buff *skb,
        if (sip_direct_signalling)
                saddr = &ct->tuplehash[!dir].tuple.src.u3;
 
-       nf_ct_expect_init(exp, SIP_EXPECT_SIGNALLING, family, saddr, &daddr,
-                         IPPROTO_UDP, NULL, &port);
+       nf_ct_expect_init(exp, SIP_EXPECT_SIGNALLING, nf_ct_l3num(ct),
+                         saddr, &daddr, IPPROTO_UDP, NULL, &port);
        exp->timeout.expires = sip_timeout * HZ;
        exp->helper = nfct_help(ct)->helper;
        exp->flags = NF_CT_EXPECT_PERMANENT | NF_CT_EXPECT_INACTIVE;
@@ -1192,7 +1195,6 @@ static const struct sip_handler sip_handlers[] = {
 static int process_sip_response(struct sk_buff *skb,
                                const char **dptr, unsigned int *datalen)
 {
-       static const struct sip_handler *handler;
        enum ip_conntrack_info ctinfo;
        struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
        unsigned int matchoff, matchlen;
@@ -1213,6 +1215,8 @@ static int process_sip_response(struct sk_buff *skb,
        dataoff = matchoff + matchlen + 1;
 
        for (i = 0; i < ARRAY_SIZE(sip_handlers); i++) {
+               const struct sip_handler *handler;
+
                handler = &sip_handlers[i];
                if (handler->response == NULL)
                        continue;
@@ -1227,13 +1231,14 @@ static int process_sip_response(struct sk_buff *skb,
 static int process_sip_request(struct sk_buff *skb,
                               const char **dptr, unsigned int *datalen)
 {
-       static const struct sip_handler *handler;
        enum ip_conntrack_info ctinfo;
        struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
        unsigned int matchoff, matchlen;
        unsigned int cseq, i;
 
        for (i = 0; i < ARRAY_SIZE(sip_handlers); i++) {
+               const struct sip_handler *handler;
+
                handler = &sip_handlers[i];
                if (handler->request == NULL)
                        continue;