- struct tcphdr *th = tcp_hdr(skb), *t1;
- struct sk_buff *buff;
- struct flowi fl;
- struct net *net = dev_net(skb->dst->dev);
- struct sock *ctl_sk = net->ipv6.tcp_sk;
- unsigned int tot_len = sizeof(*th);
-#ifdef CONFIG_TCP_MD5SIG
- struct tcp_md5sig_key *key;
-#endif
-
- if (th->rst)
- return;
-
- if (!ipv6_unicast_destination(skb))
- return;
-
-#ifdef CONFIG_TCP_MD5SIG
- if (sk)
- key = tcp_v6_md5_do_lookup(sk, &ipv6_hdr(skb)->daddr);
- else
- key = NULL;
-
- if (key)
- tot_len += TCPOLEN_MD5SIG_ALIGNED;
-#endif
-
- /*
- * We need to grab some memory, and put together an RST,
- * and then put it into the queue to be sent.
- */
-
- buff = alloc_skb(MAX_HEADER + sizeof(struct ipv6hdr) + tot_len,
- GFP_ATOMIC);
- if (buff == NULL)
- return;
-
- skb_reserve(buff, MAX_HEADER + sizeof(struct ipv6hdr) + tot_len);
-
- t1 = (struct tcphdr *) skb_push(buff, tot_len);
-
- /* Swap the send and the receive. */
- memset(t1, 0, sizeof(*t1));
- t1->dest = th->source;
- t1->source = th->dest;
- t1->doff = tot_len / 4;
- t1->rst = 1;