[DCCP] ccid3: Reorder packet history source file
[safe/jmp/linux-2.6] / net / dccp / ipv4.c
index 61c0901..ff81679 100644 (file)
@@ -244,7 +244,7 @@ static void dccp_v4_err(struct sk_buff *skb, u32 info)
        seq = dccp_hdr_seq(skb);
        if (sk->sk_state != DCCP_LISTEN &&
            !between48(seq, dp->dccps_swl, dp->dccps_swh)) {
-               NET_INC_STATS(LINUX_MIB_OUTOFWINDOWICMPS);
+               NET_INC_STATS_BH(LINUX_MIB_OUTOFWINDOWICMPS);
                goto out;
        }
 
@@ -344,7 +344,7 @@ out:
        sock_put(sk);
 }
 
-static inline u16 dccp_v4_csum_finish(struct sk_buff *skb,
+static inline __sum16 dccp_v4_csum_finish(struct sk_buff *skb,
                                      __be32 src, __be32 dst)
 {
        return csum_tcpudp_magic(src, dst, skb->len, IPPROTO_DCCP, skb->csum);
@@ -509,7 +509,7 @@ out:
        return err;
 }
 
-static void dccp_v4_ctl_send_reset(struct sk_buff *rxskb)
+static void dccp_v4_ctl_send_reset(struct sock *sk, struct sk_buff *rxskb)
 {
        int err;
        struct dccp_hdr *rxdh = dccp_hdr(rxskb), *dh;
@@ -518,7 +518,7 @@ static void dccp_v4_ctl_send_reset(struct sk_buff *rxskb)
                                       sizeof(struct dccp_hdr_reset);
        struct sk_buff *skb;
        struct dst_entry *dst;
-       u64 seqno;
+       u64 seqno = 0;
 
        /* Never send a reset in response to a reset. */
        if (rxdh->dccph_type == DCCP_PKT_RESET)
@@ -552,13 +552,11 @@ static void dccp_v4_ctl_send_reset(struct sk_buff *rxskb)
                                DCCP_SKB_CB(rxskb)->dccpd_reset_code;
 
        /* See "8.3.1. Abnormal Termination" in RFC 4340 */
-       seqno = 0;
        if (DCCP_SKB_CB(rxskb)->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ)
                dccp_set_seqno(&seqno, DCCP_SKB_CB(rxskb)->dccpd_ack_seq + 1);
 
        dccp_hdr_set_seq(dh, seqno);
-       dccp_hdr_set_ack(dccp_hdr_ack_bits(skb),
-                        DCCP_SKB_CB(rxskb)->dccpd_seq);
+       dccp_hdr_set_ack(dccp_hdr_ack_bits(skb), DCCP_SKB_CB(rxskb)->dccpd_seq);
 
        dccp_csum_outgoing(skb);
        dh->dccph_checksum = dccp_v4_csum_finish(skb, rxskb->nh.iph->saddr,
@@ -726,7 +724,7 @@ int dccp_v4_do_rcv(struct sock *sk, struct sk_buff *skb)
        return 0;
 
 reset:
-       dccp_v4_ctl_send_reset(skb);
+       dccp_v4_ctl_send_reset(sk, skb);
 discard:
        kfree_skb(skb);
        return 0;
@@ -734,6 +732,11 @@ discard:
 
 EXPORT_SYMBOL_GPL(dccp_v4_do_rcv);
 
+/**
+ *     dccp_invalid_packet  -  check for malformed packets
+ *     Implements RFC 4340, 8.5:  Step 1: Check header basics
+ *     Packets that fail these checks are ignored and do not receive Resets.
+ */
 int dccp_invalid_packet(struct sk_buff *skb)
 {
        const struct dccp_hdr *dh;
@@ -742,50 +745,43 @@ int dccp_invalid_packet(struct sk_buff *skb)
        if (skb->pkt_type != PACKET_HOST)
                return 1;
 
+       /* If the packet is shorter than 12 bytes, drop packet and return */
        if (!pskb_may_pull(skb, sizeof(struct dccp_hdr))) {
-               LIMIT_NETDEBUG(KERN_WARNING "DCCP: pskb_may_pull failed\n");
+               DCCP_WARN("pskb_may_pull failed\n");
                return 1;
        }
 
        dh = dccp_hdr(skb);
 
-       /* If the packet type is not understood, drop packet and return */
+       /* If P.type is not understood, drop packet and return */
        if (dh->dccph_type >= DCCP_PKT_INVALID) {
-               LIMIT_NETDEBUG(KERN_WARNING "DCCP: invalid packet type\n");
+               DCCP_WARN("invalid packet type\n");
                return 1;
        }
 
        /*
-        * If P.Data Offset is too small for packet type, or too large for
-        * packet, drop packet and return
+        * If P.Data Offset is too small for packet type, drop packet and return
         */
        if (dh->dccph_doff < dccp_hdr_len(skb) / sizeof(u32)) {
-               LIMIT_NETDEBUG(KERN_WARNING "DCCP: P.Data Offset(%u) "
-                                           "too small 1\n",
-                              dh->dccph_doff);
+               DCCP_WARN("P.Data Offset(%u) too small\n", dh->dccph_doff);
                return 1;
        }
-
+       /*
+        * If P.Data Offset is too too large for packet, drop packet and return
+        */
        if (!pskb_may_pull(skb, dh->dccph_doff * sizeof(u32))) {
-               LIMIT_NETDEBUG(KERN_WARNING "DCCP: P.Data Offset(%u) "
-                                           "too small 2\n",
-                              dh->dccph_doff);
+               DCCP_WARN("P.Data Offset(%u) too large\n", dh->dccph_doff);
                return 1;
        }
 
-       dh = dccp_hdr(skb);
-
        /*
         * If P.type is not Data, Ack, or DataAck and P.X == 0 (the packet
         * has short sequence numbers), drop packet and return
         */
-       if (dh->dccph_x == 0 &&
-           dh->dccph_type != DCCP_PKT_DATA &&
-           dh->dccph_type != DCCP_PKT_ACK &&
-           dh->dccph_type != DCCP_PKT_DATAACK) {
-               LIMIT_NETDEBUG(KERN_WARNING "DCCP: P.type (%s) not Data, Ack "
-                                           "nor DataAck and P.X == 0\n",
-                              dccp_packet_name(dh->dccph_type));
+       if (dh->dccph_type >= DCCP_PKT_DATA    &&
+           dh->dccph_type <= DCCP_PKT_DATAACK && dh->dccph_x == 0)  {
+               DCCP_WARN("P.type (%s) not Data || [Data]Ack, while P.X == 0\n",
+                         dccp_packet_name(dh->dccph_type));
                return 1;
        }
 
@@ -795,9 +791,8 @@ int dccp_invalid_packet(struct sk_buff *skb)
         */
        cscov = dccp_csum_coverage(skb);
        if (cscov > skb->len) {
-               LIMIT_NETDEBUG(KERN_WARNING
-                              "DCCP: P.CsCov %u exceeds packet length %d\n",
-                              dh->dccph_cscov, skb->len);
+               DCCP_WARN("P.CsCov %u exceeds packet length %d\n",
+                         dh->dccph_cscov, skb->len);
                return 1;
        }
 
@@ -824,9 +819,7 @@ static int dccp_v4_rcv(struct sk_buff *skb)
 
        /* Step 1: If header checksum is incorrect, drop packet and return */
        if (dccp_v4_csum_finish(skb, skb->nh.iph->saddr, skb->nh.iph->daddr)) {
-               LIMIT_NETDEBUG(KERN_WARNING
-                              "%s: dropped packet with invalid checksum\n",
-                              __FUNCTION__);
+               DCCP_WARN("dropped packet with invalid checksum\n");
                goto discard_it;
        }
 
@@ -900,7 +893,7 @@ static int dccp_v4_rcv(struct sk_buff *skb)
                goto discard_and_relse;
        nf_reset(skb);
 
-       return sk_receive_skb(sk, skb);
+       return sk_receive_skb(sk, skb, 1);
 
 no_dccp_socket:
        if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb))
@@ -914,7 +907,7 @@ no_dccp_socket:
        if (dh->dccph_type != DCCP_PKT_RESET) {
                DCCP_SKB_CB(skb)->dccpd_reset_code =
                                        DCCP_RESET_CODE_NO_CONNECTION;
-               dccp_v4_ctl_send_reset(skb);
+               dccp_v4_ctl_send_reset(sk, skb);
        }
 
 discard_it: