1 /* 2 * Copyright (c) 2007-2012 Nicira, Inc. 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of version 2 of the GNU General Public 6 * License as published by the Free Software Foundation. 7 * 8 * This program is distributed in the hope that it will be useful, but 9 * WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 * General Public License for more details. 12 * 13 * You should have received a copy of the GNU General Public License 14 * along with this program; if not, write to the Free Software 15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 16 * 02110-1301, USA 17 */ 18 19 #include <linux/netdevice.h> 20 #include <net/genetlink.h> 21 22 #include "datapath.h" 23 #include "vport-internal_dev.h" 24 #include "vport-netdev.h" 25 26 static int dp_device_event(struct notifier_block *unused, unsigned long event, 27 void *ptr) 28 { 29 struct net_device *dev = ptr; 30 struct vport *vport; 31 32 if (ovs_is_internal_dev(dev)) 33 vport = ovs_internal_dev_get_vport(dev); 34 else 35 vport = ovs_netdev_get_vport(dev); 36 37 if (!vport) 38 return NOTIFY_DONE; 39 40 switch (event) { 41 case NETDEV_UNREGISTER: 42 if (!ovs_is_internal_dev(dev)) { 43 struct sk_buff *notify; 44 struct datapath *dp = vport->dp; 45 46 notify = ovs_vport_cmd_build_info(vport, 0, 0, 47 OVS_VPORT_CMD_DEL); 48 ovs_dp_detach_port(vport); 49 if (IS_ERR(notify)) { 50 netlink_set_err(ovs_dp_get_net(dp)->genl_sock, 0, 51 ovs_dp_vport_multicast_group.id, 52 PTR_ERR(notify)); 53 break; 54 } 55 56 genlmsg_multicast_netns(ovs_dp_get_net(dp), notify, 0, 57 ovs_dp_vport_multicast_group.id, 58 GFP_KERNEL); 59 } 60 break; 61 } 62 63 return NOTIFY_DONE; 64 } 65 66 struct notifier_block ovs_dp_device_notifier = { 67 .notifier_call = dp_device_event 68 }; 69