e0bd14c5227226aea32de0d559ce8a43c0fc362b
[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         p = vport_get_dp_port(vport);
34
35         if (!p)
36                 return NOTIFY_DONE;
37         dp = p->dp;
38
39         switch (event) {
40         case NETDEV_UNREGISTER:
41                 mutex_lock(&dp->mutex);
42                 dp_detach_port(p, 1);
43                 mutex_unlock(&dp->mutex);
44                 break;
45
46         case NETDEV_CHANGENAME:
47                 if (p->port_no != ODPP_LOCAL) {
48                         mutex_lock(&dp->mutex);
49                         dp_sysfs_del_if(p);
50                         dp_sysfs_add_if(p);
51                         mutex_unlock(&dp->mutex);
52                 }
53                 break;
54
55         case NETDEV_CHANGEMTU:
56                 if (!is_internal_dev(dev))
57                         set_internal_devs_mtu(dp);
58                 break;
59         }
60         return NOTIFY_DONE;
61 }
62
63 struct notifier_block dp_device_notifier = {
64         .notifier_call = dp_device_event
65 };