diff options
Diffstat (limited to 'net/dccp')
-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 5871c02..f97b85d 100644 --- a/net/dccp/dccp.h +++ b/net/dccp/dccp.h @@ -118,7 +118,6 @@ DECLARE_SNMP_STAT(struct dccp_mib, dccp_statistics); #define DCCP_ADD_STATS_USER(field, val) \ SNMP_ADD_STATS_USER(dccp_statistics, field, val) -extern int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb); extern int dccp_retransmit_skb(struct sock *sk, struct sk_buff *skb); extern int dccp_send_response(struct sock *sk); diff --git a/net/dccp/output.c b/net/dccp/output.c index d59f86f..c25b042 100644 --- a/net/dccp/output.c +++ b/net/dccp/output.c @@ -12,6 +12,7 @@ #include <linux/config.h> #include <linux/dccp.h> +#include <linux/kernel.h> #include <linux/skbuff.h> #include <net/sock.h> @@ -25,13 +26,20 @@ static inline void dccp_event_ack_sent(struct sock *sk) inet_csk_clear_xmit_timer(sk, ICSK_TIME_DACK); } +static inline void dccp_skb_entail(struct sock *sk, struct sk_buff *skb) +{ + skb_set_owner_w(skb, sk); + WARN_ON(sk->sk_send_head); + sk->sk_send_head = skb; +} + /* * All SKB's seen here are completely headerless. It is our * job to build the DCCP header, and pass the packet down to * IP so it can do the same plus pass the packet off to the * device. */ -int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb) +static int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb) { if (likely(skb != NULL)) { const struct inet_sock *inet = inet_sk(sk); @@ -63,6 +71,9 @@ int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb) skb->h.raw = skb_push(skb, dccp_header_size); dh = dccp_hdr(skb); + /* + * Only data packets should come through with skb->sk set. + */ if (!skb->sk) skb_set_owner_w(skb, sk); @@ -393,10 +404,8 @@ int dccp_connect(struct sock *sk) DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_REQUEST; skb->csum = 0; - skb_set_owner_w(skb, sk); - BUG_TRAP(sk->sk_send_head == NULL); - sk->sk_send_head = skb; + dccp_skb_entail(sk, skb); dccp_transmit_skb(sk, skb_clone(skb, GFP_KERNEL)); DCCP_INC_STATS(DCCP_MIB_ACTIVEOPENS); @@ -425,7 +434,6 @@ void dccp_send_ack(struct sock *sk) skb_reserve(skb, MAX_DCCP_HEADER); skb->csum = 0; DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_ACK; - skb_set_owner_w(skb, sk); dccp_transmit_skb(sk, skb); } } @@ -482,7 +490,6 @@ void dccp_send_sync(struct sock *sk, const u64 seq, DCCP_SKB_CB(skb)->dccpd_type = pkt_type; DCCP_SKB_CB(skb)->dccpd_seq = seq; - skb_set_owner_w(skb, sk); dccp_transmit_skb(sk, skb); } @@ -507,10 +514,8 @@ void dccp_send_close(struct sock *sk, const int active) DCCP_SKB_CB(skb)->dccpd_type = dp->dccps_role == DCCP_ROLE_CLIENT ? DCCP_PKT_CLOSE : DCCP_PKT_CLOSEREQ; - skb_set_owner_w(skb, sk); if (active) { - BUG_TRAP(sk->sk_send_head == NULL); - sk->sk_send_head = skb; + dccp_skb_entail(sk, skb); dccp_transmit_skb(sk, skb_clone(skb, prio)); } else dccp_transmit_skb(sk, skb); |