Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 911aeb10 authored by David S. Miller's avatar David S. Miller
Browse files


Jesse Gross says:

====================
One patch for net/3.12 fixing an issue where devices could be in an
invalid state they are removed while still attached to OVS.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 706e282b b07c2651
Loading
Loading
Loading
Loading
+5 −2
Original line number Diff line number Diff line
@@ -65,8 +65,7 @@ void ovs_dp_notify_wq(struct work_struct *work)
					continue;

				netdev_vport = netdev_vport_priv(vport);
				if (netdev_vport->dev->reg_state == NETREG_UNREGISTERED ||
				    netdev_vport->dev->reg_state == NETREG_UNREGISTERING)
				if (!(netdev_vport->dev->priv_flags & IFF_OVS_DATAPATH))
					dp_detach_port_notify(vport);
			}
		}
@@ -88,6 +87,10 @@ static int dp_device_event(struct notifier_block *unused, unsigned long event,
		return NOTIFY_DONE;

	if (event == NETDEV_UNREGISTER) {
		/* upper_dev_unlink and decrement promisc immediately */
		ovs_netdev_detach_dev(vport);

		/* schedule vport destroy, dev_put and genl notification */
		ovs_net = net_generic(dev_net(dev), ovs_net_id);
		queue_work(system_wq, &ovs_net->dp_notify_work);
	}
+13 −3
Original line number Diff line number Diff line
@@ -150,15 +150,25 @@ static void free_port_rcu(struct rcu_head *rcu)
	ovs_vport_free(vport_from_priv(netdev_vport));
}

static void netdev_destroy(struct vport *vport)
void ovs_netdev_detach_dev(struct vport *vport)
{
	struct netdev_vport *netdev_vport = netdev_vport_priv(vport);

	rtnl_lock();
	ASSERT_RTNL();
	netdev_vport->dev->priv_flags &= ~IFF_OVS_DATAPATH;
	netdev_rx_handler_unregister(netdev_vport->dev);
	netdev_upper_dev_unlink(netdev_vport->dev, get_dpdev(vport->dp));
	netdev_upper_dev_unlink(netdev_vport->dev,
				netdev_master_upper_dev_get(netdev_vport->dev));
	dev_set_promiscuity(netdev_vport->dev, -1);
}

static void netdev_destroy(struct vport *vport)
{
	struct netdev_vport *netdev_vport = netdev_vport_priv(vport);

	rtnl_lock();
	if (netdev_vport->dev->priv_flags & IFF_OVS_DATAPATH)
		ovs_netdev_detach_dev(vport);
	rtnl_unlock();

	call_rcu(&netdev_vport->rcu, free_port_rcu);
+1 −0
Original line number Diff line number Diff line
@@ -39,5 +39,6 @@ netdev_vport_priv(const struct vport *vport)
}

const char *ovs_netdev_get_name(const struct vport *);
void ovs_netdev_detach_dev(struct vport *);

#endif /* vport_netdev.h */