linux/net/core/dev_ioctl.c
<<
>>
Prefs
   1#include <linux/kmod.h>
   2#include <linux/netdevice.h>
   3#include <linux/etherdevice.h>
   4#include <linux/rtnetlink.h>
   5#include <linux/net_tstamp.h>
   6#include <linux/wireless.h>
   7#include <net/wext.h>
   8
   9/*
  10 *      Map an interface index to its name (SIOCGIFNAME)
  11 */
  12
  13/*
  14 *      We need this ioctl for efficient implementation of the
  15 *      if_indextoname() function required by the IPv6 API.  Without
  16 *      it, we would have to search all the interfaces to find a
  17 *      match.  --pb
  18 */
  19
  20static int dev_ifname(struct net *net, struct ifreq __user *arg)
  21{
  22        struct ifreq ifr;
  23        int error;
  24
  25        /*
  26         *      Fetch the caller's info block.
  27         */
  28
  29        if (copy_from_user(&ifr, arg, sizeof(struct ifreq)))
  30                return -EFAULT;
  31
  32        error = netdev_get_name(net, ifr.ifr_name, ifr.ifr_ifindex);
  33        if (error)
  34                return error;
  35
  36        if (copy_to_user(arg, &ifr, sizeof(struct ifreq)))
  37                return -EFAULT;
  38        return 0;
  39}
  40
  41static gifconf_func_t *gifconf_list[NPROTO];
  42
  43/**
  44 *      register_gifconf        -       register a SIOCGIF handler
  45 *      @family: Address family
  46 *      @gifconf: Function handler
  47 *
  48 *      Register protocol dependent address dumping routines. The handler
  49 *      that is passed must not be freed or reused until it has been replaced
  50 *      by another handler.
  51 */
  52int register_gifconf(unsigned int family, gifconf_func_t *gifconf)
  53{
  54        if (family >= NPROTO)
  55                return -EINVAL;
  56        gifconf_list[family] = gifconf;
  57        return 0;
  58}
  59EXPORT_SYMBOL(register_gifconf);
  60
  61/*
  62 *      Perform a SIOCGIFCONF call. This structure will change
  63 *      size eventually, and there is nothing I can do about it.
  64 *      Thus we will need a 'compatibility mode'.
  65 */
  66
  67static int dev_ifconf(struct net *net, char __user *arg)
  68{
  69        struct ifconf ifc;
  70        struct net_device *dev;
  71        char __user *pos;
  72        int len;
  73        int total;
  74        int i;
  75
  76        /*
  77         *      Fetch the caller's info block.
  78         */
  79
  80        if (copy_from_user(&ifc, arg, sizeof(struct ifconf)))
  81                return -EFAULT;
  82
  83        pos = ifc.ifc_buf;
  84        len = ifc.ifc_len;
  85
  86        /*
  87         *      Loop over the interfaces, and write an info block for each.
  88         */
  89
  90        total = 0;
  91        for_each_netdev(net, dev) {
  92                for (i = 0; i < NPROTO; i++) {
  93                        if (gifconf_list[i]) {
  94                                int done;
  95                                if (!pos)
  96                                        done = gifconf_list[i](dev, NULL, 0);
  97                                else
  98                                        done = gifconf_list[i](dev, pos + total,
  99                                                               len - total);
 100                                if (done < 0)
 101                                        return -EFAULT;
 102                                total += done;
 103                        }
 104                }
 105        }
 106
 107        /*
 108         *      All done.  Write the updated control block back to the caller.
 109         */
 110        ifc.ifc_len = total;
 111
 112        /*
 113         *      Both BSD and Solaris return 0 here, so we do too.
 114         */
 115        return copy_to_user(arg, &ifc, sizeof(struct ifconf)) ? -EFAULT : 0;
 116}
 117
 118/*
 119 *      Perform the SIOCxIFxxx calls, inside rcu_read_lock()
 120 */
 121static int dev_ifsioc_locked(struct net *net, struct ifreq *ifr, unsigned int cmd)
 122{
 123        int err;
 124        struct net_device *dev = dev_get_by_name_rcu(net, ifr->ifr_name);
 125
 126        if (!dev)
 127                return -ENODEV;
 128
 129        switch (cmd) {
 130        case SIOCGIFFLAGS:      /* Get interface flags */
 131                ifr->ifr_flags = (short) dev_get_flags(dev);
 132                return 0;
 133
 134        case SIOCGIFMETRIC:     /* Get the metric on the interface
 135                                   (currently unused) */
 136                ifr->ifr_metric = 0;
 137                return 0;
 138
 139        case SIOCGIFMTU:        /* Get the MTU of a device */
 140                ifr->ifr_mtu = dev->mtu;
 141                return 0;
 142
 143        case SIOCGIFHWADDR:
 144                if (!dev->addr_len)
 145                        memset(ifr->ifr_hwaddr.sa_data, 0, sizeof ifr->ifr_hwaddr.sa_data);
 146                else
 147                        memcpy(ifr->ifr_hwaddr.sa_data, dev->dev_addr,
 148                               min(sizeof ifr->ifr_hwaddr.sa_data, (size_t) dev->addr_len));
 149                ifr->ifr_hwaddr.sa_family = dev->type;
 150                return 0;
 151
 152        case SIOCGIFSLAVE:
 153                err = -EINVAL;
 154                break;
 155
 156        case SIOCGIFMAP:
 157                ifr->ifr_map.mem_start = dev->mem_start;
 158                ifr->ifr_map.mem_end   = dev->mem_end;
 159                ifr->ifr_map.base_addr = dev->base_addr;
 160                ifr->ifr_map.irq       = dev->irq;
 161                ifr->ifr_map.dma       = dev->dma;
 162                ifr->ifr_map.port      = dev->if_port;
 163                return 0;
 164
 165        case SIOCGIFINDEX:
 166                ifr->ifr_ifindex = dev->ifindex;
 167                return 0;
 168
 169        case SIOCGIFTXQLEN:
 170                ifr->ifr_qlen = dev->tx_queue_len;
 171                return 0;
 172
 173        default:
 174                /* dev_ioctl() should ensure this case
 175                 * is never reached
 176                 */
 177                WARN_ON(1);
 178                err = -ENOTTY;
 179                break;
 180
 181        }
 182        return err;
 183}
 184
 185static int net_hwtstamp_validate(struct ifreq *ifr)
 186{
 187        struct hwtstamp_config cfg;
 188        enum hwtstamp_tx_types tx_type;
 189        enum hwtstamp_rx_filters rx_filter;
 190        int tx_type_valid = 0;
 191        int rx_filter_valid = 0;
 192
 193        if (copy_from_user(&cfg, ifr->ifr_data, sizeof(cfg)))
 194                return -EFAULT;
 195
 196        if (cfg.flags) /* reserved for future extensions */
 197                return -EINVAL;
 198
 199        tx_type = cfg.tx_type;
 200        rx_filter = cfg.rx_filter;
 201
 202        switch (tx_type) {
 203        case HWTSTAMP_TX_OFF:
 204        case HWTSTAMP_TX_ON:
 205        case HWTSTAMP_TX_ONESTEP_SYNC:
 206                tx_type_valid = 1;
 207                break;
 208        }
 209
 210        switch (rx_filter) {
 211        case HWTSTAMP_FILTER_NONE:
 212        case HWTSTAMP_FILTER_ALL:
 213        case HWTSTAMP_FILTER_SOME:
 214        case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
 215        case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
 216        case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
 217        case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
 218        case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
 219        case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
 220        case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
 221        case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
 222        case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
 223        case HWTSTAMP_FILTER_PTP_V2_EVENT:
 224        case HWTSTAMP_FILTER_PTP_V2_SYNC:
 225        case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
 226                rx_filter_valid = 1;
 227                break;
 228        }
 229
 230        if (!tx_type_valid || !rx_filter_valid)
 231                return -ERANGE;
 232
 233        return 0;
 234}
 235
 236/*
 237 *      Perform the SIOCxIFxxx calls, inside rtnl_lock()
 238 */
 239static int dev_ifsioc(struct net *net, struct ifreq *ifr, unsigned int cmd)
 240{
 241        int err;
 242        struct net_device *dev = __dev_get_by_name(net, ifr->ifr_name);
 243        const struct net_device_ops *ops;
 244
 245        if (!dev)
 246                return -ENODEV;
 247
 248        ops = dev->netdev_ops;
 249
 250        switch (cmd) {
 251        case SIOCSIFFLAGS:      /* Set interface flags */
 252                return dev_change_flags(dev, ifr->ifr_flags);
 253
 254        case SIOCSIFMETRIC:     /* Set the metric on the interface
 255                                   (currently unused) */
 256                return -EOPNOTSUPP;
 257
 258        case SIOCSIFMTU:        /* Set the MTU of a device */
 259                return dev_set_mtu(dev, ifr->ifr_mtu);
 260
 261        case SIOCSIFHWADDR:
 262                return dev_set_mac_address(dev, &ifr->ifr_hwaddr);
 263
 264        case SIOCSIFHWBROADCAST:
 265                if (ifr->ifr_hwaddr.sa_family != dev->type)
 266                        return -EINVAL;
 267                memcpy(dev->broadcast, ifr->ifr_hwaddr.sa_data,
 268                       min(sizeof ifr->ifr_hwaddr.sa_data, (size_t) dev->addr_len));
 269                call_netdevice_notifiers(NETDEV_CHANGEADDR, dev);
 270                return 0;
 271
 272        case SIOCSIFMAP:
 273                if (ops->ndo_set_config) {
 274                        if (!netif_device_present(dev))
 275                                return -ENODEV;
 276                        return ops->ndo_set_config(dev, &ifr->ifr_map);
 277                }
 278                return -EOPNOTSUPP;
 279
 280        case SIOCADDMULTI:
 281                if (!ops->ndo_set_rx_mode ||
 282                    ifr->ifr_hwaddr.sa_family != AF_UNSPEC)
 283                        return -EINVAL;
 284                if (!netif_device_present(dev))
 285                        return -ENODEV;
 286                return dev_mc_add_global(dev, ifr->ifr_hwaddr.sa_data);
 287
 288        case SIOCDELMULTI:
 289                if (!ops->ndo_set_rx_mode ||
 290                    ifr->ifr_hwaddr.sa_family != AF_UNSPEC)
 291                        return -EINVAL;
 292                if (!netif_device_present(dev))
 293                        return -ENODEV;
 294                return dev_mc_del_global(dev, ifr->ifr_hwaddr.sa_data);
 295
 296        case SIOCSIFTXQLEN:
 297                if (ifr->ifr_qlen < 0)
 298                        return -EINVAL;
 299                dev->tx_queue_len = ifr->ifr_qlen;
 300                return 0;
 301
 302        case SIOCSIFNAME:
 303                ifr->ifr_newname[IFNAMSIZ-1] = '\0';
 304                return dev_change_name(dev, ifr->ifr_newname);
 305
 306        case SIOCSHWTSTAMP:
 307                err = net_hwtstamp_validate(ifr);
 308                if (err)
 309                        return err;
 310                /* fall through */
 311
 312        /*
 313         *      Unknown or private ioctl
 314         */
 315        default:
 316                if ((cmd >= SIOCDEVPRIVATE &&
 317                    cmd <= SIOCDEVPRIVATE + 15) ||
 318                    cmd == SIOCBONDENSLAVE ||
 319                    cmd == SIOCBONDRELEASE ||
 320                    cmd == SIOCBONDSETHWADDR ||
 321                    cmd == SIOCBONDSLAVEINFOQUERY ||
 322                    cmd == SIOCBONDINFOQUERY ||
 323                    cmd == SIOCBONDCHANGEACTIVE ||
 324                    cmd == SIOCGMIIPHY ||
 325                    cmd == SIOCGMIIREG ||
 326                    cmd == SIOCSMIIREG ||
 327                    cmd == SIOCBRADDIF ||
 328                    cmd == SIOCBRDELIF ||
 329                    cmd == SIOCSHWTSTAMP ||
 330                    cmd == SIOCWANDEV) {
 331                        err = -EOPNOTSUPP;
 332                        if (ops->ndo_do_ioctl) {
 333                                if (netif_device_present(dev))
 334                                        err = ops->ndo_do_ioctl(dev, ifr, cmd);
 335                                else
 336                                        err = -ENODEV;
 337                        }
 338                } else
 339                        err = -EINVAL;
 340
 341        }
 342        return err;
 343}
 344
 345/**
 346 *      dev_load        - load a network module
 347 *      @net: the applicable net namespace
 348 *      @name: name of interface
 349 *
 350 *      If a network interface is not present and the process has suitable
 351 *      privileges this function loads the module. If module loading is not
 352 *      available in this kernel then it becomes a nop.
 353 */
 354
 355void dev_load(struct net *net, const char *name)
 356{
 357        struct net_device *dev;
 358        int no_module;
 359
 360        rcu_read_lock();
 361        dev = dev_get_by_name_rcu(net, name);
 362        rcu_read_unlock();
 363
 364        no_module = !dev;
 365        if (no_module && capable(CAP_NET_ADMIN))
 366                no_module = request_module("netdev-%s", name);
 367        if (no_module && capable(CAP_SYS_MODULE)) {
 368                if (!request_module("%s", name))
 369                        pr_warn("Loading kernel module for a network device with CAP_SYS_MODULE (deprecated).  Use CAP_NET_ADMIN and alias netdev-%s instead.\n",
 370                                name);
 371        }
 372}
 373EXPORT_SYMBOL(dev_load);
 374
 375/*
 376 *      This function handles all "interface"-type I/O control requests. The actual
 377 *      'doing' part of this is dev_ifsioc above.
 378 */
 379
 380/**
 381 *      dev_ioctl       -       network device ioctl
 382 *      @net: the applicable net namespace
 383 *      @cmd: command to issue
 384 *      @arg: pointer to a struct ifreq in user space
 385 *
 386 *      Issue ioctl functions to devices. This is normally called by the
 387 *      user space syscall interfaces but can sometimes be useful for
 388 *      other purposes. The return value is the return from the syscall if
 389 *      positive or a negative errno code on error.
 390 */
 391
 392int dev_ioctl(struct net *net, unsigned int cmd, void __user *arg)
 393{
 394        struct ifreq ifr;
 395        int ret;
 396        char *colon;
 397
 398        /* One special case: SIOCGIFCONF takes ifconf argument
 399           and requires shared lock, because it sleeps writing
 400           to user space.
 401         */
 402
 403        if (cmd == SIOCGIFCONF) {
 404                rtnl_lock();
 405                ret = dev_ifconf(net, (char __user *) arg);
 406                rtnl_unlock();
 407                return ret;
 408        }
 409        if (cmd == SIOCGIFNAME)
 410                return dev_ifname(net, (struct ifreq __user *)arg);
 411
 412        if (copy_from_user(&ifr, arg, sizeof(struct ifreq)))
 413                return -EFAULT;
 414
 415        ifr.ifr_name[IFNAMSIZ-1] = 0;
 416
 417        colon = strchr(ifr.ifr_name, ':');
 418        if (colon)
 419                *colon = 0;
 420
 421        /*
 422         *      See which interface the caller is talking about.
 423         */
 424
 425        switch (cmd) {
 426        /*
 427         *      These ioctl calls:
 428         *      - can be done by all.
 429         *      - atomic and do not require locking.
 430         *      - return a value
 431         */
 432        case SIOCGIFFLAGS:
 433        case SIOCGIFMETRIC:
 434        case SIOCGIFMTU:
 435        case SIOCGIFHWADDR:
 436        case SIOCGIFSLAVE:
 437        case SIOCGIFMAP:
 438        case SIOCGIFINDEX:
 439        case SIOCGIFTXQLEN:
 440                dev_load(net, ifr.ifr_name);
 441                rcu_read_lock();
 442                ret = dev_ifsioc_locked(net, &ifr, cmd);
 443                rcu_read_unlock();
 444                if (!ret) {
 445                        if (colon)
 446                                *colon = ':';
 447                        if (copy_to_user(arg, &ifr,
 448                                         sizeof(struct ifreq)))
 449                                ret = -EFAULT;
 450                }
 451                return ret;
 452
 453        case SIOCETHTOOL:
 454                dev_load(net, ifr.ifr_name);
 455                rtnl_lock();
 456                ret = dev_ethtool(net, &ifr);
 457                rtnl_unlock();
 458                if (!ret) {
 459                        if (colon)
 460                                *colon = ':';
 461                        if (copy_to_user(arg, &ifr,
 462                                         sizeof(struct ifreq)))
 463                                ret = -EFAULT;
 464                }
 465                return ret;
 466
 467        /*
 468         *      These ioctl calls:
 469         *      - require superuser power.
 470         *      - require strict serialization.
 471         *      - return a value
 472         */
 473        case SIOCGMIIPHY:
 474        case SIOCGMIIREG:
 475        case SIOCSIFNAME:
 476                if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
 477                        return -EPERM;
 478                dev_load(net, ifr.ifr_name);
 479                rtnl_lock();
 480                ret = dev_ifsioc(net, &ifr, cmd);
 481                rtnl_unlock();
 482                if (!ret) {
 483                        if (colon)
 484                                *colon = ':';
 485                        if (copy_to_user(arg, &ifr,
 486                                         sizeof(struct ifreq)))
 487                                ret = -EFAULT;
 488                }
 489                return ret;
 490
 491        /*
 492         *      These ioctl calls:
 493         *      - require superuser power.
 494         *      - require strict serialization.
 495         *      - do not return a value
 496         */
 497        case SIOCSIFMAP:
 498        case SIOCSIFTXQLEN:
 499                if (!capable(CAP_NET_ADMIN))
 500                        return -EPERM;
 501                /* fall through */
 502        /*
 503         *      These ioctl calls:
 504         *      - require local superuser power.
 505         *      - require strict serialization.
 506         *      - do not return a value
 507         */
 508        case SIOCSIFFLAGS:
 509        case SIOCSIFMETRIC:
 510        case SIOCSIFMTU:
 511        case SIOCSIFHWADDR:
 512        case SIOCSIFSLAVE:
 513        case SIOCADDMULTI:
 514        case SIOCDELMULTI:
 515        case SIOCSIFHWBROADCAST:
 516        case SIOCSMIIREG:
 517        case SIOCBONDENSLAVE:
 518        case SIOCBONDRELEASE:
 519        case SIOCBONDSETHWADDR:
 520        case SIOCBONDCHANGEACTIVE:
 521        case SIOCBRADDIF:
 522        case SIOCBRDELIF:
 523        case SIOCSHWTSTAMP:
 524                if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
 525                        return -EPERM;
 526                /* fall through */
 527        case SIOCBONDSLAVEINFOQUERY:
 528        case SIOCBONDINFOQUERY:
 529                dev_load(net, ifr.ifr_name);
 530                rtnl_lock();
 531                ret = dev_ifsioc(net, &ifr, cmd);
 532                rtnl_unlock();
 533                return ret;
 534
 535        case SIOCGIFMEM:
 536                /* Get the per device memory space. We can add this but
 537                 * currently do not support it */
 538        case SIOCSIFMEM:
 539                /* Set the per device memory buffer space.
 540                 * Not applicable in our case */
 541        case SIOCSIFLINK:
 542                return -ENOTTY;
 543
 544        /*
 545         *      Unknown or private ioctl.
 546         */
 547        default:
 548                if (cmd == SIOCWANDEV ||
 549                    (cmd >= SIOCDEVPRIVATE &&
 550                     cmd <= SIOCDEVPRIVATE + 15)) {
 551                        dev_load(net, ifr.ifr_name);
 552                        rtnl_lock();
 553                        ret = dev_ifsioc(net, &ifr, cmd);
 554                        rtnl_unlock();
 555                        if (!ret && copy_to_user(arg, &ifr,
 556                                                 sizeof(struct ifreq)))
 557                                ret = -EFAULT;
 558                        return ret;
 559                }
 560                /* Take care of Wireless Extensions */
 561                if (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST)
 562                        return wext_handle_ioctl(net, &ifr, cmd, arg);
 563                return -ENOTTY;
 564        }
 565}
 566