]> err.no Git - linux-2.6/blobdiff - net/dccp/ipv4.c
Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
[linux-2.6] / net / dccp / ipv4.c
index 42d9c878d4c34e12f3e05bf3345beaf3aee5b075..3fc75dbee4b8e4d068a0b4598fc96900c5a90842 100644 (file)
@@ -309,6 +309,16 @@ static int dccp_v4_connect(struct sock *sk, struct sockaddr *uaddr,
                                                            usin->sin_port);
        dccp_update_gss(sk, dp->dccps_iss);
 
+       /*
+        * SWL and AWL are initially adjusted so that they are not less than
+        * the initial Sequence Numbers received and sent, respectively:
+        *      SWL := max(GSR + 1 - floor(W/4), ISR),
+        *      AWL := max(GSS - W' + 1, ISS).
+        * These adjustments MUST be applied only at the beginning of the
+        * connection.
+        */
+       dccp_set_seqno(&dp->dccps_awl, max48(dp->dccps_awl, dp->dccps_iss));
+
        inet->id = dp->dccps_iss ^ jiffies;
 
        err = dccp_connect(sk);
@@ -376,7 +386,7 @@ static inline void dccp_do_pmtu_discovery(struct sock *sk,
                 *      probing, since DCCP-Sync probes do not risk application
                 *      data loss.
                 */
-               dccp_send_sync(sk, dp->dccps_gsr);
+               dccp_send_sync(sk, dp->dccps_gsr, DCCP_PKT_SYNC);
        } /* else let the usual retransmit timer handle it */
 }
 
@@ -617,9 +627,6 @@ out:
        sock_put(sk);
 }
 
-extern struct sk_buff *dccp_make_reset(struct sock *sk, struct dst_entry *dst,
-                                      enum dccp_reset_codes code);
-
 int dccp_v4_send_reset(struct sock *sk, enum dccp_reset_codes code)
 {
        struct sk_buff *skb;
@@ -881,7 +888,7 @@ static struct dst_entry* dccp_v4_route_skb(struct sock *sk,
        return &rt->u.dst;
 }
 
-void dccp_v4_ctl_send_reset(struct sk_buff *rxskb)
+static void dccp_v4_ctl_send_reset(struct sk_buff *rxskb)
 {
        int err;
        struct dccp_hdr *rxdh = dccp_hdr(rxskb), *dh;
@@ -890,6 +897,7 @@ 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;
 
        /* Never send a reset in response to a reset. */
        if (rxdh->dccph_type == DCCP_PKT_RESET)
@@ -923,7 +931,12 @@ void dccp_v4_ctl_send_reset(struct sk_buff *rxskb)
        dccp_hdr_reset(skb)->dccph_reset_code =
                                DCCP_SKB_CB(rxskb)->dccpd_reset_code;
 
-       dccp_hdr_set_seq(dh, DCCP_SKB_CB(rxskb)->dccpd_ack_seq);
+       /* See "8.3.1. Abnormal Termination" in draft-ietf-dccp-spec-11 */
+       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);
 
@@ -1011,7 +1024,7 @@ static inline int dccp_invalid_packet(struct sk_buff *skb)
                return 1;
 
        if (!pskb_may_pull(skb, sizeof(struct dccp_hdr))) {
-               dccp_pr_debug("pskb_may_pull failed\n");
+               LIMIT_NETDEBUG(KERN_WARNING "DCCP: pskb_may_pull failed\n");
                return 1;
        }
 
@@ -1019,7 +1032,7 @@ static inline int dccp_invalid_packet(struct sk_buff *skb)
 
        /* If the packet type is not understood, drop packet and return */
        if (dh->dccph_type >= DCCP_PKT_INVALID) {
-               dccp_pr_debug("invalid packet type\n");
+               LIMIT_NETDEBUG(KERN_WARNING "DCCP: invalid packet type\n");
                return 1;
        }
 
@@ -1028,13 +1041,16 @@ static inline int dccp_invalid_packet(struct sk_buff *skb)
         * packet, drop packet and return
         */
        if (dh->dccph_doff < dccp_hdr_len(skb) / sizeof(u32)) {
-               dccp_pr_debug("Offset(%u) too small 1\n", dh->dccph_doff);
+               LIMIT_NETDEBUG(KERN_WARNING "DCCP: P.Data Offset(%u) "
+                                           "too small 1\n",
+                              dh->dccph_doff);
                return 1;
        }
 
        if (!pskb_may_pull(skb, dh->dccph_doff * sizeof(u32))) {
-               dccp_pr_debug("P.Data Offset(%u) too small 2\n",
-                             dh->dccph_doff);
+               LIMIT_NETDEBUG(KERN_WARNING "DCCP: P.Data Offset(%u) "
+                                           "too small 2\n",
+                              dh->dccph_doff);
                return 1;
        }
 
@@ -1048,15 +1064,17 @@ static inline int dccp_invalid_packet(struct sk_buff *skb)
            dh->dccph_type != DCCP_PKT_DATA &&
            dh->dccph_type != DCCP_PKT_ACK &&
            dh->dccph_type != DCCP_PKT_DATAACK) {
-               dccp_pr_debug("P.type (%s) not Data, Ack nor DataAck and "
-                             "P.X == 0\n", dccp_packet_name(dh->dccph_type));
+               LIMIT_NETDEBUG(KERN_WARNING "DCCP: P.type (%s) not Data, Ack "
+                                           "nor DataAck and P.X == 0\n",
+                              dccp_packet_name(dh->dccph_type));
                return 1;
        }
 
        /* If the header checksum is incorrect, drop packet and return */
        if (dccp_v4_verify_checksum(skb, skb->nh.iph->saddr,
                                    skb->nh.iph->daddr) < 0) {
-               dccp_pr_debug("header checksum is incorrect\n");
+               LIMIT_NETDEBUG(KERN_WARNING "DCCP: header checksum is "
+                                           "incorrect\n");
                return 1;
        }
 
@@ -1262,13 +1280,14 @@ static int dccp_v4_init_sock(struct sock *sk)
        dccp_init_xmit_timers(sk);
        inet_csk(sk)->icsk_rto = DCCP_TIMEOUT_INIT;
        sk->sk_state = DCCP_CLOSED;
+       sk->sk_write_space = dccp_write_space;
        dp->dccps_mss_cache = 536;
        dp->dccps_role = DCCP_ROLE_UNDEFINED;
 
        return 0;
 }
 
-int dccp_v4_destroy_sock(struct sock *sk)
+static int dccp_v4_destroy_sock(struct sock *sk)
 {
        struct dccp_sock *dp = dccp_sk(sk);
 
@@ -1285,6 +1304,8 @@ int dccp_v4_destroy_sock(struct sock *sk)
        if (inet_csk(sk)->icsk_bind_hash != NULL)
                inet_put_port(&dccp_hashinfo, sk);
 
+       ccid_hc_rx_exit(dp->dccps_hc_rx_ccid, sk);
+       ccid_hc_tx_exit(dp->dccps_hc_tx_ccid, sk);
        dccp_ackpkts_free(dp->dccps_hc_rx_ackpkts);
        dp->dccps_hc_rx_ackpkts = NULL;
        ccid_exit(dp->dccps_hc_rx_ccid, sk);