Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
[deliverable/linux.git] / net / core / dev.c
index 89e33a5d4d932c54af74a08cb080809affc7dd67..3e645f3751bf43e436952294390828c90541992a 100644 (file)
@@ -959,18 +959,30 @@ int dev_alloc_name(struct net_device *dev, const char *name)
 }
 EXPORT_SYMBOL(dev_alloc_name);
 
-static int dev_get_valid_name(struct net_device *dev, const char *name)
+static int dev_alloc_name_ns(struct net *net,
+                            struct net_device *dev,
+                            const char *name)
 {
-       struct net *net;
+       char buf[IFNAMSIZ];
+       int ret;
 
-       BUG_ON(!dev_net(dev));
-       net = dev_net(dev);
+       ret = __dev_alloc_name(net, name, buf);
+       if (ret >= 0)
+               strlcpy(dev->name, buf, IFNAMSIZ);
+       return ret;
+}
+
+static int dev_get_valid_name(struct net *net,
+                             struct net_device *dev,
+                             const char *name)
+{
+       BUG_ON(!net);
 
        if (!dev_valid_name(name))
                return -EINVAL;
 
        if (strchr(name, '%'))
-               return dev_alloc_name(dev, name);
+               return dev_alloc_name_ns(net, dev, name);
        else if (__dev_get_by_name(net, name))
                return -EEXIST;
        else if (dev->name != name)
@@ -1006,7 +1018,7 @@ int dev_change_name(struct net_device *dev, const char *newname)
 
        memcpy(oldname, dev->name, IFNAMSIZ);
 
-       err = dev_get_valid_name(dev, newname);
+       err = dev_get_valid_name(net, dev, newname);
        if (err < 0)
                return err;
 
@@ -1109,11 +1121,23 @@ void netdev_state_change(struct net_device *dev)
 }
 EXPORT_SYMBOL(netdev_state_change);
 
-int netdev_bonding_change(struct net_device *dev, unsigned long event)
+/**
+ *     netdev_notify_peers - notify network peers about existence of @dev
+ *     @dev: network device
+ *
+ * Generate traffic such that interested network peers are aware of
+ * @dev, such as by generating a gratuitous ARP. This may be used when
+ * a device wants to inform the rest of the network about some sort of
+ * reconfiguration such as a failover event or virtual machine
+ * migration.
+ */
+void netdev_notify_peers(struct net_device *dev)
 {
-       return call_netdevice_notifiers(event, dev);
+       rtnl_lock();
+       call_netdevice_notifiers(NETDEV_NOTIFY_PEERS, dev);
+       rtnl_unlock();
 }
-EXPORT_SYMBOL(netdev_bonding_change);
+EXPORT_SYMBOL(netdev_notify_peers);
 
 /**
  *     dev_load        - load a network module
@@ -1394,7 +1418,6 @@ rollback:
                                nb->notifier_call(nb, NETDEV_DOWN, dev);
                        }
                        nb->notifier_call(nb, NETDEV_UNREGISTER, dev);
-                       nb->notifier_call(nb, NETDEV_UNREGISTER_BATCH, dev);
                }
        }
 
@@ -1436,7 +1459,6 @@ int unregister_netdevice_notifier(struct notifier_block *nb)
                                nb->notifier_call(nb, NETDEV_DOWN, dev);
                        }
                        nb->notifier_call(nb, NETDEV_UNREGISTER, dev);
-                       nb->notifier_call(nb, NETDEV_UNREGISTER_BATCH, dev);
                }
        }
 unlock:
@@ -2175,9 +2197,7 @@ EXPORT_SYMBOL(netif_skb_features);
 /*
  * Returns true if either:
  *     1. skb has frag_list and the device doesn't support FRAGLIST, or
- *     2. skb is fragmented and the device does not support SG, or if
- *        at least one of fragments is in highmem and device does not
- *        support DMA from it.
+ *     2. skb is fragmented and the device does not support SG.
  */
 static inline int skb_needs_linearize(struct sk_buff *skb,
                                      int features)
