2 * Copyright (c) 2007-2012 Nicira, Inc.
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.
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.
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
19 #include <linux/netdevice.h>
20 #include <net/genetlink.h>
21 #include <net/netns/generic.h>
24 #include "vport-internal_dev.h"
25 #include "vport-netdev.h"
27 static void dp_detach_port_notify(struct vport
*vport
)
29 struct sk_buff
*notify
;
33 notify
= ovs_vport_cmd_build_info(vport
, ovs_dp_get_net(dp
),
34 0, 0, OVS_VPORT_CMD_DEL
);
35 ovs_dp_detach_port(vport
);
37 genl_set_err(&dp_vport_genl_family
, ovs_dp_get_net(dp
), 0,
42 genlmsg_multicast_netns(&dp_vport_genl_family
,
43 ovs_dp_get_net(dp
), notify
, 0,
47 void ovs_dp_notify_wq(struct work_struct
*work
)
49 struct ovs_net
*ovs_net
= container_of(work
, struct ovs_net
, dp_notify_work
);
53 list_for_each_entry(dp
, &ovs_net
->dps
, list_node
) {
56 for (i
= 0; i
< DP_VPORT_HASH_BUCKETS
; i
++) {
60 hlist_for_each_entry_safe(vport
, n
, &dp
->ports
[i
], dp_hash_node
) {
61 if (vport
->ops
->type
== OVS_VPORT_TYPE_INTERNAL
)
64 if (!(vport
->dev
->priv_flags
& IFF_OVS_DATAPATH
))
65 dp_detach_port_notify(vport
);
72 static int dp_device_event(struct notifier_block
*unused
, unsigned long event
,
75 struct ovs_net
*ovs_net
;
76 struct net_device
*dev
= netdev_notifier_info_to_dev(ptr
);
77 struct vport
*vport
= NULL
;
79 if (!ovs_is_internal_dev(dev
))
80 vport
= ovs_netdev_get_vport(dev
);
85 if (event
== NETDEV_UNREGISTER
) {
86 /* upper_dev_unlink and decrement promisc immediately */
87 ovs_netdev_detach_dev(vport
);
89 /* schedule vport destroy, dev_put and genl notification */
90 ovs_net
= net_generic(dev_net(dev
), ovs_net_id
);
91 queue_work(system_wq
, &ovs_net
->dp_notify_work
);
97 struct notifier_block ovs_dp_device_notifier
= {
98 .notifier_call
= dp_device_event