Files
openflow/datapath/dp_notify.c
T
Justin Pettit 1400bbb7eb Use device notifier in Linux kernel switch for detecting port status changes.
To report on link status and whether a port is administratively enabled or
disabled, the reference switches poll.  This change uses the Linux kernel's
device notification system, so that polling isn't necessary.
2008-09-19 16:10:28 -07:00

64 lines
1.3 KiB
C

/*
* Distributed under the terms of the GNU GPL version 2.
* Copyright (c) 2007, 2008 The Board of Trustees of The Leland
* Stanford Junior University
*/
/* Handle changes to managed devices */
#include <linux/netdevice.h>
#include "datapath.h"
static int dp_device_event(struct notifier_block *unused, unsigned long event,
void *ptr)
{
struct net_device *dev = ptr;
struct net_bridge_port *p = dev->br_port;
unsigned long int flags;
uint32_t orig_status;
/* Check if monitored port */
if (!p)
return NOTIFY_DONE;
spin_lock_irqsave(&p->lock, flags);
orig_status = p->status;
switch (event) {
case NETDEV_CHANGE:
if (netif_carrier_ok(p->dev))
p->status &= ~OFPPFL_LINK_DOWN;
else
p->status |= OFPPFL_LINK_DOWN;
break;
case NETDEV_DOWN:
p->status |= OFPPFL_PORT_DOWN;
break;
case NETDEV_UP:
p->status &= ~OFPPFL_PORT_DOWN;
break;
case NETDEV_UNREGISTER:
/* xxx Make sure this is correct */
spin_unlock_irqrestore(&p->lock, flags);
dp_del_switch_port(p);
return NOTIFY_DONE;
break;
}
spin_unlock_irqrestore(&p->lock, flags);
if (orig_status != p->status)
dp_send_port_status(p, OFPPR_MOD);
return NOTIFY_DONE;
}
struct notifier_block dp_device_notifier = {
.notifier_call = dp_device_event
};