]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - net/ipv6/udp.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
[linux.git] / net / ipv6 / udp.c
index 2596ffdeebeaaa60f096d774f3da32bd5486a2f4..2464fba569b4eb39452bd81f94cbe80227368fc9 100644 (file)
@@ -285,11 +285,10 @@ int udpv6_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
        struct inet_sock *inet = inet_sk(sk);
        struct sk_buff *skb;
        unsigned int ulen, copied;
-       int peeked, peeking, off;
-       int err;
+       int off, err, peeking = flags & MSG_PEEK;
        int is_udplite = IS_UDPLITE(sk);
+       struct udp_mib __percpu *mib;
        bool checksum_valid = false;
-       struct udp_mib *mib;
        int is_udp4;
 
        if (flags & MSG_ERRQUEUE)
@@ -299,9 +298,8 @@ int udpv6_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
                return ipv6_recv_rxpmtu(sk, msg, len, addr_len);
 
 try_again:
-       peeking = flags & MSG_PEEK;
        off = sk_peek_offset(sk, flags);
-       skb = __skb_recv_udp(sk, flags, noblock, &peeked, &off, &err);
+       skb = __skb_recv_udp(sk, flags, noblock, &off, &err);
        if (!skb)
                return err;
 
@@ -340,14 +338,14 @@ int udpv6_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
                        goto csum_copy_err;
        }
        if (unlikely(err)) {
-               if (!peeked) {
+               if (!peeking) {
                        atomic_inc(&sk->sk_drops);
                        SNMP_INC_STATS(mib, UDP_MIB_INERRORS);
                }
                kfree_skb(skb);
                return err;
        }
-       if (!peeked)
+       if (!peeking)
                SNMP_INC_STATS(mib, UDP_MIB_INDATAGRAMS);
 
        sock_recv_ts_and_drops(msg, sk, skb);
@@ -420,17 +418,19 @@ EXPORT_SYMBOL(udpv6_encap_enable);
  */
 static int __udp6_lib_err_encap_no_sk(struct sk_buff *skb,
                                      struct inet6_skb_parm *opt,
-                                     u8 type, u8 code, int offset, u32 info)
+                                     u8 type, u8 code, int offset, __be32 info)
 {
        int i;
 
        for (i = 0; i < MAX_IPTUN_ENCAP_OPS; i++) {
                int (*handler)(struct sk_buff *skb, struct inet6_skb_parm *opt,
-                              u8 type, u8 code, int offset, u32 info);
+                              u8 type, u8 code, int offset, __be32 info);
+               const struct ip6_tnl_encap_ops *encap;
 
-               if (!ip6tun_encaps[i])
+               encap = rcu_dereference(ip6tun_encaps[i]);
+               if (!encap)
                        continue;
-               handler = rcu_dereference(ip6tun_encaps[i]->err_handler);
+               handler = encap->err_handler;
                if (handler && !handler(skb, opt, type, code, offset, info))
                        return 0;
        }
@@ -1045,6 +1045,8 @@ static void udp_v6_flush_pending_frames(struct sock *sk)
 static int udpv6_pre_connect(struct sock *sk, struct sockaddr *uaddr,
                             int addr_len)
 {
+       if (addr_len < offsetofend(struct sockaddr, sa_family))
+               return -EINVAL;
        /* The following checks are replicated from __ip6_datagram_connect()
         * and intended to prevent BPF program called below from accessing
         * bytes that are out of the bound specified by user in addr_len.