Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec...
authorDavid S. Miller <davem@davemloft.net>
Wed, 13 Nov 2019 19:28:54 +0000 (11:28 -0800)
committerDavid S. Miller <davem@davemloft.net>
Wed, 13 Nov 2019 19:28:54 +0000 (11:28 -0800)
Steffen Klassert says:

====================
pull request (net-next): ipsec-next 2019-11-13

1) Remove a unnecessary net_exit function from the xfrm interface.
   From Xin Long.

2) Assign xfrm4_udp_encap_rcv to a UDP socket only if xfrm
   is configured. From Alexey Dobriyan.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
1  2 
net/ipv4/udp.c
net/xfrm/xfrm_interface.c

diff --combined net/ipv4/udp.c
@@@ -388,7 -388,7 +388,7 @@@ static int compute_score(struct sock *s
                return -1;
        score += 4;
  
 -      if (sk->sk_incoming_cpu == raw_smp_processor_id())
 +      if (READ_ONCE(sk->sk_incoming_cpu) == raw_smp_processor_id())
                score++;
        return score;
  }
@@@ -821,7 -821,6 +821,7 @@@ static int udp_send_skb(struct sk_buff 
        int is_udplite = IS_UDPLITE(sk);
        int offset = skb_transport_offset(skb);
        int len = skb->len - offset;
 +      int datalen = len - sizeof(*uh);
        __wsum csum = 0;
  
        /*
                        return -EIO;
                }
  
 -              skb_shinfo(skb)->gso_size = cork->gso_size;
 -              skb_shinfo(skb)->gso_type = SKB_GSO_UDP_L4;
 -              skb_shinfo(skb)->gso_segs = DIV_ROUND_UP(len - sizeof(uh),
 -                                                       cork->gso_size);
 +              if (datalen > cork->gso_size) {
 +                      skb_shinfo(skb)->gso_size = cork->gso_size;
 +                      skb_shinfo(skb)->gso_type = SKB_GSO_UDP_L4;
 +                      skb_shinfo(skb)->gso_segs = DIV_ROUND_UP(datalen,
 +                                                               cork->gso_size);
 +              }
                goto csum_partial;
        }
  
@@@ -1316,20 -1313,6 +1316,20 @@@ static void udp_set_dev_scratch(struct 
                scratch->_tsize_state |= UDP_SKB_IS_STATELESS;
  }
  
 +static void udp_skb_csum_unnecessary_set(struct sk_buff *skb)
 +{
 +      /* We come here after udp_lib_checksum_complete() returned 0.
 +       * This means that __skb_checksum_complete() might have
 +       * set skb->csum_valid to 1.
 +       * On 64bit platforms, we can set csum_unnecessary
 +       * to true, but only if the skb is not shared.
 +       */
 +#if BITS_PER_LONG == 64
 +      if (!skb_shared(skb))
 +              udp_skb_scratch(skb)->csum_unnecessary = true;
 +#endif
 +}
 +
  static int udp_skb_truesize(struct sk_buff *skb)
  {
        return udp_skb_scratch(skb)->_tsize_state & ~UDP_SKB_IS_STATELESS;
@@@ -1564,7 -1547,10 +1564,7 @@@ static struct sk_buff *__first_packet_l
                        *total += skb->truesize;
                        kfree_skb(skb);
                } else {
 -                      /* the csum related bits could be changed, refresh
 -                       * the scratch area
 -                       */
 -                      udp_set_dev_scratch(skb);
 +                      udp_skb_csum_unnecessary_set(skb);
                        break;
                }
        }
