196b45cbd956ce83908378d87d009b05645353f22Cong Wang#include <linux/kmod.h> 296b45cbd956ce83908378d87d009b05645353f22Cong Wang#include <linux/netdevice.h> 396b45cbd956ce83908378d87d009b05645353f22Cong Wang#include <linux/etherdevice.h> 496b45cbd956ce83908378d87d009b05645353f22Cong Wang#include <linux/rtnetlink.h> 596b45cbd956ce83908378d87d009b05645353f22Cong Wang#include <linux/net_tstamp.h> 696b45cbd956ce83908378d87d009b05645353f22Cong Wang#include <linux/wireless.h> 796b45cbd956ce83908378d87d009b05645353f22Cong Wang#include <net/wext.h> 896b45cbd956ce83908378d87d009b05645353f22Cong Wang 996b45cbd956ce83908378d87d009b05645353f22Cong Wang/* 1096b45cbd956ce83908378d87d009b05645353f22Cong Wang * Map an interface index to its name (SIOCGIFNAME) 1196b45cbd956ce83908378d87d009b05645353f22Cong Wang */ 1296b45cbd956ce83908378d87d009b05645353f22Cong Wang 1396b45cbd956ce83908378d87d009b05645353f22Cong Wang/* 1496b45cbd956ce83908378d87d009b05645353f22Cong Wang * We need this ioctl for efficient implementation of the 1596b45cbd956ce83908378d87d009b05645353f22Cong Wang * if_indextoname() function required by the IPv6 API. Without 1696b45cbd956ce83908378d87d009b05645353f22Cong Wang * it, we would have to search all the interfaces to find a 1796b45cbd956ce83908378d87d009b05645353f22Cong Wang * match. --pb 1896b45cbd956ce83908378d87d009b05645353f22Cong Wang */ 1996b45cbd956ce83908378d87d009b05645353f22Cong Wang 2096b45cbd956ce83908378d87d009b05645353f22Cong Wangstatic int dev_ifname(struct net *net, struct ifreq __user *arg) 2196b45cbd956ce83908378d87d009b05645353f22Cong Wang{ 2296b45cbd956ce83908378d87d009b05645353f22Cong Wang struct ifreq ifr; 235dbe7c178d3f0a4634f088d9e729f1909b9ddcd1Nicolas Schichan int error; 2496b45cbd956ce83908378d87d009b05645353f22Cong Wang 2596b45cbd956ce83908378d87d009b05645353f22Cong Wang /* 2696b45cbd956ce83908378d87d009b05645353f22Cong Wang * Fetch the caller's info block. 2796b45cbd956ce83908378d87d009b05645353f22Cong Wang */ 2896b45cbd956ce83908378d87d009b05645353f22Cong Wang 2996b45cbd956ce83908378d87d009b05645353f22Cong Wang if (copy_from_user(&ifr, arg, sizeof(struct ifreq))) 3096b45cbd956ce83908378d87d009b05645353f22Cong Wang return -EFAULT; 3196b45cbd956ce83908378d87d009b05645353f22Cong Wang 325dbe7c178d3f0a4634f088d9e729f1909b9ddcd1Nicolas Schichan error = netdev_get_name(net, ifr.ifr_name, ifr.ifr_ifindex); 335dbe7c178d3f0a4634f088d9e729f1909b9ddcd1Nicolas Schichan if (error) 345dbe7c178d3f0a4634f088d9e729f1909b9ddcd1Nicolas Schichan return error; 3596b45cbd956ce83908378d87d009b05645353f22Cong Wang 3696b45cbd956ce83908378d87d009b05645353f22Cong Wang if (copy_to_user(arg, &ifr, sizeof(struct ifreq))) 3796b45cbd956ce83908378d87d009b05645353f22Cong Wang return -EFAULT; 3896b45cbd956ce83908378d87d009b05645353f22Cong Wang return 0; 3996b45cbd956ce83908378d87d009b05645353f22Cong Wang} 4096b45cbd956ce83908378d87d009b05645353f22Cong Wang 4196b45cbd956ce83908378d87d009b05645353f22Cong Wangstatic gifconf_func_t *gifconf_list[NPROTO]; 4296b45cbd956ce83908378d87d009b05645353f22Cong Wang 4396b45cbd956ce83908378d87d009b05645353f22Cong Wang/** 4496b45cbd956ce83908378d87d009b05645353f22Cong Wang * register_gifconf - register a SIOCGIF handler 4596b45cbd956ce83908378d87d009b05645353f22Cong Wang * @family: Address family 4696b45cbd956ce83908378d87d009b05645353f22Cong Wang * @gifconf: Function handler 4796b45cbd956ce83908378d87d009b05645353f22Cong Wang * 4896b45cbd956ce83908378d87d009b05645353f22Cong Wang * Register protocol dependent address dumping routines. The handler 4996b45cbd956ce83908378d87d009b05645353f22Cong Wang * that is passed must not be freed or reused until it has been replaced 5096b45cbd956ce83908378d87d009b05645353f22Cong Wang * by another handler. 5196b45cbd956ce83908378d87d009b05645353f22Cong Wang */ 5296b45cbd956ce83908378d87d009b05645353f22Cong Wangint register_gifconf(unsigned int family, gifconf_func_t *gifconf) 5396b45cbd956ce83908378d87d009b05645353f22Cong Wang{ 5496b45cbd956ce83908378d87d009b05645353f22Cong Wang if (family >= NPROTO) 5596b45cbd956ce83908378d87d009b05645353f22Cong Wang return -EINVAL; 5696b45cbd956ce83908378d87d009b05645353f22Cong Wang gifconf_list[family] = gifconf; 5796b45cbd956ce83908378d87d009b05645353f22Cong Wang return 0; 5896b45cbd956ce83908378d87d009b05645353f22Cong Wang} 5996b45cbd956ce83908378d87d009b05645353f22Cong WangEXPORT_SYMBOL(register_gifconf); 6096b45cbd956ce83908378d87d009b05645353f22Cong Wang 6196b45cbd956ce83908378d87d009b05645353f22Cong Wang/* 6296b45cbd956ce83908378d87d009b05645353f22Cong Wang * Perform a SIOCGIFCONF call. This structure will change 6396b45cbd956ce83908378d87d009b05645353f22Cong Wang * size eventually, and there is nothing I can do about it. 6496b45cbd956ce83908378d87d009b05645353f22Cong Wang * Thus we will need a 'compatibility mode'. 6596b45cbd956ce83908378d87d009b05645353f22Cong Wang */ 6696b45cbd956ce83908378d87d009b05645353f22Cong Wang 6796b45cbd956ce83908378d87d009b05645353f22Cong Wangstatic int dev_ifconf(struct net *net, char __user *arg) 6896b45cbd956ce83908378d87d009b05645353f22Cong Wang{ 6996b45cbd956ce83908378d87d009b05645353f22Cong Wang struct ifconf ifc; 7096b45cbd956ce83908378d87d009b05645353f22Cong Wang struct net_device *dev; 7196b45cbd956ce83908378d87d009b05645353f22Cong Wang char __user *pos; 7296b45cbd956ce83908378d87d009b05645353f22Cong Wang int len; 7396b45cbd956ce83908378d87d009b05645353f22Cong Wang int total; 7496b45cbd956ce83908378d87d009b05645353f22Cong Wang int i; 7596b45cbd956ce83908378d87d009b05645353f22Cong Wang 7696b45cbd956ce83908378d87d009b05645353f22Cong Wang /* 7796b45cbd956ce83908378d87d009b05645353f22Cong Wang * Fetch the caller's info block. 7896b45cbd956ce83908378d87d009b05645353f22Cong Wang */ 7996b45cbd956ce83908378d87d009b05645353f22Cong Wang 8096b45cbd956ce83908378d87d009b05645353f22Cong Wang if (copy_from_user(&ifc, arg, sizeof(struct ifconf))) 8196b45cbd956ce83908378d87d009b05645353f22Cong Wang return -EFAULT; 8296b45cbd956ce83908378d87d009b05645353f22Cong Wang 8396b45cbd956ce83908378d87d009b05645353f22Cong Wang pos = ifc.ifc_buf; 8496b45cbd956ce83908378d87d009b05645353f22Cong Wang len = ifc.ifc_len; 8596b45cbd956ce83908378d87d009b05645353f22Cong Wang 8696b45cbd956ce83908378d87d009b05645353f22Cong Wang /* 8796b45cbd956ce83908378d87d009b05645353f22Cong Wang * Loop over the interfaces, and write an info block for each. 8896b45cbd956ce83908378d87d009b05645353f22Cong Wang */ 8996b45cbd956ce83908378d87d009b05645353f22Cong Wang 9096b45cbd956ce83908378d87d009b05645353f22Cong Wang total = 0; 9196b45cbd956ce83908378d87d009b05645353f22Cong Wang for_each_netdev(net, dev) { 9296b45cbd956ce83908378d87d009b05645353f22Cong Wang for (i = 0; i < NPROTO; i++) { 9396b45cbd956ce83908378d87d009b05645353f22Cong Wang if (gifconf_list[i]) { 9496b45cbd956ce83908378d87d009b05645353f22Cong Wang int done; 9596b45cbd956ce83908378d87d009b05645353f22Cong Wang if (!pos) 9696b45cbd956ce83908378d87d009b05645353f22Cong Wang done = gifconf_list[i](dev, NULL, 0); 9796b45cbd956ce83908378d87d009b05645353f22Cong Wang else 9896b45cbd956ce83908378d87d009b05645353f22Cong Wang done = gifconf_list[i](dev, pos + total, 9996b45cbd956ce83908378d87d009b05645353f22Cong Wang len - total); 10096b45cbd956ce83908378d87d009b05645353f22Cong Wang if (done < 0) 10196b45cbd956ce83908378d87d009b05645353f22Cong Wang return -EFAULT; 10296b45cbd956ce83908378d87d009b05645353f22Cong Wang total += done; 10396b45cbd956ce83908378d87d009b05645353f22Cong Wang } 10496b45cbd956ce83908378d87d009b05645353f22Cong Wang } 10596b45cbd956ce83908378d87d009b05645353f22Cong Wang } 10696b45cbd956ce83908378d87d009b05645353f22Cong Wang 10796b45cbd956ce83908378d87d009b05645353f22Cong Wang /* 10896b45cbd956ce83908378d87d009b05645353f22Cong Wang * All done. Write the updated control block back to the caller. 10996b45cbd956ce83908378d87d009b05645353f22Cong Wang */ 11096b45cbd956ce83908378d87d009b05645353f22Cong Wang ifc.ifc_len = total; 11196b45cbd956ce83908378d87d009b05645353f22Cong Wang 11296b45cbd956ce83908378d87d009b05645353f22Cong Wang /* 11396b45cbd956ce83908378d87d009b05645353f22Cong Wang * Both BSD and Solaris return 0 here, so we do too. 11496b45cbd956ce83908378d87d009b05645353f22Cong Wang */ 11596b45cbd956ce83908378d87d009b05645353f22Cong Wang return copy_to_user(arg, &ifc, sizeof(struct ifconf)) ? -EFAULT : 0; 11696b45cbd956ce83908378d87d009b05645353f22Cong Wang} 11796b45cbd956ce83908378d87d009b05645353f22Cong Wang 11896b45cbd956ce83908378d87d009b05645353f22Cong Wang/* 11996b45cbd956ce83908378d87d009b05645353f22Cong Wang * Perform the SIOCxIFxxx calls, inside rcu_read_lock() 12096b45cbd956ce83908378d87d009b05645353f22Cong Wang */ 12196b45cbd956ce83908378d87d009b05645353f22Cong Wangstatic int dev_ifsioc_locked(struct net *net, struct ifreq *ifr, unsigned int cmd) 12296b45cbd956ce83908378d87d009b05645353f22Cong Wang{ 12396b45cbd956ce83908378d87d009b05645353f22Cong Wang int err; 12496b45cbd956ce83908378d87d009b05645353f22Cong Wang struct net_device *dev = dev_get_by_name_rcu(net, ifr->ifr_name); 12596b45cbd956ce83908378d87d009b05645353f22Cong Wang 12696b45cbd956ce83908378d87d009b05645353f22Cong Wang if (!dev) 12796b45cbd956ce83908378d87d009b05645353f22Cong Wang return -ENODEV; 12896b45cbd956ce83908378d87d009b05645353f22Cong Wang 12996b45cbd956ce83908378d87d009b05645353f22Cong Wang switch (cmd) { 13096b45cbd956ce83908378d87d009b05645353f22Cong Wang case SIOCGIFFLAGS: /* Get interface flags */ 13196b45cbd956ce83908378d87d009b05645353f22Cong Wang ifr->ifr_flags = (short) dev_get_flags(dev); 13296b45cbd956ce83908378d87d009b05645353f22Cong Wang return 0; 13396b45cbd956ce83908378d87d009b05645353f22Cong Wang 13496b45cbd956ce83908378d87d009b05645353f22Cong Wang case SIOCGIFMETRIC: /* Get the metric on the interface 13596b45cbd956ce83908378d87d009b05645353f22Cong Wang (currently unused) */ 13696b45cbd956ce83908378d87d009b05645353f22Cong Wang ifr->ifr_metric = 0; 13796b45cbd956ce83908378d87d009b05645353f22Cong Wang return 0; 13896b45cbd956ce83908378d87d009b05645353f22Cong Wang 13996b45cbd956ce83908378d87d009b05645353f22Cong Wang case SIOCGIFMTU: /* Get the MTU of a device */ 14096b45cbd956ce83908378d87d009b05645353f22Cong Wang ifr->ifr_mtu = dev->mtu; 14196b45cbd956ce83908378d87d009b05645353f22Cong Wang return 0; 14296b45cbd956ce83908378d87d009b05645353f22Cong Wang 14396b45cbd956ce83908378d87d009b05645353f22Cong Wang case SIOCGIFHWADDR: 14496b45cbd956ce83908378d87d009b05645353f22Cong Wang if (!dev->addr_len) 14596b45cbd956ce83908378d87d009b05645353f22Cong Wang memset(ifr->ifr_hwaddr.sa_data, 0, sizeof ifr->ifr_hwaddr.sa_data); 14696b45cbd956ce83908378d87d009b05645353f22Cong Wang else 14796b45cbd956ce83908378d87d009b05645353f22Cong Wang memcpy(ifr->ifr_hwaddr.sa_data, dev->dev_addr, 14896b45cbd956ce83908378d87d009b05645353f22Cong Wang min(sizeof ifr->ifr_hwaddr.sa_data, (size_t) dev->addr_len)); 14996b45cbd956ce83908378d87d009b05645353f22Cong Wang ifr->ifr_hwaddr.sa_family = dev->type; 15096b45cbd956ce83908378d87d009b05645353f22Cong Wang return 0; 15196b45cbd956ce83908378d87d009b05645353f22Cong Wang 15296b45cbd956ce83908378d87d009b05645353f22Cong Wang case SIOCGIFSLAVE: 15396b45cbd956ce83908378d87d009b05645353f22Cong Wang err = -EINVAL; 15496b45cbd956ce83908378d87d009b05645353f22Cong Wang break; 15596b45cbd956ce83908378d87d009b05645353f22Cong Wang 15696b45cbd956ce83908378d87d009b05645353f22Cong Wang case SIOCGIFMAP: 15796b45cbd956ce83908378d87d009b05645353f22Cong Wang ifr->ifr_map.mem_start = dev->mem_start; 15896b45cbd956ce83908378d87d009b05645353f22Cong Wang ifr->ifr_map.mem_end = dev->mem_end; 15996b45cbd956ce83908378d87d009b05645353f22Cong Wang ifr->ifr_map.base_addr = dev->base_addr; 16096b45cbd956ce83908378d87d009b05645353f22Cong Wang ifr->ifr_map.irq = dev->irq; 16196b45cbd956ce83908378d87d009b05645353f22Cong Wang ifr->ifr_map.dma = dev->dma; 16296b45cbd956ce83908378d87d009b05645353f22Cong Wang ifr->ifr_map.port = dev->if_port; 16396b45cbd956ce83908378d87d009b05645353f22Cong Wang return 0; 16496b45cbd956ce83908378d87d009b05645353f22Cong Wang 16596b45cbd956ce83908378d87d009b05645353f22Cong Wang case SIOCGIFINDEX: 16696b45cbd956ce83908378d87d009b05645353f22Cong Wang ifr->ifr_ifindex = dev->ifindex; 16796b45cbd956ce83908378d87d009b05645353f22Cong Wang return 0; 16896b45cbd956ce83908378d87d009b05645353f22Cong Wang 16996b45cbd956ce83908378d87d009b05645353f22Cong Wang case SIOCGIFTXQLEN: 17096b45cbd956ce83908378d87d009b05645353f22Cong Wang ifr->ifr_qlen = dev->tx_queue_len; 17196b45cbd956ce83908378d87d009b05645353f22Cong Wang return 0; 17296b45cbd956ce83908378d87d009b05645353f22Cong Wang 17396b45cbd956ce83908378d87d009b05645353f22Cong Wang default: 17496b45cbd956ce83908378d87d009b05645353f22Cong Wang /* dev_ioctl() should ensure this case 17596b45cbd956ce83908378d87d009b05645353f22Cong Wang * is never reached 17696b45cbd956ce83908378d87d009b05645353f22Cong Wang */ 17796b45cbd956ce83908378d87d009b05645353f22Cong Wang WARN_ON(1); 17896b45cbd956ce83908378d87d009b05645353f22Cong Wang err = -ENOTTY; 17996b45cbd956ce83908378d87d009b05645353f22Cong Wang break; 18096b45cbd956ce83908378d87d009b05645353f22Cong Wang 18196b45cbd956ce83908378d87d009b05645353f22Cong Wang } 18296b45cbd956ce83908378d87d009b05645353f22Cong Wang return err; 18396b45cbd956ce83908378d87d009b05645353f22Cong Wang} 18496b45cbd956ce83908378d87d009b05645353f22Cong Wang 18596b45cbd956ce83908378d87d009b05645353f22Cong Wangstatic int net_hwtstamp_validate(struct ifreq *ifr) 18696b45cbd956ce83908378d87d009b05645353f22Cong Wang{ 18796b45cbd956ce83908378d87d009b05645353f22Cong Wang struct hwtstamp_config cfg; 18896b45cbd956ce83908378d87d009b05645353f22Cong Wang enum hwtstamp_tx_types tx_type; 18996b45cbd956ce83908378d87d009b05645353f22Cong Wang enum hwtstamp_rx_filters rx_filter; 19096b45cbd956ce83908378d87d009b05645353f22Cong Wang int tx_type_valid = 0; 19196b45cbd956ce83908378d87d009b05645353f22Cong Wang int rx_filter_valid = 0; 19296b45cbd956ce83908378d87d009b05645353f22Cong Wang 19396b45cbd956ce83908378d87d009b05645353f22Cong Wang if (copy_from_user(&cfg, ifr->ifr_data, sizeof(cfg))) 19496b45cbd956ce83908378d87d009b05645353f22Cong Wang return -EFAULT; 19596b45cbd956ce83908378d87d009b05645353f22Cong Wang 19696b45cbd956ce83908378d87d009b05645353f22Cong Wang if (cfg.flags) /* reserved for future extensions */ 19796b45cbd956ce83908378d87d009b05645353f22Cong Wang return -EINVAL; 19896b45cbd956ce83908378d87d009b05645353f22Cong Wang 19996b45cbd956ce83908378d87d009b05645353f22Cong Wang tx_type = cfg.tx_type; 20096b45cbd956ce83908378d87d009b05645353f22Cong Wang rx_filter = cfg.rx_filter; 20196b45cbd956ce83908378d87d009b05645353f22Cong Wang 20296b45cbd956ce83908378d87d009b05645353f22Cong Wang switch (tx_type) { 20396b45cbd956ce83908378d87d009b05645353f22Cong Wang case HWTSTAMP_TX_OFF: 20496b45cbd956ce83908378d87d009b05645353f22Cong Wang case HWTSTAMP_TX_ON: 20596b45cbd956ce83908378d87d009b05645353f22Cong Wang case HWTSTAMP_TX_ONESTEP_SYNC: 20696b45cbd956ce83908378d87d009b05645353f22Cong Wang tx_type_valid = 1; 20796b45cbd956ce83908378d87d009b05645353f22Cong Wang break; 20896b45cbd956ce83908378d87d009b05645353f22Cong Wang } 20996b45cbd956ce83908378d87d009b05645353f22Cong Wang 21096b45cbd956ce83908378d87d009b05645353f22Cong Wang switch (rx_filter) { 21196b45cbd956ce83908378d87d009b05645353f22Cong Wang case HWTSTAMP_FILTER_NONE: 21296b45cbd956ce83908378d87d009b05645353f22Cong Wang case HWTSTAMP_FILTER_ALL: 21396b45cbd956ce83908378d87d009b05645353f22Cong Wang case HWTSTAMP_FILTER_SOME: 21496b45cbd956ce83908378d87d009b05645353f22Cong Wang case HWTSTAMP_FILTER_PTP_V1_L4_EVENT: 21596b45cbd956ce83908378d87d009b05645353f22Cong Wang case HWTSTAMP_FILTER_PTP_V1_L4_SYNC: 21696b45cbd956ce83908378d87d009b05645353f22Cong Wang case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ: 21796b45cbd956ce83908378d87d009b05645353f22Cong Wang case HWTSTAMP_FILTER_PTP_V2_L4_EVENT: 21896b45cbd956ce83908378d87d009b05645353f22Cong Wang case HWTSTAMP_FILTER_PTP_V2_L4_SYNC: 21996b45cbd956ce83908378d87d009b05645353f22Cong Wang case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ: 22096b45cbd956ce83908378d87d009b05645353f22Cong Wang case HWTSTAMP_FILTER_PTP_V2_L2_EVENT: 22196b45cbd956ce83908378d87d009b05645353f22Cong Wang case HWTSTAMP_FILTER_PTP_V2_L2_SYNC: 22296b45cbd956ce83908378d87d009b05645353f22Cong Wang case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ: 22396b45cbd956ce83908378d87d009b05645353f22Cong Wang case HWTSTAMP_FILTER_PTP_V2_EVENT: 22496b45cbd956ce83908378d87d009b05645353f22Cong Wang case HWTSTAMP_FILTER_PTP_V2_SYNC: 22596b45cbd956ce83908378d87d009b05645353f22Cong Wang case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ: 22696b45cbd956ce83908378d87d009b05645353f22Cong Wang rx_filter_valid = 1; 22796b45cbd956ce83908378d87d009b05645353f22Cong Wang break; 22896b45cbd956ce83908378d87d009b05645353f22Cong Wang } 22996b45cbd956ce83908378d87d009b05645353f22Cong Wang 23096b45cbd956ce83908378d87d009b05645353f22Cong Wang if (!tx_type_valid || !rx_filter_valid) 23196b45cbd956ce83908378d87d009b05645353f22Cong Wang return -ERANGE; 23296b45cbd956ce83908378d87d009b05645353f22Cong Wang 23396b45cbd956ce83908378d87d009b05645353f22Cong Wang return 0; 23496b45cbd956ce83908378d87d009b05645353f22Cong Wang} 23596b45cbd956ce83908378d87d009b05645353f22Cong Wang 23696b45cbd956ce83908378d87d009b05645353f22Cong Wang/* 23796b45cbd956ce83908378d87d009b05645353f22Cong Wang * Perform the SIOCxIFxxx calls, inside rtnl_lock() 23896b45cbd956ce83908378d87d009b05645353f22Cong Wang */ 23996b45cbd956ce83908378d87d009b05645353f22Cong Wangstatic int dev_ifsioc(struct net *net, struct ifreq *ifr, unsigned int cmd) 24096b45cbd956ce83908378d87d009b05645353f22Cong Wang{ 24196b45cbd956ce83908378d87d009b05645353f22Cong Wang int err; 24296b45cbd956ce83908378d87d009b05645353f22Cong Wang struct net_device *dev = __dev_get_by_name(net, ifr->ifr_name); 24396b45cbd956ce83908378d87d009b05645353f22Cong Wang const struct net_device_ops *ops; 24496b45cbd956ce83908378d87d009b05645353f22Cong Wang 24596b45cbd956ce83908378d87d009b05645353f22Cong Wang if (!dev) 24696b45cbd956ce83908378d87d009b05645353f22Cong Wang return -ENODEV; 24796b45cbd956ce83908378d87d009b05645353f22Cong Wang 24896b45cbd956ce83908378d87d009b05645353f22Cong Wang ops = dev->netdev_ops; 24996b45cbd956ce83908378d87d009b05645353f22Cong Wang 25096b45cbd956ce83908378d87d009b05645353f22Cong Wang switch (cmd) { 25196b45cbd956ce83908378d87d009b05645353f22Cong Wang case SIOCSIFFLAGS: /* Set interface flags */ 25296b45cbd956ce83908378d87d009b05645353f22Cong Wang return dev_change_flags(dev, ifr->ifr_flags); 25396b45cbd956ce83908378d87d009b05645353f22Cong Wang 25496b45cbd956ce83908378d87d009b05645353f22Cong Wang case SIOCSIFMETRIC: /* Set the metric on the interface 25596b45cbd956ce83908378d87d009b05645353f22Cong Wang (currently unused) */ 25696b45cbd956ce83908378d87d009b05645353f22Cong Wang return -EOPNOTSUPP; 25796b45cbd956ce83908378d87d009b05645353f22Cong Wang 25896b45cbd956ce83908378d87d009b05645353f22Cong Wang case SIOCSIFMTU: /* Set the MTU of a device */ 25996b45cbd956ce83908378d87d009b05645353f22Cong Wang return dev_set_mtu(dev, ifr->ifr_mtu); 26096b45cbd956ce83908378d87d009b05645353f22Cong Wang 26196b45cbd956ce83908378d87d009b05645353f22Cong Wang case SIOCSIFHWADDR: 26296b45cbd956ce83908378d87d009b05645353f22Cong Wang return dev_set_mac_address(dev, &ifr->ifr_hwaddr); 26396b45cbd956ce83908378d87d009b05645353f22Cong Wang 26496b45cbd956ce83908378d87d009b05645353f22Cong Wang case SIOCSIFHWBROADCAST: 26596b45cbd956ce83908378d87d009b05645353f22Cong Wang if (ifr->ifr_hwaddr.sa_family != dev->type) 26696b45cbd956ce83908378d87d009b05645353f22Cong Wang return -EINVAL; 26796b45cbd956ce83908378d87d009b05645353f22Cong Wang memcpy(dev->broadcast, ifr->ifr_hwaddr.sa_data, 26896b45cbd956ce83908378d87d009b05645353f22Cong Wang min(sizeof ifr->ifr_hwaddr.sa_data, (size_t) dev->addr_len)); 26996b45cbd956ce83908378d87d009b05645353f22Cong Wang call_netdevice_notifiers(NETDEV_CHANGEADDR, dev); 27096b45cbd956ce83908378d87d009b05645353f22Cong Wang return 0; 27196b45cbd956ce83908378d87d009b05645353f22Cong Wang 27296b45cbd956ce83908378d87d009b05645353f22Cong Wang case SIOCSIFMAP: 27396b45cbd956ce83908378d87d009b05645353f22Cong Wang if (ops->ndo_set_config) { 27496b45cbd956ce83908378d87d009b05645353f22Cong Wang if (!netif_device_present(dev)) 27596b45cbd956ce83908378d87d009b05645353f22Cong Wang return -ENODEV; 27696b45cbd956ce83908378d87d009b05645353f22Cong Wang return ops->ndo_set_config(dev, &ifr->ifr_map); 27796b45cbd956ce83908378d87d009b05645353f22Cong Wang } 27896b45cbd956ce83908378d87d009b05645353f22Cong Wang return -EOPNOTSUPP; 27996b45cbd956ce83908378d87d009b05645353f22Cong Wang 28096b45cbd956ce83908378d87d009b05645353f22Cong Wang case SIOCADDMULTI: 28196b45cbd956ce83908378d87d009b05645353f22Cong Wang if (!ops->ndo_set_rx_mode || 28296b45cbd956ce83908378d87d009b05645353f22Cong Wang ifr->ifr_hwaddr.sa_family != AF_UNSPEC) 28396b45cbd956ce83908378d87d009b05645353f22Cong Wang return -EINVAL; 28496b45cbd956ce83908378d87d009b05645353f22Cong Wang if (!netif_device_present(dev)) 28596b45cbd956ce83908378d87d009b05645353f22Cong Wang return -ENODEV; 28696b45cbd956ce83908378d87d009b05645353f22Cong Wang return dev_mc_add_global(dev, ifr->ifr_hwaddr.sa_data); 28796b45cbd956ce83908378d87d009b05645353f22Cong Wang 28896b45cbd956ce83908378d87d009b05645353f22Cong Wang case SIOCDELMULTI: 28996b45cbd956ce83908378d87d009b05645353f22Cong Wang if (!ops->ndo_set_rx_mode || 29096b45cbd956ce83908378d87d009b05645353f22Cong Wang ifr->ifr_hwaddr.sa_family != AF_UNSPEC) 29196b45cbd956ce83908378d87d009b05645353f22Cong Wang return -EINVAL; 29296b45cbd956ce83908378d87d009b05645353f22Cong Wang if (!netif_device_present(dev)) 29396b45cbd956ce83908378d87d009b05645353f22Cong Wang return -ENODEV; 29496b45cbd956ce83908378d87d009b05645353f22Cong Wang return dev_mc_del_global(dev, ifr->ifr_hwaddr.sa_data); 29596b45cbd956ce83908378d87d009b05645353f22Cong Wang 29696b45cbd956ce83908378d87d009b05645353f22Cong Wang case SIOCSIFTXQLEN: 29796b45cbd956ce83908378d87d009b05645353f22Cong Wang if (ifr->ifr_qlen < 0) 29896b45cbd956ce83908378d87d009b05645353f22Cong Wang return -EINVAL; 29996b45cbd956ce83908378d87d009b05645353f22Cong Wang dev->tx_queue_len = ifr->ifr_qlen; 30096b45cbd956ce83908378d87d009b05645353f22Cong Wang return 0; 30196b45cbd956ce83908378d87d009b05645353f22Cong Wang 30296b45cbd956ce83908378d87d009b05645353f22Cong Wang case SIOCSIFNAME: 30396b45cbd956ce83908378d87d009b05645353f22Cong Wang ifr->ifr_newname[IFNAMSIZ-1] = '\0'; 30496b45cbd956ce83908378d87d009b05645353f22Cong Wang return dev_change_name(dev, ifr->ifr_newname); 30596b45cbd956ce83908378d87d009b05645353f22Cong Wang 30696b45cbd956ce83908378d87d009b05645353f22Cong Wang case SIOCSHWTSTAMP: 30796b45cbd956ce83908378d87d009b05645353f22Cong Wang err = net_hwtstamp_validate(ifr); 30896b45cbd956ce83908378d87d009b05645353f22Cong Wang if (err) 30996b45cbd956ce83908378d87d009b05645353f22Cong Wang return err; 31096b45cbd956ce83908378d87d009b05645353f22Cong Wang /* fall through */ 31196b45cbd956ce83908378d87d009b05645353f22Cong Wang 31296b45cbd956ce83908378d87d009b05645353f22Cong Wang /* 31396b45cbd956ce83908378d87d009b05645353f22Cong Wang * Unknown or private ioctl 31496b45cbd956ce83908378d87d009b05645353f22Cong Wang */ 31596b45cbd956ce83908378d87d009b05645353f22Cong Wang default: 31696b45cbd956ce83908378d87d009b05645353f22Cong Wang if ((cmd >= SIOCDEVPRIVATE && 31796b45cbd956ce83908378d87d009b05645353f22Cong Wang cmd <= SIOCDEVPRIVATE + 15) || 31896b45cbd956ce83908378d87d009b05645353f22Cong Wang cmd == SIOCBONDENSLAVE || 31996b45cbd956ce83908378d87d009b05645353f22Cong Wang cmd == SIOCBONDRELEASE || 32096b45cbd956ce83908378d87d009b05645353f22Cong Wang cmd == SIOCBONDSETHWADDR || 32196b45cbd956ce83908378d87d009b05645353f22Cong Wang cmd == SIOCBONDSLAVEINFOQUERY || 32296b45cbd956ce83908378d87d009b05645353f22Cong Wang cmd == SIOCBONDINFOQUERY || 32396b45cbd956ce83908378d87d009b05645353f22Cong Wang cmd == SIOCBONDCHANGEACTIVE || 32496b45cbd956ce83908378d87d009b05645353f22Cong Wang cmd == SIOCGMIIPHY || 32596b45cbd956ce83908378d87d009b05645353f22Cong Wang cmd == SIOCGMIIREG || 32696b45cbd956ce83908378d87d009b05645353f22Cong Wang cmd == SIOCSMIIREG || 32796b45cbd956ce83908378d87d009b05645353f22Cong Wang cmd == SIOCBRADDIF || 32896b45cbd956ce83908378d87d009b05645353f22Cong Wang cmd == SIOCBRDELIF || 32996b45cbd956ce83908378d87d009b05645353f22Cong Wang cmd == SIOCSHWTSTAMP || 330fd468c74bd4d6949736810a80d6ca05eb20fba84Ben Hutchings cmd == SIOCGHWTSTAMP || 33196b45cbd956ce83908378d87d009b05645353f22Cong Wang cmd == SIOCWANDEV) { 33296b45cbd956ce83908378d87d009b05645353f22Cong Wang err = -EOPNOTSUPP; 33396b45cbd956ce83908378d87d009b05645353f22Cong Wang if (ops->ndo_do_ioctl) { 33496b45cbd956ce83908378d87d009b05645353f22Cong Wang if (netif_device_present(dev)) 33596b45cbd956ce83908378d87d009b05645353f22Cong Wang err = ops->ndo_do_ioctl(dev, ifr, cmd); 33696b45cbd956ce83908378d87d009b05645353f22Cong Wang else 33796b45cbd956ce83908378d87d009b05645353f22Cong Wang err = -ENODEV; 33896b45cbd956ce83908378d87d009b05645353f22Cong Wang } 33996b45cbd956ce83908378d87d009b05645353f22Cong Wang } else 34096b45cbd956ce83908378d87d009b05645353f22Cong Wang err = -EINVAL; 34196b45cbd956ce83908378d87d009b05645353f22Cong Wang 34296b45cbd956ce83908378d87d009b05645353f22Cong Wang } 34396b45cbd956ce83908378d87d009b05645353f22Cong Wang return err; 34496b45cbd956ce83908378d87d009b05645353f22Cong Wang} 34596b45cbd956ce83908378d87d009b05645353f22Cong Wang 34696b45cbd956ce83908378d87d009b05645353f22Cong Wang/** 34796b45cbd956ce83908378d87d009b05645353f22Cong Wang * dev_load - load a network module 34896b45cbd956ce83908378d87d009b05645353f22Cong Wang * @net: the applicable net namespace 34996b45cbd956ce83908378d87d009b05645353f22Cong Wang * @name: name of interface 35096b45cbd956ce83908378d87d009b05645353f22Cong Wang * 35196b45cbd956ce83908378d87d009b05645353f22Cong Wang * If a network interface is not present and the process has suitable 35296b45cbd956ce83908378d87d009b05645353f22Cong Wang * privileges this function loads the module. If module loading is not 35396b45cbd956ce83908378d87d009b05645353f22Cong Wang * available in this kernel then it becomes a nop. 35496b45cbd956ce83908378d87d009b05645353f22Cong Wang */ 35596b45cbd956ce83908378d87d009b05645353f22Cong Wang 35696b45cbd956ce83908378d87d009b05645353f22Cong Wangvoid dev_load(struct net *net, const char *name) 35796b45cbd956ce83908378d87d009b05645353f22Cong Wang{ 35896b45cbd956ce83908378d87d009b05645353f22Cong Wang struct net_device *dev; 35996b45cbd956ce83908378d87d009b05645353f22Cong Wang int no_module; 36096b45cbd956ce83908378d87d009b05645353f22Cong Wang 36196b45cbd956ce83908378d87d009b05645353f22Cong Wang rcu_read_lock(); 36296b45cbd956ce83908378d87d009b05645353f22Cong Wang dev = dev_get_by_name_rcu(net, name); 36396b45cbd956ce83908378d87d009b05645353f22Cong Wang rcu_read_unlock(); 36496b45cbd956ce83908378d87d009b05645353f22Cong Wang 36596b45cbd956ce83908378d87d009b05645353f22Cong Wang no_module = !dev; 36696b45cbd956ce83908378d87d009b05645353f22Cong Wang if (no_module && capable(CAP_NET_ADMIN)) 36796b45cbd956ce83908378d87d009b05645353f22Cong Wang no_module = request_module("netdev-%s", name); 368e020836d953eb1ce5b9221b32f4613646a4d5772Daniel Borkmann if (no_module && capable(CAP_SYS_MODULE)) 369e020836d953eb1ce5b9221b32f4613646a4d5772Daniel Borkmann request_module("%s", name); 37096b45cbd956ce83908378d87d009b05645353f22Cong Wang} 37196b45cbd956ce83908378d87d009b05645353f22Cong WangEXPORT_SYMBOL(dev_load); 37296b45cbd956ce83908378d87d009b05645353f22Cong Wang 37396b45cbd956ce83908378d87d009b05645353f22Cong Wang/* 37496b45cbd956ce83908378d87d009b05645353f22Cong Wang * This function handles all "interface"-type I/O control requests. The actual 37596b45cbd956ce83908378d87d009b05645353f22Cong Wang * 'doing' part of this is dev_ifsioc above. 37696b45cbd956ce83908378d87d009b05645353f22Cong Wang */ 37796b45cbd956ce83908378d87d009b05645353f22Cong Wang 37896b45cbd956ce83908378d87d009b05645353f22Cong Wang/** 37996b45cbd956ce83908378d87d009b05645353f22Cong Wang * dev_ioctl - network device ioctl 38096b45cbd956ce83908378d87d009b05645353f22Cong Wang * @net: the applicable net namespace 38196b45cbd956ce83908378d87d009b05645353f22Cong Wang * @cmd: command to issue 38296b45cbd956ce83908378d87d009b05645353f22Cong Wang * @arg: pointer to a struct ifreq in user space 38396b45cbd956ce83908378d87d009b05645353f22Cong Wang * 38496b45cbd956ce83908378d87d009b05645353f22Cong Wang * Issue ioctl functions to devices. This is normally called by the 38596b45cbd956ce83908378d87d009b05645353f22Cong Wang * user space syscall interfaces but can sometimes be useful for 38696b45cbd956ce83908378d87d009b05645353f22Cong Wang * other purposes. The return value is the return from the syscall if 38796b45cbd956ce83908378d87d009b05645353f22Cong Wang * positive or a negative errno code on error. 38896b45cbd956ce83908378d87d009b05645353f22Cong Wang */ 38996b45cbd956ce83908378d87d009b05645353f22Cong Wang 39096b45cbd956ce83908378d87d009b05645353f22Cong Wangint dev_ioctl(struct net *net, unsigned int cmd, void __user *arg) 39196b45cbd956ce83908378d87d009b05645353f22Cong Wang{ 39296b45cbd956ce83908378d87d009b05645353f22Cong Wang struct ifreq ifr; 39396b45cbd956ce83908378d87d009b05645353f22Cong Wang int ret; 39496b45cbd956ce83908378d87d009b05645353f22Cong Wang char *colon; 39596b45cbd956ce83908378d87d009b05645353f22Cong Wang 39696b45cbd956ce83908378d87d009b05645353f22Cong Wang /* One special case: SIOCGIFCONF takes ifconf argument 39796b45cbd956ce83908378d87d009b05645353f22Cong Wang and requires shared lock, because it sleeps writing 39896b45cbd956ce83908378d87d009b05645353f22Cong Wang to user space. 39996b45cbd956ce83908378d87d009b05645353f22Cong Wang */ 40096b45cbd956ce83908378d87d009b05645353f22Cong Wang 40196b45cbd956ce83908378d87d009b05645353f22Cong Wang if (cmd == SIOCGIFCONF) { 40296b45cbd956ce83908378d87d009b05645353f22Cong Wang rtnl_lock(); 40396b45cbd956ce83908378d87d009b05645353f22Cong Wang ret = dev_ifconf(net, (char __user *) arg); 40496b45cbd956ce83908378d87d009b05645353f22Cong Wang rtnl_unlock(); 40596b45cbd956ce83908378d87d009b05645353f22Cong Wang return ret; 40696b45cbd956ce83908378d87d009b05645353f22Cong Wang } 40796b45cbd956ce83908378d87d009b05645353f22Cong Wang if (cmd == SIOCGIFNAME) 40896b45cbd956ce83908378d87d009b05645353f22Cong Wang return dev_ifname(net, (struct ifreq __user *)arg); 40996b45cbd956ce83908378d87d009b05645353f22Cong Wang 41096b45cbd956ce83908378d87d009b05645353f22Cong Wang if (copy_from_user(&ifr, arg, sizeof(struct ifreq))) 41196b45cbd956ce83908378d87d009b05645353f22Cong Wang return -EFAULT; 41296b45cbd956ce83908378d87d009b05645353f22Cong Wang 41396b45cbd956ce83908378d87d009b05645353f22Cong Wang ifr.ifr_name[IFNAMSIZ-1] = 0; 41496b45cbd956ce83908378d87d009b05645353f22Cong Wang 41596b45cbd956ce83908378d87d009b05645353f22Cong Wang colon = strchr(ifr.ifr_name, ':'); 41696b45cbd956ce83908378d87d009b05645353f22Cong Wang if (colon) 41796b45cbd956ce83908378d87d009b05645353f22Cong Wang *colon = 0; 41896b45cbd956ce83908378d87d009b05645353f22Cong Wang 41996b45cbd956ce83908378d87d009b05645353f22Cong Wang /* 42096b45cbd956ce83908378d87d009b05645353f22Cong Wang * See which interface the caller is talking about. 42196b45cbd956ce83908378d87d009b05645353f22Cong Wang */ 42296b45cbd956ce83908378d87d009b05645353f22Cong Wang 42396b45cbd956ce83908378d87d009b05645353f22Cong Wang switch (cmd) { 42496b45cbd956ce83908378d87d009b05645353f22Cong Wang /* 42596b45cbd956ce83908378d87d009b05645353f22Cong Wang * These ioctl calls: 42696b45cbd956ce83908378d87d009b05645353f22Cong Wang * - can be done by all. 42796b45cbd956ce83908378d87d009b05645353f22Cong Wang * - atomic and do not require locking. 42896b45cbd956ce83908378d87d009b05645353f22Cong Wang * - return a value 42996b45cbd956ce83908378d87d009b05645353f22Cong Wang */ 43096b45cbd956ce83908378d87d009b05645353f22Cong Wang case SIOCGIFFLAGS: 43196b45cbd956ce83908378d87d009b05645353f22Cong Wang case SIOCGIFMETRIC: 43296b45cbd956ce83908378d87d009b05645353f22Cong Wang case SIOCGIFMTU: 43396b45cbd956ce83908378d87d009b05645353f22Cong Wang case SIOCGIFHWADDR: 43496b45cbd956ce83908378d87d009b05645353f22Cong Wang case SIOCGIFSLAVE: 43596b45cbd956ce83908378d87d009b05645353f22Cong Wang case SIOCGIFMAP: 43696b45cbd956ce83908378d87d009b05645353f22Cong Wang case SIOCGIFINDEX: 43796b45cbd956ce83908378d87d009b05645353f22Cong Wang case SIOCGIFTXQLEN: 43896b45cbd956ce83908378d87d009b05645353f22Cong Wang dev_load(net, ifr.ifr_name); 43996b45cbd956ce83908378d87d009b05645353f22Cong Wang rcu_read_lock(); 44096b45cbd956ce83908378d87d009b05645353f22Cong Wang ret = dev_ifsioc_locked(net, &ifr, cmd); 44196b45cbd956ce83908378d87d009b05645353f22Cong Wang rcu_read_unlock(); 44296b45cbd956ce83908378d87d009b05645353f22Cong Wang if (!ret) { 44396b45cbd956ce83908378d87d009b05645353f22Cong Wang if (colon) 44496b45cbd956ce83908378d87d009b05645353f22Cong Wang *colon = ':'; 44596b45cbd956ce83908378d87d009b05645353f22Cong Wang if (copy_to_user(arg, &ifr, 44696b45cbd956ce83908378d87d009b05645353f22Cong Wang sizeof(struct ifreq))) 44796b45cbd956ce83908378d87d009b05645353f22Cong Wang ret = -EFAULT; 44896b45cbd956ce83908378d87d009b05645353f22Cong Wang } 44996b45cbd956ce83908378d87d009b05645353f22Cong Wang return ret; 45096b45cbd956ce83908378d87d009b05645353f22Cong Wang 45196b45cbd956ce83908378d87d009b05645353f22Cong Wang case SIOCETHTOOL: 45296b45cbd956ce83908378d87d009b05645353f22Cong Wang dev_load(net, ifr.ifr_name); 45396b45cbd956ce83908378d87d009b05645353f22Cong Wang rtnl_lock(); 45496b45cbd956ce83908378d87d009b05645353f22Cong Wang ret = dev_ethtool(net, &ifr); 45596b45cbd956ce83908378d87d009b05645353f22Cong Wang rtnl_unlock(); 45696b45cbd956ce83908378d87d009b05645353f22Cong Wang if (!ret) { 45796b45cbd956ce83908378d87d009b05645353f22Cong Wang if (colon) 45896b45cbd956ce83908378d87d009b05645353f22Cong Wang *colon = ':'; 45996b45cbd956ce83908378d87d009b05645353f22Cong Wang if (copy_to_user(arg, &ifr, 46096b45cbd956ce83908378d87d009b05645353f22Cong Wang sizeof(struct ifreq))) 46196b45cbd956ce83908378d87d009b05645353f22Cong Wang ret = -EFAULT; 46296b45cbd956ce83908378d87d009b05645353f22Cong Wang } 46396b45cbd956ce83908378d87d009b05645353f22Cong Wang return ret; 46496b45cbd956ce83908378d87d009b05645353f22Cong Wang 46596b45cbd956ce83908378d87d009b05645353f22Cong Wang /* 46696b45cbd956ce83908378d87d009b05645353f22Cong Wang * These ioctl calls: 46796b45cbd956ce83908378d87d009b05645353f22Cong Wang * - require superuser power. 46896b45cbd956ce83908378d87d009b05645353f22Cong Wang * - require strict serialization. 46996b45cbd956ce83908378d87d009b05645353f22Cong Wang * - return a value 47096b45cbd956ce83908378d87d009b05645353f22Cong Wang */ 47196b45cbd956ce83908378d87d009b05645353f22Cong Wang case SIOCGMIIPHY: 47296b45cbd956ce83908378d87d009b05645353f22Cong Wang case SIOCGMIIREG: 47396b45cbd956ce83908378d87d009b05645353f22Cong Wang case SIOCSIFNAME: 47496b45cbd956ce83908378d87d009b05645353f22Cong Wang if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) 47596b45cbd956ce83908378d87d009b05645353f22Cong Wang return -EPERM; 47696b45cbd956ce83908378d87d009b05645353f22Cong Wang dev_load(net, ifr.ifr_name); 47796b45cbd956ce83908378d87d009b05645353f22Cong Wang rtnl_lock(); 47896b45cbd956ce83908378d87d009b05645353f22Cong Wang ret = dev_ifsioc(net, &ifr, cmd); 47996b45cbd956ce83908378d87d009b05645353f22Cong Wang rtnl_unlock(); 48096b45cbd956ce83908378d87d009b05645353f22Cong Wang if (!ret) { 48196b45cbd956ce83908378d87d009b05645353f22Cong Wang if (colon) 48296b45cbd956ce83908378d87d009b05645353f22Cong Wang *colon = ':'; 48396b45cbd956ce83908378d87d009b05645353f22Cong Wang if (copy_to_user(arg, &ifr, 48496b45cbd956ce83908378d87d009b05645353f22Cong Wang sizeof(struct ifreq))) 48596b45cbd956ce83908378d87d009b05645353f22Cong Wang ret = -EFAULT; 48696b45cbd956ce83908378d87d009b05645353f22Cong Wang } 48796b45cbd956ce83908378d87d009b05645353f22Cong Wang return ret; 48896b45cbd956ce83908378d87d009b05645353f22Cong Wang 48996b45cbd956ce83908378d87d009b05645353f22Cong Wang /* 49096b45cbd956ce83908378d87d009b05645353f22Cong Wang * These ioctl calls: 49196b45cbd956ce83908378d87d009b05645353f22Cong Wang * - require superuser power. 49296b45cbd956ce83908378d87d009b05645353f22Cong Wang * - require strict serialization. 49396b45cbd956ce83908378d87d009b05645353f22Cong Wang * - do not return a value 49496b45cbd956ce83908378d87d009b05645353f22Cong Wang */ 49596b45cbd956ce83908378d87d009b05645353f22Cong Wang case SIOCSIFMAP: 49696b45cbd956ce83908378d87d009b05645353f22Cong Wang case SIOCSIFTXQLEN: 49796b45cbd956ce83908378d87d009b05645353f22Cong Wang if (!capable(CAP_NET_ADMIN)) 49896b45cbd956ce83908378d87d009b05645353f22Cong Wang return -EPERM; 49996b45cbd956ce83908378d87d009b05645353f22Cong Wang /* fall through */ 50096b45cbd956ce83908378d87d009b05645353f22Cong Wang /* 50196b45cbd956ce83908378d87d009b05645353f22Cong Wang * These ioctl calls: 50296b45cbd956ce83908378d87d009b05645353f22Cong Wang * - require local superuser power. 50396b45cbd956ce83908378d87d009b05645353f22Cong Wang * - require strict serialization. 50496b45cbd956ce83908378d87d009b05645353f22Cong Wang * - do not return a value 50596b45cbd956ce83908378d87d009b05645353f22Cong Wang */ 50696b45cbd956ce83908378d87d009b05645353f22Cong Wang case SIOCSIFFLAGS: 50796b45cbd956ce83908378d87d009b05645353f22Cong Wang case SIOCSIFMETRIC: 50896b45cbd956ce83908378d87d009b05645353f22Cong Wang case SIOCSIFMTU: 50996b45cbd956ce83908378d87d009b05645353f22Cong Wang case SIOCSIFHWADDR: 51096b45cbd956ce83908378d87d009b05645353f22Cong Wang case SIOCSIFSLAVE: 51196b45cbd956ce83908378d87d009b05645353f22Cong Wang case SIOCADDMULTI: 51296b45cbd956ce83908378d87d009b05645353f22Cong Wang case SIOCDELMULTI: 51396b45cbd956ce83908378d87d009b05645353f22Cong Wang case SIOCSIFHWBROADCAST: 51496b45cbd956ce83908378d87d009b05645353f22Cong Wang case SIOCSMIIREG: 51596b45cbd956ce83908378d87d009b05645353f22Cong Wang case SIOCBONDENSLAVE: 51696b45cbd956ce83908378d87d009b05645353f22Cong Wang case SIOCBONDRELEASE: 51796b45cbd956ce83908378d87d009b05645353f22Cong Wang case SIOCBONDSETHWADDR: 51896b45cbd956ce83908378d87d009b05645353f22Cong Wang case SIOCBONDCHANGEACTIVE: 51996b45cbd956ce83908378d87d009b05645353f22Cong Wang case SIOCBRADDIF: 52096b45cbd956ce83908378d87d009b05645353f22Cong Wang case SIOCBRDELIF: 52196b45cbd956ce83908378d87d009b05645353f22Cong Wang case SIOCSHWTSTAMP: 52296b45cbd956ce83908378d87d009b05645353f22Cong Wang if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) 52396b45cbd956ce83908378d87d009b05645353f22Cong Wang return -EPERM; 52496b45cbd956ce83908378d87d009b05645353f22Cong Wang /* fall through */ 52596b45cbd956ce83908378d87d009b05645353f22Cong Wang case SIOCBONDSLAVEINFOQUERY: 52696b45cbd956ce83908378d87d009b05645353f22Cong Wang case SIOCBONDINFOQUERY: 52796b45cbd956ce83908378d87d009b05645353f22Cong Wang dev_load(net, ifr.ifr_name); 52896b45cbd956ce83908378d87d009b05645353f22Cong Wang rtnl_lock(); 52996b45cbd956ce83908378d87d009b05645353f22Cong Wang ret = dev_ifsioc(net, &ifr, cmd); 53096b45cbd956ce83908378d87d009b05645353f22Cong Wang rtnl_unlock(); 53196b45cbd956ce83908378d87d009b05645353f22Cong Wang return ret; 53296b45cbd956ce83908378d87d009b05645353f22Cong Wang 53396b45cbd956ce83908378d87d009b05645353f22Cong Wang case SIOCGIFMEM: 53496b45cbd956ce83908378d87d009b05645353f22Cong Wang /* Get the per device memory space. We can add this but 53596b45cbd956ce83908378d87d009b05645353f22Cong Wang * currently do not support it */ 53696b45cbd956ce83908378d87d009b05645353f22Cong Wang case SIOCSIFMEM: 53796b45cbd956ce83908378d87d009b05645353f22Cong Wang /* Set the per device memory buffer space. 53896b45cbd956ce83908378d87d009b05645353f22Cong Wang * Not applicable in our case */ 53996b45cbd956ce83908378d87d009b05645353f22Cong Wang case SIOCSIFLINK: 54096b45cbd956ce83908378d87d009b05645353f22Cong Wang return -ENOTTY; 54196b45cbd956ce83908378d87d009b05645353f22Cong Wang 54296b45cbd956ce83908378d87d009b05645353f22Cong Wang /* 54396b45cbd956ce83908378d87d009b05645353f22Cong Wang * Unknown or private ioctl. 54496b45cbd956ce83908378d87d009b05645353f22Cong Wang */ 54596b45cbd956ce83908378d87d009b05645353f22Cong Wang default: 54696b45cbd956ce83908378d87d009b05645353f22Cong Wang if (cmd == SIOCWANDEV || 547fd468c74bd4d6949736810a80d6ca05eb20fba84Ben Hutchings cmd == SIOCGHWTSTAMP || 54896b45cbd956ce83908378d87d009b05645353f22Cong Wang (cmd >= SIOCDEVPRIVATE && 54996b45cbd956ce83908378d87d009b05645353f22Cong Wang cmd <= SIOCDEVPRIVATE + 15)) { 55096b45cbd956ce83908378d87d009b05645353f22Cong Wang dev_load(net, ifr.ifr_name); 55196b45cbd956ce83908378d87d009b05645353f22Cong Wang rtnl_lock(); 55296b45cbd956ce83908378d87d009b05645353f22Cong Wang ret = dev_ifsioc(net, &ifr, cmd); 55396b45cbd956ce83908378d87d009b05645353f22Cong Wang rtnl_unlock(); 55496b45cbd956ce83908378d87d009b05645353f22Cong Wang if (!ret && copy_to_user(arg, &ifr, 55596b45cbd956ce83908378d87d009b05645353f22Cong Wang sizeof(struct ifreq))) 55696b45cbd956ce83908378d87d009b05645353f22Cong Wang ret = -EFAULT; 55796b45cbd956ce83908378d87d009b05645353f22Cong Wang return ret; 55896b45cbd956ce83908378d87d009b05645353f22Cong Wang } 55996b45cbd956ce83908378d87d009b05645353f22Cong Wang /* Take care of Wireless Extensions */ 56096b45cbd956ce83908378d87d009b05645353f22Cong Wang if (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST) 56196b45cbd956ce83908378d87d009b05645353f22Cong Wang return wext_handle_ioctl(net, &ifr, cmd, arg); 56296b45cbd956ce83908378d87d009b05645353f22Cong Wang return -ENOTTY; 56396b45cbd956ce83908378d87d009b05645353f22Cong Wang } 56496b45cbd956ce83908378d87d009b05645353f22Cong Wang} 565