|
@@ -2442,7 +2442,16 @@ int tcp_send_synack(struct sock *sk)
|
|
|
return tcp_transmit_skb(sk, skb, 1, GFP_ATOMIC);
|
|
|
}
|
|
|
|
|
|
-/* Prepare a SYN-ACK. */
|
|
|
+/**
|
|
|
+ * tcp_make_synack - Prepare a SYN-ACK.
|
|
|
+ * sk: listener socket
|
|
|
+ * dst: dst entry attached to the SYNACK
|
|
|
+ * req: request_sock pointer
|
|
|
+ * rvp: request_values pointer
|
|
|
+ *
|
|
|
+ * Allocate one skb and build a SYNACK packet.
|
|
|
+ * @dst is consumed : Caller should not use it again.
|
|
|
+ */
|
|
|
struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst,
|
|
|
struct request_sock *req,
|
|
|
struct request_values *rvp)
|
|
@@ -2462,13 +2471,14 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst,
|
|
|
if (cvp != NULL && cvp->s_data_constant && cvp->s_data_desired)
|
|
|
s_data_desired = cvp->s_data_desired;
|
|
|
skb = alloc_skb(MAX_TCP_HEADER + 15 + s_data_desired, GFP_ATOMIC);
|
|
|
- if (skb == NULL)
|
|
|
+ if (unlikely(!skb)) {
|
|
|
+ dst_release(dst);
|
|
|
return NULL;
|
|
|
-
|
|
|
+ }
|
|
|
/* Reserve space for headers. */
|
|
|
skb_reserve(skb, MAX_TCP_HEADER);
|
|
|
|
|
|
- skb_dst_set(skb, dst_clone(dst));
|
|
|
+ skb_dst_set(skb, dst);
|
|
|
|
|
|
mss = dst_metric_advmss(dst);
|
|
|
if (tp->rx_opt.user_mss && tp->rx_opt.user_mss < mss)
|