@@@ -1588,7 -1574,7 +1588,7 @@@ static int first_packet_length(struct s
  
        spin_lock_bh(&rcvq->lock);
        skb = __first_packet_length(sk, rcvq, &total);
 -      if (!skb && !skb_queue_empty(sk_queue)) {
 +      if (!skb && !skb_queue_empty_lockless(sk_queue)) {
                spin_lock(&sk_queue->lock);
                skb_queue_splice_tail_init(sk_queue, rcvq);
                spin_unlock(&sk_queue->lock);
@@@ -1661,7 -1647,7 +1661,7 @@@ struct sk_buff *__skb_recv_udp(struct s
                                return skb;
                        }
  
 -                      if (skb_queue_empty(sk_queue)) {
 +                      if (skb_queue_empty_lockless(sk_queue)) {
                                spin_unlock_bh(&queue->lock);
                                goto busy_check;
                        }
@@@ -1687,7 -1673,7 +1687,7 @@@ busy_check
                                break;
  
                        sk_busy_loop(sk, flags & MSG_DONTWAIT);
 -              } while (!skb_queue_empty(sk_queue));
 +              } while (!skb_queue_empty_lockless(sk_queue));
  
                /* sk_queue is empty, reader_queue may contain peeked packets */
        } while (timeo &&
@@@ -1983,7 -1969,7 +1983,7 @@@ static int udp_queue_rcv_one_skb(struc
         */
        if (!xfrm4_policy_check(sk, XFRM_POLICY_IN, skb))
                goto drop;
 -      nf_reset(skb);
 +      nf_reset_ct(skb);
  
        if (static_branch_unlikely(&udp_encap_needed_key) && up->encap_type) {
                int (*encap_rcv)(struct sock *sk, struct sk_buff *skb);
@@@ -2312,7 -2298,7 +2312,7 @@@ int __udp4_lib_rcv(struct sk_buff *skb
  
        if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb))
                goto drop;
 -      nf_reset(skb);
 +      nf_reset_ct(skb);
  
        /* No socket. Drop packet silently, if checksum is wrong */
        if (udp_lib_checksum_complete(skb))
@@@ -2534,9 -2520,11 +2534,11 @@@ int udp_lib_setsockopt(struct sock *sk
        case UDP_ENCAP:
                switch (val) {
                case 0:
+ #ifdef CONFIG_XFRM
                case UDP_ENCAP_ESPINUDP:
                case UDP_ENCAP_ESPINUDP_NON_IKE:
                        up->encap_rcv = xfrm4_udp_encap_rcv;
+ #endif
                        /* FALLTHROUGH */
                case UDP_ENCAP_L2TPINUDP:
                        up->encap_type = val;
@@@ -2723,7 -2711,7 +2725,7 @@@ __poll_t udp_poll(struct file *file, st
        __poll_t mask = datagram_poll(file, sock, wait);
        struct sock *sk = sock->sk;
  
 -      if (!skb_queue_empty(&udp_sk(sk)->reader_queue))
 +      if (!skb_queue_empty_lockless(&udp_sk(sk)->reader_queue))
                mask |= EPOLLIN | EPOLLRDNORM;
  
        /* Check for false positives due to checksum errors */
@@@ -185,7 -185,7 +185,7 @@@ static void xfrmi_scrub_packet(struct s
        skb->skb_iif = 0;
        skb->ignore_df = 0;
        skb_dst_drop(skb);
 -      nf_reset(skb);
 +      nf_reset_ct(skb);
        nf_reset_trace(skb);
  
        if (!xnet)
@@@ -732,30 -732,7 +732,7 @@@ static struct rtnl_link_ops xfrmi_link_
        .get_link_net   = xfrmi_get_link_net,
  };
  
- static void __net_exit xfrmi_destroy_interfaces(struct xfrmi_net *xfrmn)
- {
-       struct xfrm_if *xi;
-       LIST_HEAD(list);
-       xi = rtnl_dereference(xfrmn->xfrmi[0]);
-       if (!xi)
-               return;
-       unregister_netdevice_queue(xi->dev, &list);
-       unregister_netdevice_many(&list);
- }
- static void __net_exit xfrmi_exit_net(struct net *net)
- {
-       struct xfrmi_net *xfrmn = net_generic(net, xfrmi_net_id);
-       rtnl_lock();
-       xfrmi_destroy_interfaces(xfrmn);
-       rtnl_unlock();
- }
  static struct pernet_operations xfrmi_net_ops = {
-       .exit = xfrmi_exit_net,
        .id   = &xfrmi_net_id,
        .size = sizeof(struct xfrmi_net),
  };