[ovs-dev] [PATCH] datapath: Fix net exit.

Pravin Shelar pshelar at nicira.com
Fri Feb 20 23:45:32 UTC 2015


On Fri, Feb 20, 2015 at 3:21 PM, Andy Zhou <azhou at nicira.com> wrote:
> There is a style warning:
>
> WARNING: line over 80 characters
> #63: FILE: datapath/datapath.c:2132:
> +            hlist_for_each_entry(vport, &dp->ports[i], dp_hash_node) {
>

This is fine from code reading perspective, so I kept it as it is and
pushed it to branch-2.1, 2.3 and master.

Thanks.

> Otherwise, looks good.
> Acked-by: Andy Zhou <azhou at nicira.com>
>
> On Fri, Feb 20, 2015 at 2:59 PM, Pravin B Shelar <pshelar at nicira.com> wrote:
>> Open vSwitch allows moving internal vport to different namespace
>> while still connected to the bridge. But when namespace deleted
>> OVS does not detach these vports, that results in dangling
>> pointer to netdevice which causes kernel panic as follows.
>> This issue is fixed by detaching all ovs ports from the deleted
>> namespace at net-exit.
>>
>> BUG: unable to handle kernel NULL pointer dereference at 0000000000000028
>> IP: [<ffffffffa0aadaa5>] ovs_vport_locate+0x35/0x80 [openvswitch]
>> Oops: 0000 [#1] SMP
>> Call Trace:
>>  [<ffffffffa0aa6391>] lookup_vport+0x21/0xd0 [openvswitch]
>>  [<ffffffffa0aa65f9>] ovs_vport_cmd_get+0x59/0xf0 [openvswitch]
>>  [<ffffffff8167e07c>] genl_family_rcv_msg+0x1bc/0x3e0
>>  [<ffffffff8167e319>] genl_rcv_msg+0x79/0xc0
>>  [<ffffffff8167d919>] netlink_rcv_skb+0xb9/0xe0
>>  [<ffffffff8167deac>] genl_rcv+0x2c/0x40
>>  [<ffffffff8167cffd>] netlink_unicast+0x12d/0x1c0
>>  [<ffffffff8167d3da>] netlink_sendmsg+0x34a/0x6b0
>>  [<ffffffff8162e140>] sock_sendmsg+0xa0/0xe0
>>  [<ffffffff8162e5e8>] ___sys_sendmsg+0x408/0x420
>>  [<ffffffff8162f541>] __sys_sendmsg+0x51/0x90
>>  [<ffffffff8162f592>] SyS_sendmsg+0x12/0x20
>>  [<ffffffff81764ee9>] system_call_fastpath+0x12/0x17
>>
>> Reported-by: Assaf Muller <amuller at redhat.com>
>> Fixes: 46df7b81454("openvswitch: Add support for network namespaces.")
>> Signed-off-by: Pravin B Shelar <pshelar at nicira.com>
>> Reviewed-by: Thomas Graf <tgraf at noironetworks.com>
>> Signed-off-by: David S. Miller <davem at davemloft.net>
>> ---
>>  datapath/datapath.c |   45 +++++++++++++++++++++++++++++++++++++++++++--
>>  datapath/vport.h    |    2 ++
>>  2 files changed, 45 insertions(+), 2 deletions(-)
>>
>> diff --git a/datapath/datapath.c b/datapath/datapath.c
>> index c5c926b..b99cc3d 100644
>> --- a/datapath/datapath.c
>> +++ b/datapath/datapath.c
>> @@ -2117,14 +2117,55 @@ static int __net_init ovs_init_net(struct net *net)
>>         return 0;
>>  }
>>
>> -static void __net_exit ovs_exit_net(struct net *net)
>> +static void __net_exit list_vports_from_net(struct net *net, struct net *dnet,
>> +                                           struct list_head *head)
>>  {
>> -       struct datapath *dp, *dp_next;
>>         struct ovs_net *ovs_net = net_generic(net, ovs_net_id);
>> +       struct datapath *dp;
>> +
>> +       list_for_each_entry(dp, &ovs_net->dps, list_node) {
>> +               int i;
>> +
>> +               for (i = 0; i < DP_VPORT_HASH_BUCKETS; i++) {
>> +                       struct vport *vport;
>> +
>> +                       hlist_for_each_entry(vport, &dp->ports[i], dp_hash_node) {
>> +                               struct netdev_vport *netdev_vport;
>> +
>> +                               if (vport->ops->type != OVS_VPORT_TYPE_INTERNAL)
>> +                                       continue;
>> +
>> +                               netdev_vport = netdev_vport_priv(vport);
>> +                               if (dev_net(netdev_vport->dev) == dnet)
>> +                                       list_add(&vport->detach_list, head);
>> +                       }
>> +               }
>> +       }
>> +}
>> +
>> +static void __net_exit ovs_exit_net(struct net *dnet)
>> +{
>> +       struct datapath *dp, *dp_next;
>> +       struct ovs_net *ovs_net = net_generic(dnet, ovs_net_id);
>> +       struct vport *vport, *vport_next;
>> +       struct net *net;
>> +       LIST_HEAD(head);
>>
>>         ovs_lock();
>>         list_for_each_entry_safe(dp, dp_next, &ovs_net->dps, list_node)
>>                 __dp_destroy(dp);
>> +
>> +       rtnl_lock();
>> +       for_each_net(net)
>> +               list_vports_from_net(net, dnet, &head);
>> +       rtnl_unlock();
>> +
>> +       /* Detach all vports from given namespace. */
>> +       list_for_each_entry_safe(vport, vport_next, &head, detach_list) {
>> +               list_del(&vport->detach_list);
>> +               ovs_dp_detach_port(vport);
>> +       }
>> +
>>         ovs_unlock();
>>
>>         cancel_work_sync(&ovs_net->dp_notify_work);
>> diff --git a/datapath/vport.h b/datapath/vport.h
>> index a08a7ce..e256fc0 100644
>> --- a/datapath/vport.h
>> +++ b/datapath/vport.h
>> @@ -101,6 +101,7 @@ struct vport_portids {
>>   * @ops: Class structure.
>>   * @percpu_stats: Points to per-CPU statistics used and maintained by vport
>>   * @err_stats: Points to error statistics used and maintained by vport
>> + * @detach_list: list used for detaching vport in net-exit call.
>>   */
>>  struct vport {
>>         struct rcu_head rcu;
>> @@ -115,6 +116,7 @@ struct vport {
>>         struct pcpu_sw_netstats __percpu *percpu_stats;
>>
>>         struct vport_err_stats err_stats;
>> +       struct list_head detach_list;
>>  };
>>
>>  /**
>> --
>> 1.7.1
>>
>> _______________________________________________
>> dev mailing list
>> dev at openvswitch.org
>> http://openvswitch.org/mailman/listinfo/dev



More information about the dev mailing list