[IPV4]: cleanup
[powerpc.git] / net / ipv4 / ip_sockglue.c
index 2d05c41..c5e4164 100644 (file)
@@ -4,7 +4,7 @@
  *             interface as the means of communication with the user level.
  *
  *             The IP to API glue.
- *             
+ *
  * Version:    $Id: ip_sockglue.c,v 1.62 2002/02/01 22:01:04 davem Exp $
  *
  * Authors:    see ip.c
@@ -12,7 +12,7 @@
  * Fixes:
  *             Many            :       Split from ip.c , see ip.c for history.
  *             Martin Mares    :       TOS setting fixed.
- *             Alan Cox        :       Fixed a couple of oopses in Martin's 
+ *             Alan Cox        :       Fixed a couple of oopses in Martin's
  *                                     TOS tweaks.
  *             Mike McLagan    :       Routing by source
  */
@@ -20,7 +20,6 @@
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/mm.h>
-#include <linux/sched.h>
 #include <linux/skbuff.h>
 #include <linux/ip.h>
 #include <linux/icmp.h>
@@ -253,8 +252,8 @@ int ip_ra_control(struct sock *sk, unsigned char on, void (*destructor)(struct s
        return 0;
 }
 
-void ip_icmp_error(struct sock *sk, struct sk_buff *skb, int err, 
-                  u16 port, u32 info, u8 *payload)
+void ip_icmp_error(struct sock *sk, struct sk_buff *skb, int err,
+                  __be16 port, u32 info, u8 *payload)
 {
        struct inet_sock *inet = inet_sk(sk);
        struct sock_exterr_skb *serr;
@@ -266,10 +265,10 @@ void ip_icmp_error(struct sock *sk, struct sk_buff *skb, int err,
        if (!skb)
                return;
 
-       serr = SKB_EXT_ERR(skb);  
+       serr = SKB_EXT_ERR(skb);
        serr->ee.ee_errno = err;
        serr->ee.ee_origin = SO_EE_ORIGIN_ICMP;
-       serr->ee.ee_type = skb->h.icmph->type; 
+       serr->ee.ee_type = skb->h.icmph->type;
        serr->ee.ee_code = skb->h.icmph->code;
        serr->ee.ee_pad = 0;
        serr->ee.ee_info = info;
@@ -283,7 +282,7 @@ void ip_icmp_error(struct sock *sk, struct sk_buff *skb, int err,
                kfree_skb(skb);
 }
 
-void ip_local_error(struct sock *sk, int err, u32 daddr, u16 port, u32 info)
+void ip_local_error(struct sock *sk, int err, __be32 daddr, __be16 port, u32 info)
 {
        struct inet_sock *inet = inet_sk(sk);
        struct sock_exterr_skb *serr;
@@ -301,10 +300,10 @@ void ip_local_error(struct sock *sk, int err, u32 daddr, u16 port, u32 info)
        skb->nh.iph = iph;
        iph->daddr = daddr;
 
-       serr = SKB_EXT_ERR(skb);  
+       serr = SKB_EXT_ERR(skb);
        serr->ee.ee_errno = err;
        serr->ee.ee_origin = SO_EE_ORIGIN_LOCAL;
-       serr->ee.ee_type = 0; 
+       serr->ee.ee_type = 0;
        serr->ee.ee_code = 0;
        serr->ee.ee_pad = 0;
        serr->ee.ee_info = info;
@@ -319,7 +318,7 @@ void ip_local_error(struct sock *sk, int err, u32 daddr, u16 port, u32 info)
                kfree_skb(skb);
 }
 
-/* 
+/*
  *     Handle MSG_ERRQUEUE
  */
 int ip_recv_error(struct sock *sk, struct msghdr *msg, int len)
@@ -355,7 +354,7 @@ int ip_recv_error(struct sock *sk, struct msghdr *msg, int len)
        sin = (struct sockaddr_in *)msg->msg_name;
        if (sin) {
                sin->sin_family = AF_INET;
-               sin->sin_addr.s_addr = *(u32*)(skb->nh.raw + serr->addr_offset);
+               sin->sin_addr.s_addr = *(__be32*)(skb->nh.raw + serr->addr_offset);
                sin->sin_port = serr->port;
                memset(&sin->sin_zero, 0, sizeof(sin->sin_zero));
        }
@@ -391,7 +390,7 @@ int ip_recv_error(struct sock *sk, struct msghdr *msg, int len)
        } else
                spin_unlock_bh(&sk->sk_error_queue.lock);
 
-out_free_skb:  
+out_free_skb:
        kfree_skb(skb);
 out:
        return err;
@@ -404,20 +403,20 @@ out:
  */
 
 static int do_ip_setsockopt(struct sock *sk, int level,
-               int optname, char __user *optval, int optlen)
+                           int optname, char __user *optval, int optlen)
 {
        struct inet_sock *inet = inet_sk(sk);
        int val=0,err;
 
-       if (((1<<optname) & ((1<<IP_PKTINFO) | (1<<IP_RECVTTL) | 
-                           (1<<IP_RECVOPTS) | (1<<IP_RECVTOS) | 
-                           (1<<IP_RETOPTS) | (1<<IP_TOS) | 
-                           (1<<IP_TTL) | (1<<IP_HDRINCL) | 
-                           (1<<IP_MTU_DISCOVER) | (1<<IP_RECVERR) | 
-                           (1<<IP_ROUTER_ALERT) | (1<<IP_FREEBIND) |
-                           (1<<IP_PASSSEC))) ||
-                               optname == IP_MULTICAST_TTL || 
-                               optname == IP_MULTICAST_LOOP) { 
+       if (((1<<optname) & ((1<<IP_PKTINFO) | (1<<IP_RECVTTL) |
+                            (1<<IP_RECVOPTS) | (1<<IP_RECVTOS) |
+                            (1<<IP_RETOPTS) | (1<<IP_TOS) |
+                            (1<<IP_TTL) | (1<<IP_HDRINCL) |
+                            (1<<IP_MTU_DISCOVER) | (1<<IP_RECVERR) |
+                            (1<<IP_ROUTER_ALERT) | (1<<IP_FREEBIND) |
+                            (1<<IP_PASSSEC))) ||
+           optname == IP_MULTICAST_TTL ||
+           optname == IP_MULTICAST_LOOP) {
                if (optlen >= sizeof(int)) {
                        if (get_user(val, (int __user *) optval))
                                return -EFAULT;
@@ -441,444 +440,444 @@ static int do_ip_setsockopt(struct sock *sk, int level,
        lock_sock(sk);
 
        switch (optname) {
-               case IP_OPTIONS:
-               {
-                       struct ip_options * opt = NULL;
-                       if (optlen > 40 || optlen < 0)
-                               goto e_inval;
-                       err = ip_options_get_from_user(&opt, optval, optlen);
-                       if (err)
-                               break;
-                       if (inet->is_icsk) {
-                               struct inet_connection_sock *icsk = inet_csk(sk);
+       case IP_OPTIONS:
+       {
+               struct ip_options * opt = NULL;
+               if (optlen > 40 || optlen < 0)
+                       goto e_inval;
+               err = ip_options_get_from_user(&opt, optval, optlen);
+               if (err)
+                       break;
+               if (inet->is_icsk) {
+                       struct inet_connection_sock *icsk = inet_csk(sk);
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-                               if (sk->sk_family == PF_INET ||
-                                   (!((1 << sk->sk_state) &
-                                      (TCPF_LISTEN | TCPF_CLOSE)) &&
-                                    inet->daddr != LOOPBACK4_IPV6)) {
+                       if (sk->sk_family == PF_INET ||
+                           (!((1 << sk->sk_state) &
+                              (TCPF_LISTEN | TCPF_CLOSE)) &&
+                            inet->daddr != LOOPBACK4_IPV6)) {
 #endif
-                                       if (inet->opt)
-                                               icsk->icsk_ext_hdr_len -= inet->opt->optlen;
-                                       if (opt)
-                                               icsk->icsk_ext_hdr_len += opt->optlen;
-                                       icsk->icsk_sync_mss(sk, icsk->icsk_pmtu_cookie);
+                               if (inet->opt)
+                                       icsk->icsk_ext_hdr_len -= inet->opt->optlen;
+                               if (opt)
+                                       icsk->icsk_ext_hdr_len += opt->optlen;
+                               icsk->icsk_sync_mss(sk, icsk->icsk_pmtu_cookie);
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-                               }
-#endif
                        }
-                       opt = xchg(&inet->opt, opt);
-                       kfree(opt);
-                       break;
+#endif
                }
-               case IP_PKTINFO:
-                       if (val)
-                               inet->cmsg_flags |= IP_CMSG_PKTINFO;
-                       else
-                               inet->cmsg_flags &= ~IP_CMSG_PKTINFO;
-                       break;
-               case IP_RECVTTL:
-                       if (val)
-                               inet->cmsg_flags |=  IP_CMSG_TTL;
-                       else
-                               inet->cmsg_flags &= ~IP_CMSG_TTL;
-                       break;
-               case IP_RECVTOS:
-                       if (val)
-                               inet->cmsg_flags |=  IP_CMSG_TOS;
-                       else
-                               inet->cmsg_flags &= ~IP_CMSG_TOS;
-                       break;
-               case IP_RECVOPTS:
-                       if (val)
-                               inet->cmsg_flags |=  IP_CMSG_RECVOPTS;
-                       else
-                               inet->cmsg_flags &= ~IP_CMSG_RECVOPTS;
-                       break;
-               case IP_RETOPTS:
-                       if (val)
-                               inet->cmsg_flags |= IP_CMSG_RETOPTS;
-                       else
-                               inet->cmsg_flags &= ~IP_CMSG_RETOPTS;
+               opt = xchg(&inet->opt, opt);
+               kfree(opt);
+               break;
+       }
+       case IP_PKTINFO:
+               if (val)
+                       inet->cmsg_flags |= IP_CMSG_PKTINFO;
+               else
+                       inet->cmsg_flags &= ~IP_CMSG_PKTINFO;
+               break;
+       case IP_RECVTTL:
+               if (val)
+                       inet->cmsg_flags |=  IP_CMSG_TTL;
+               else
+                       inet->cmsg_flags &= ~IP_CMSG_TTL;
+               break;
+       case IP_RECVTOS:
+               if (val)
+                       inet->cmsg_flags |=  IP_CMSG_TOS;
+               else
+                       inet->cmsg_flags &= ~IP_CMSG_TOS;
+               break;
+       case IP_RECVOPTS:
+               if (val)
+                       inet->cmsg_flags |=  IP_CMSG_RECVOPTS;
+               else
+                       inet->cmsg_flags &= ~IP_CMSG_RECVOPTS;
+               break;
+       case IP_RETOPTS:
+               if (val)
+                       inet->cmsg_flags |= IP_CMSG_RETOPTS;
+               else
+                       inet->cmsg_flags &= ~IP_CMSG_RETOPTS;
+               break;
+       case IP_PASSSEC:
+               if (val)
+                       inet->cmsg_flags |= IP_CMSG_PASSSEC;
+               else
+                       inet->cmsg_flags &= ~IP_CMSG_PASSSEC;
+               break;
+       case IP_TOS:    /* This sets both TOS and Precedence */
+               if (sk->sk_type == SOCK_STREAM) {
+                       val &= ~3;
+                       val |= inet->tos & 3;
+               }
+               if (IPTOS_PREC(val) >= IPTOS_PREC_CRITIC_ECP &&
+                   !capable(CAP_NET_ADMIN)) {
+                       err = -EPERM;
                        break;
-               case IP_PASSSEC:
-                       if (val)
-                               inet->cmsg_flags |= IP_CMSG_PASSSEC;
-                       else
-                               inet->cmsg_flags &= ~IP_CMSG_PASSSEC;
+               }
+               if (inet->tos != val) {
+                       inet->tos = val;
+                       sk->sk_priority = rt_tos2priority(val);
+                       sk_dst_reset(sk);
+               }
+               break;
+       case IP_TTL:
+               if (optlen<1)
+                       goto e_inval;
+               if (val != -1 && (val < 1 || val>255))
+                       goto e_inval;
+               inet->uc_ttl = val;
+               break;
+       case IP_HDRINCL:
+               if (sk->sk_type != SOCK_RAW) {
+                       err = -ENOPROTOOPT;
                        break;
-               case IP_TOS:    /* This sets both TOS and Precedence */
-                       if (sk->sk_type == SOCK_STREAM) {
-                               val &= ~3;
-                               val |= inet->tos & 3;
-                       }
-                       if (IPTOS_PREC(val) >= IPTOS_PREC_CRITIC_ECP && 
-                           !capable(CAP_NET_ADMIN)) {
-                               err = -EPERM;
+               }
+               inet->hdrincl = val ? 1 : 0;
+               break;
+       case IP_MTU_DISCOVER:
+               if (val<0 || val>2)
+                       goto e_inval;
+               inet->pmtudisc = val;
+               break;
+       case IP_RECVERR:
+               inet->recverr = !!val;
+               if (!val)
+                       skb_queue_purge(&sk->sk_error_queue);
+               break;
+       case IP_MULTICAST_TTL:
+               if (sk->sk_type == SOCK_STREAM)
+                       goto e_inval;
+               if (optlen<1)
+                       goto e_inval;
+               if (val==-1)
+                       val = 1;
+               if (val < 0 || val > 255)
+                       goto e_inval;
+               inet->mc_ttl = val;
+               break;
+       case IP_MULTICAST_LOOP:
+               if (optlen<1)
+                       goto e_inval;
+               inet->mc_loop = !!val;
+               break;
+       case IP_MULTICAST_IF:
+       {
+               struct ip_mreqn mreq;
+               struct net_device *dev = NULL;
+
+               if (sk->sk_type == SOCK_STREAM)
+                       goto e_inval;
+               /*
+                *      Check the arguments are allowable
+                */
+
+               err = -EFAULT;
+               if (optlen >= sizeof(struct ip_mreqn)) {
+                       if (copy_from_user(&mreq,optval,sizeof(mreq)))
                                break;
-                       }
-                       if (inet->tos != val) {
-                               inet->tos = val;
-                               sk->sk_priority = rt_tos2priority(val);
-                               sk_dst_reset(sk); 
-                       }
-                       break;
-               case IP_TTL:
-                       if (optlen<1)
-                               goto e_inval;
-                       if (val != -1 && (val < 1 || val>255))
-                               goto e_inval;
-                       inet->uc_ttl = val;
-                       break;
-               case IP_HDRINCL:
-                       if (sk->sk_type != SOCK_RAW) {
-                               err = -ENOPROTOOPT;
+               } else {
+                       memset(&mreq, 0, sizeof(mreq));
+                       if (optlen >= sizeof(struct in_addr) &&
+                           copy_from_user(&mreq.imr_address,optval,sizeof(struct in_addr)))
+                               break;
+               }
+
+               if (!mreq.imr_ifindex) {
+                       if (mreq.imr_address.s_addr == INADDR_ANY) {
+                               inet->mc_index = 0;
+                               inet->mc_addr  = 0;
+                               err = 0;
                                break;
                        }
-                       inet->hdrincl = val ? 1 : 0;
-                       break;
-               case IP_MTU_DISCOVER:
-                       if (val<0 || val>2)
-                               goto e_inval;
-                       inet->pmtudisc = val;
-                       break;
-               case IP_RECVERR:
-                       inet->recverr = !!val;
-                       if (!val)
-                               skb_queue_purge(&sk->sk_error_queue);
-                       break;
-               case IP_MULTICAST_TTL:
-                       if (sk->sk_type == SOCK_STREAM)
-                               goto e_inval;
-                       if (optlen<1)
-                               goto e_inval;
-                       if (val==-1)
-                               val = 1;
-                       if (val < 0 || val > 255)
-                               goto e_inval;
-                       inet->mc_ttl = val;
-                       break;
-               case IP_MULTICAST_LOOP: 
-                       if (optlen<1)
-                               goto e_inval;
-                       inet->mc_loop = !!val;
-                       break;
-               case IP_MULTICAST_IF: 
-               {
-                       struct ip_mreqn mreq;
-                       struct net_device *dev = NULL;
+                       dev = ip_dev_find(mreq.imr_address.s_addr);
+                       if (dev) {
+                               mreq.imr_ifindex = dev->ifindex;
+                               dev_put(dev);
+                       }
+               } else
+                       dev = __dev_get_by_index(mreq.imr_ifindex);
 
-                       if (sk->sk_type == SOCK_STREAM)
-                               goto e_inval;
-                       /*
-                        *      Check the arguments are allowable
-                        */
 
-                       err = -EFAULT;
-                       if (optlen >= sizeof(struct ip_mreqn)) {
-                               if (copy_from_user(&mreq,optval,sizeof(mreq)))
-                                       break;
-                       } else {
-                               memset(&mreq, 0, sizeof(mreq));
-                               if (optlen >= sizeof(struct in_addr) &&
-                                   copy_from_user(&mreq.imr_address,optval,sizeof(struct in_addr)))
-                                       break;
-                       }
+               err = -EADDRNOTAVAIL;
+               if (!dev)
+                       break;
 
-                       if (!mreq.imr_ifindex) {
-                               if (mreq.imr_address.s_addr == INADDR_ANY) {
-                                       inet->mc_index = 0;
-                                       inet->mc_addr  = 0;
-                                       err = 0;
-                                       break;
-                               }
-                               dev = ip_dev_find(mreq.imr_address.s_addr);
-                               if (dev) {
-                                       mreq.imr_ifindex = dev->ifindex;
-                                       dev_put(dev);
-                               }
-                       } else
-                               dev = __dev_get_by_index(mreq.imr_ifindex);
+               err = -EINVAL;
+               if (sk->sk_bound_dev_if &&
+                   mreq.imr_ifindex != sk->sk_bound_dev_if)
+                       break;
 
+               inet->mc_index = mreq.imr_ifindex;
+               inet->mc_addr  = mreq.imr_address.s_addr;
+               err = 0;
+               break;
+       }
 
-                       err = -EADDRNOTAVAIL;
-                       if (!dev)
-                               break;
+       case IP_ADD_MEMBERSHIP:
+       case IP_DROP_MEMBERSHIP:
+       {
+               struct ip_mreqn mreq;
 
-                       err = -EINVAL;
-                       if (sk->sk_bound_dev_if &&
-                           mreq.imr_ifindex != sk->sk_bound_dev_if)
+               if (optlen < sizeof(struct ip_mreq))
+                       goto e_inval;
+               err = -EFAULT;
+               if (optlen >= sizeof(struct ip_mreqn)) {
+                       if (copy_from_user(&mreq,optval,sizeof(mreq)))
+                               break;
+               } else {
+                       memset(&mreq, 0, sizeof(mreq));
+                       if (copy_from_user(&mreq,optval,sizeof(struct ip_mreq)))
                                break;
+               }
+
+               if (optname == IP_ADD_MEMBERSHIP)
+                       err = ip_mc_join_group(sk, &mreq);
+               else
+                       err = ip_mc_leave_group(sk, &mreq);
+               break;
+       }
+       case IP_MSFILTER:
+       {
+               extern int sysctl_igmp_max_msf;
+               struct ip_msfilter *msf;
 
-                       inet->mc_index = mreq.imr_ifindex;
-                       inet->mc_addr  = mreq.imr_address.s_addr;
-                       err = 0;
+               if (optlen < IP_MSFILTER_SIZE(0))
+                       goto e_inval;
+               if (optlen > sysctl_optmem_max) {
+                       err = -ENOBUFS;
                        break;
                }
+               msf = kmalloc(optlen, GFP_KERNEL);
+               if (msf == 0) {
+                       err = -ENOBUFS;
+                       break;
+               }
+               err = -EFAULT;
+               if (copy_from_user(msf, optval, optlen)) {
+                       kfree(msf);
+                       break;
+               }
+               /* numsrc >= (1G-4) overflow in 32 bits */
+               if (msf->imsf_numsrc >= 0x3ffffffcU ||
+                   msf->imsf_numsrc > sysctl_igmp_max_msf) {
+                       kfree(msf);
+                       err = -ENOBUFS;
+                       break;
+               }
+               if (IP_MSFILTER_SIZE(msf->imsf_numsrc) > optlen) {
+                       kfree(msf);
+                       err = -EINVAL;
+                       break;
+               }
+               err = ip_mc_msfilter(sk, msf, 0);
+               kfree(msf);
+               break;
+       }
+       case IP_BLOCK_SOURCE:
+       case IP_UNBLOCK_SOURCE:
+       case IP_ADD_SOURCE_MEMBERSHIP:
+       case IP_DROP_SOURCE_MEMBERSHIP:
+       {
+               struct ip_mreq_source mreqs;
+               int omode, add;
 
-               case IP_ADD_MEMBERSHIP:
-               case IP_DROP_MEMBERSHIP: 
-               {
-                       struct ip_mreqn mreq;
-
-                       if (optlen < sizeof(struct ip_mreq))
-                               goto e_inval;
+               if (optlen != sizeof(struct ip_mreq_source))
+                       goto e_inval;
+               if (copy_from_user(&mreqs, optval, sizeof(mreqs))) {
                        err = -EFAULT;
-                       if (optlen >= sizeof(struct ip_mreqn)) {
-                               if(copy_from_user(&mreq,optval,sizeof(mreq)))
-                                       break;
-                       } else {
-                               memset(&mreq, 0, sizeof(mreq));
-                               if (copy_from_user(&mreq,optval,sizeof(struct ip_mreq)))
-                                       break; 
-                       }
-
-                       if (optname == IP_ADD_MEMBERSHIP)
-                               err = ip_mc_join_group(sk, &mreq);
-                       else
-                               err = ip_mc_leave_group(sk, &mreq);
                        break;
                }
-               case IP_MSFILTER:
-               {
-                       extern int sysctl_igmp_max_msf;
-                       struct ip_msfilter *msf;
+               if (optname == IP_BLOCK_SOURCE) {
+                       omode = MCAST_EXCLUDE;
+                       add = 1;
+               } else if (optname == IP_UNBLOCK_SOURCE) {
+                       omode = MCAST_EXCLUDE;
+                       add = 0;
+               } else if (optname == IP_ADD_SOURCE_MEMBERSHIP) {
+                       struct ip_mreqn mreq;
 
-                       if (optlen < IP_MSFILTER_SIZE(0))
-                               goto e_inval;
-                       if (optlen > sysctl_optmem_max) {
-                               err = -ENOBUFS;
-                               break;
-                       }
-                       msf = kmalloc(optlen, GFP_KERNEL);
-                       if (msf == 0) {
-                               err = -ENOBUFS;
+                       mreq.imr_multiaddr.s_addr = mreqs.imr_multiaddr;
+                       mreq.imr_address.s_addr = mreqs.imr_interface;
+                       mreq.imr_ifindex = 0;
+                       err = ip_mc_join_group(sk, &mreq);
+                       if (err && err != -EADDRINUSE)
                                break;
-                       }
+                       omode = MCAST_INCLUDE;
+                       add = 1;
+               } else /* IP_DROP_SOURCE_MEMBERSHIP */ {
+                       omode = MCAST_INCLUDE;
+                       add = 0;
+               }
+               err = ip_mc_source(add, omode, sk, &mreqs, 0);
+               break;
+       }
+       case MCAST_JOIN_GROUP:
+       case MCAST_LEAVE_GROUP:
+       {
+               struct group_req greq;
+               struct sockaddr_in *psin;
+               struct ip_mreqn mreq;
+
+               if (optlen < sizeof(struct group_req))
+                       goto e_inval;
+               err = -EFAULT;
+               if (copy_from_user(&greq, optval, sizeof(greq)))
+                       break;
+               psin = (struct sockaddr_in *)&greq.gr_group;
+               if (psin->sin_family != AF_INET)
+                       goto e_inval;
+               memset(&mreq, 0, sizeof(mreq));
+               mreq.imr_multiaddr = psin->sin_addr;
+               mreq.imr_ifindex = greq.gr_interface;
+
+               if (optname == MCAST_JOIN_GROUP)
+                       err = ip_mc_join_group(sk, &mreq);
+               else
+                       err = ip_mc_leave_group(sk, &mreq);
+               break;
+       }
+       case MCAST_JOIN_SOURCE_GROUP:
+       case MCAST_LEAVE_SOURCE_GROUP:
+       case MCAST_BLOCK_SOURCE:
+       case MCAST_UNBLOCK_SOURCE:
+       {
+               struct group_source_req greqs;
+               struct ip_mreq_source mreqs;
+               struct sockaddr_in *psin;
+               int omode, add;
+
+               if (optlen != sizeof(struct group_source_req))
+                       goto e_inval;
+               if (copy_from_user(&greqs, optval, sizeof(greqs))) {
                        err = -EFAULT;
-                       if (copy_from_user(msf, optval, optlen)) {
-                               kfree(msf);
-                               break;
-                       }
-                       /* numsrc >= (1G-4) overflow in 32 bits */
-                       if (msf->imsf_numsrc >= 0x3ffffffcU ||
-                           msf->imsf_numsrc > sysctl_igmp_max_msf) {
-                               kfree(msf);
-                               err = -ENOBUFS;
-                               break;
-                       }
-                       if (IP_MSFILTER_SIZE(msf->imsf_numsrc) > optlen) {
-                               kfree(msf);
-                               err = -EINVAL;
-                               break;
-                       }
-                       err = ip_mc_msfilter(sk, msf, 0);
-                       kfree(msf);
                        break;
                }
-               case IP_BLOCK_SOURCE:
-               case IP_UNBLOCK_SOURCE:
-               case IP_ADD_SOURCE_MEMBERSHIP:
-               case IP_DROP_SOURCE_MEMBERSHIP:
-               {
-                       struct ip_mreq_source mreqs;
-                       int omode, add;
-
-                       if (optlen != sizeof(struct ip_mreq_source))
-                               goto e_inval;
-                       if (copy_from_user(&mreqs, optval, sizeof(mreqs))) {
-                               err = -EFAULT;
-                               break;
-                       }
-                       if (optname == IP_BLOCK_SOURCE) {
-                               omode = MCAST_EXCLUDE;
-                               add = 1;
-                       } else if (optname == IP_UNBLOCK_SOURCE) {
-                               omode = MCAST_EXCLUDE;
-                               add = 0;
-                       } else if (optname == IP_ADD_SOURCE_MEMBERSHIP) {
-                               struct ip_mreqn mreq;
-
-                               mreq.imr_multiaddr.s_addr = mreqs.imr_multiaddr;
-                               mreq.imr_address.s_addr = mreqs.imr_interface;
-                               mreq.imr_ifindex = 0;
-                               err = ip_mc_join_group(sk, &mreq);
-                               if (err && err != -EADDRINUSE)
-                                       break;
-                               omode = MCAST_INCLUDE;
-                               add = 1;
-                       } else /* IP_DROP_SOURCE_MEMBERSHIP */ {
-                               omode = MCAST_INCLUDE;
-                               add = 0;
-                       }
-                       err = ip_mc_source(add, omode, sk, &mreqs, 0);
+               if (greqs.gsr_group.ss_family != AF_INET ||
+                   greqs.gsr_source.ss_family != AF_INET) {
+                       err = -EADDRNOTAVAIL;
                        break;
                }
-               case MCAST_JOIN_GROUP:
-               case MCAST_LEAVE_GROUP: 
-               {
-                       struct group_req greq;
-                       struct sockaddr_in *psin;
+               psin = (struct sockaddr_in *)&greqs.gsr_group;
+               mreqs.imr_multiaddr = psin->sin_addr.s_addr;
+               psin = (struct sockaddr_in *)&greqs.gsr_source;
+               mreqs.imr_sourceaddr = psin->sin_addr.s_addr;
+               mreqs.imr_interface = 0; /* use index for mc_source */
+
+               if (optname == MCAST_BLOCK_SOURCE) {
+                       omode = MCAST_EXCLUDE;
+                       add = 1;
+               } else if (optname == MCAST_UNBLOCK_SOURCE) {
+                       omode = MCAST_EXCLUDE;
+                       add = 0;
+               } else if (optname == MCAST_JOIN_SOURCE_GROUP) {
                        struct ip_mreqn mreq;
 
-                       if (optlen < sizeof(struct group_req))
-                               goto e_inval;
-                       err = -EFAULT;
-                       if(copy_from_user(&greq, optval, sizeof(greq)))
-                               break;
-                       psin = (struct sockaddr_in *)&greq.gr_group;
-                       if (psin->sin_family != AF_INET)
-                               goto e_inval;
-                       memset(&mreq, 0, sizeof(mreq));
+                       psin = (struct sockaddr_in *)&greqs.gsr_group;
                        mreq.imr_multiaddr = psin->sin_addr;
-                       mreq.imr_ifindex = greq.gr_interface;
-
-                       if (optname == MCAST_JOIN_GROUP)
-                               err = ip_mc_join_group(sk, &mreq);
-                       else
-                               err = ip_mc_leave_group(sk, &mreq);
+                       mreq.imr_address.s_addr = 0;
+                       mreq.imr_ifindex = greqs.gsr_interface;
+                       err = ip_mc_join_group(sk, &mreq);
+                       if (err && err != -EADDRINUSE)
+                               break;
+                       greqs.gsr_interface = mreq.imr_ifindex;
+                       omode = MCAST_INCLUDE;
+                       add = 1;
+               } else /* MCAST_LEAVE_SOURCE_GROUP */ {
+                       omode = MCAST_INCLUDE;
+                       add = 0;
+               }
+               err = ip_mc_source(add, omode, sk, &mreqs,
+                                  greqs.gsr_interface);
+               break;
+       }
+       case MCAST_MSFILTER:
+       {
+               extern int sysctl_igmp_max_msf;
+               struct sockaddr_in *psin;
+               struct ip_msfilter *msf = NULL;
+               struct group_filter *gsf = NULL;
+               int msize, i, ifindex;
+
+               if (optlen < GROUP_FILTER_SIZE(0))
+                       goto e_inval;
+               if (optlen > sysctl_optmem_max) {
+                       err = -ENOBUFS;
                        break;
                }
-               case MCAST_JOIN_SOURCE_GROUP:
-               case MCAST_LEAVE_SOURCE_GROUP:
-               case MCAST_BLOCK_SOURCE:
-               case MCAST_UNBLOCK_SOURCE:
-               {
-                       struct group_source_req greqs;
-                       struct ip_mreq_source mreqs;
-                       struct sockaddr_in *psin;
-                       int omode, add;
-
-                       if (optlen != sizeof(struct group_source_req))
-                               goto e_inval;
-                       if (copy_from_user(&greqs, optval, sizeof(greqs))) {
-                               err = -EFAULT;
-                               break;
-                       }
-                       if (greqs.gsr_group.ss_family != AF_INET ||
-                           greqs.gsr_source.ss_family != AF_INET) {
-                               err = -EADDRNOTAVAIL;
-                               break;
-                       }
-                       psin = (struct sockaddr_in *)&greqs.gsr_group;
-                       mreqs.imr_multiaddr = psin->sin_addr.s_addr;
-                       psin = (struct sockaddr_in *)&greqs.gsr_source;
-                       mreqs.imr_sourceaddr = psin->sin_addr.s_addr;
-                       mreqs.imr_interface = 0; /* use index for mc_source */
-
-                       if (optname == MCAST_BLOCK_SOURCE) {
-                               omode = MCAST_EXCLUDE;
-                               add = 1;
-                       } else if (optname == MCAST_UNBLOCK_SOURCE) {
-                               omode = MCAST_EXCLUDE;
-                               add = 0;
-                       } else if (optname == MCAST_JOIN_SOURCE_GROUP) {
-                               struct ip_mreqn mreq;
-
-                               psin = (struct sockaddr_in *)&greqs.gsr_group;
-                               mreq.imr_multiaddr = psin->sin_addr;
-                               mreq.imr_address.s_addr = 0;
-                               mreq.imr_ifindex = greqs.gsr_interface;
-                               err = ip_mc_join_group(sk, &mreq);
-                               if (err && err != -EADDRINUSE)
-                                       break;
-                               greqs.gsr_interface = mreq.imr_ifindex;
-                               omode = MCAST_INCLUDE;
-                               add = 1;
-                       } else /* MCAST_LEAVE_SOURCE_GROUP */ {
-                               omode = MCAST_INCLUDE;
-                               add = 0;
-                       }
-                       err = ip_mc_source(add, omode, sk, &mreqs,
-                               greqs.gsr_interface);
+               gsf = kmalloc(optlen,GFP_KERNEL);
+               if (gsf == 0) {
+                       err = -ENOBUFS;
                        break;
                }
-               case MCAST_MSFILTER:
-               {
-                       extern int sysctl_igmp_max_msf;
-                       struct sockaddr_in *psin;
-                       struct ip_msfilter *msf = NULL;
-                       struct group_filter *gsf = NULL;
-                       int msize, i, ifindex;
-
-                       if (optlen < GROUP_FILTER_SIZE(0))
-                               goto e_inval;
-                       if (optlen > sysctl_optmem_max) {
-                               err = -ENOBUFS;
-                               break;
-                       }
-                       gsf = kmalloc(optlen,GFP_KERNEL);
-                       if (gsf == 0) {
-                               err = -ENOBUFS;
-                               break;
-                       }
-                       err = -EFAULT;
-                       if (copy_from_user(gsf, optval, optlen)) {
-                               goto mc_msf_out;
-                       }
-                       /* numsrc >= (4G-140)/128 overflow in 32 bits */
-                       if (gsf->gf_numsrc >= 0x1ffffff ||
-                           gsf->gf_numsrc > sysctl_igmp_max_msf) {
-                               err = -ENOBUFS;
-                               goto mc_msf_out;
-                       }
-                       if (GROUP_FILTER_SIZE(gsf->gf_numsrc) > optlen) {
-                               err = -EINVAL;
-                               goto mc_msf_out;
-                       }
-                       msize = IP_MSFILTER_SIZE(gsf->gf_numsrc);
-                       msf = kmalloc(msize,GFP_KERNEL);
-                       if (msf == 0) {
-                               err = -ENOBUFS;
-                               goto mc_msf_out;
-                       }
-                       ifindex = gsf->gf_interface;
-                       psin = (struct sockaddr_in *)&gsf->gf_group;
-                       if (psin->sin_family != AF_INET) {
-                               err = -EADDRNOTAVAIL;
-                               goto mc_msf_out;
-                       }
-                       msf->imsf_multiaddr = psin->sin_addr.s_addr;
-                       msf->imsf_interface = 0;
-                       msf->imsf_fmode = gsf->gf_fmode;
-                       msf->imsf_numsrc = gsf->gf_numsrc;
+               err = -EFAULT;
+               if (copy_from_user(gsf, optval, optlen)) {
+                       goto mc_msf_out;
+               }
+               /* numsrc >= (4G-140)/128 overflow in 32 bits */
+               if (gsf->gf_numsrc >= 0x1ffffff ||
+                   gsf->gf_numsrc > sysctl_igmp_max_msf) {
+                       err = -ENOBUFS;
+                       goto mc_msf_out;
+               }
+               if (GROUP_FILTER_SIZE(gsf->gf_numsrc) > optlen) {
+                       err = -EINVAL;
+                       goto mc_msf_out;
+               }
+               msize = IP_MSFILTER_SIZE(gsf->gf_numsrc);
+               msf = kmalloc(msize,GFP_KERNEL);
+               if (msf == 0) {
+                       err = -ENOBUFS;
+                       goto mc_msf_out;
+               }
+               ifindex = gsf->gf_interface;
+               psin = (struct sockaddr_in *)&gsf->gf_group;
+               if (psin->sin_family != AF_INET) {
                        err = -EADDRNOTAVAIL;
-                       for (i=0; i<gsf->gf_numsrc; ++i) {
-                               psin = (struct sockaddr_in *)&gsf->gf_slist[i];
-
-                               if (psin->sin_family != AF_INET)
-                                       goto mc_msf_out;
-                               msf->imsf_slist[i] = psin->sin_addr.s_addr;
-                       }
-                       kfree(gsf);
-                       gsf = NULL;
-
-                       err = ip_mc_msfilter(sk, msf, ifindex);
-mc_msf_out:
-                       kfree(msf);
-                       kfree(gsf);
-                       break;
+                       goto mc_msf_out;
                }
-               case IP_ROUTER_ALERT:   
-                       err = ip_ra_control(sk, val ? 1 : 0, NULL);
-                       break;
+               msf->imsf_multiaddr = psin->sin_addr.s_addr;
+               msf->imsf_interface = 0;
+               msf->imsf_fmode = gsf->gf_fmode;
+               msf->imsf_numsrc = gsf->gf_numsrc;
+               err = -EADDRNOTAVAIL;
+               for (i=0; i<gsf->gf_numsrc; ++i) {
+                       psin = (struct sockaddr_in *)&gsf->gf_slist[i];
 
-               case IP_FREEBIND:
-                       if (optlen<1)
-                               goto e_inval;
-                       inet->freebind = !!val; 
-                       break;                  
-               case IP_IPSEC_POLICY:
-               case IP_XFRM_POLICY:
-                       err = -EPERM;
-                       if (!capable(CAP_NET_ADMIN))
-                               break;
-                       err = xfrm_user_policy(sk, optname, optval, optlen);
+                       if (psin->sin_family != AF_INET)
+                               goto mc_msf_out;
+                       msf->imsf_slist[i] = psin->sin_addr.s_addr;
+               }
+               kfree(gsf);
+               gsf = NULL;
+
+               err = ip_mc_msfilter(sk, msf, ifindex);
+       mc_msf_out:
+               kfree(msf);
+               kfree(gsf);
+               break;
+       }
+       case IP_ROUTER_ALERT:
+               err = ip_ra_control(sk, val ? 1 : 0, NULL);
+               break;
+
+       case IP_FREEBIND:
+               if (optlen<1)
+                       goto e_inval;
+               inet->freebind = !!val;
+               break;
+
+       case IP_IPSEC_POLICY:
+       case IP_XFRM_POLICY:
+               err = -EPERM;
+               if (!capable(CAP_NET_ADMIN))
                        break;
+               err = xfrm_user_policy(sk, optname, optval, optlen);
+               break;
 
-               default:
-                       err = -ENOPROTOOPT;
-                       break;
+       default:
+               err = -ENOPROTOOPT;
+               break;
        }
        release_sock(sk);
        return err;
@@ -949,214 +948,213 @@ EXPORT_SYMBOL(compat_ip_setsockopt);
  */
 
 static int do_ip_getsockopt(struct sock *sk, int level, int optname,
-               char __user *optval, int __user *optlen)
+                           char __user *optval, int __user *optlen)
 {
        struct inet_sock *inet = inet_sk(sk);
        int val;
        int len;
-       
-       if(level!=SOL_IP)
+
+       if (level != SOL_IP)
                return -EOPNOTSUPP;
 
 #ifdef CONFIG_IP_MROUTE
-       if(optname>=MRT_BASE && optname <=MRT_BASE+10)
-       {
+       if (optname >= MRT_BASE && optname <= MRT_BASE+10) {
                return ip_mroute_getsockopt(sk,optname,optval,optlen);
        }
 #endif
 
-       if(get_user(len,optlen))
+       if (get_user(len,optlen))
                return -EFAULT;
-       if(len < 0)
+       if (len < 0)
                return -EINVAL;
-               
+
        lock_sock(sk);
 
-       switch(optname) {
-               case IP_OPTIONS:
-                       {
-                               unsigned char optbuf[sizeof(struct ip_options)+40];
-                               struct ip_options * opt = (struct ip_options*)optbuf;
-                               opt->optlen = 0;
-                               if (inet->opt)
-                                       memcpy(optbuf, inet->opt,
-                                              sizeof(struct ip_options)+
-                                              inet->opt->optlen);
-                               release_sock(sk);
-
-                               if (opt->optlen == 0) 
-                                       return put_user(0, optlen);
-
-                               ip_options_undo(opt);
-
-                               len = min_t(unsigned int, len, opt->optlen);
-                               if(put_user(len, optlen))
-                                       return -EFAULT;
-                               if(copy_to_user(optval, opt->__data, len))
-                                       return -EFAULT;
-                               return 0;
-                       }
-               case IP_PKTINFO:
-                       val = (inet->cmsg_flags & IP_CMSG_PKTINFO) != 0;
-                       break;
-               case IP_RECVTTL:
-                       val = (inet->cmsg_flags & IP_CMSG_TTL) != 0;
-                       break;
-               case IP_RECVTOS:
-                       val = (inet->cmsg_flags & IP_CMSG_TOS) != 0;
-                       break;
-               case IP_RECVOPTS:
-                       val = (inet->cmsg_flags & IP_CMSG_RECVOPTS) != 0;
-                       break;
-               case IP_RETOPTS:
-                       val = (inet->cmsg_flags & IP_CMSG_RETOPTS) != 0;
-                       break;
-               case IP_PASSSEC:
-                       val = (inet->cmsg_flags & IP_CMSG_PASSSEC) != 0;
-                       break;
-               case IP_TOS:
-                       val = inet->tos;
-                       break;
-               case IP_TTL:
-                       val = (inet->uc_ttl == -1 ?
-                              sysctl_ip_default_ttl :
-                              inet->uc_ttl);
-                       break;
-               case IP_HDRINCL:
-                       val = inet->hdrincl;
-                       break;
-               case IP_MTU_DISCOVER:
-                       val = inet->pmtudisc;
-                       break;
-               case IP_MTU:
-               {
-                       struct dst_entry *dst;
-                       val = 0;
-                       dst = sk_dst_get(sk);
-                       if (dst) {
-                               val = dst_mtu(dst);
-                               dst_release(dst);
-                       }
-                       if (!val) {
-                               release_sock(sk);
-                               return -ENOTCONN;
-                       }
-                       break;
+       switch (optname) {
+       case IP_OPTIONS:
+       {
+               unsigned char optbuf[sizeof(struct ip_options)+40];
+               struct ip_options * opt = (struct ip_options*)optbuf;
+               opt->optlen = 0;
+               if (inet->opt)
+                       memcpy(optbuf, inet->opt,
+                              sizeof(struct ip_options)+
+                              inet->opt->optlen);
+               release_sock(sk);
+
+               if (opt->optlen == 0)
+                       return put_user(0, optlen);
+
+               ip_options_undo(opt);
+
+               len = min_t(unsigned int, len, opt->optlen);
+               if (put_user(len, optlen))
+                       return -EFAULT;
+               if (copy_to_user(optval, opt->__data, len))
+                       return -EFAULT;
+               return 0;
+       }
+       case IP_PKTINFO:
+               val = (inet->cmsg_flags & IP_CMSG_PKTINFO) != 0;
+               break;
+       case IP_RECVTTL:
+               val = (inet->cmsg_flags & IP_CMSG_TTL) != 0;
+               break;
+       case IP_RECVTOS:
+               val = (inet->cmsg_flags & IP_CMSG_TOS) != 0;
+               break;
+       case IP_RECVOPTS:
+               val = (inet->cmsg_flags & IP_CMSG_RECVOPTS) != 0;
+               break;
+       case IP_RETOPTS:
+               val = (inet->cmsg_flags & IP_CMSG_RETOPTS) != 0;
+               break;
+       case IP_PASSSEC:
+               val = (inet->cmsg_flags & IP_CMSG_PASSSEC) != 0;
+               break;
+       case IP_TOS:
+               val = inet->tos;
+               break;
+       case IP_TTL:
+               val = (inet->uc_ttl == -1 ?
+                      sysctl_ip_default_ttl :
+                      inet->uc_ttl);
+               break;
+       case IP_HDRINCL:
+               val = inet->hdrincl;
+               break;
+       case IP_MTU_DISCOVER:
+               val = inet->pmtudisc;
+               break;
+       case IP_MTU:
+       {
+               struct dst_entry *dst;
+               val = 0;
+               dst = sk_dst_get(sk);
+               if (dst) {
+                       val = dst_mtu(dst);
+                       dst_release(dst);
                }
-               case IP_RECVERR:
-                       val = inet->recverr;
-                       break;
-               case IP_MULTICAST_TTL:
-                       val = inet->mc_ttl;
-                       break;
-               case IP_MULTICAST_LOOP:
-                       val = inet->mc_loop;
-                       break;
-               case IP_MULTICAST_IF:
-               {
-                       struct in_addr addr;
-                       len = min_t(unsigned int, len, sizeof(struct in_addr));
-                       addr.s_addr = inet->mc_addr;
+               if (!val) {
                        release_sock(sk);
-
-                       if(put_user(len, optlen))
-                               return -EFAULT;
-                       if(copy_to_user(optval, &addr, len))
-                               return -EFAULT;
-                       return 0;
+                       return -ENOTCONN;
                }
-               case IP_MSFILTER:
-               {
-                       struct ip_msfilter msf;
-                       int err;
+               break;
+       }
+       case IP_RECVERR:
+               val = inet->recverr;
+               break;
+       case IP_MULTICAST_TTL:
+               val = inet->mc_ttl;
+               break;
+       case IP_MULTICAST_LOOP:
+               val = inet->mc_loop;
+               break;
+       case IP_MULTICAST_IF:
+       {
+               struct in_addr addr;
+               len = min_t(unsigned int, len, sizeof(struct in_addr));
+               addr.s_addr = inet->mc_addr;
+               release_sock(sk);
 
-                       if (len < IP_MSFILTER_SIZE(0)) {
-                               release_sock(sk);
-                               return -EINVAL;
-                       }
-                       if (copy_from_user(&msf, optval, IP_MSFILTER_SIZE(0))) {
-                               release_sock(sk);
-                               return -EFAULT;
-                       }
-                       err = ip_mc_msfget(sk, &msf,
-                               (struct ip_msfilter __user *)optval, optlen);
+               if (put_user(len, optlen))
+                       return -EFAULT;
+               if (copy_to_user(optval, &addr, len))
+                       return -EFAULT;
+               return 0;
+       }
+       case IP_MSFILTER:
+       {
+               struct ip_msfilter msf;
+               int err;
+
+               if (len < IP_MSFILTER_SIZE(0)) {
                        release_sock(sk);
-                       return err;
+                       return -EINVAL;
                }
-               case MCAST_MSFILTER:
-               {
-                       struct group_filter gsf;
-                       int err;
-
-                       if (len < GROUP_FILTER_SIZE(0)) {
-                               release_sock(sk);
-                               return -EINVAL;
-                       }
-                       if (copy_from_user(&gsf, optval, GROUP_FILTER_SIZE(0))) {
-                               release_sock(sk);
-                               return -EFAULT;
-                       }
-                       err = ip_mc_gsfget(sk, &gsf,
-                               (struct group_filter __user *)optval, optlen);
+               if (copy_from_user(&msf, optval, IP_MSFILTER_SIZE(0))) {
                        release_sock(sk);
-                       return err;
+                       return -EFAULT;
                }
-               case IP_PKTOPTIONS:             
-               {
-                       struct msghdr msg;
+               err = ip_mc_msfget(sk, &msf,
+                                  (struct ip_msfilter __user *)optval, optlen);
+               release_sock(sk);
+               return err;
+       }
+       case MCAST_MSFILTER:
+       {
+               struct group_filter gsf;
+               int err;
 
+               if (len < GROUP_FILTER_SIZE(0)) {
                        release_sock(sk);
+                       return -EINVAL;
+               }
+               if (copy_from_user(&gsf, optval, GROUP_FILTER_SIZE(0))) {
+                       release_sock(sk);
+                       return -EFAULT;
+               }
+               err = ip_mc_gsfget(sk, &gsf,
+                                  (struct group_filter __user *)optval, optlen);
+               release_sock(sk);
+               return err;
+       }
+       case IP_PKTOPTIONS:
+       {
+               struct msghdr msg;
+
+               release_sock(sk);
 
-                       if (sk->sk_type != SOCK_STREAM)
-                               return -ENOPROTOOPT;
+               if (sk->sk_type != SOCK_STREAM)
+                       return -ENOPROTOOPT;
 
-                       msg.msg_control = optval;
-                       msg.msg_controllen = len;
-                       msg.msg_flags = 0;
+               msg.msg_control = optval;
+               msg.msg_controllen = len;
+               msg.msg_flags = 0;
 
-                       if (inet->cmsg_flags & IP_CMSG_PKTINFO) {
-                               struct in_pktinfo info;
+               if (inet->cmsg_flags & IP_CMSG_PKTINFO) {
+                       struct in_pktinfo info;
 
-                               info.ipi_addr.s_addr = inet->rcv_saddr;
-                               info.ipi_spec_dst.s_addr = inet->rcv_saddr;
-                               info.ipi_ifindex = inet->mc_index;
-                               put_cmsg(&msg, SOL_IP, IP_PKTINFO, sizeof(info), &info);
-                       }
-                       if (inet->cmsg_flags & IP_CMSG_TTL) {
-                               int hlim = inet->mc_ttl;
-                               put_cmsg(&msg, SOL_IP, IP_TTL, sizeof(hlim), &hlim);
-                       }
-                       len -= msg.msg_controllen;
-                       return put_user(len, optlen);
+                       info.ipi_addr.s_addr = inet->rcv_saddr;
+                       info.ipi_spec_dst.s_addr = inet->rcv_saddr;
+                       info.ipi_ifindex = inet->mc_index;
+                       put_cmsg(&msg, SOL_IP, IP_PKTINFO, sizeof(info), &info);
                }
-               case IP_FREEBIND: 
-                       val = inet->freebind; 
-                       break; 
-               default:
-                       release_sock(sk);
-                       return -ENOPROTOOPT;
+               if (inet->cmsg_flags & IP_CMSG_TTL) {
+                       int hlim = inet->mc_ttl;
+                       put_cmsg(&msg, SOL_IP, IP_TTL, sizeof(hlim), &hlim);
+               }
+               len -= msg.msg_controllen;
+               return put_user(len, optlen);
+       }
+       case IP_FREEBIND:
+               val = inet->freebind;
+               break;
+       default:
+               release_sock(sk);
+               return -ENOPROTOOPT;
        }
        release_sock(sk);
-       
+
        if (len < sizeof(int) && len > 0 && val>=0 && val<255) {
                unsigned char ucval = (unsigned char)val;
                len = 1;
-               if(put_user(len, optlen))
+               if (put_user(len, optlen))
                        return -EFAULT;
-               if(copy_to_user(optval,&ucval,1))
+               if (copy_to_user(optval,&ucval,1))
                        return -EFAULT;
        } else {
                len = min_t(unsigned int, sizeof(int), len);
-               if(put_user(len, optlen))
+               if (put_user(len, optlen))
                        return -EFAULT;
-               if(copy_to_user(optval,&val,len))
+               if (copy_to_user(optval,&val,len))
                        return -EFAULT;
        }
        return 0;
 }
 
 int ip_getsockopt(struct sock *sk, int level,
-               int optname, char __user *optval, int __user *optlen)
+                 int optname, char __user *optval, int __user *optlen)
 {
        int err;
 
@@ -1168,9 +1166,9 @@ int ip_getsockopt(struct sock *sk, int level,
                && (optname < MRT_BASE || optname > MRT_BASE+10)
 #endif
           ) {
-               int len;
+               int len;
 
-               if(get_user(len,optlen))
+               if (get_user(len,optlen))
                        return -EFAULT;
 
                lock_sock(sk);
@@ -1197,7 +1195,7 @@ int compat_ip_getsockopt(struct sock *sk, int level, int optname,
            && (optname < MRT_BASE || optname > MRT_BASE+10)
 #endif
           ) {
-               int len;
+               int len;
 
                if (get_user(len, optlen))
                        return -EFAULT;