linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git] / net / ipv4 / udp.c
index f2f34a4..3f849b6 100644 (file)
@@ -616,7 +616,7 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
                                goto out;
                        if (daddr == IPI_LOOPBACK && !vx_check(0, VX_ADMIN))
                                daddr = fl.fl4_dst = nxi->ipv4[0];
-#ifdef CONFIG_VSERVER_REMAP_SADDR
+#ifdef VSERVER_REMAP_SADDR
                        if (saddr == IPI_LOOPBACK && !vx_check(0, VX_ADMIN))
                                saddr = fl.fl4_src = nxi->ipv4[0];
 #endif
@@ -910,23 +910,32 @@ static int udp_encap_rcv(struct sock * sk, struct sk_buff *skb)
        return 1; 
 #else
        struct udp_sock *up = udp_sk(sk);
-       struct udphdr *uh = skb->h.uh;
+       struct udphdr *uh;
        struct iphdr *iph;
        int iphlen, len;
   
-       __u8 *udpdata = (__u8 *)uh + sizeof(struct udphdr);
-       __u32 *udpdata32 = (__u32 *)udpdata;
+       __u8 *udpdata;
+       __u32 *udpdata32;
        __u16 encap_type = up->encap_type;
 
        /* if we're overly short, let UDP handle it */
-       if (udpdata > skb->tail)
+       len = skb->len - sizeof(struct udphdr);
+       if (len <= 0)
                return 1;
 
        /* if this is not encapsulated socket, then just return now */
        if (!encap_type)
                return 1;
 
-       len = skb->tail - udpdata;
+       /* If this is a paged skb, make sure we pull up
+        * whatever data we need to look at. */
+       if (!pskb_may_pull(skb, sizeof(struct udphdr) + min(len, 8)))
+               return 1;
+
+       /* Now we can get the pointers */
+       uh = skb->h.uh;
+       udpdata = (__u8 *)uh + sizeof(struct udphdr);
+       udpdata32 = (__u32 *)udpdata;
 
        switch (encap_type) {
        default:
@@ -1305,13 +1314,16 @@ static int udp_destroy_sock(struct sock *sk)
 /*
  *     Socket option code for UDP
  */
-static int do_udp_setsockopt(struct sock *sk, int level, int optname,
+static int udp_setsockopt(struct sock *sk, int level, int optname, 
                          char __user *optval, int optlen)
 {
        struct udp_sock *up = udp_sk(sk);
        int val;
        int err = 0;
 
+       if (level != SOL_UDP)
+               return ip_setsockopt(sk, level, optname, optval, optlen);
+
        if(optlen<sizeof(int))
                return -EINVAL;
 
@@ -1351,30 +1363,15 @@ static int do_udp_setsockopt(struct sock *sk, int level, int optname,
        return err;
 }
 
-static int udp_setsockopt(struct sock *sk, int level, int optname,
-                         char __user *optval, int optlen)
-{
-       if (level != SOL_UDP)
-               return ip_setsockopt(sk, level, optname, optval, optlen);
-       return do_udp_setsockopt(sk, level, optname, optval, optlen);
-}
-
-#ifdef CONFIG_COMPAT
-static int compat_udp_setsockopt(struct sock *sk, int level, int optname,
-                                char __user *optval, int optlen)
-{
-       if (level != SOL_UDP)
-               return compat_ip_setsockopt(sk, level, optname, optval, optlen);
-       return do_udp_setsockopt(sk, level, optname, optval, optlen);
-}
-#endif
-
-static int do_udp_getsockopt(struct sock *sk, int level, int optname,
+static int udp_getsockopt(struct sock *sk, int level, int optname, 
                          char __user *optval, int __user *optlen)
 {
        struct udp_sock *up = udp_sk(sk);
        int val, len;
 
+       if (level != SOL_UDP)
+               return ip_getsockopt(sk, level, optname, optval, optlen);
+
        if(get_user(len,optlen))
                return -EFAULT;
 
@@ -1403,23 +1400,6 @@ static int do_udp_getsockopt(struct sock *sk, int level, int optname,
        return 0;
 }
 
-static int udp_getsockopt(struct sock *sk, int level, int optname,
-                         char __user *optval, int __user *optlen)
-{
-       if (level != SOL_UDP)
-               return ip_getsockopt(sk, level, optname, optval, optlen);
-       return do_udp_getsockopt(sk, level, optname, optval, optlen);
-}
-
-#ifdef CONFIG_COMPAT
-static int compat_udp_getsockopt(struct sock *sk, int level, int optname,
-                                char __user *optval, int __user *optlen)
-{
-       if (level != SOL_UDP)
-               return compat_ip_getsockopt(sk, level, optname, optval, optlen);
-       return do_udp_getsockopt(sk, level, optname, optval, optlen);
-}
-#endif
 /**
  *     udp_poll - wait for a UDP event.
  *     @file - file struct
@@ -1468,27 +1448,23 @@ unsigned int udp_poll(struct file *file, struct socket *sock, poll_table *wait)
 }
 
 struct proto udp_prot = {
-       .name              = "UDP",
-       .owner             = THIS_MODULE,
-       .close             = udp_close,
-       .connect           = ip4_datagram_connect,
-       .disconnect        = udp_disconnect,
-       .ioctl             = udp_ioctl,
-       .destroy           = udp_destroy_sock,
-       .setsockopt        = udp_setsockopt,
-       .getsockopt        = udp_getsockopt,
-       .sendmsg           = udp_sendmsg,
-       .recvmsg           = udp_recvmsg,
-       .sendpage          = udp_sendpage,
-       .backlog_rcv       = udp_queue_rcv_skb,
-       .hash              = udp_v4_hash,
-       .unhash            = udp_v4_unhash,
-       .get_port          = udp_v4_get_port,
-       .obj_size          = sizeof(struct udp_sock),
-#ifdef CONFIG_COMPAT
-       .compat_setsockopt = compat_udp_setsockopt,
-       .compat_getsockopt = compat_udp_getsockopt,
-#endif
+       .name =         "UDP",
+       .owner =        THIS_MODULE,
+       .close =        udp_close,
+       .connect =      ip4_datagram_connect,
+       .disconnect =   udp_disconnect,
+       .ioctl =        udp_ioctl,
+       .destroy =      udp_destroy_sock,
+       .setsockopt =   udp_setsockopt,
+       .getsockopt =   udp_getsockopt,
+       .sendmsg =      udp_sendmsg,
+       .recvmsg =      udp_recvmsg,
+       .sendpage =     udp_sendpage,
+       .backlog_rcv =  udp_queue_rcv_skb,
+       .hash =         udp_v4_hash,
+       .unhash =       udp_v4_unhash,
+       .get_port =     udp_v4_get_port,
+       .obj_size =     sizeof(struct udp_sock),
 };
 
 /* ------------------------------------------------------------------------ */