• I
    tcpv6: convert opt[] -> topt in tcp_v6_send_reset · 81ada62d
    Ilpo Järvinen 提交于
    after this I get:
    
    $ diff-funcs tcp_v6_send_reset tcp_ipv6.c tcp_ipv6.c tcp_v6_send_ack
     --- tcp_ipv6.c:tcp_v6_send_reset()
     +++ tcp_ipv6.c:tcp_v6_send_ack()
    @@ -1,4 +1,5 @@
    -static void tcp_v6_send_reset(struct sock *sk, struct sk_buff *skb)
    +static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win,
    u32 ts,
    +                           struct tcp_md5sig_key *key)
     {
            struct tcphdr *th = tcp_hdr(skb), *t1;
            struct sk_buff *buff;
    @@ -7,31 +8,14 @@
            struct sock *ctl_sk = net->ipv6.tcp_sk;
            unsigned int tot_len = sizeof(struct tcphdr);
            __be32 *topt;
    -#ifdef CONFIG_TCP_MD5SIG
    -       struct tcp_md5sig_key *key;
    -#endif
    -
    -       if (th->rst)
    -               return;
    -
    -       if (!ipv6_unicast_destination(skb))
    -               return;
    
    +       if (ts)
    +               tot_len += TCPOLEN_TSTAMP_ALIGNED;
     #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)
    @@ -46,18 +30,20 @@
            t1->dest = th->source;
            t1->source = th->dest;
            t1->doff = tot_len / 4;
    -       t1->rst = 1;
    -
    -       if(th->ack) {
    -               t1->seq = th->ack_seq;
    -       } else {
    -               t1->ack = 1;
    -               t1->ack_seq = htonl(ntohl(th->seq) + th->syn + th->fin
    -                                   + skb->len - (th->doff<<2));
    -       }
    +       t1->seq = htonl(seq);
    +       t1->ack_seq = htonl(ack);
    +       t1->ack = 1;
    +       t1->window = htons(win);
    
            topt = (__be32 *)(t1 + 1);
    
    +       if (ts) {
    +               *topt++ = htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) |
    +                               (TCPOPT_TIMESTAMP << 8) |
    TCPOLEN_TIMESTAMP);
    +               *topt++ = htonl(tcp_time_stamp);
    +               *topt++ = htonl(ts);
    +       }
    +
     #ifdef CONFIG_TCP_MD5SIG
            if (key) {
                    *topt++ = htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) |
    @@ -84,15 +70,10 @@
            fl.fl_ip_sport = t1->source;
            security_skb_classify_flow(skb, &fl);
    
    -       /* Pass a socket to ip6_dst_lookup either it is for RST
    -        * Underlying function will use this to retrieve the network
    -        * namespace
    -        */
            if (!ip6_dst_lookup(ctl_sk, &buff->dst, &fl)) {
                    if (xfrm_lookup(&buff->dst, &fl, NULL, 0) >= 0) {
                            ip6_xmit(ctl_sk, buff, &fl, NULL, 0);
                            TCP_INC_STATS_BH(net, TCP_MIB_OUTSEGS);
    -                       TCP_INC_STATS_BH(net, TCP_MIB_OUTRSTS);
                            return;
                    }
            }
    
    
    ...which starts to be trivial to combine.
    Signed-off-by: NIlpo Järvinen <ilpo.jarvinen@helsinki.fi>
    Signed-off-by: NDavid S. Miller <davem@davemloft.net>
    81ada62d
tcp_ipv6.c 53.9 KB