Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
[firefly-linux-kernel-4.4.55.git] / net / ipv6 / tcp_ipv6.c
index 9b6460055df5683d70dea9d3f09d24c325ee89e7..e51bd1a58264eb9a98d5ed863967ee799a802b44 100644 (file)
@@ -386,9 +386,17 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
 
                if (dst)
                        dst->ops->redirect(dst, sk, skb);
+               goto out;
        }
 
        if (type == ICMPV6_PKT_TOOBIG) {
+               /* We are not interested in TCP_LISTEN and open_requests
+                * (SYN-ACKs send out by Linux are always <576bytes so
+                * they should go through unfragmented).
+                */
+               if (sk->sk_state == TCP_LISTEN)
+                       goto out;
+
                tp->mtu_info = ntohl(info);
                if (!sock_owned_by_user(sk))
                        tcp_v6_mtu_reduced(sk);
@@ -454,7 +462,6 @@ out:
 static int tcp_v6_send_synack(struct sock *sk, struct dst_entry *dst,
                              struct flowi6 *fl6,
                              struct request_sock *req,
-                             struct request_values *rvp,
                              u16 queue_mapping)
 {
        struct inet6_request_sock *treq = inet6_rsk(req);
@@ -466,7 +473,7 @@ static int tcp_v6_send_synack(struct sock *sk, struct dst_entry *dst,
        if (!dst && (dst = inet6_csk_route_req(sk, fl6, req)) == NULL)
                goto done;
 
-       skb = tcp_make_synack(sk, dst, req, rvp, NULL);
+       skb = tcp_make_synack(sk, dst, req, NULL);
 
        if (skb) {
                __tcp_v6_send_check(skb, &treq->loc_addr, &treq->rmt_addr);
@@ -481,13 +488,12 @@ done:
        return err;
 }
 
-static int tcp_v6_rtx_synack(struct sock *sk, struct request_sock *req,
-                            struct request_values *rvp)
+static int tcp_v6_rtx_synack(struct sock *sk, struct request_sock *req)
 {
        struct flowi6 fl6;
        int res;
 
-       res = tcp_v6_send_synack(sk, NULL, &fl6, req, rvp, 0);
+       res = tcp_v6_send_synack(sk, NULL, &fl6, req, 0);
        if (!res)
                TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_RETRANSSEGS);
        return res;
@@ -940,9 +946,7 @@ static struct sock *tcp_v6_hnd_req(struct sock *sk,struct sk_buff *skb)
  */
 static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
 {
-       struct tcp_extend_values tmp_ext;
        struct tcp_options_received tmp_opt;
-       const u8 *hash_location;
        struct request_sock *req;
        struct inet6_request_sock *treq;
        struct ipv6_pinfo *np = inet6_sk(sk);
@@ -980,50 +984,7 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
        tcp_clear_options(&tmp_opt);
        tmp_opt.mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - sizeof(struct ipv6hdr);
        tmp_opt.user_mss = tp->rx_opt.user_mss;
-       tcp_parse_options(skb, &tmp_opt, &hash_location, 0, NULL);
-
-       if (tmp_opt.cookie_plus > 0 &&
-           tmp_opt.saw_tstamp &&
-           !tp->rx_opt.cookie_out_never &&
-           (sysctl_tcp_cookie_size > 0 ||
-            (tp->cookie_values != NULL &&
-             tp->cookie_values->cookie_desired > 0))) {
-               u8 *c;
-               u32 *d;
-               u32 *mess = &tmp_ext.cookie_bakery[COOKIE_DIGEST_WORDS];
-               int l = tmp_opt.cookie_plus - TCPOLEN_COOKIE_BASE;
-
-               if (tcp_cookie_generator(&tmp_ext.cookie_bakery[0]) != 0)
-                       goto drop_and_free;
-
-               /* Secret recipe starts with IP addresses */
-               d = (__force u32 *)&ipv6_hdr(skb)->daddr.s6_addr32[0];
-               *mess++ ^= *d++;
-               *mess++ ^= *d++;
-               *mess++ ^= *d++;
-               *mess++ ^= *d++;
-               d = (__force u32 *)&ipv6_hdr(skb)->saddr.s6_addr32[0];
-               *mess++ ^= *d++;
-               *mess++ ^= *d++;
-               *mess++ ^= *d++;
-               *mess++ ^= *d++;
-
-               /* plus variable length Initiator Cookie */
-               c = (u8 *)mess;
-               while (l-- > 0)
-                       *c++ ^= *hash_location++;
-
-               want_cookie = false;    /* not our kind of cookie */
-               tmp_ext.cookie_out_never = 0; /* false */
-               tmp_ext.cookie_plus = tmp_opt.cookie_plus;
-       } else if (!tp->rx_opt.cookie_in_always) {
-               /* redundant indications, but ensure initialization. */
-               tmp_ext.cookie_out_never = 1; /* true */
-               tmp_ext.cookie_plus = 0;
-       } else {
-               goto drop_and_free;
-       }
-       tmp_ext.cookie_in_always = tp->rx_opt.cookie_in_always;
+       tcp_parse_options(skb, &tmp_opt, 0, NULL);
 
        if (want_cookie && !tmp_opt.saw_tstamp)
                tcp_clear_options(&tmp_opt);
@@ -1101,7 +1062,6 @@ have_isn:
                goto drop_and_release;
 
        if (tcp_v6_send_synack(sk, dst, &fl6, req,
-                              (struct request_values *)&tmp_ext,
                               skb_get_queue_mapping(skb)) ||
            want_cookie)
                goto drop_and_free;