]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - net/core/dev.c
Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
[linux-2.6-omap-h63xx.git] / net / core / dev.c
index e0489ca731c57f17dda1ce30cfc7747098c4e221..83231a27ae028caa5c0757d35c9d107220e8711e 100644 (file)
 #include <linux/wireless.h>
 #include <net/iw_handler.h>
 #include <asm/current.h>
+#include <linux/audit.h>
 
 /*
  *     The list of packet types we will receive (as opposed to discard)
@@ -192,7 +193,7 @@ static inline struct hlist_head *dev_index_hash(int ifindex)
  *     Our notifier list
  */
 
-static struct notifier_block *netdev_chain;
+static BLOCKING_NOTIFIER_HEAD(netdev_chain);
 
 /*
  *     Device drivers call our routines to queue packets here. We empty the
@@ -735,7 +736,8 @@ int dev_change_name(struct net_device *dev, char *newname)
        if (!err) {
                hlist_del(&dev->name_hlist);
                hlist_add_head(&dev->name_hlist, dev_name_hash(dev->name));
-               notifier_call_chain(&netdev_chain, NETDEV_CHANGENAME, dev);
+               blocking_notifier_call_chain(&netdev_chain,
+                               NETDEV_CHANGENAME, dev);
        }
 
        return err;
@@ -749,7 +751,7 @@ int dev_change_name(struct net_device *dev, char *newname)
  */
 void netdev_features_change(struct net_device *dev)
 {
-       notifier_call_chain(&netdev_chain, NETDEV_FEAT_CHANGE, dev);
+       blocking_notifier_call_chain(&netdev_chain, NETDEV_FEAT_CHANGE, dev);
 }
 EXPORT_SYMBOL(netdev_features_change);
 
@@ -764,7 +766,8 @@ EXPORT_SYMBOL(netdev_features_change);
 void netdev_state_change(struct net_device *dev)
 {
        if (dev->flags & IFF_UP) {
-               notifier_call_chain(&netdev_chain, NETDEV_CHANGE, dev);
+               blocking_notifier_call_chain(&netdev_chain,
+                               NETDEV_CHANGE, dev);
                rtmsg_ifinfo(RTM_NEWLINK, dev, 0);
        }
 }
@@ -861,7 +864,7 @@ int dev_open(struct net_device *dev)
                /*
                 *      ... and announce new interface.
                 */
-               notifier_call_chain(&netdev_chain, NETDEV_UP, dev);
+               blocking_notifier_call_chain(&netdev_chain, NETDEV_UP, dev);
        }
        return ret;
 }
@@ -884,7 +887,7 @@ int dev_close(struct net_device *dev)
         *      Tell people we are going down, so that they can
         *      prepare to death, when device is still operating.
         */
-       notifier_call_chain(&netdev_chain, NETDEV_GOING_DOWN, dev);
+       blocking_notifier_call_chain(&netdev_chain, NETDEV_GOING_DOWN, dev);
 
        dev_deactivate(dev);
 
@@ -921,7 +924,7 @@ int dev_close(struct net_device *dev)
        /*
         * Tell people we are down
         */
-       notifier_call_chain(&netdev_chain, NETDEV_DOWN, dev);
+       blocking_notifier_call_chain(&netdev_chain, NETDEV_DOWN, dev);
 
        return 0;
 }
@@ -952,7 +955,7 @@ int register_netdevice_notifier(struct notifier_block *nb)
        int err;
 
        rtnl_lock();
-       err = notifier_chain_register(&netdev_chain, nb);
+       err = blocking_notifier_chain_register(&netdev_chain, nb);
        if (!err) {
                for (dev = dev_base; dev; dev = dev->next) {
                        nb->notifier_call(nb, NETDEV_REGISTER, dev);
@@ -980,7 +983,7 @@ int unregister_netdevice_notifier(struct notifier_block *nb)
        int err;
 
        rtnl_lock();
-       err = notifier_chain_unregister(&netdev_chain, nb);
+       err = blocking_notifier_chain_unregister(&netdev_chain, nb);
        rtnl_unlock();
        return err;
 }
@@ -991,12 +994,12 @@ int unregister_netdevice_notifier(struct notifier_block *nb)
  *      @v:   pointer passed unmodified to notifier function
  *
  *     Call all network notifier blocks.  Parameters and return value
- *     are as for notifier_call_chain().
+ *     are as for blocking_notifier_call_chain().
  */
 
 int call_netdevice_notifiers(unsigned long val, void *v)
 {
-       return notifier_call_chain(&netdev_chain, val, v);
+       return blocking_notifier_call_chain(&netdev_chain, val, v);
 }
 
 /* When > 0 there are consumers of rx skb time stamps */
@@ -1077,6 +1080,70 @@ void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev)
        rcu_read_unlock();
 }
 
