linux/net/core/link_watch.c
<<
>>
Prefs
   1/*
   2 * Linux network device link state notification
   3 *
   4 * Author:
   5 *     Stefan Rompf <sux@loplof.de>
   6 *
   7 * This program is free software; you can redistribute it and/or
   8 * modify it under the terms of the GNU General Public License
   9 * as published by the Free Software Foundation; either version
  10 * 2 of the License, or (at your option) any later version.
  11 *
  12 */
  13
  14#include <linux/module.h>
  15#include <linux/netdevice.h>
  16#include <linux/if.h>
  17#include <net/sock.h>
  18#include <net/pkt_sched.h>
  19#include <linux/rtnetlink.h>
  20#include <linux/jiffies.h>
  21#include <linux/spinlock.h>
  22#include <linux/slab.h>
  23#include <linux/workqueue.h>
  24#include <linux/bitops.h>
  25#include <asm/types.h>
  26
  27
  28enum lw_bits {
  29        LW_URGENT = 0,
  30};
  31
  32static unsigned long linkwatch_flags;
  33static unsigned long linkwatch_nextevent;
  34
  35static void linkwatch_event(struct work_struct *dummy);
  36static DECLARE_DELAYED_WORK(linkwatch_work, linkwatch_event);
  37
  38static struct net_device *lweventlist;
  39static DEFINE_SPINLOCK(lweventlist_lock);
  40
  41static unsigned char default_operstate(const struct net_device *dev)
  42{
  43        if (!netif_carrier_ok(dev))
  44                return (dev->ifindex != dev->iflink ?
  45                        IF_OPER_LOWERLAYERDOWN : IF_OPER_DOWN);
  46
  47        if (netif_dormant(dev))
  48                return IF_OPER_DORMANT;
  49
  50        return IF_OPER_UP;
  51}
  52
  53
  54static void rfc2863_policy(struct net_device *dev)
  55{
  56        unsigned char operstate = default_operstate(dev);
  57
  58        if (operstate == dev->operstate)
  59                return;
  60
  61        write_lock_bh(&dev_base_lock);
  62
  63        switch(dev->link_mode) {
  64        case IF_LINK_MODE_DORMANT:
  65                if (operstate == IF_OPER_UP)
  66                        operstate = IF_OPER_DORMANT;
  67                break;
  68
  69        case IF_LINK_MODE_DEFAULT:
  70        default:
  71                break;
  72        }
  73
  74        dev->operstate = operstate;
  75
  76        write_unlock_bh(&dev_base_lock);
  77}
  78
  79
  80static bool linkwatch_urgent_event(struct net_device *dev)
  81{
  82        return netif_running(dev) && netif_carrier_ok(dev) &&
  83                qdisc_tx_changing(dev);
  84}
  85
  86
  87static void linkwatch_add_event(struct net_device *dev)
  88{
  89        unsigned long flags;
  90
  91        spin_lock_irqsave(&lweventlist_lock, flags);
  92        dev->link_watch_next = lweventlist;
  93        lweventlist = dev;
  94        spin_unlock_irqrestore(&lweventlist_lock, flags);
  95}
  96
  97
  98static void linkwatch_schedule_work(int urgent)
  99{
 100        unsigned long delay = linkwatch_nextevent - jiffies;
 101
 102        if (test_bit(LW_URGENT, &linkwatch_flags))
 103                return;
 104
 105        /* Minimise down-time: drop delay for up event. */
 106        if (urgent) {
 107                if (test_and_set_bit(LW_URGENT, &linkwatch_flags))
 108                        return;
 109                delay = 0;
 110        }
 111
 112        /* If we wrap around we'll delay it by at most HZ. */
 113        if (delay > HZ)
 114                delay = 0;
 115
 116        /*
 117         * This is true if we've scheduled it immeditately or if we don't
 118         * need an immediate execution and it's already pending.
 119         */
 120        if (schedule_delayed_work(&linkwatch_work, delay) == !delay)
 121                return;
 122
 123        /* Don't bother if there is nothing urgent. */
 124        if (!test_bit(LW_URGENT, &linkwatch_flags))
 125                return;
 126
 127        /* It's already running which is good enough. */
 128        if (!cancel_delayed_work(&linkwatch_work))
 129                return;
 130
 131        /* Otherwise we reschedule it again for immediate exection. */
 132        schedule_delayed_work(&linkwatch_work, 0);
 133}
 134
 135
 136static void __linkwatch_run_queue(int urgent_only)
 137{
 138        struct net_device *next;
 139
 140        /*
 141         * Limit the number of linkwatch events to one
 142         * per second so that a runaway driver does not
 143         * cause a storm of messages on the netlink
 144         * socket.  This limit does not apply to up events
 145         * while the device qdisc is down.
 146         */
 147        if (!urgent_only)
 148                linkwatch_nextevent = jiffies + HZ;
 149        /* Limit wrap-around effect on delay. */
 150        else if (time_after(linkwatch_nextevent, jiffies + HZ))
 151                linkwatch_nextevent = jiffies;
 152
 153        clear_bit(LW_URGENT, &linkwatch_flags);
 154
 155        spin_lock_irq(&lweventlist_lock);
 156        next = lweventlist;
 157        lweventlist = NULL;
 158        spin_unlock_irq(&lweventlist_lock);
 159
 160        while (next) {
 161                struct net_device *dev = next;
 162
 163                next = dev->link_watch_next;
 164
 165                if (urgent_only && !linkwatch_urgent_event(dev)) {
 166                        linkwatch_add_event(dev);
 167                        continue;
 168                }
 169
 170                /*
 171                 * Make sure the above read is complete since it can be
 172                 * rewritten as soon as we clear the bit below.
 173                 */
 174                smp_mb__before_clear_bit();
 175
 176                /* We are about to handle this device,
 177                 * so new events can be accepted
 178                 */
 179                clear_bit(__LINK_STATE_LINKWATCH_PENDING, &dev->state);
 180
 181                rfc2863_policy(dev);
 182                if (dev->flags & IFF_UP) {
 183                        if (netif_carrier_ok(dev))
 184                                dev_activate(dev);
 185                        else
 186                                dev_deactivate(dev);
 187
 188                        netdev_state_change(dev);
 189                }
 190
 191                dev_put(dev);
 192        }
 193
 194        if (lweventlist)
 195                linkwatch_schedule_work(0);
 196}
 197
 198
 199/* Must be called with the rtnl semaphore held */
 200void linkwatch_run_queue(void)
 201{
 202        __linkwatch_run_queue(0);
 203}
 204
 205
 206static void linkwatch_event(struct work_struct *dummy)
 207{
 208        rtnl_lock();
 209        __linkwatch_run_queue(time_after(linkwatch_nextevent, jiffies));
 210        rtnl_unlock();
 211}
 212
 213
 214void linkwatch_fire_event(struct net_device *dev)
 215{
 216        bool urgent = linkwatch_urgent_event(dev);
 217
 218        if (!test_and_set_bit(__LINK_STATE_LINKWATCH_PENDING, &dev->state)) {
 219                dev_hold(dev);
 220
 221                linkwatch_add_event(dev);
 222        } else if (!urgent)
 223                return;
 224
 225        linkwatch_schedule_work(urgent);
 226}
 227
 228EXPORT_SYMBOL(linkwatch_fire_event);
 229