Merge tag 'v3.16-rc5' into timers/core
[sfrench/cifs-2.6.git] / net / l2tp / l2tp_core.c
index a4e37d7158dcca42455a04eaf0460a48e39242fd..bea259043205ebe3605c34ed35da504807792af1 100644 (file)
@@ -495,52 +495,6 @@ out:
        spin_unlock_bh(&session->reorder_q.lock);
 }
 
-static inline int l2tp_verify_udp_checksum(struct sock *sk,
-                                          struct sk_buff *skb)
-{
-       struct udphdr *uh = udp_hdr(skb);
-       u16 ulen = ntohs(uh->len);
-       __wsum psum;
-
-       if (sk->sk_no_check || skb_csum_unnecessary(skb))
-               return 0;
-
-#if IS_ENABLED(CONFIG_IPV6)
-       if (sk->sk_family == PF_INET6 && !l2tp_tunnel(sk)->v4mapped) {
-               if (!uh->check) {
-                       LIMIT_NETDEBUG(KERN_INFO "L2TP: IPv6: checksum is 0\n");
-                       return 1;
-               }
-               if ((skb->ip_summed == CHECKSUM_COMPLETE) &&
-                   !csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
-                                    &ipv6_hdr(skb)->daddr, ulen,
-                                    IPPROTO_UDP, skb->csum)) {
-                       skb->ip_summed = CHECKSUM_UNNECESSARY;
-                       return 0;
-               }
-               skb->csum = ~csum_unfold(csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
-                                                        &ipv6_hdr(skb)->daddr,
-                                                        skb->len, IPPROTO_UDP,
-                                                        0));
-       } else
-#endif
-       {
-               struct inet_sock *inet;
-               if (!uh->check)
-                       return 0;
-               inet = inet_sk(sk);
-               psum = csum_tcpudp_nofold(inet->inet_saddr, inet->inet_daddr,
-                                         ulen, IPPROTO_UDP, 0);
-
-               if ((skb->ip_summed == CHECKSUM_COMPLETE) &&
-                   !csum_fold(csum_add(psum, skb->csum)))
-                       return 0;
-               skb->csum = psum;
-       }
-
-       return __skb_checksum_complete(skb);
-}
-
 static int l2tp_seq_check_rx_window(struct l2tp_session *session, u32 nr)
 {
        u32 nws;
@@ -895,8 +849,7 @@ static int l2tp_udp_recv_core(struct l2tp_tunnel *tunnel, struct sk_buff *skb,
        u16 version;
        int length;
 
-       if (tunnel->sock && l2tp_verify_udp_checksum(tunnel->sock, skb))
-               goto discard_bad_csum;
+       /* UDP has verifed checksum */
 
        /* UDP always verifies the packet length. */
        __skb_pull(skb, sizeof(struct udphdr));
@@ -979,14 +932,6 @@ static int l2tp_udp_recv_core(struct l2tp_tunnel *tunnel, struct sk_buff *skb,
 
        return 0;
 
-discard_bad_csum:
-       LIMIT_NETDEBUG("%s: UDP: bad checksum\n", tunnel->name);
-       UDP_INC_STATS_USER(tunnel->l2tp_net, UDP_MIB_INERRORS, 0);
-       atomic_long_inc(&tunnel->stats.rx_errors);
-       kfree_skb(skb);
-
-       return 0;
-
 error:
        /* Put UDP header back */
        __skb_push(skb, sizeof(struct udphdr));
@@ -1128,7 +1073,7 @@ static int l2tp_xmit_core(struct l2tp_session *session, struct sk_buff *skb,
        }
 
        /* Queue the packet to IP for output */
-       skb->local_df = 1;
+       skb->ignore_df = 1;
 #if IS_ENABLED(CONFIG_IPV6)
        if (tunnel->sock->sk_family == PF_INET6 && !tunnel->v4mapped)
                error = inet6_csk_xmit(tunnel->sock, skb, NULL);
@@ -1150,31 +1095,6 @@ static int l2tp_xmit_core(struct l2tp_session *session, struct sk_buff *skb,
        return 0;
 }
 
-#if IS_ENABLED(CONFIG_IPV6)
-static void l2tp_xmit_ipv6_csum(struct sock *sk, struct sk_buff *skb,
-                               int udp_len)
-{
-       struct ipv6_pinfo *np = inet6_sk(sk);
-       struct udphdr *uh = udp_hdr(skb);
-
-       if (!skb_dst(skb) || !skb_dst(skb)->dev ||
-           !(skb_dst(skb)->dev->features & NETIF_F_IPV6_CSUM)) {
-               __wsum csum = skb_checksum(skb, 0, udp_len, 0);
-               skb->ip_summed = CHECKSUM_UNNECESSARY;
-               uh->check = csum_ipv6_magic(&np->saddr, &sk->sk_v6_daddr, udp_len,
-                                           IPPROTO_UDP, csum);
-               if (uh->check == 0)
-                       uh->check = CSUM_MANGLED_0;
-       } else {
-               skb->ip_summed = CHECKSUM_PARTIAL;
-               skb->csum_start = skb_transport_header(skb) - skb->head;
-               skb->csum_offset = offsetof(struct udphdr, check);
-               uh->check = ~csum_ipv6_magic(&np->saddr, &sk->sk_v6_daddr,
-                                            udp_len, IPPROTO_UDP, 0);
-       }
-}
-#endif
-
 /* If caller requires the skb to have a ppp header, the header must be
  * inserted in the skb data before calling this function.
  */
@@ -1186,7 +1106,6 @@ int l2tp_xmit_skb(struct l2tp_session *session, struct sk_buff *skb, int hdr_len
        struct flowi *fl;
        struct udphdr *uh;
        struct inet_sock *inet;
-       __wsum csum;
        int headroom;
        int uhlen = (tunnel->encap == L2TP_ENCAPTYPE_UDP) ? sizeof(struct udphdr) : 0;
        int udp_len;
@@ -1235,33 +1154,17 @@ int l2tp_xmit_skb(struct l2tp_session *session, struct sk_buff *skb, int hdr_len
                uh->dest = inet->inet_dport;
                udp_len = uhlen + hdr_len + data_len;
                uh->len = htons(udp_len);
-               uh->check = 0;
 
                /* Calculate UDP checksum if configured to do so */
 #if IS_ENABLED(CONFIG_IPV6)
                if (sk->sk_family == PF_INET6 && !tunnel->v4mapped)
-                       l2tp_xmit_ipv6_csum(sk, skb, udp_len);
+                       udp6_set_csum(udp_get_no_check6_tx(sk),
+                                     skb, &inet6_sk(sk)->saddr,
+                                     &sk->sk_v6_daddr, udp_len);
                else
 #endif
-               if (sk->sk_no_check == UDP_CSUM_NOXMIT)
-                       skb->ip_summed = CHECKSUM_NONE;
-               else if ((skb_dst(skb) && skb_dst(skb)->dev) &&
-                        (!(skb_dst(skb)->dev->features & NETIF_F_V4_CSUM))) {
-                       skb->ip_summed = CHECKSUM_COMPLETE;
-                       csum = skb_checksum(skb, 0, udp_len, 0);
-                       uh->check = csum_tcpudp_magic(inet->inet_saddr,
-                                                     inet->inet_daddr,
-                                                     udp_len, IPPROTO_UDP, csum);
-                       if (uh->check == 0)
-                               uh->check = CSUM_MANGLED_0;
-               } else {
-                       skb->ip_summed = CHECKSUM_PARTIAL;
-                       skb->csum_start = skb_transport_header(skb) - skb->head;
-                       skb->csum_offset = offsetof(struct udphdr, check);
-                       uh->check = ~csum_tcpudp_magic(inet->inet_saddr,
-                                                      inet->inet_daddr,
-                                                      udp_len, IPPROTO_UDP, 0);
-               }
+               udp_set_csum(sk->sk_no_check_tx, skb, inet->inet_saddr,
+                            inet->inet_daddr, udp_len);
                break;
 
        case L2TP_ENCAPTYPE_IP:
@@ -1490,6 +1393,11 @@ static int l2tp_tunnel_sock_create(struct net *net,
                                             sizeof(udp6_addr), 0);
                        if (err < 0)
                                goto out;
+
+                       if (cfg->udp6_zero_tx_checksums)
+                               udp_set_no_check6_tx(sock->sk, true);
+                       if (cfg->udp6_zero_rx_checksums)
+                               udp_set_no_check6_rx(sock->sk, true);
                } else
 #endif
                {
@@ -1518,7 +1426,7 @@ static int l2tp_tunnel_sock_create(struct net *net,
                }
 
                if (!cfg->use_udp_checksums)
-                       sock->sk->sk_no_check = UDP_CSUM_NOXMIT;
+                       sock->sk->sk_no_check_tx = 1;
 
                break;