Merge git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf
[linux-2.6-microblaze.git] / net / ipv4 / udp.c
index 99d743e..15f5504 100644 (file)
@@ -1782,6 +1782,35 @@ busy_check:
 }
 EXPORT_SYMBOL(__skb_recv_udp);
 
+int udp_read_sock(struct sock *sk, read_descriptor_t *desc,
+                 sk_read_actor_t recv_actor)
+{
+       int copied = 0;
+
+       while (1) {
+               struct sk_buff *skb;
+               int err, used;
+
+               skb = skb_recv_udp(sk, 0, 1, &err);
+               if (!skb)
+                       return err;
+               used = recv_actor(desc, skb, 0, skb->len);
+               if (used <= 0) {
+                       if (!copied)
+                               copied = used;
+                       break;
+               } else if (used <= skb->len) {
+                       copied += used;
+               }
+
+               if (!desc->count)
+                       break;
+       }
+
+       return copied;
+}
+EXPORT_SYMBOL(udp_read_sock);
+
 /*
  *     This should be easy, if there is something there we
  *     return it, otherwise we block.
@@ -2178,6 +2207,8 @@ static int udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
        segs = udp_rcv_segment(sk, skb, true);
        skb_list_walk_safe(segs, skb, next) {
                __skb_pull(skb, skb_transport_offset(skb));
+
+               udp_post_segment_fix_csum(skb);
                ret = udp_queue_rcv_one_skb(sk, skb);
                if (ret > 0)
                        ip_protocol_deliver_rcu(dev_net(skb->dev), skb, ret);
@@ -2664,9 +2695,12 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname,
 
        case UDP_GRO:
                lock_sock(sk);
+
+               /* when enabling GRO, accept the related GSO packet type */
                if (valbool)
                        udp_tunnel_encap_enable(sk->sk_socket);
                up->gro_enabled = valbool;
+               up->accept_udp_l4 = valbool;
                release_sock(sk);
                break;
 
@@ -2853,6 +2887,9 @@ struct proto udp_prot = {
        .unhash                 = udp_lib_unhash,
        .rehash                 = udp_v4_rehash,
        .get_port               = udp_v4_get_port,
+#ifdef CONFIG_BPF_SYSCALL
+       .psock_update_sk_prot   = udp_bpf_update_proto,
+#endif
        .memory_allocated       = &udp_memory_allocated,
        .sysctl_mem             = sysctl_udp_mem,
        .sysctl_wmem_offset     = offsetof(struct net, ipv4.sysctl_udp_wmem_min),