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,
 146                               sizeof(ifr->ifr_hwaddr.sa_data));
 147                else
 148                        memcpy(ifr->ifr_hwaddr.sa_data, dev->dev_addr,
 149                               min(sizeof(ifr->ifr_hwaddr.sa_data),
 150                                   (size_t)dev->addr_len));
 151                ifr->ifr_hwaddr.sa_family = dev->type;
 152                return 0;
 153
 154        case SIOCGIFSLAVE:
 155                err = -EINVAL;
 156                break;
 157
 158        case SIOCGIFMAP:
 159                ifr->ifr_map.mem_start = dev->mem_start;
 160                ifr->ifr_map.mem_end   = dev->mem_end;
 161                ifr->ifr_map.base_addr = dev->base_addr;
 162                ifr->ifr_map.irq       = dev->irq;
 163                ifr->ifr_map.dma       = dev->dma;
 164                ifr->ifr_map.port      = dev->if_port;
 165                return 0;
 166
 167        case SIOCGIFINDEX:
 168                ifr->ifr_ifindex = dev->ifindex;
 169                return 0;
 170
 171        case SIOCGIFTXQLEN:
 172                ifr->ifr_qlen = dev->tx_queue_len;
 173                return 0;
 174
 175        default:
 176                /* dev_ioctl() should ensure this case
 177                 * is never reached
 178                 */
 179                WARN_ON(1);
 180                err = -ENOTTY;
 181                break;
 182
 183        }
 184        return err;
 185}
 186
 187static int net_hwtstamp_validate(struct ifreq *ifr)
 188{
 189        struct hwtstamp_config cfg;
 190        enum hwtstamp_tx_types tx_type;
 191        enum hwtstamp_rx_filters rx_filter;
 192        int tx_type_valid = 0;
 193        int rx_filter_valid = 0;
 194
 195        if (copy_from_user(&cfg, ifr->ifr_data, sizeof(cfg)))
 196                return -EFAULT;
 197
 198        if (cfg.flags) /* reserved for future extensions */
 199                return -EINVAL;
 200
 201        tx_type = cfg.tx_type;
 202        rx_filter = cfg.rx_filter;
 203
 204        switch (tx_type) {
 205        case HWTSTAMP_TX_OFF:
 206        case HWTSTAMP_TX_ON:
 207        case HWTSTAMP_TX_ONESTEP_SYNC:
 208                tx_type_valid = 1;
 209                break;
 210        }
 211
 212        switch (rx_filter) {
 213        case HWTSTAMP_FILTER_NONE:
 214        case HWTSTAMP_FILTER_ALL:
 215        case HWTSTAMP_FILTER_SOME:
 216        case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
 217        case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
 218        case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
 219        case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
 220        case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
 221        case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
 222        case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
 223        case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
 224        case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
 225        case HWTSTAMP_FILTER_PTP_V2_EVENT:
 226        case HWTSTAMP_FILTER_PTP_V2_SYNC:
 227        case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
 228                rx_filter_valid = 1;
 229                break;
 230        }
 231
 232        if (!tx_type_valid || !rx_filter_valid)
 233                return -ERANGE;
 234
 235        return 0;
 236}
 237
 238/*
 239 *      Perform the SIOCxIFxxx calls, inside rtnl_lock()
 240 */
 241static int dev_ifsioc(struct net *net, struct ifreq *ifr, unsigned int cmd)
 242{
 243        int err;
 244        struct net_device *dev = __dev_get_by_name(net, ifr->ifr_name);
 245        const struct net_device_ops *ops;
 246
 247        if (!dev)
 248                return -ENODEV;
 249
 250        ops = dev->netdev_ops;
 251
 252        switch (cmd) {
 253        case SIOCSIFFLAGS:      /* Set interface flags */
 254                return dev_change_flags(dev, ifr->ifr_flags);
 255
 256        case SIOCSIFMETRIC:     /* Set the metric on the interface
 257                                   (currently unused) */
 258                return -EOPNOTSUPP;
 259
 260        case SIOCSIFMTU:        /* Set the MTU of a device */
 261                return dev_set_mtu(dev, ifr->ifr_mtu);
 262
 263        case SIOCSIFHWADDR:
 264                return dev_set_mac_address(dev, &ifr->ifr_hwaddr);
 265
 266        case SIOCSIFHWBROADCAST:
 267                if (ifr->ifr_hwaddr.sa_family != dev->type)
 268                        return -EINVAL;
 269                memcpy(dev->broadcast, ifr->ifr_hwaddr.sa_data,
 270                       min(sizeof(ifr->ifr_hwaddr.sa_data),
 271                           (size_t)dev->addr_len));
 272                call_netdevice_notifiers(NETDEV_CHANGEADDR, dev);
 273                return 0;
 274
 275        case SIOCSIFMAP:
 276                if (ops->ndo_set_config) {
 277                        if (!netif_device_present(dev))
 278                                return -ENODEV;
 279                        return ops->ndo_set_config(dev, &ifr->ifr_map);
 280                }
 281                return -EOPNOTSUPP;
 282
 283        case SIOCADDMULTI:
 284                if (!ops->ndo_set_rx_mode ||
 285                    ifr->ifr_hwaddr.sa_family != AF_UNSPEC)
 286                        return -EINVAL;
 287                if (!netif_device_present(dev))
 288                        return -ENODEV;
 289                return dev_mc_add_global(dev, ifr->ifr_hwaddr.sa_data);
 290
 291        case SIOCDELMULTI:
 292                if (!ops->ndo_set_rx_mode ||
 293                    ifr->ifr_hwaddr.sa_family != AF_UNSPEC)
 294                        return -EINVAL;
 295                if (!netif_device_present(dev))
 296                        return -ENODEV;
 297                return dev_mc_del_global(dev, ifr->ifr_hwaddr.sa_data);
 298
 299        case SIOCSIFTXQLEN:
 300                if (ifr->ifr_qlen < 0)
 301                        return -EINVAL;
 302                dev->tx_queue_len = ifr->ifr_qlen;
 303                return 0;
 304
 305        case SIOCSIFNAME:
 306                ifr->ifr_newname[IFNAMSIZ-1] = '\0';
 307                return dev_change_name(dev, ifr->ifr_newname);
 308
 309        case SIOCSHWTSTAMP:
 310                err = net_hwtstamp_validate(ifr);
 311                if (err)
 312                        return err;
 313                /* fall through */
 314
 315        /*
 316         *      Unknown or private ioctl
 317         */
 318        default:
 319                if ((cmd >= SIOCDEVPRIVATE &&
 320                    cmd <= SIOCDEVPRIVATE + 15) ||
 321                    cmd == SIOCBONDENSLAVE ||
 322                    cmd == SIOCBONDRELEASE ||
 323                    cmd == SIOCBONDSETHWADDR ||
 324                    cmd == SIOCBONDSLAVEINFOQUERY ||
 325                    cmd == SIOCBONDINFOQUERY ||
 326                    cmd == SIOCBONDCHANGEACTIVE ||
 327                    cmd == SIOCGMIIPHY ||
 328                    cmd == SIOCGMIIREG ||
 329                    cmd == SIOCSMIIREG ||
 330                    cmd == SIOCBRADDIF ||
 331                    cmd == SIOCBRDELIF ||
 332                    cmd == SIOCSHWTSTAMP ||
 333                    cmd == SIOCGHWTSTAMP ||
 334                    cmd == SIOCWANDEV) {
 335                        err = -EOPNOTSUPP;
 336                        if (ops->ndo_do_ioctl) {
 337                                if (netif_device_present(dev))
 338                                        err = ops->ndo_do_ioctl(dev, ifr, cmd);
 339                                else
 340                                        err = -ENODEV;
 341                        }
 342                } else
 343                        err = -EINVAL;
 344
 345        }
 346        return err;
 347}
 348
 349/**
 350 *      dev_load        - load a network module
 351 *      @net: the applicable net namespace
 352 *      @name: name of interface
 353 *
 354 *      If a network interface is not present and the process has suitable
 355 *      privileges this function loads the module. If module loading is not
 356 *      available in this kernel then it becomes a nop.
 357 */
 358
 359void dev_load(struct net *net, const char *name)
 360{
 361        struct net_device *dev;
 362        int no_module;
 363
 364        rcu_read_lock();
 365        dev = dev_get_by_name_rcu(net, name);
 366        rcu_read_unlock();
 367
 368        no_module = !dev;
 369        if (no_module && capable(CAP_NET_ADMIN))
 370                no_module = request_module("netdev-%s", name);
 371        if (no_module && capable(CAP_SYS_MODULE))
 372                request_module("%s", name);
 373}
 374EXPORT_SYMBOL(dev_load);
 375
 376/*
 377 *      This function handles all "interface"-type I/O control requests. The actual
 378 *      'doing' part of this is dev_ifsioc above.
 379 */
 380
 381/**
 382 *      dev_ioctl       -       network device ioctl
 383 *      @net: the applicable net namespace
 384 *      @cmd: command to issue
 385 *      @arg: pointer to a struct ifreq in user space
 386 *
 387 *      Issue ioctl functions to devices. This is normally called by the
 388 *      user space syscall interfaces but can sometimes be useful for
 389 *      other purposes. The return value is the return from the syscall if
 390 *      positive or a negative errno code on error.
 391 */
 392
 393int dev_ioctl(struct net *net, unsigned int cmd, void __user *arg)
 394{
 395        struct ifreq ifr;
 396        int ret;
 397        char *colon;
 398
 399        /* One special case: SIOCGIFCONF takes ifconf argument
 400           and requires shared lock, because it sleeps writing
 401           to user space.
 402         */
 403
 404        if (cmd == SIOCGIFCONF) {
 405                rtnl_lock();
 406                ret = dev_ifconf(net, (char __user *) arg);
 407                rtnl_unlock();
 408                return ret;
 409        }
 410        if (cmd == SIOCGIFNAME)
 411                return dev_ifname(net, (struct ifreq __user *)arg);
 412
 413        if (copy_from_user(&ifr, arg, sizeof(struct ifreq)))
 414                return -EFAULT;
 415
 416        ifr.ifr_name[IFNAMSIZ-1] = 0;
 417
 418        colon = strchr(ifr.ifr_name, ':');
 419        if (colon)
 420                *colon = 0;
 421
 422        /*
 423         *      See which interface the caller is talking about.
 424         */
 425
 426        switch (cmd) {
 427        /*
 428         *      These ioctl calls:
 429         *      - can be done by all.
 430         *      - atomic and do not require locking.
 431         *      - return a value
 432         */
 433        case SIOCGIFFLAGS:
 434        case SIOCGIFMETRIC:
 435        case SIOCGIFMTU:
 436        case SIOCGIFHWADDR:
 437        case SIOCGIFSLAVE:
 438        case SIOCGIFMAP:
 439        case SIOCGIFINDEX:
 440        case SIOCGIFTXQLEN:
 441                dev_load(net, ifr.ifr_name);
 442                rcu_read_lock();
 443                ret = dev_ifsioc_locked(net, &ifr, cmd);
 444                rcu_read_unlock();
 445                if (!ret) {
 446                        if (colon)
 447                                *colon = ':';
 448                        if (copy_to_user(arg, &ifr,
 449                                         sizeof(struct ifreq)))
 450                                ret = -EFAULT;
 451                }
 452                return ret;
 453
 454        case SIOCETHTOOL:
 455                dev_load(net, ifr.ifr_name);
 456                rtnl_lock();
 457                ret = dev_ethtool(net, &ifr);
 458                rtnl_unlock();
 459                if (!ret) {
 460                        if (colon)
 461                                *colon = ':';
 462                        if (copy_to_user(arg, &ifr,
 463                                         sizeof(struct ifreq)))
 464                                ret = -EFAULT;
 465                }
 466                return ret;
 467
 468        /*
 469         *      These ioctl calls:
 470         *      - require superuser power.
 471         *      - require strict serialization.
 472         *      - return a value
 473         */
 474        case SIOCGMIIPHY:
 475        case SIOCGMIIREG:
 476        case SIOCSIFNAME:
 477                if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
 478                        return -EPERM;
 479                dev_load(net, ifr.ifr_name);
 480                rtnl_lock();
 481                ret = dev_ifsioc(net, &ifr, cmd);
 482                rtnl_unlock();
 483                if (!ret) {
 484                        if (colon)
 485                                *colon = ':';
 486                        if (copy_to_user(arg, &ifr,
 487                                         sizeof(struct ifreq)))
 488                                ret = -EFAULT;
 489                }
 490                return ret;
 491
 492        /*
 493         *      These ioctl calls:
 494         *      - require superuser power.
 495         *      - require strict serialization.
 496         *      - do not return a value
 497         */
 498        case SIOCSIFMAP:
 499        case SIOCSIFTXQLEN:
 500                if (!capable(CAP_NET_ADMIN))
 501                        return -EPERM;
 502                /* fall through */
 503        /*
 504         *      These ioctl calls:
 505         *      - require local superuser power.
 506         *      - require strict serialization.
 507         *      - do not return a value
 508         */
 509        case SIOCSIFFLAGS:
 510        case SIOCSIFMETRIC:
 511        case SIOCSIFMTU:
 512        case SIOCSIFHWADDR:
 513        case SIOCSIFSLAVE:
 514        case SIOCADDMULTI:
 515        case SIOCDELMULTI:
 516        case SIOCSIFHWBROADCAST:
 517        case SIOCSMIIREG:
 518        case SIOCBONDENSLAVE:
 519        case SIOCBONDRELEASE:
 520        case SIOCBONDSETHWADDR:
 521        case SIOCBONDCHANGEACTIVE:
 522        case SIOCBRADDIF:
 523        case SIOCBRDELIF:
 524        case SIOCSHWTSTAMP:
 525                if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
 526                        return -EPERM;
 527                /* fall through */
 528        case SIOCBONDSLAVEINFOQUERY:
 529        case SIOCBONDINFOQUERY:
 530                dev_load(net, ifr.ifr_name);
 531                rtnl_lock();
 532                ret = dev_ifsioc(net, &ifr, cmd);
 533                rtnl_unlock();
 534                return ret;
 535
 536        case SIOCGIFMEM:
 537                /* Get the per device memory space. We can add this but
 538                 * currently do not support it */
 539        case SIOCSIFMEM:
 540                /* Set the per device memory buffer space.
 541                 * Not applicable in our case */
 542        case SIOCSIFLINK:
 543                return -ENOTTY;
 544
 545        /*
 546         *      Unknown or private ioctl.
 547         */
 548        default:
 549                if (cmd == SIOCWANDEV ||
 550                    cmd == SIOCGHWTSTAMP ||
 551                    (cmd >= SIOCDEVPRIVATE &&
 552                     cmd <= SIOCDEVPRIVATE + 15)) {
 553                        dev_load(net, ifr.ifr_name);
 554                        rtnl_lock();
 555                        ret = dev_ifsioc(net, &ifr, cmd);
 556                        rtnl_unlock();
 557                        if (!ret && copy_to_user(arg, &ifr,
 558                                                 sizeof(struct ifreq)))
 559                                ret = -EFAULT;
 560                        return ret;
 561                }
 562                /* Take care of Wireless Extensions */
 563                if (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST)
 564                        return wext_handle_ioctl(net, &ifr, cmd, arg);
 565                return -ENOTTY;
 566        }
 567}
 568