datapath: Add generic virtual port layer.
[sliver-openvswitch.git] / datapath / dp_notify.c
1 /*
2  * Distributed under the terms of the GNU GPL version 2.
3  * Copyright (c) 2007, 2008, 2009, 2010 Nicira Networks.
4  *
5  * Significant portions of this file may be copied from parts of the Linux
6  * kernel, by Linus Torvalds and others.
7  */
8
9 /* Handle changes to managed devices */
10
11 #include <linux/netdevice.h>
12
13 #include "datapath.h"
14 #include "vport-internal_dev.h"
15 #include "vport-netdev.h"
16
17 static int dp_device_event(struct notifier_block *unused, unsigned long event, 
18                 void *ptr) 
19 {
20         struct net_device *dev = ptr;
21         struct vport *vport;
22         struct dp_port *p;
23         struct datapath *dp;
24
25         if (is_internal_dev(dev))
26                 vport = internal_dev_get_vport(dev);
27         else {
28                 vport = netdev_get_vport(dev);
29
30                 if (!vport)
31                         return NOTIFY_DONE;
32         }
33
34         p = vport_get_dp_port(vport);
35
36         if (!p)
37                 return NOTIFY_DONE;
38         dp = p->dp;
39
40         switch (event) {
41         case NETDEV_UNREGISTER:
42                 mutex_lock(&dp->mutex);
43                 dp_detach_port(p, 1);
44                 mutex_unlock(&dp->mutex);
45                 break;
46
47         case NETDEV_CHANGENAME:
48                 if (p->port_no != ODPP_LOCAL) {
49                         mutex_lock(&dp->mutex);
50                         dp_sysfs_del_if(p);
51                         dp_sysfs_add_if(p);
52                         mutex_unlock(&dp->mutex);
53                 }
54                 break;
55
56         case NETDEV_CHANGEMTU:
57                 if (!is_internal_dev(dev)) {
58                         mutex_lock(&dp->mutex);
59                         set_internal_devs_mtu(dp);
60                         mutex_unlock(&dp->mutex);
61                 }
62                 break;
63         }
64         return NOTIFY_DONE;
65 }
66
67 struct notifier_block dp_device_notifier = {
68         .notifier_call = dp_device_event
69 };