linux/net/ipv4/ip_sockglue.c
<<
>>
Prefs
   1/*
   2 * INET         An implementation of the TCP/IP protocol suite for the LINUX
   3 *              operating system.  INET is implemented using the  BSD Socket
   4 *              interface as the means of communication with the user level.
   5 *
   6 *              The IP to API glue.
   7 *
   8 * Authors:     see ip.c
   9 *
  10 * Fixes:
  11 *              Many            :       Split from ip.c , see ip.c for history.
  12 *              Martin Mares    :       TOS setting fixed.
  13 *              Alan Cox        :       Fixed a couple of oopses in Martin's
  14 *                                      TOS tweaks.
  15 *              Mike McLagan    :       Routing by source
  16 */
  17
  18#include <linux/module.h>
  19#include <linux/types.h>
  20#include <linux/mm.h>
  21#include <linux/skbuff.h>
  22#include <linux/ip.h>
  23#include <linux/icmp.h>
  24#include <linux/inetdevice.h>
  25#include <linux/netdevice.h>
  26#include <linux/slab.h>
  27#include <net/sock.h>
  28#include <net/ip.h>
  29#include <net/icmp.h>
  30#include <net/tcp_states.h>
  31#include <linux/udp.h>
  32#include <linux/igmp.h>
  33#include <linux/netfilter.h>
  34#include <linux/route.h>
  35#include <linux/mroute.h>
  36#include <net/inet_ecn.h>
  37#include <net/route.h>
  38#include <net/xfrm.h>
  39#include <net/compat.h>
  40#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
  41#include <net/transp_v6.h>
  42#endif
  43
  44#include <linux/errqueue.h>
  45#include <asm/uaccess.h>
  46
  47#define IP_CMSG_PKTINFO         1
  48#define IP_CMSG_TTL             2
  49#define IP_CMSG_TOS             4
  50#define IP_CMSG_RECVOPTS        8
  51#define IP_CMSG_RETOPTS         16
  52#define IP_CMSG_PASSSEC         32
  53#define IP_CMSG_ORIGDSTADDR     64
  54
  55/*
  56 *      SOL_IP control messages.
  57 */
  58
  59static void ip_cmsg_recv_pktinfo(struct msghdr *msg, struct sk_buff *skb)
  60{
  61        struct in_pktinfo info;
  62        struct rtable *rt = skb_rtable(skb);
  63
  64        info.ipi_addr.s_addr = ip_hdr(skb)->daddr;
  65        if (rt) {
  66                info.ipi_ifindex = rt->rt_iif;
  67                info.ipi_spec_dst.s_addr = rt->rt_spec_dst;
  68        } else {
  69                info.ipi_ifindex = 0;
  70                info.ipi_spec_dst.s_addr = 0;
  71        }
  72
  73        put_cmsg(msg, SOL_IP, IP_PKTINFO, sizeof(info), &info);
  74}
  75
  76static void ip_cmsg_recv_ttl(struct msghdr *msg, struct sk_buff *skb)
  77{
  78        int ttl = ip_hdr(skb)->ttl;
  79        put_cmsg(msg, SOL_IP, IP_TTL, sizeof(int), &ttl);
  80}
  81
  82static void ip_cmsg_recv_tos(struct msghdr *msg, struct sk_buff *skb)
  83{
  84        put_cmsg(msg, SOL_IP, IP_TOS, 1, &ip_hdr(skb)->tos);
  85}
  86
  87static void ip_cmsg_recv_opts(struct msghdr *msg, struct sk_buff *skb)
  88{
  89        if (IPCB(skb)->opt.optlen == 0)
  90                return;
  91
  92        put_cmsg(msg, SOL_IP, IP_RECVOPTS, IPCB(skb)->opt.optlen,
  93                 ip_hdr(skb) + 1);
  94}
  95
  96
  97static void ip_cmsg_recv_retopts(struct msghdr *msg, struct sk_buff *skb)
  98{
  99        unsigned char optbuf[sizeof(struct ip_options) + 40];
 100        struct ip_options * opt = (struct ip_options *)optbuf;
 101
 102        if (IPCB(skb)->opt.optlen == 0)
 103                return;
 104
 105        if (ip_options_echo(opt, skb)) {
 106                msg->msg_flags |= MSG_CTRUNC;
 107                return;
 108        }
 109        ip_options_undo(opt);
 110
 111        put_cmsg(msg, SOL_IP, IP_RETOPTS, opt->optlen, opt->__data);
 112}
 113
 114static void ip_cmsg_recv_security(struct msghdr *msg, struct sk_buff *skb)
 115{
 116        char *secdata;
 117        u32 seclen, secid;
 118        int err;
 119
 120        err = security_socket_getpeersec_dgram(NULL, skb, &secid);
 121        if (err)
 122                return;
 123
 124        err = security_secid_to_secctx(secid, &secdata, &seclen);
 125        if (err)
 126                return;
 127
 128        put_cmsg(msg, SOL_IP, SCM_SECURITY, seclen, secdata);
 129        security_release_secctx(secdata, seclen);
 130}
 131
 132static void ip_cmsg_recv_dstaddr(struct msghdr *msg, struct sk_buff *skb)
 133{
 134        struct sockaddr_in sin;
 135        const struct iphdr *iph = ip_hdr(skb);
 136        __be16 *ports = (__be16 *)skb_transport_header(skb);
 137
 138        if (skb_transport_offset(skb) + 4 > skb->len)
 139                return;
 140
 141        /* All current transport protocols have the port numbers in the
 142         * first four bytes of the transport header and this function is
 143         * written with this assumption in mind.
 144         */
 145
 146        sin.sin_family = AF_INET;
 147        sin.sin_addr.s_addr = iph->daddr;
 148        sin.sin_port = ports[1];
 149        memset(sin.sin_zero, 0, sizeof(sin.sin_zero));
 150
 151        put_cmsg(msg, SOL_IP, IP_ORIGDSTADDR, sizeof(sin), &sin);
 152}
 153
 154void ip_cmsg_recv(struct msghdr *msg, struct sk_buff *skb)
 155{
 156        struct inet_sock *inet = inet_sk(skb->sk);
 157        unsigned flags = inet->cmsg_flags;
 158
 159        /* Ordered by supposed usage frequency */
 160        if (flags & 1)
 161                ip_cmsg_recv_pktinfo(msg, skb);
 162        if ((flags >>= 1) == 0)
 163                return;
 164
 165        if (flags & 1)
 166                ip_cmsg_recv_ttl(msg, skb);
 167        if ((flags >>= 1) == 0)
 168                return;
 169
 170        if (flags & 1)
 171                ip_cmsg_recv_tos(msg, skb);
 172        if ((flags >>= 1) == 0)
 173                return;
 174
 175        if (flags & 1)
 176                ip_cmsg_recv_opts(msg, skb);
 177        if ((flags >>= 1) == 0)
 178                return;
 179
 180        if (flags & 1)
 181                ip_cmsg_recv_retopts(msg, skb);
 182        if ((flags >>= 1) == 0)
 183                return;
 184
 185        if (flags & 1)
 186                ip_cmsg_recv_security(msg, skb);
 187
 188        if ((flags >>= 1) == 0)
 189                return;
 190        if (flags & 1)
 191                ip_cmsg_recv_dstaddr(msg, skb);
 192
 193}
 194EXPORT_SYMBOL(ip_cmsg_recv);
 195
 196int ip_cmsg_send(struct net *net, struct msghdr *msg, struct ipcm_cookie *ipc)
 197{
 198        int err;
 199        struct cmsghdr *cmsg;
 200
 201        for (cmsg = CMSG_FIRSTHDR(msg); cmsg; cmsg = CMSG_NXTHDR(msg, cmsg)) {
 202                if (!CMSG_OK(msg, cmsg))
 203                        return -EINVAL;
 204                if (cmsg->cmsg_level != SOL_IP)
 205                        continue;
 206                switch (cmsg->cmsg_type) {
 207                case IP_RETOPTS:
 208                        err = cmsg->cmsg_len - CMSG_ALIGN(sizeof(struct cmsghdr));
 209                        err = ip_options_get(net, &ipc->opt, CMSG_DATA(cmsg),
 210                                             err < 40 ? err : 40);
 211                        if (err)
 212                                return err;
 213                        break;
 214                case IP_PKTINFO:
 215                {
 216                        struct in_pktinfo *info;
 217                        if (cmsg->cmsg_len != CMSG_LEN(sizeof(struct in_pktinfo)))
 218                                return -EINVAL;
 219                        info = (struct in_pktinfo *)CMSG_DATA(cmsg);
 220                        ipc->oif = info->ipi_ifindex;
 221                        ipc->addr = info->ipi_spec_dst.s_addr;
 222                        break;
 223                }
 224                default:
 225                        return -EINVAL;
 226                }
 227        }
 228        return 0;
 229}
 230
 231
 232/* Special input handler for packets caught by router alert option.
 233   They are selected only by protocol field, and then processed likely
 234   local ones; but only if someone wants them! Otherwise, router
 235   not running rsvpd will kill RSVP.
 236
 237   It is user level problem, what it will make with them.
 238   I have no idea, how it will masquearde or NAT them (it is joke, joke :-)),
 239   but receiver should be enough clever f.e. to forward mtrace requests,
 240   sent to multicast group to reach destination designated router.
 241 */
 242struct ip_ra_chain __rcu *ip_ra_chain;
 243static DEFINE_SPINLOCK(ip_ra_lock);
 244
 245
 246static void ip_ra_destroy_rcu(struct rcu_head *head)
 247{
 248        struct ip_ra_chain *ra = container_of(head, struct ip_ra_chain, rcu);
 249
 250        sock_put(ra->saved_sk);
 251        kfree(ra);
 252}
 253
 254int ip_ra_control(struct sock *sk, unsigned char on,
 255                  void (*destructor)(struct sock *))
 256{
 257        struct ip_ra_chain *ra, *new_ra;
 258        struct ip_ra_chain __rcu **rap;
 259
 260        if (sk->sk_type != SOCK_RAW || inet_sk(sk)->inet_num == IPPROTO_RAW)
 261                return -EINVAL;
 262
 263        new_ra = on ? kmalloc(sizeof(*new_ra), GFP_KERNEL) : NULL;
 264
 265        spin_lock_bh(&ip_ra_lock);
 266        for (rap = &ip_ra_chain;
 267             (ra = rcu_dereference_protected(*rap,
 268                        lockdep_is_held(&ip_ra_lock))) != NULL;
 269             rap = &ra->next) {
 270                if (ra->sk == sk) {
 271                        if (on) {
 272                                spin_unlock_bh(&ip_ra_lock);
 273                                kfree(new_ra);
 274                                return -EADDRINUSE;
 275                        }
 276                        /* dont let ip_call_ra_chain() use sk again */
 277                        ra->sk = NULL;
 278                        rcu_assign_pointer(*rap, ra->next);
 279                        spin_unlock_bh(&ip_ra_lock);
 280
 281                        if (ra->destructor)
 282                                ra->destructor(sk);
 283                        /*
 284                         * Delay sock_put(sk) and kfree(ra) after one rcu grace
 285                         * period. This guarantee ip_call_ra_chain() dont need
 286                         * to mess with socket refcounts.
 287                         */
 288                        ra->saved_sk = sk;
 289                        call_rcu(&ra->rcu, ip_ra_destroy_rcu);
 290                        return 0;
 291                }
 292        }
 293        if (new_ra == NULL) {
 294                spin_unlock_bh(&ip_ra_lock);
 295                return -ENOBUFS;
 296        }
 297        new_ra->sk = sk;
 298        new_ra->destructor = destructor;
 299
 300        new_ra->next = ra;
 301        rcu_assign_pointer(*rap, new_ra);
 302        sock_hold(sk);
 303        spin_unlock_bh(&ip_ra_lock);
 304
 305        return 0;
 306}
 307
 308void ip_icmp_error(struct sock *sk, struct sk_buff *skb, int err,
 309                   __be16 port, u32 info, u8 *payload)
 310{
 311        struct sock_exterr_skb *serr;
 312
 313        skb = skb_clone(skb, GFP_ATOMIC);
 314        if (!skb)
 315                return;
 316
 317        serr = SKB_EXT_ERR(skb);
 318        serr->ee.ee_errno = err;
 319        serr->ee.ee_origin = SO_EE_ORIGIN_ICMP;
 320        serr->ee.ee_type = icmp_hdr(skb)->type;
 321        serr->ee.ee_code = icmp_hdr(skb)->code;
 322        serr->ee.ee_pad = 0;
 323        serr->ee.ee_info = info;
 324        serr->ee.ee_data = 0;
 325        serr->addr_offset = (u8 *)&(((struct iphdr *)(icmp_hdr(skb) + 1))->daddr) -
 326                                   skb_network_header(skb);
 327        serr->port = port;
 328
 329        if (skb_pull(skb, payload - skb->data) != NULL) {
 330                skb_reset_transport_header(skb);
 331                if (sock_queue_err_skb(sk, skb) == 0)
 332                        return;
 333        }
 334        kfree_skb(skb);
 335}
 336
 337void ip_local_error(struct sock *sk, int err, __be32 daddr, __be16 port, u32 info)
 338{
 339        struct inet_sock *inet = inet_sk(sk);
 340        struct sock_exterr_skb *serr;
 341        struct iphdr *iph;
 342        struct sk_buff *skb;
 343
 344        if (!inet->recverr)
 345                return;
 346
 347        skb = alloc_skb(sizeof(struct iphdr), GFP_ATOMIC);
 348        if (!skb)
 349                return;
 350
 351        skb_put(skb, sizeof(struct iphdr));
 352        skb_reset_network_header(skb);
 353        iph = ip_hdr(skb);
 354        iph->daddr = daddr;
 355
 356        serr = SKB_EXT_ERR(skb);
 357        serr->ee.ee_errno = err;
 358        serr->ee.ee_origin = SO_EE_ORIGIN_LOCAL;
 359        serr->ee.ee_type = 0;
 360        serr->ee.ee_code = 0;
 361        serr->ee.ee_pad = 0;
 362        serr->ee.ee_info = info;
 363        serr->ee.ee_data = 0;
 364        serr->addr_offset = (u8 *)&iph->daddr - skb_network_header(skb);
 365        serr->port = port;
 366
 367        __skb_pull(skb, skb_tail_pointer(skb) - skb->data);
 368        skb_reset_transport_header(skb);
 369
 370        if (sock_queue_err_skb(sk, skb))
 371                kfree_skb(skb);
 372}
 373
 374/*
 375 *      Handle MSG_ERRQUEUE
 376 */
 377int ip_recv_error(struct sock *sk, struct msghdr *msg, int len)
 378{
 379        struct sock_exterr_skb *serr;
 380        struct sk_buff *skb, *skb2;
 381        struct sockaddr_in *sin;
 382        struct {
 383                struct sock_extended_err ee;
 384                struct sockaddr_in       offender;
 385        } errhdr;
 386        int err;
 387        int copied;
 388
 389        err = -EAGAIN;
 390        skb = skb_dequeue(&sk->sk_error_queue);
 391        if (skb == NULL)
 392                goto out;
 393
 394        copied = skb->len;
 395        if (copied > len) {
 396                msg->msg_flags |= MSG_TRUNC;
 397                copied = len;
 398        }
 399        err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
 400        if (err)
 401                goto out_free_skb;
 402
 403        sock_recv_timestamp(msg, sk, skb);
 404
 405        serr = SKB_EXT_ERR(skb);
 406
 407        sin = (struct sockaddr_in *)msg->msg_name;
 408        if (sin) {
 409                sin->sin_family = AF_INET;
 410                sin->sin_addr.s_addr = *(__be32 *)(skb_network_header(skb) +
 411                                                   serr->addr_offset);
 412                sin->sin_port = serr->port;
 413                memset(&sin->sin_zero, 0, sizeof(sin->sin_zero));
 414        }
 415
 416        memcpy(&errhdr.ee, &serr->ee, sizeof(struct sock_extended_err));
 417        sin = &errhdr.offender;
 418        sin->sin_family = AF_UNSPEC;
 419        if (serr->ee.ee_origin == SO_EE_ORIGIN_ICMP) {
 420                struct inet_sock *inet = inet_sk(sk);
 421
 422                sin->sin_family = AF_INET;
 423                sin->sin_addr.s_addr = ip_hdr(skb)->saddr;
 424                sin->sin_port = 0;
 425                memset(&sin->sin_zero, 0, sizeof(sin->sin_zero));
 426                if (inet->cmsg_flags)
 427                        ip_cmsg_recv(msg, skb);
 428        }
 429
 430        put_cmsg(msg, SOL_IP, IP_RECVERR, sizeof(errhdr), &errhdr);
 431
 432        /* Now we could try to dump offended packet options */
 433
 434        msg->msg_flags |= MSG_ERRQUEUE;
 435        err = copied;
 436
 437        /* Reset and regenerate socket error */
 438        spin_lock_bh(&sk->sk_error_queue.lock);
 439        sk->sk_err = 0;
 440        skb2 = skb_peek(&sk->sk_error_queue);
 441        if (skb2 != NULL) {
 442                sk->sk_err = SKB_EXT_ERR(skb2)->ee.ee_errno;
 443                spin_unlock_bh(&sk->sk_error_queue.lock);
 444                sk->sk_error_report(sk);
 445        } else
 446                spin_unlock_bh(&sk->sk_error_queue.lock);
 447
 448out_free_skb:
 449        kfree_skb(skb);
 450out:
 451        return err;
 452}
 453
 454
 455static void opt_kfree_rcu(struct rcu_head *head)
 456{
 457        kfree(container_of(head, struct ip_options_rcu, rcu));
 458}
 459
 460/*
 461 *      Socket option code for IP. This is the end of the line after any
 462 *      TCP,UDP etc options on an IP socket.
 463 */
 464
 465static int do_ip_setsockopt(struct sock *sk, int level,
 466                            int optname, char __user *optval, unsigned int optlen)
 467{
 468        struct inet_sock *inet = inet_sk(sk);
 469        int val = 0, err;
 470
 471        if (((1<<optname) & ((1<<IP_PKTINFO) | (1<<IP_RECVTTL) |
 472                             (1<<IP_RECVOPTS) | (1<<IP_RECVTOS) |
 473                             (1<<IP_RETOPTS) | (1<<IP_TOS) |
 474                             (1<<IP_TTL) | (1<<IP_HDRINCL) |
 475                             (1<<IP_MTU_DISCOVER) | (1<<IP_RECVERR) |
 476                             (1<<IP_ROUTER_ALERT) | (1<<IP_FREEBIND) |
 477                             (1<<IP_PASSSEC) | (1<<IP_TRANSPARENT) |
 478                             (1<<IP_MINTTL) | (1<<IP_NODEFRAG))) ||
 479            optname == IP_MULTICAST_TTL ||
 480            optname == IP_MULTICAST_ALL ||
 481            optname == IP_MULTICAST_LOOP ||
 482            optname == IP_RECVORIGDSTADDR) {
 483                if (optlen >= sizeof(int)) {
 484                        if (get_user(val, (int __user *) optval))
 485                                return -EFAULT;
 486                } else if (optlen >= sizeof(char)) {
 487                        unsigned char ucval;
 488
 489                        if (get_user(ucval, (unsigned char __user *) optval))
 490                                return -EFAULT;
 491                        val = (int) ucval;
 492                }
 493        }
 494
 495        /* If optlen==0, it is equivalent to val == 0 */
 496
 497        if (ip_mroute_opt(optname))
 498                return ip_mroute_setsockopt(sk, optname, optval, optlen);
 499
 500        err = 0;
 501        lock_sock(sk);
 502
 503        switch (optname) {
 504        case IP_OPTIONS:
 505        {
 506                struct ip_options_rcu *old, *opt = NULL;
 507
 508                if (optlen > 40)
 509                        goto e_inval;
 510                err = ip_options_get_from_user(sock_net(sk), &opt,
 511                                               optval, optlen);
 512                if (err)
 513                        break;
 514                old = rcu_dereference_protected(inet->inet_opt,
 515                                                sock_owned_by_user(sk));
 516                if (inet->is_icsk) {
 517                        struct inet_connection_sock *icsk = inet_csk(sk);
 518#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
 519                        if (sk->sk_family == PF_INET ||
 520                            (!((1 << sk->sk_state) &
 521                               (TCPF_LISTEN | TCPF_CLOSE)) &&
 522                             inet->inet_daddr != LOOPBACK4_IPV6)) {
 523#endif
 524                                if (old)
 525                                        icsk->icsk_ext_hdr_len -= old->opt.optlen;
 526                                if (opt)
 527                                        icsk->icsk_ext_hdr_len += opt->opt.optlen;
 528                                icsk->icsk_sync_mss(sk, icsk->icsk_pmtu_cookie);
 529#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
 530                        }
 531#endif
 532                }
 533                rcu_assign_pointer(inet->inet_opt, opt);
 534                if (old)
 535                        call_rcu(&old->rcu, opt_kfree_rcu);
 536                break;
 537        }
 538        case IP_PKTINFO:
 539                if (val)
 540                        inet->cmsg_flags |= IP_CMSG_PKTINFO;
 541                else
 542                        inet->cmsg_flags &= ~IP_CMSG_PKTINFO;
 543                break;
 544        case IP_RECVTTL:
 545                if (val)
 546                        inet->cmsg_flags |=  IP_CMSG_TTL;
 547                else
 548                        inet->cmsg_flags &= ~IP_CMSG_TTL;
 549                break;
 550        case IP_RECVTOS:
 551                if (val)
 552                        inet->cmsg_flags |=  IP_CMSG_TOS;
 553                else
 554                        inet->cmsg_flags &= ~IP_CMSG_TOS;
 555                break;
 556        case IP_RECVOPTS:
 557                if (val)
 558                        inet->cmsg_flags |=  IP_CMSG_RECVOPTS;
 559                else
 560                        inet->cmsg_flags &= ~IP_CMSG_RECVOPTS;
 561                break;
 562        case IP_RETOPTS:
 563                if (val)
 564                        inet->cmsg_flags |= IP_CMSG_RETOPTS;
 565                else
 566                        inet->cmsg_flags &= ~IP_CMSG_RETOPTS;
 567                break;
 568        case IP_PASSSEC:
 569                if (val)
 570                        inet->cmsg_flags |= IP_CMSG_PASSSEC;
 571                else
 572                        inet->cmsg_flags &= ~IP_CMSG_PASSSEC;
 573                break;
 574        case IP_RECVORIGDSTADDR:
 575                if (val)
 576                        inet->cmsg_flags |= IP_CMSG_ORIGDSTADDR;
 577                else
 578                        inet->cmsg_flags &= ~IP_CMSG_ORIGDSTADDR;
 579                break;
 580        case IP_TOS:    /* This sets both TOS and Precedence */
 581                if (sk->sk_type == SOCK_STREAM) {
 582                        val &= ~INET_ECN_MASK;
 583                        val |= inet->tos & INET_ECN_MASK;
 584                }
 585                if (inet->tos != val) {
 586                        inet->tos = val;
 587                        sk->sk_priority = rt_tos2priority(val);
 588                        sk_dst_reset(sk);
 589                }
 590                break;
 591        case IP_TTL:
 592                if (optlen < 1)
 593                        goto e_inval;
 594                if (val != -1 && (val < 0 || val > 255))
 595                        goto e_inval;
 596                inet->uc_ttl = val;
 597                break;
 598        case IP_HDRINCL:
 599                if (sk->sk_type != SOCK_RAW) {
 600                        err = -ENOPROTOOPT;
 601                        break;
 602                }
 603                inet->hdrincl = val ? 1 : 0;
 604                break;
 605        case IP_NODEFRAG:
 606                if (sk->sk_type != SOCK_RAW) {
 607                        err = -ENOPROTOOPT;
 608                        break;
 609                }
 610                inet->nodefrag = val ? 1 : 0;
 611                break;
 612        case IP_MTU_DISCOVER:
 613                if (val < IP_PMTUDISC_DONT || val > IP_PMTUDISC_PROBE)
 614                        goto e_inval;
 615                inet->pmtudisc = val;
 616                break;
 617        case IP_RECVERR:
 618                inet->recverr = !!val;
 619                if (!val)
 620                        skb_queue_purge(&sk->sk_error_queue);
 621                break;
 622        case IP_MULTICAST_TTL:
 623                if (sk->sk_type == SOCK_STREAM)
 624                        goto e_inval;
 625                if (optlen < 1)
 626                        goto e_inval;
 627                if (val == -1)
 628                        val = 1;
 629                if (val < 0 || val > 255)
 630                        goto e_inval;
 631                inet->mc_ttl = val;
 632                break;
 633        case IP_MULTICAST_LOOP:
 634                if (optlen < 1)
 635                        goto e_inval;
 636                inet->mc_loop = !!val;
 637                break;
 638        case IP_MULTICAST_IF:
 639        {
 640                struct ip_mreqn mreq;
 641                struct net_device *dev = NULL;
 642
 643                if (sk->sk_type == SOCK_STREAM)
 644                        goto e_inval;
 645                /*
 646                 *      Check the arguments are allowable
 647                 */
 648
 649                if (optlen < sizeof(struct in_addr))
 650                        goto e_inval;
 651
 652                err = -EFAULT;
 653                if (optlen >= sizeof(struct ip_mreqn)) {
 654                        if (copy_from_user(&mreq, optval, sizeof(mreq)))
 655                                break;
 656                } else {
 657                        memset(&mreq, 0, sizeof(mreq));
 658                        if (optlen >= sizeof(struct in_addr) &&
 659                            copy_from_user(&mreq.imr_address, optval,
 660                                           sizeof(struct in_addr)))
 661                                break;
 662                }
 663
 664                if (!mreq.imr_ifindex) {
 665                        if (mreq.imr_address.s_addr == htonl(INADDR_ANY)) {
 666                                inet->mc_index = 0;
 667                                inet->mc_addr  = 0;
 668                                err = 0;
 669                                break;
 670                        }
 671                        dev = ip_dev_find(sock_net(sk), mreq.imr_address.s_addr);
 672                        if (dev)
 673                                mreq.imr_ifindex = dev->ifindex;
 674                } else
 675                        dev = dev_get_by_index(sock_net(sk), mreq.imr_ifindex);
 676
 677
 678                err = -EADDRNOTAVAIL;
 679                if (!dev)
 680                        break;
 681                dev_put(dev);
 682
 683                err = -EINVAL;
 684                if (sk->sk_bound_dev_if &&
 685                    mreq.imr_ifindex != sk->sk_bound_dev_if)
 686                        break;
 687
 688                inet->mc_index = mreq.imr_ifindex;
 689                inet->mc_addr  = mreq.imr_address.s_addr;
 690                err = 0;
 691                break;
 692        }
 693
 694        case IP_ADD_MEMBERSHIP:
 695        case IP_DROP_MEMBERSHIP:
 696        {
 697                struct ip_mreqn mreq;
 698
 699                err = -EPROTO;
 700                if (inet_sk(sk)->is_icsk)
 701                        break;
 702
 703                if (optlen < sizeof(struct ip_mreq))
 704                        goto e_inval;
 705                err = -EFAULT;
 706                if (optlen >= sizeof(struct ip_mreqn)) {
 707                        if (copy_from_user(&mreq, optval, sizeof(mreq)))
 708                                break;
 709                } else {
 710                        memset(&mreq, 0, sizeof(mreq));
 711                        if (copy_from_user(&mreq, optval, sizeof(struct ip_mreq)))
 712                                break;
 713                }
 714
 715                if (optname == IP_ADD_MEMBERSHIP)
 716                        err = ip_mc_join_group(sk, &mreq);
 717                else
 718                        err = ip_mc_leave_group(sk, &mreq);
 719                break;
 720        }
 721        case IP_MSFILTER:
 722        {
 723                struct ip_msfilter *msf;
 724
 725                if (optlen < IP_MSFILTER_SIZE(0))
 726                        goto e_inval;
 727                if (optlen > sysctl_optmem_max) {
 728                        err = -ENOBUFS;
 729                        break;
 730                }
 731                msf = kmalloc(optlen, GFP_KERNEL);
 732                if (!msf) {
 733                        err = -ENOBUFS;
 734                        break;
 735                }
 736                err = -EFAULT;
 737                if (copy_from_user(msf, optval, optlen)) {
 738                        kfree(msf);
 739                        break;
 740                }
 741                /* numsrc >= (1G-4) overflow in 32 bits */
 742                if (msf->imsf_numsrc >= 0x3ffffffcU ||
 743                    msf->imsf_numsrc > sysctl_igmp_max_msf) {
 744                        kfree(msf);
 745                        err = -ENOBUFS;
 746                        break;
 747                }
 748                if (IP_MSFILTER_SIZE(msf->imsf_numsrc) > optlen) {
 749                        kfree(msf);
 750                        err = -EINVAL;
 751                        break;
 752                }
 753                err = ip_mc_msfilter(sk, msf, 0);
 754                kfree(msf);
 755                break;
 756        }
 757        case IP_BLOCK_SOURCE:
 758        case IP_UNBLOCK_SOURCE:
 759        case IP_ADD_SOURCE_MEMBERSHIP:
 760        case IP_DROP_SOURCE_MEMBERSHIP:
 761        {
 762                struct ip_mreq_source mreqs;
 763                int omode, add;
 764
 765                if (optlen != sizeof(struct ip_mreq_source))
 766                        goto e_inval;
 767                if (copy_from_user(&mreqs, optval, sizeof(mreqs))) {
 768                        err = -EFAULT;
 769                        break;
 770                }
 771                if (optname == IP_BLOCK_SOURCE) {
 772                        omode = MCAST_EXCLUDE;
 773                        add = 1;
 774                } else if (optname == IP_UNBLOCK_SOURCE) {
 775                        omode = MCAST_EXCLUDE;
 776                        add = 0;
 777                } else if (optname == IP_ADD_SOURCE_MEMBERSHIP) {
 778                        struct ip_mreqn mreq;
 779
 780                        mreq.imr_multiaddr.s_addr = mreqs.imr_multiaddr;
 781                        mreq.imr_address.s_addr = mreqs.imr_interface;
 782                        mreq.imr_ifindex = 0;
 783                        err = ip_mc_join_group(sk, &mreq);
 784                        if (err && err != -EADDRINUSE)
 785                                break;
 786                        omode = MCAST_INCLUDE;
 787                        add = 1;
 788                } else /* IP_DROP_SOURCE_MEMBERSHIP */ {
 789                        omode = MCAST_INCLUDE;
 790                        add = 0;
 791                }
 792                err = ip_mc_source(add, omode, sk, &mreqs, 0);
 793                break;
 794        }
 795        case MCAST_JOIN_GROUP:
 796        case MCAST_LEAVE_GROUP:
 797        {
 798                struct group_req greq;
 799                struct sockaddr_in *psin;
 800                struct ip_mreqn mreq;
 801
 802                if (optlen < sizeof(struct group_req))
 803                        goto e_inval;
 804                err = -EFAULT;
 805                if (copy_from_user(&greq, optval, sizeof(greq)))
 806                        break;
 807                psin = (struct sockaddr_in *)&greq.gr_group;
 808                if (psin->sin_family != AF_INET)
 809                        goto e_inval;
 810                memset(&mreq, 0, sizeof(mreq));
 811                mreq.imr_multiaddr = psin->sin_addr;
 812                mreq.imr_ifindex = greq.gr_interface;
 813
 814                if (optname == MCAST_JOIN_GROUP)
 815                        err = ip_mc_join_group(sk, &mreq);
 816                else
 817                        err = ip_mc_leave_group(sk, &mreq);
 818                break;
 819        }
 820        case MCAST_JOIN_SOURCE_GROUP:
 821        case MCAST_LEAVE_SOURCE_GROUP:
 822        case MCAST_BLOCK_SOURCE:
 823        case MCAST_UNBLOCK_SOURCE:
 824        {
 825                struct group_source_req greqs;
 826                struct ip_mreq_source mreqs;
 827                struct sockaddr_in *psin;
 828                int omode, add;
 829
 830                if (optlen != sizeof(struct group_source_req))
 831                        goto e_inval;
 832                if (copy_from_user(&greqs, optval, sizeof(greqs))) {
 833                        err = -EFAULT;
 834                        break;
 835                }
 836                if (greqs.gsr_group.ss_family != AF_INET ||
 837                    greqs.gsr_source.ss_family != AF_INET) {
 838                        err = -EADDRNOTAVAIL;
 839                        break;
 840                }
 841                psin = (struct sockaddr_in *)&greqs.gsr_group;
 842                mreqs.imr_multiaddr = psin->sin_addr.s_addr;
 843                psin = (struct sockaddr_in *)&greqs.gsr_source;
 844                mreqs.imr_sourceaddr = psin->sin_addr.s_addr;
 845                mreqs.imr_interface = 0; /* use index for mc_source */
 846
 847                if (optname == MCAST_BLOCK_SOURCE) {
 848                        omode = MCAST_EXCLUDE;
 849                        add = 1;
 850                } else if (optname == MCAST_UNBLOCK_SOURCE) {
 851                        omode = MCAST_EXCLUDE;
 852                        add = 0;
 853                } else if (optname == MCAST_JOIN_SOURCE_GROUP) {
 854                        struct ip_mreqn mreq;
 855
 856                        psin = (struct sockaddr_in *)&greqs.gsr_group;
 857                        mreq.imr_multiaddr = psin->sin_addr;
 858                        mreq.imr_address.s_addr = 0;
 859                        mreq.imr_ifindex = greqs.gsr_interface;
 860                        err = ip_mc_join_group(sk, &mreq);
 861                        if (err && err != -EADDRINUSE)
 862                                break;
 863                        greqs.gsr_interface = mreq.imr_ifindex;
 864                        omode = MCAST_INCLUDE;
 865                        add = 1;
 866                } else /* MCAST_LEAVE_SOURCE_GROUP */ {
 867                        omode = MCAST_INCLUDE;
 868                        add = 0;
 869                }
 870                err = ip_mc_source(add, omode, sk, &mreqs,
 871                                   greqs.gsr_interface);
 872                break;
 873        }
 874        case MCAST_MSFILTER:
 875        {
 876                struct sockaddr_in *psin;
 877                struct ip_msfilter *msf = NULL;
 878                struct group_filter *gsf = NULL;
 879                int msize, i, ifindex;
 880
 881                if (optlen < GROUP_FILTER_SIZE(0))
 882                        goto e_inval;
 883                if (optlen > sysctl_optmem_max) {
 884                        err = -ENOBUFS;
 885                        break;
 886                }
 887                gsf = kmalloc(optlen, GFP_KERNEL);
 888                if (!gsf) {
 889                        err = -ENOBUFS;
 890                        break;
 891                }
 892                err = -EFAULT;
 893                if (copy_from_user(gsf, optval, optlen))
 894                        goto mc_msf_out;
 895
 896                /* numsrc >= (4G-140)/128 overflow in 32 bits */
 897                if (gsf->gf_numsrc >= 0x1ffffff ||
 898                    gsf->gf_numsrc > sysctl_igmp_max_msf) {
 899                        err = -ENOBUFS;
 900                        goto mc_msf_out;
 901                }
 902                if (GROUP_FILTER_SIZE(gsf->gf_numsrc) > optlen) {
 903                        err = -EINVAL;
 904                        goto mc_msf_out;
 905                }
 906                msize = IP_MSFILTER_SIZE(gsf->gf_numsrc);
 907                msf = kmalloc(msize, GFP_KERNEL);
 908                if (!msf) {
 909                        err = -ENOBUFS;
 910                        goto mc_msf_out;
 911                }
 912                ifindex = gsf->gf_interface;
 913                psin = (struct sockaddr_in *)&gsf->gf_group;
 914                if (psin->sin_family != AF_INET) {
 915                        err = -EADDRNOTAVAIL;
 916                        goto mc_msf_out;
 917                }
 918                msf->imsf_multiaddr = psin->sin_addr.s_addr;
 919                msf->imsf_interface = 0;
 920                msf->imsf_fmode = gsf->gf_fmode;
 921                msf->imsf_numsrc = gsf->gf_numsrc;
 922                err = -EADDRNOTAVAIL;
 923                for (i = 0; i < gsf->gf_numsrc; ++i) {
 924                        psin = (struct sockaddr_in *)&gsf->gf_slist[i];
 925
 926                        if (psin->sin_family != AF_INET)
 927                                goto mc_msf_out;
 928                        msf->imsf_slist[i] = psin->sin_addr.s_addr;
 929                }
 930                kfree(gsf);
 931                gsf = NULL;
 932
 933                err = ip_mc_msfilter(sk, msf, ifindex);
 934mc_msf_out:
 935                kfree(msf);
 936                kfree(gsf);
 937                break;
 938        }
 939        case IP_MULTICAST_ALL:
 940                if (optlen < 1)
 941                        goto e_inval;
 942                if (val != 0 && val != 1)
 943                        goto e_inval;
 944                inet->mc_all = val;
 945                break;
 946        case IP_ROUTER_ALERT:
 947                err = ip_ra_control(sk, val ? 1 : 0, NULL);
 948                break;
 949
 950        case IP_FREEBIND:
 951                if (optlen < 1)
 952                        goto e_inval;
 953                inet->freebind = !!val;
 954                break;
 955
 956        case IP_IPSEC_POLICY:
 957        case IP_XFRM_POLICY:
 958                err = -EPERM;
 959                if (!capable(CAP_NET_ADMIN))
 960                        break;
 961                err = xfrm_user_policy(sk, optname, optval, optlen);
 962                break;
 963
 964        case IP_TRANSPARENT:
 965                if (!!val && !capable(CAP_NET_RAW) && !capable(CAP_NET_ADMIN)) {
 966                        err = -EPERM;
 967                        break;
 968                }
 969                if (optlen < 1)
 970                        goto e_inval;
 971                inet->transparent = !!val;
 972                break;
 973
 974        case IP_MINTTL:
 975                if (optlen < 1)
 976                        goto e_inval;
 977                if (val < 0 || val > 255)
 978                        goto e_inval;
 979                inet->min_ttl = val;
 980                break;
 981
 982        default:
 983                err = -ENOPROTOOPT;
 984                break;
 985        }
 986        release_sock(sk);
 987        return err;
 988
 989e_inval:
 990        release_sock(sk);
 991        return -EINVAL;
 992}
 993
 994/**
 995 * ip_queue_rcv_skb - Queue an skb into sock receive queue
 996 * @sk: socket
 997 * @skb: buffer
 998 *
 999 * Queues an skb into socket receive queue. If IP_CMSG_PKTINFO option
1000 * is not set, we drop skb dst entry now, while dst cache line is hot.
1001 */
1002int ip_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
1003{
1004        if (!(inet_sk(sk)->cmsg_flags & IP_CMSG_PKTINFO))
1005                skb_dst_drop(skb);
1006        return sock_queue_rcv_skb(sk, skb);
1007}
1008EXPORT_SYMBOL(ip_queue_rcv_skb);
1009
1010int ip_setsockopt(struct sock *sk, int level,
1011                int optname, char __user *optval, unsigned int optlen)
1012{
1013        int err;
1014
1015        if (level != SOL_IP)
1016                return -ENOPROTOOPT;
1017
1018        err = do_ip_setsockopt(sk, level, optname, optval, optlen);
1019#ifdef CONFIG_NETFILTER
1020        /* we need to exclude all possible ENOPROTOOPTs except default case */
1021        if (err == -ENOPROTOOPT && optname != IP_HDRINCL &&
1022                        optname != IP_IPSEC_POLICY &&
1023                        optname != IP_XFRM_POLICY &&
1024                        !ip_mroute_opt(optname)) {
1025                lock_sock(sk);
1026                err = nf_setsockopt(sk, PF_INET, optname, optval, optlen);
1027                release_sock(sk);
1028        }
1029#endif
1030        return err;
1031}
1032EXPORT_SYMBOL(ip_setsockopt);
1033
1034#ifdef CONFIG_COMPAT
1035int compat_ip_setsockopt(struct sock *sk, int level, int optname,
1036                         char __user *optval, unsigned int optlen)
1037{
1038        int err;
1039
1040        if (level != SOL_IP)
1041                return -ENOPROTOOPT;
1042
1043        if (optname >= MCAST_JOIN_GROUP && optname <= MCAST_MSFILTER)
1044                return compat_mc_setsockopt(sk, level, optname, optval, optlen,
1045                        ip_setsockopt);
1046
1047        err = do_ip_setsockopt(sk, level, optname, optval, optlen);
1048#ifdef CONFIG_NETFILTER
1049        /* we need to exclude all possible ENOPROTOOPTs except default case */
1050        if (err == -ENOPROTOOPT && optname != IP_HDRINCL &&
1051                        optname != IP_IPSEC_POLICY &&
1052                        optname != IP_XFRM_POLICY &&
1053                        !ip_mroute_opt(optname)) {
1054                lock_sock(sk);
1055                err = compat_nf_setsockopt(sk, PF_INET, optname,
1056                                           optval, optlen);
1057                release_sock(sk);
1058        }
1059#endif
1060        return err;
1061}
1062EXPORT_SYMBOL(compat_ip_setsockopt);
1063#endif
1064
1065/*
1066 *      Get the options. Note for future reference. The GET of IP options gets
1067 *      the _received_ ones. The set sets the _sent_ ones.
1068 */
1069
1070static int do_ip_getsockopt(struct sock *sk, int level, int optname,
1071                            char __user *optval, int __user *optlen, unsigned flags)
1072{
1073        struct inet_sock *inet = inet_sk(sk);
1074        int val;
1075        int len;
1076
1077        if (level != SOL_IP)
1078                return -EOPNOTSUPP;
1079
1080        if (ip_mroute_opt(optname))
1081                return ip_mroute_getsockopt(sk, optname, optval, optlen);
1082
1083        if (get_user(len, optlen))
1084                return -EFAULT;
1085        if (len < 0)
1086                return -EINVAL;
1087
1088        lock_sock(sk);
1089
1090        switch (optname) {
1091        case IP_OPTIONS:
1092        {
1093                unsigned char optbuf[sizeof(struct ip_options)+40];
1094                struct ip_options *opt = (struct ip_options *)optbuf;
1095                struct ip_options_rcu *inet_opt;
1096
1097                inet_opt = rcu_dereference_protected(inet->inet_opt,
1098                                                     sock_owned_by_user(sk));
1099                opt->optlen = 0;
1100                if (inet_opt)
1101                        memcpy(optbuf, &inet_opt->opt,
1102                               sizeof(struct ip_options) +
1103                               inet_opt->opt.optlen);
1104                release_sock(sk);
1105
1106                if (opt->optlen == 0)
1107                        return put_user(0, optlen);
1108
1109                ip_options_undo(opt);
1110
1111                len = min_t(unsigned int, len, opt->optlen);
1112                if (put_user(len, optlen))
1113                        return -EFAULT;
1114                if (copy_to_user(optval, opt->__data, len))
1115                        return -EFAULT;
1116                return 0;
1117        }
1118        case IP_PKTINFO:
1119                val = (inet->cmsg_flags & IP_CMSG_PKTINFO) != 0;
1120                break;
1121        case IP_RECVTTL:
1122                val = (inet->cmsg_flags & IP_CMSG_TTL) != 0;
1123                break;
1124        case IP_RECVTOS:
1125                val = (inet->cmsg_flags & IP_CMSG_TOS) != 0;
1126                break;
1127        case IP_RECVOPTS:
1128                val = (inet->cmsg_flags & IP_CMSG_RECVOPTS) != 0;
1129                break;
1130        case IP_RETOPTS:
1131                val = (inet->cmsg_flags & IP_CMSG_RETOPTS) != 0;
1132                break;
1133        case IP_PASSSEC:
1134                val = (inet->cmsg_flags & IP_CMSG_PASSSEC) != 0;
1135                break;
1136        case IP_RECVORIGDSTADDR:
1137                val = (inet->cmsg_flags & IP_CMSG_ORIGDSTADDR) != 0;
1138                break;
1139        case IP_TOS:
1140                val = inet->tos;
1141                break;
1142        case IP_TTL:
1143                val = (inet->uc_ttl == -1 ?
1144                       sysctl_ip_default_ttl :
1145                       inet->uc_ttl);
1146                break;
1147        case IP_HDRINCL:
1148                val = inet->hdrincl;
1149                break;
1150        case IP_NODEFRAG:
1151                val = inet->nodefrag;
1152                break;
1153        case IP_MTU_DISCOVER:
1154                val = inet->pmtudisc;
1155                break;
1156        case IP_MTU:
1157        {
1158                struct dst_entry *dst;
1159                val = 0;
1160                dst = sk_dst_get(sk);
1161                if (dst) {
1162                        val = dst_mtu(dst);
1163                        dst_release(dst);
1164                }
1165                if (!val) {
1166                        release_sock(sk);
1167                        return -ENOTCONN;
1168                }
1169                break;
1170        }
1171        case IP_RECVERR:
1172                val = inet->recverr;
1173                break;
1174        case IP_MULTICAST_TTL:
1175                val = inet->mc_ttl;
1176                break;
1177        case IP_MULTICAST_LOOP:
1178                val = inet->mc_loop;
1179                break;
1180        case IP_MULTICAST_IF:
1181        {
1182                struct in_addr addr;
1183                len = min_t(unsigned int, len, sizeof(struct in_addr));
1184                addr.s_addr = inet->mc_addr;
1185                release_sock(sk);
1186
1187                if (put_user(len, optlen))
1188                        return -EFAULT;
1189                if (copy_to_user(optval, &addr, len))
1190                        return -EFAULT;
1191                return 0;
1192        }
1193        case IP_MSFILTER:
1194        {
1195                struct ip_msfilter msf;
1196                int err;
1197
1198                if (len < IP_MSFILTER_SIZE(0)) {
1199                        release_sock(sk);
1200                        return -EINVAL;
1201                }
1202                if (copy_from_user(&msf, optval, IP_MSFILTER_SIZE(0))) {
1203                        release_sock(sk);
1204                        return -EFAULT;
1205                }
1206                err = ip_mc_msfget(sk, &msf,
1207                                   (struct ip_msfilter __user *)optval, optlen);
1208                release_sock(sk);
1209                return err;
1210        }
1211        case MCAST_MSFILTER:
1212        {
1213                struct group_filter gsf;
1214                int err;
1215
1216                if (len < GROUP_FILTER_SIZE(0)) {
1217                        release_sock(sk);
1218                        return -EINVAL;
1219                }
1220                if (copy_from_user(&gsf, optval, GROUP_FILTER_SIZE(0))) {
1221                        release_sock(sk);
1222                        return -EFAULT;
1223                }
1224                err = ip_mc_gsfget(sk, &gsf,
1225                                   (struct group_filter __user *)optval,
1226                                   optlen);
1227                release_sock(sk);
1228                return err;
1229        }
1230        case IP_MULTICAST_ALL:
1231                val = inet->mc_all;
1232                break;
1233        case IP_PKTOPTIONS:
1234        {
1235                struct msghdr msg;
1236
1237                release_sock(sk);
1238
1239                if (sk->sk_type != SOCK_STREAM)
1240                        return -ENOPROTOOPT;
1241
1242                msg.msg_control = optval;
1243                msg.msg_controllen = len;
1244                msg.msg_flags = flags;
1245
1246                if (inet->cmsg_flags & IP_CMSG_PKTINFO) {
1247                        struct in_pktinfo info;
1248
1249                        info.ipi_addr.s_addr = inet->inet_rcv_saddr;
1250                        info.ipi_spec_dst.s_addr = inet->inet_rcv_saddr;
1251                        info.ipi_ifindex = inet->mc_index;
1252                        put_cmsg(&msg, SOL_IP, IP_PKTINFO, sizeof(info), &info);
1253                }
1254                if (inet->cmsg_flags & IP_CMSG_TTL) {
1255                        int hlim = inet->mc_ttl;
1256                        put_cmsg(&msg, SOL_IP, IP_TTL, sizeof(hlim), &hlim);
1257                }
1258                len -= msg.msg_controllen;
1259                return put_user(len, optlen);
1260        }
1261        case IP_FREEBIND:
1262                val = inet->freebind;
1263                break;
1264        case IP_TRANSPARENT:
1265                val = inet->transparent;
1266                break;
1267        case IP_MINTTL:
1268                val = inet->min_ttl;
1269                break;
1270        default:
1271                release_sock(sk);
1272                return -ENOPROTOOPT;
1273        }
1274        release_sock(sk);
1275
1276        if (len < sizeof(int) && len > 0 && val >= 0 && val <= 255) {
1277                unsigned char ucval = (unsigned char)val;
1278                len = 1;
1279                if (put_user(len, optlen))
1280                        return -EFAULT;
1281                if (copy_to_user(optval, &ucval, 1))
1282                        return -EFAULT;
1283        } else {
1284                len = min_t(unsigned int, sizeof(int), len);
1285                if (put_user(len, optlen))
1286                        return -EFAULT;
1287                if (copy_to_user(optval, &val, len))
1288                        return -EFAULT;
1289        }
1290        return 0;
1291}
1292
1293int ip_getsockopt(struct sock *sk, int level,
1294                  int optname, char __user *optval, int __user *optlen)
1295{
1296        int err;
1297
1298        err = do_ip_getsockopt(sk, level, optname, optval, optlen, 0);
1299#ifdef CONFIG_NETFILTER
1300        /* we need to exclude all possible ENOPROTOOPTs except default case */
1301        if (err == -ENOPROTOOPT && optname != IP_PKTOPTIONS &&
1302                        !ip_mroute_opt(optname)) {
1303                int len;
1304
1305                if (get_user(len, optlen))
1306                        return -EFAULT;
1307
1308                lock_sock(sk);
1309                err = nf_getsockopt(sk, PF_INET, optname, optval,
1310                                &len);
1311                release_sock(sk);
1312                if (err >= 0)
1313                        err = put_user(len, optlen);
1314                return err;
1315        }
1316#endif
1317        return err;
1318}
1319EXPORT_SYMBOL(ip_getsockopt);
1320
1321#ifdef CONFIG_COMPAT
1322int compat_ip_getsockopt(struct sock *sk, int level, int optname,
1323                         char __user *optval, int __user *optlen)
1324{
1325        int err;
1326
1327        if (optname == MCAST_MSFILTER)
1328                return compat_mc_getsockopt(sk, level, optname, optval, optlen,
1329                        ip_getsockopt);
1330
1331        err = do_ip_getsockopt(sk, level, optname, optval, optlen,
1332                MSG_CMSG_COMPAT);
1333
1334#ifdef CONFIG_NETFILTER
1335        /* we need to exclude all possible ENOPROTOOPTs except default case */
1336        if (err == -ENOPROTOOPT && optname != IP_PKTOPTIONS &&
1337                        !ip_mroute_opt(optname)) {
1338                int len;
1339
1340                if (get_user(len, optlen))
1341                        return -EFAULT;
1342
1343                lock_sock(sk);
1344                err = compat_nf_getsockopt(sk, PF_INET, optname, optval, &len);
1345                release_sock(sk);
1346                if (err >= 0)
1347                        err = put_user(len, optlen);
1348                return err;
1349        }
1350#endif
1351        return err;
1352}
1353EXPORT_SYMBOL(compat_ip_getsockopt);
1354#endif
1355