aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/dccp/dccp.h1
-rw-r--r--net/dccp/output.c23
2 files changed, 14 insertions, 10 deletions
diff --git a/net/dccp/dccp.h b/net/dccp/dccp.h
index 5871c027f9dc..f97b85d55ad8 100644
--- a/net/dccp/dccp.h
+++ b/net/dccp/dccp.h
@@ -118,7 +118,6 @@ DECLARE_SNMP_STAT(struct dccp_mib, dccp_statistics);
118#define DCCP_ADD_STATS_USER(field, val) \ 118#define DCCP_ADD_STATS_USER(field, val) \
119 SNMP_ADD_STATS_USER(dccp_statistics, field, val) 119 SNMP_ADD_STATS_USER(dccp_statistics, field, val)
120 120
121extern int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb);
122extern int dccp_retransmit_skb(struct sock *sk, struct sk_buff *skb); 121extern int dccp_retransmit_skb(struct sock *sk, struct sk_buff *skb);
123 122
124extern int dccp_send_response(struct sock *sk); 123extern int dccp_send_response(struct sock *sk);
diff --git a/net/dccp/output.c b/net/dccp/output.c
index d59f86f7ceab..c25b0423887a 100644
--- a/net/dccp/output.c
+++ b/net/dccp/output.c
@@ -12,6 +12,7 @@
12 12
13#include <linux/config.h> 13#include <linux/config.h>
14#include <linux/dccp.h> 14#include <linux/dccp.h>
15#include <linux/kernel.h>
15#include <linux/skbuff.h> 16#include <linux/skbuff.h>
16 17
17#include <net/sock.h> 18#include <net/sock.h>
@@ -25,13 +26,20 @@ static inline void dccp_event_ack_sent(struct sock *sk)
25 inet_csk_clear_xmit_timer(sk, ICSK_TIME_DACK); 26 inet_csk_clear_xmit_timer(sk, ICSK_TIME_DACK);
26} 27}
27 28
29static inline void dccp_skb_entail(struct sock *sk, struct sk_buff *skb)
30{
31 skb_set_owner_w(skb, sk);
32 WARN_ON(sk->sk_send_head);
33 sk->sk_send_head = skb;
34}
35
28/* 36/*
29 * All SKB's seen here are completely headerless. It is our 37 * All SKB's seen here are completely headerless. It is our
30 * job to build the DCCP header, and pass the packet down to 38 * job to build the DCCP header, and pass the packet down to
31 * IP so it can do the same plus pass the packet off to the 39 * IP so it can do the same plus pass the packet off to the
32 * device. 40 * device.
33 */ 41 */
34int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb) 42static int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb)
35{ 43{
36 if (likely(skb != NULL)) { 44 if (likely(skb != NULL)) {
37 const struct inet_sock *inet = inet_sk(sk); 45 const struct inet_sock *inet = inet_sk(sk);
@@ -63,6 +71,9 @@ int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb)
63 skb->h.raw = skb_push(skb, dccp_header_size); 71 skb->h.raw = skb_push(skb, dccp_header_size);
64 dh = dccp_hdr(skb); 72 dh = dccp_hdr(skb);
65 73
74 /*
75 * Only data packets should come through with skb->sk set.
76 */
66 if (!skb->sk) 77 if (!skb->sk)
67 skb_set_owner_w(skb, sk); 78 skb_set_owner_w(skb, sk);
68 79
@@ -393,10 +404,8 @@ int dccp_connect(struct sock *sk)
393 404
394 DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_REQUEST; 405 DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_REQUEST;
395 skb->csum = 0; 406 skb->csum = 0;
396 skb_set_owner_w(skb, sk);
397 407
398 BUG_TRAP(sk->sk_send_head == NULL); 408 dccp_skb_entail(sk, skb);
399 sk->sk_send_head = skb;
400 dccp_transmit_skb(sk, skb_clone(skb, GFP_KERNEL)); 409 dccp_transmit_skb(sk, skb_clone(skb, GFP_KERNEL));
401 DCCP_INC_STATS(DCCP_MIB_ACTIVEOPENS); 410 DCCP_INC_STATS(DCCP_MIB_ACTIVEOPENS);
402 411
@@ -425,7 +434,6 @@ void dccp_send_ack(struct sock *sk)
425 skb_reserve(skb, MAX_DCCP_HEADER); 434 skb_reserve(skb, MAX_DCCP_HEADER);
426 skb->csum = 0; 435 skb->csum = 0;
427 DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_ACK; 436 DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_ACK;
428 skb_set_owner_w(skb, sk);
429 dccp_transmit_skb(sk, skb); 437 dccp_transmit_skb(sk, skb);
430 } 438 }
431} 439}
@@ -482,7 +490,6 @@ void dccp_send_sync(struct sock *sk, const u64 seq,
482 DCCP_SKB_CB(skb)->dccpd_type = pkt_type; 490 DCCP_SKB_CB(skb)->dccpd_type = pkt_type;
483 DCCP_SKB_CB(skb)->dccpd_seq = seq; 491 DCCP_SKB_CB(skb)->dccpd_seq = seq;
484 492
485 skb_set_owner_w(skb, sk);
486 dccp_transmit_skb(sk, skb); 493 dccp_transmit_skb(sk, skb);
487} 494}
488 495
@@ -507,10 +514,8 @@ void dccp_send_close(struct sock *sk, const int active)
507 DCCP_SKB_CB(skb)->dccpd_type = dp->dccps_role == DCCP_ROLE_CLIENT ? 514 DCCP_SKB_CB(skb)->dccpd_type = dp->dccps_role == DCCP_ROLE_CLIENT ?
508 DCCP_PKT_CLOSE : DCCP_PKT_CLOSEREQ; 515 DCCP_PKT_CLOSE : DCCP_PKT_CLOSEREQ;
509 516
510 skb_set_owner_w(skb, sk);
511 if (active) { 517 if (active) {
512 BUG_TRAP(sk->sk_send_head == NULL); 518 dccp_skb_entail(sk, skb);
513 sk->sk_send_head = skb;
514 dccp_transmit_skb(sk, skb_clone(skb, prio)); 519 dccp_transmit_skb(sk, skb_clone(skb, prio));
515 } else 520 } else
516 dccp_transmit_skb(sk, skb); 521 dccp_transmit_skb(sk, skb);