@@ -2206,9 +2226,6 @@ int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev,
                if (dev->priv_flags & IFF_XMIT_DST_RELEASE)
                        skb_dst_drop(skb);
 
-               if (!list_empty(&ptype_all))
-                       dev_queue_xmit_nit(skb, dev);
-
                features = netif_skb_features(skb);
 
                if (vlan_tx_tag_present(skb) &&
@@ -2243,6 +2260,9 @@ int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev,
                        }
                }
 
+               if (!list_empty(&ptype_all))
+                       dev_queue_xmit_nit(skb, dev);
+
                skb_len = skb->len;
                rc = ops->ndo_start_xmit(skb, dev);
                trace_net_dev_xmit(skb, rc, dev, skb_len);
@@ -2265,6 +2285,9 @@ gso:
                if (dev->priv_flags & IFF_XMIT_DST_RELEASE)
                        skb_dst_drop(nskb);
 
+               if (!list_empty(&ptype_all))
+                       dev_queue_xmit_nit(nskb, dev);
+
                skb_len = nskb->len;
                rc = ops->ndo_start_xmit(nskb, dev);
                trace_net_dev_xmit(nskb, rc, dev, skb_len);
@@ -2374,8 +2397,8 @@ static inline int get_xps_queue(struct net_device *dev, struct sk_buff *skb)
 #endif
 }
 
-static struct netdev_queue *dev_pick_tx(struct net_device *dev,
-                                       struct sk_buff *skb)
+struct netdev_queue *netdev_pick_tx(struct net_device *dev,
+                                   struct sk_buff *skb)
 {
        int queue_index;
        const struct net_device_ops *ops = dev->netdev_ops;
@@ -2549,7 +2572,7 @@ int dev_queue_xmit(struct sk_buff *skb)
 
        skb_update_prio(skb);
 
-       txq = dev_pick_tx(dev, skb);
+       txq = netdev_pick_tx(dev, skb);
        q = rcu_dereference_bh(txq->qdisc);
 
 #ifdef CONFIG_NET_CLS_ACT
@@ -4512,8 +4535,8 @@ static void dev_change_rx_flags(struct net_device *dev, int flags)
 static int __dev_set_promiscuity(struct net_device *dev, int inc)
 {
        unsigned int old_flags = dev->flags;
-       uid_t uid;
-       gid_t gid;
+       kuid_t uid;
+       kgid_t gid;
 
        ASSERT_RTNL();
 
@@ -4545,7 +4568,8 @@ static int __dev_set_promiscuity(struct net_device *dev, int inc)
                                dev->name, (dev->flags & IFF_PROMISC),
                                (old_flags & IFF_PROMISC),
                                audit_get_loginuid(current),
-                               uid, gid,
+                               from_kuid(&init_user_ns, uid),
+                               from_kgid(&init_user_ns, gid),
                                audit_get_sessionid(current));
                }
 
@@ -5238,12 +5262,12 @@ int dev_ioctl(struct net *net, unsigned int cmd, void __user *arg)
  */
 static int dev_new_index(struct net *net)
 {
-       static int ifindex;
+       int ifindex = net->ifindex;
        for (;;) {
                if (++ifindex <= 0)
                        ifindex = 1;
                if (!__dev_get_by_index(net, ifindex))
-                       return ifindex;
+                       return net->ifindex = ifindex;
        }
 }
 
@@ -5321,10 +5345,6 @@ static void rollback_registered_many(struct list_head *head)
                netdev_unregister_kobject(dev);
        }
 
-       /* Process any work delayed until the end of the batch */
-       dev = list_first_entry(head, struct net_device, unreg_list);
-       call_netdevice_notifiers(NETDEV_UNREGISTER_BATCH, dev);
-
        synchronize_net();
 
        list_for_each_entry(dev, head, unreg_list)
@@ -5582,7 +5602,7 @@ int register_netdevice(struct net_device *dev)
 
        dev->iflink = -1;
 