+
+void __netif_schedule(struct net_device *dev)
+{
+       if (!test_and_set_bit(__LINK_STATE_SCHED, &dev->state)) {
+               unsigned long flags;
+               struct softnet_data *sd;
+
+               local_irq_save(flags);
+               sd = &__get_cpu_var(softnet_data);
+               dev->next_sched = sd->output_queue;
+               sd->output_queue = dev;
+               raise_softirq_irqoff(NET_TX_SOFTIRQ);
+               local_irq_restore(flags);
+       }
+}
+EXPORT_SYMBOL(__netif_schedule);
+
+void __netif_rx_schedule(struct net_device *dev)
+{
+       unsigned long flags;
+
+       local_irq_save(flags);
+       dev_hold(dev);
+       list_add_tail(&dev->poll_list, &__get_cpu_var(softnet_data).poll_list);
+       if (dev->quota < 0)
+               dev->quota += dev->weight;
+       else
+               dev->quota = dev->weight;
+       __raise_softirq_irqoff(NET_RX_SOFTIRQ);
+       local_irq_restore(flags);
+}
+EXPORT_SYMBOL(__netif_rx_schedule);
+
+void dev_kfree_skb_any(struct sk_buff *skb)
+{
+       if (in_irq() || irqs_disabled())
+               dev_kfree_skb_irq(skb);
+       else
+               dev_kfree_skb(skb);
+}
+EXPORT_SYMBOL(dev_kfree_skb_any);
+
+
+/* Hot-plugging. */
+void netif_device_detach(struct net_device *dev)
+{
+       if (test_and_clear_bit(__LINK_STATE_PRESENT, &dev->state) &&
+           netif_running(dev)) {
+               netif_stop_queue(dev);
+       }
+}
+EXPORT_SYMBOL(netif_device_detach);
+
+void netif_device_attach(struct net_device *dev)
+{
+       if (!test_and_set_bit(__LINK_STATE_PRESENT, &dev->state) &&
+           netif_running(dev)) {
+               netif_wake_queue(dev);
+               __netdev_watchdog_up(dev);
+       }
+}
+EXPORT_SYMBOL(netif_device_attach);
+
+
 /*
  * Invalidate hardware checksum when packet is to be mangled, and
  * complete checksum manually on outgoing path.
@@ -2147,6 +2214,12 @@ void dev_set_promiscuity(struct net_device *dev, int inc)
                printk(KERN_INFO "device %s %s promiscuous mode\n",
                       dev->name, (dev->flags & IFF_PROMISC) ? "entered" :
                                                               "left");
+               audit_log(current->audit_context, GFP_ATOMIC,
+                       AUDIT_ANOM_PROMISCUOUS,
+                       "dev=%s prom=%d old_prom=%d auid=%u",
+                       dev->name, (dev->flags & IFF_PROMISC),
+                       (old_flags & IFF_PROMISC),
+                       audit_get_loginuid(current->audit_context)); 
        }
 }
 
@@ -2235,7 +2308,8 @@ int dev_change_flags(struct net_device *dev, unsigned flags)
        if (dev->flags & IFF_UP &&
            ((old_flags ^ dev->flags) &~ (IFF_UP | IFF_PROMISC | IFF_ALLMULTI |
                                          IFF_VOLATILE)))
-               notifier_call_chain(&netdev_chain, NETDEV_CHANGE, dev);
+               blocking_notifier_call_chain(&netdev_chain,
+                               NETDEV_CHANGE, dev);
 
        if ((flags ^ dev->gflags) & IFF_PROMISC) {
                int inc = (flags & IFF_PROMISC) ? +1 : -1;
@@ -2279,8 +2353,8 @@ int dev_set_mtu(struct net_device *dev, int new_mtu)
        else
                dev->mtu = new_mtu;
        if (!err && dev->flags & IFF_UP)
-               notifier_call_chain(&netdev_chain,
-                                   NETDEV_CHANGEMTU, dev);
+               blocking_notifier_call_chain(&netdev_chain,
+                               NETDEV_CHANGEMTU, dev);
        return err;
 }
 
@@ -2296,7 +2370,8 @@ int dev_set_mac_address(struct net_device *dev, struct sockaddr *sa)
                return -ENODEV;
        err = dev->set_mac_address(dev, sa);
        if (!err)
-               notifier_call_chain(&netdev_chain, NETDEV_CHANGEADDR, dev);
+               blocking_notifier_call_chain(&netdev_chain,
+                               NETDEV_CHANGEADDR, dev);
        return err;
 }
 
@@ -2352,7 +2427,7 @@ static int dev_ifsioc(struct ifreq *ifr, unsigned int cmd)
                                return -EINVAL;
                        memcpy(dev->broadcast, ifr->ifr_hwaddr.sa_data,
                               min(sizeof ifr->ifr_hwaddr.sa_data, (size_t) dev->addr_len));
-                       notifier_call_chain(&netdev_chain,
+                       blocking_notifier_call_chain(&netdev_chain,
                                            NETDEV_CHANGEADDR, dev);
                        return 0;
 
@@ -2806,7 +2881,7 @@ int register_netdevice(struct net_device *dev)
        write_unlock_bh(&dev_base_lock);
 
        /* Notify protocols, that a new device appeared. */
