X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=datapath%2Fvport.c;h=172261aa58985b010142d17d6310bc142380d9c2;hb=e8fa940e4af32f904ff1958a36f95ad4153eac67;hp=9881fb86f70597ca72d60e3aceff35ffc6cce817;hpb=850b6b3b9f8c38b42e315c2c07d232a33b82da3e;p=openvswitch diff --git a/datapath/vport.c b/datapath/vport.c index 9881fb86..172261aa 100644 --- a/datapath/vport.c +++ b/datapath/vport.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007-2011 Nicira Networks. + * Copyright (c) 2007-2012 Nicira, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public @@ -16,10 +16,10 @@ * 02110-1301, USA */ -#include #include #include #include +#include #include #include #include @@ -28,7 +28,9 @@ #include #include #include +#include +#include "datapath.h" #include "vport.h" #include "vport-internal_dev.h" @@ -119,9 +121,9 @@ void ovs_vport_exit(void) kfree(dev_table); } -static struct hlist_head *hash_bucket(const char *name) +static struct hlist_head *hash_bucket(struct net *net, const char *name) { - unsigned int hash = full_name_hash(name, strlen(name)); + unsigned int hash = jhash(name, strlen(name), (unsigned long) net); return &dev_table[hash & (VPORT_HASH_BUCKETS - 1)]; } @@ -132,14 +134,15 @@ static struct hlist_head *hash_bucket(const char *name) * * Must be called with RTNL or RCU read lock. */ -struct vport *ovs_vport_locate(const char *name) +struct vport *ovs_vport_locate(struct net *net, const char *name) { - struct hlist_head *bucket = hash_bucket(name); + struct hlist_head *bucket = hash_bucket(net, name); struct vport *vport; struct hlist_node *node; hlist_for_each_entry_rcu(vport, node, bucket, hash_node) - if (!strcmp(name, vport->ops->get_name(vport))) + if (!strcmp(name, vport->ops->get_name(vport)) && + net_eq(ovs_dp_get_net(vport->dp), net)) return vport; return NULL; @@ -189,6 +192,7 @@ struct vport *ovs_vport_alloc(int priv_size, const struct vport_ops *ops, vport->port_no = parms->port_no; vport->upcall_pid = parms->upcall_pid; vport->ops = ops; + INIT_HLIST_NODE(&vport->dp_hash_node); /* Initialize kobject for bridge. This will be added as * /sys/class/net//brport later, if sysfs is enabled. */ @@ -196,8 +200,10 @@ struct vport *ovs_vport_alloc(int priv_size, const struct vport_ops *ops, kobject_init(&vport->kobj, &brport_ktype); vport->percpu_stats = alloc_percpu(struct vport_percpu_stats); - if (!vport->percpu_stats) + if (!vport->percpu_stats) { + kfree(vport); return ERR_PTR(-ENOMEM); + } spin_lock_init(&vport->stats_lock); @@ -239,14 +245,17 @@ struct vport *ovs_vport_add(const struct vport_parms *parms) for (i = 0; i < n_vport_types; i++) { if (vport_ops_list[i]->type == parms->type) { + struct hlist_head *bucket; + vport = vport_ops_list[i]->create(parms); if (IS_ERR(vport)) { err = PTR_ERR(vport); goto out; } - hlist_add_head_rcu(&vport->hash_node, - hash_bucket(vport->ops->get_name(vport))); + bucket = hash_bucket(ovs_dp_get_net(vport->dp), + vport->ops->get_name(vport)); + hlist_add_head_rcu(&vport->hash_node, bucket); return vport; } }