-       ret = dev_get_valid_name(dev, dev->name);
+       ret = dev_get_valid_name(net, dev, dev->name);
        if (ret < 0)
                goto out;
 
@@ -5596,7 +5616,12 @@ int register_netdevice(struct net_device *dev)
                }
        }
 
-       dev->ifindex = dev_new_index(net);
+       ret = -EBUSY;
+       if (!dev->ifindex)
+               dev->ifindex = dev_new_index(net);
+       else if (__dev_get_by_index(net, dev->ifindex))
+               goto err_uninit;
+
        if (dev->iflink == -1)
                dev->iflink = dev->ifindex;
 
@@ -5639,6 +5664,8 @@ int register_netdevice(struct net_device *dev)
 
        set_bit(__LINK_STATE_PRESENT, &dev->state);
 
+       linkwatch_init_dev(dev);
+
        dev_init_scheduler(dev);
        dev_hold(dev);
        list_netdevice(dev);
@@ -5772,9 +5799,12 @@ static void netdev_wait_allrefs(struct net_device *dev)
 
                        /* Rebroadcast unregister notification */
                        call_netdevice_notifiers(NETDEV_UNREGISTER, dev);
-                       /* don't resend NETDEV_UNREGISTER_BATCH, _BATCH users
-                        * should have already handle it the first time */
 
+                       __rtnl_unlock();
+                       rcu_barrier();
+                       rtnl_lock();
+
+                       call_netdevice_notifiers(NETDEV_UNREGISTER_FINAL, dev);
                        if (test_bit(__LINK_STATE_LINKWATCH_PENDING,
                                     &dev->state)) {
                                /* We must not have linkwatch events
@@ -5836,9 +5866,8 @@ void netdev_run_todo(void)
 
        __rtnl_unlock();
 
-       /* Wait for rcu callbacks to finish before attempting to drain
-        * the device list.  This usually avoids a 250ms wait.
-        */
+
+       /* Wait for rcu callbacks to finish before next phase */
        if (!list_empty(&list))
                rcu_barrier();
 
@@ -5847,6 +5876,10 @@ void netdev_run_todo(void)
                        = list_first_entry(&list, struct net_device, todo_list);
                list_del(&dev->todo_list);
 
+               rtnl_lock();
+               call_netdevice_notifiers(NETDEV_UNREGISTER_FINAL, dev);
+               __rtnl_unlock();
+
                if (unlikely(dev->reg_state != NETREG_UNREGISTERING)) {
                        pr_err("network todo '%s' but state %d\n",
                               dev->name, dev->reg_state);
@@ -5942,6 +5975,8 @@ struct netdev_queue *dev_ingress_queue_create(struct net_device *dev)
        return queue;
 }
 
+static const struct ethtool_ops default_ethtool_ops;
+
 /**
  *     alloc_netdev_mqs - allocate network device
  *     @sizeof_priv:   size of private data to allocate space for
@@ -6029,6 +6064,8 @@ struct net_device *alloc_netdev_mqs(int sizeof_priv, const char *name,
 
        strcpy(dev->name, name);
        dev->group = INIT_NETDEV_GROUP;
+       if (!dev->ethtool_ops)
+               dev->ethtool_ops = &default_ethtool_ops;
        return dev;
 
 free_all:
@@ -6213,7 +6250,7 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char
                /* We get here if we can't use the current device name */
                if (!pat)
                        goto out;
-               if (dev_get_valid_name(dev, pat) < 0)
+               if (dev_get_valid_name(net, dev, pat) < 0)
                        goto out;
        }
 
@@ -6241,7 +6278,8 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char
           the device is just moving and can keep their slaves up.
        */
        call_netdevice_notifiers(NETDEV_UNREGISTER, dev);
-       call_netdevice_notifiers(NETDEV_UNREGISTER_BATCH, dev);
+       rcu_barrier();
+       call_netdevice_notifiers(NETDEV_UNREGISTER_FINAL, dev);
        rtmsg_ifinfo(RTM_DELLINK, dev, ~0U);
 
        /*
This page took 0.027826 seconds and 5 git commands to generate.