diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/dccp/dccp.h | 1 | ||||
-rw-r--r-- | net/dccp/output.c | 23 |
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 | ||
121 | extern int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb); | ||
122 | extern int dccp_retransmit_skb(struct sock *sk, struct sk_buff *skb); | 121 | extern int dccp_retransmit_skb(struct sock *sk, struct sk_buff *skb); |
123 | 122 | ||
124 | extern int dccp_send_response(struct sock *sk); | 123 | extern 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 | ||
29 | static 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 | */ |
34 | int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb) | 42 | static 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); |