]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/3.19.2/openvswitch-fix-net-exit.patch
4.14-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 3.19.2 / openvswitch-fix-net-exit.patch
CommitLineData
373f9370
GKH
1From foo@baz Wed Mar 11 11:44:33 CET 2015
2From: Pravin B Shelar <pshelar@nicira.com>
3Date: Tue, 17 Feb 2015 11:23:10 -0800
4Subject: openvswitch: Fix net exit.
5
6From: Pravin B Shelar <pshelar@nicira.com>
7
8[ Upstream commit 7b4577a9da3702049650f7095506e9afd9f68849 ]
9
10Open vSwitch allows moving internal vport to different namespace
11while still connected to the bridge. But when namespace deleted
12OVS does not detach these vports, that results in dangling
13pointer to netdevice which causes kernel panic as follows.
14This issue is fixed by detaching all ovs ports from the deleted
15namespace at net-exit.
16
17BUG: unable to handle kernel NULL pointer dereference at 0000000000000028
18IP: [<ffffffffa0aadaa5>] ovs_vport_locate+0x35/0x80 [openvswitch]
19Oops: 0000 [#1] SMP
20Call Trace:
21 [<ffffffffa0aa6391>] lookup_vport+0x21/0xd0 [openvswitch]
22 [<ffffffffa0aa65f9>] ovs_vport_cmd_get+0x59/0xf0 [openvswitch]
23 [<ffffffff8167e07c>] genl_family_rcv_msg+0x1bc/0x3e0
24 [<ffffffff8167e319>] genl_rcv_msg+0x79/0xc0
25 [<ffffffff8167d919>] netlink_rcv_skb+0xb9/0xe0
26 [<ffffffff8167deac>] genl_rcv+0x2c/0x40
27 [<ffffffff8167cffd>] netlink_unicast+0x12d/0x1c0
28 [<ffffffff8167d3da>] netlink_sendmsg+0x34a/0x6b0
29 [<ffffffff8162e140>] sock_sendmsg+0xa0/0xe0
30 [<ffffffff8162e5e8>] ___sys_sendmsg+0x408/0x420
31 [<ffffffff8162f541>] __sys_sendmsg+0x51/0x90
32 [<ffffffff8162f592>] SyS_sendmsg+0x12/0x20
33 [<ffffffff81764ee9>] system_call_fastpath+0x12/0x17
34
35Reported-by: Assaf Muller <amuller@redhat.com>
36Fixes: 46df7b81454("openvswitch: Add support for network namespaces.")
37Signed-off-by: Pravin B Shelar <pshelar@nicira.com>
38Reviewed-by: Thomas Graf <tgraf@noironetworks.com>
39Signed-off-by: David S. Miller <davem@davemloft.net>
40Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
41---
42 net/openvswitch/datapath.c | 45 +++++++++++++++++++++++++++++++++++++++++++--
43 net/openvswitch/vport.h | 2 ++
44 2 files changed, 45 insertions(+), 2 deletions(-)
45
46--- a/net/openvswitch/datapath.c
47+++ b/net/openvswitch/datapath.c
48@@ -2113,14 +2113,55 @@ static int __net_init ovs_init_net(struc
49 return 0;
50 }
51
52-static void __net_exit ovs_exit_net(struct net *net)
53+static void __net_exit list_vports_from_net(struct net *net, struct net *dnet,
54+ struct list_head *head)
55 {
56- struct datapath *dp, *dp_next;
57 struct ovs_net *ovs_net = net_generic(net, ovs_net_id);
58+ struct datapath *dp;
59+
60+ list_for_each_entry(dp, &ovs_net->dps, list_node) {
61+ int i;
62+
63+ for (i = 0; i < DP_VPORT_HASH_BUCKETS; i++) {
64+ struct vport *vport;
65+
66+ hlist_for_each_entry(vport, &dp->ports[i], dp_hash_node) {
67+ struct netdev_vport *netdev_vport;
68+
69+ if (vport->ops->type != OVS_VPORT_TYPE_INTERNAL)
70+ continue;
71+
72+ netdev_vport = netdev_vport_priv(vport);
73+ if (dev_net(netdev_vport->dev) == dnet)
74+ list_add(&vport->detach_list, head);
75+ }
76+ }
77+ }
78+}
79+
80+static void __net_exit ovs_exit_net(struct net *dnet)
81+{
82+ struct datapath *dp, *dp_next;
83+ struct ovs_net *ovs_net = net_generic(dnet, ovs_net_id);
84+ struct vport *vport, *vport_next;
85+ struct net *net;
86+ LIST_HEAD(head);
87
88 ovs_lock();
89 list_for_each_entry_safe(dp, dp_next, &ovs_net->dps, list_node)
90 __dp_destroy(dp);
91+
92+ rtnl_lock();
93+ for_each_net(net)
94+ list_vports_from_net(net, dnet, &head);
95+ rtnl_unlock();
96+
97+ /* Detach all vports from given namespace. */
98+ list_for_each_entry_safe(vport, vport_next, &head, detach_list) {
99+ list_del(&vport->detach_list);
100+ ovs_dp_detach_port(vport);
101+ }
102+
103 ovs_unlock();
104
105 cancel_work_sync(&ovs_net->dp_notify_work);
106--- a/net/openvswitch/vport.h
107+++ b/net/openvswitch/vport.h
108@@ -103,6 +103,7 @@ struct vport_portids {
109 * @ops: Class structure.
110 * @percpu_stats: Points to per-CPU statistics used and maintained by vport
111 * @err_stats: Points to error statistics used and maintained by vport
112+ * @detach_list: list used for detaching vport in net-exit call.
113 */
114 struct vport {
115 struct rcu_head rcu;
116@@ -117,6 +118,7 @@ struct vport {
117 struct pcpu_sw_netstats __percpu *percpu_stats;
118
119 struct vport_err_stats err_stats;
120+ struct list_head detach_list;
121 };
122
123 /**