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
, 0, 0,
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 struct netdev_vport
*netdev_vport
;
63 if (vport
->ops
->type
!= OVS_VPORT_TYPE_NETDEV
)
66 netdev_vport
= netdev_vport_priv(vport
);
67 if (!(netdev_vport
->dev
->priv_flags
& IFF_OVS_DATAPATH
))
68 dp_detach_port_notify(vport
);
75 static int dp_device_event(struct notifier_block
*unused
, unsigned long event
,
78 struct ovs_net
*ovs_net
;
79 struct net_device
*dev
= netdev_notifier_info_to_dev(ptr
);
80 struct vport
*vport
= NULL
;
82 if (!ovs_is_internal_dev(dev
))
83 vport
= ovs_netdev_get_vport(dev
);
88 if (event
== NETDEV_UNREGISTER
) {
89 /* upper_dev_unlink and decrement promisc immediately */
90 ovs_netdev_detach_dev(vport
);
92 /* schedule vport destroy, dev_put and genl notification */
93 ovs_net
= net_generic(dev_net(dev
), ovs_net_id
);
94 queue_work(system_wq
, &ovs_net
->dp_notify_work
);
100 struct notifier_block ovs_dp_device_notifier
= {
101 .notifier_call
= dp_device_event