aboutsummaryrefslogtreecommitdiffstats
path: root/net/dccp/ipv4.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/dccp/ipv4.c')
-rw-r--r--net/dccp/ipv4.c38
1 files changed, 5 insertions, 33 deletions
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
index 58a79c2ae55c..2312b9f4d7af 100644
--- a/net/dccp/ipv4.c
+++ b/net/dccp/ipv4.c
@@ -510,17 +510,12 @@ out:
510static void dccp_v4_ctl_send_reset(struct sock *sk, struct sk_buff *rxskb) 510static void dccp_v4_ctl_send_reset(struct sock *sk, struct sk_buff *rxskb)
511{ 511{
512 int err; 512 int err;
513 struct dccp_hdr *rxdh = dccp_hdr(rxskb), *dh;
514 const struct iphdr *rxiph; 513 const struct iphdr *rxiph;
515 const int dccp_hdr_reset_len = sizeof(struct dccp_hdr) +
516 sizeof(struct dccp_hdr_ext) +
517 sizeof(struct dccp_hdr_reset);
518 struct sk_buff *skb; 514 struct sk_buff *skb;
519 struct dst_entry *dst; 515 struct dst_entry *dst;
520 u64 seqno = 0;
521 516
522 /* Never send a reset in response to a reset. */ 517 /* Never send a reset in response to a reset. */
523 if (rxdh->dccph_type == DCCP_PKT_RESET) 518 if (dccp_hdr(rxskb)->dccph_type == DCCP_PKT_RESET)
524 return; 519 return;
525 520
526 if (((struct rtable *)rxskb->dst)->rt_type != RTN_LOCAL) 521 if (((struct rtable *)rxskb->dst)->rt_type != RTN_LOCAL)
@@ -530,37 +525,14 @@ static void dccp_v4_ctl_send_reset(struct sock *sk, struct sk_buff *rxskb)
530 if (dst == NULL) 525 if (dst == NULL)
531 return; 526 return;
532 527
533 skb = alloc_skb(dccp_v4_ctl_socket->sk->sk_prot->max_header, 528 skb = dccp_ctl_make_reset(dccp_v4_ctl_socket, rxskb);
534 GFP_ATOMIC);
535 if (skb == NULL) 529 if (skb == NULL)
536 goto out; 530 goto out;
537 531
538 /* Reserve space for headers. */
539 skb_reserve(skb, dccp_v4_ctl_socket->sk->sk_prot->max_header);
540 skb->dst = dst_clone(dst);
541
542 dh = dccp_zeroed_hdr(skb, dccp_hdr_reset_len);
543
544 /* Build DCCP header and checksum it. */
545 dh->dccph_type = DCCP_PKT_RESET;
546 dh->dccph_sport = rxdh->dccph_dport;
547 dh->dccph_dport = rxdh->dccph_sport;
548 dh->dccph_doff = dccp_hdr_reset_len / 4;
549 dh->dccph_x = 1;
550 dccp_hdr_reset(skb)->dccph_reset_code =
551 DCCP_SKB_CB(rxskb)->dccpd_reset_code;
552
553 /* See "8.3.1. Abnormal Termination" in RFC 4340 */
554 if (DCCP_SKB_CB(rxskb)->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ)
555 seqno = ADD48(DCCP_SKB_CB(rxskb)->dccpd_ack_seq, 1);
556
557 dccp_hdr_set_seq(dh, seqno);
558 dccp_hdr_set_ack(dccp_hdr_ack_bits(skb), DCCP_SKB_CB(rxskb)->dccpd_seq);
559
560 dccp_csum_outgoing(skb);
561 rxiph = ip_hdr(rxskb); 532 rxiph = ip_hdr(rxskb);
562 dh->dccph_checksum = dccp_v4_csum_finish(skb, rxiph->saddr, 533 dccp_hdr(skb)->dccph_checksum = dccp_v4_csum_finish(skb, rxiph->saddr,
563 rxiph->daddr); 534 rxiph->daddr);
535 skb->dst = dst_clone(dst);
564 536
565 bh_lock_sock(dccp_v4_ctl_socket->sk); 537 bh_lock_sock(dccp_v4_ctl_socket->sk);
566 err = ip_build_and_send_pkt(skb, dccp_v4_ctl_socket->sk, 538 err = ip_build_and_send_pkt(skb, dccp_v4_ctl_socket->sk,