-       notifier_call_chain(&netdev_chain, NETDEV_REGISTER, dev);
+       blocking_notifier_call_chain(&netdev_chain, NETDEV_REGISTER, dev);
 
        /* Finish registration after unlock */
        net_set_todo(dev);
@@ -2885,7 +2960,7 @@ static void netdev_wait_allrefs(struct net_device *dev)
                        rtnl_lock();
 
                        /* Rebroadcast unregister notification */
-                       notifier_call_chain(&netdev_chain,
+                       blocking_notifier_call_chain(&netdev_chain,
                                            NETDEV_UNREGISTER, dev);
 
                        if (test_bit(__LINK_STATE_LINKWATCH_PENDING,
@@ -2967,11 +3042,11 @@ void netdev_run_todo(void)
 
                switch(dev->reg_state) {
                case NETREG_REGISTERING:
+                       dev->reg_state = NETREG_REGISTERED;
                        err = netdev_register_sysfs(dev);
                        if (err)
                                printk(KERN_ERR "%s: failed sysfs registration (%d)\n",
                                       dev->name, err);
-                       dev->reg_state = NETREG_REGISTERED;
                        break;
 
                case NETREG_UNREGISTERING:
@@ -3025,12 +3100,11 @@ struct net_device *alloc_netdev(int sizeof_priv, const char *name,
        alloc_size = (sizeof(*dev) + NETDEV_ALIGN_CONST) & ~NETDEV_ALIGN_CONST;
        alloc_size += sizeof_priv + NETDEV_ALIGN_CONST;
 
-       p = kmalloc(alloc_size, GFP_KERNEL);
+       p = kzalloc(alloc_size, GFP_KERNEL);
        if (!p) {
                printk(KERN_ERR "alloc_dev: Unable to allocate device.\n");
                return NULL;
        }
-       memset(p, 0, alloc_size);
 
        dev = (struct net_device *)
                (((long)p + NETDEV_ALIGN_CONST) & ~NETDEV_ALIGN_CONST);
@@ -3141,7 +3215,7 @@ int unregister_netdevice(struct net_device *dev)
        /* Notify protocols, that we are about to destroy
           this device. They should clean all the things.
        */
-       notifier_call_chain(&netdev_chain, NETDEV_UNREGISTER, dev);
+       blocking_notifier_call_chain(&netdev_chain, NETDEV_UNREGISTER, dev);
        
        /*
         *      Flush the multicast chain
@@ -3272,7 +3346,7 @@ static int __init net_dev_init(void)
         *      Initialise the packet receive queues.
         */
 
-       for_each_cpu(i) {
+       for_each_possible_cpu(i) {
                struct softnet_data *queue;
 
                queue = &per_cpu(softnet_data, i);