diff options
Diffstat (limited to 'net/openvswitch/vport.c')
-rw-r--r-- | net/openvswitch/vport.c | 27 |
1 files changed, 17 insertions, 10 deletions
diff --git a/net/openvswitch/vport.c b/net/openvswitch/vport.c index 6140336e79d7..03779e8a2622 100644 --- a/net/openvswitch/vport.c +++ b/net/openvswitch/vport.c | |||
@@ -16,10 +16,10 @@ | |||
16 | * 02110-1301, USA | 16 | * 02110-1301, USA |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include <linux/dcache.h> | ||
20 | #include <linux/etherdevice.h> | 19 | #include <linux/etherdevice.h> |
21 | #include <linux/if.h> | 20 | #include <linux/if.h> |
22 | #include <linux/if_vlan.h> | 21 | #include <linux/if_vlan.h> |
22 | #include <linux/jhash.h> | ||
23 | #include <linux/kernel.h> | 23 | #include <linux/kernel.h> |
24 | #include <linux/list.h> | 24 | #include <linux/list.h> |
25 | #include <linux/mutex.h> | 25 | #include <linux/mutex.h> |
@@ -27,7 +27,9 @@ | |||
27 | #include <linux/rcupdate.h> | 27 | #include <linux/rcupdate.h> |
28 | #include <linux/rtnetlink.h> | 28 | #include <linux/rtnetlink.h> |
29 | #include <linux/compat.h> | 29 | #include <linux/compat.h> |
30 | #include <net/net_namespace.h> | ||
30 | 31 | ||
32 | #include "datapath.h" | ||
31 | #include "vport.h" | 33 | #include "vport.h" |
32 | #include "vport-internal_dev.h" | 34 | #include "vport-internal_dev.h" |
33 | 35 | ||
@@ -67,9 +69,9 @@ void ovs_vport_exit(void) | |||
67 | kfree(dev_table); | 69 | kfree(dev_table); |
68 | } | 70 | } |
69 | 71 | ||
70 | static struct hlist_head *hash_bucket(const char *name) | 72 | static struct hlist_head *hash_bucket(struct net *net, const char *name) |
71 | { | 73 | { |
72 | unsigned int hash = full_name_hash(name, strlen(name)); | 74 | unsigned int hash = jhash(name, strlen(name), (unsigned long) net); |
73 | return &dev_table[hash & (VPORT_HASH_BUCKETS - 1)]; | 75 | return &dev_table[hash & (VPORT_HASH_BUCKETS - 1)]; |
74 | } | 76 | } |
75 | 77 | ||
@@ -80,14 +82,15 @@ static struct hlist_head *hash_bucket(const char *name) | |||
80 | * | 82 | * |
81 | * Must be called with RTNL or RCU read lock. | 83 | * Must be called with RTNL or RCU read lock. |
82 | */ | 84 | */ |
83 | struct vport *ovs_vport_locate(const char *name) | 85 | struct vport *ovs_vport_locate(struct net *net, const char *name) |
84 | { | 86 | { |
85 | struct hlist_head *bucket = hash_bucket(name); | 87 | struct hlist_head *bucket = hash_bucket(net, name); |
86 | struct vport *vport; | 88 | struct vport *vport; |
87 | struct hlist_node *node; | 89 | struct hlist_node *node; |
88 | 90 | ||
89 | hlist_for_each_entry_rcu(vport, node, bucket, hash_node) | 91 | hlist_for_each_entry_rcu(vport, node, bucket, hash_node) |
90 | if (!strcmp(name, vport->ops->get_name(vport))) | 92 | if (!strcmp(name, vport->ops->get_name(vport)) && |
93 | net_eq(ovs_dp_get_net(vport->dp), net)) | ||
91 | return vport; | 94 | return vport; |
92 | 95 | ||
93 | return NULL; | 96 | return NULL; |
@@ -122,8 +125,9 @@ struct vport *ovs_vport_alloc(int priv_size, const struct vport_ops *ops, | |||
122 | 125 | ||
123 | vport->dp = parms->dp; | 126 | vport->dp = parms->dp; |
124 | vport->port_no = parms->port_no; | 127 | vport->port_no = parms->port_no; |
125 | vport->upcall_pid = parms->upcall_pid; | 128 | vport->upcall_portid = parms->upcall_portid; |
126 | vport->ops = ops; | 129 | vport->ops = ops; |
130 | INIT_HLIST_NODE(&vport->dp_hash_node); | ||
127 | 131 | ||
128 | vport->percpu_stats = alloc_percpu(struct vport_percpu_stats); | 132 | vport->percpu_stats = alloc_percpu(struct vport_percpu_stats); |
129 | if (!vport->percpu_stats) { | 133 | if (!vport->percpu_stats) { |
@@ -170,14 +174,17 @@ struct vport *ovs_vport_add(const struct vport_parms *parms) | |||
170 | 174 | ||
171 | for (i = 0; i < ARRAY_SIZE(vport_ops_list); i++) { | 175 | for (i = 0; i < ARRAY_SIZE(vport_ops_list); i++) { |
172 | if (vport_ops_list[i]->type == parms->type) { | 176 | if (vport_ops_list[i]->type == parms->type) { |
177 | struct hlist_head *bucket; | ||
178 | |||
173 | vport = vport_ops_list[i]->create(parms); | 179 | vport = vport_ops_list[i]->create(parms); |
174 | if (IS_ERR(vport)) { | 180 | if (IS_ERR(vport)) { |
175 | err = PTR_ERR(vport); | 181 | err = PTR_ERR(vport); |
176 | goto out; | 182 | goto out; |
177 | } | 183 | } |
178 | 184 | ||
179 | hlist_add_head_rcu(&vport->hash_node, | 185 | bucket = hash_bucket(ovs_dp_get_net(vport->dp), |
180 | hash_bucket(vport->ops->get_name(vport))); | 186 | vport->ops->get_name(vport)); |
187 | hlist_add_head_rcu(&vport->hash_node, bucket); | ||
181 | return vport; | 188 | return vport; |
182 | } | 189 | } |
183 | } | 190 | } |
@@ -391,7 +398,7 @@ void ovs_vport_record_error(struct vport *vport, enum vport_err_type err_type) | |||
391 | case VPORT_E_TX_ERROR: | 398 | case VPORT_E_TX_ERROR: |
392 | vport->err_stats.tx_errors++; | 399 | vport->err_stats.tx_errors++; |
393 | break; | 400 | break; |
394 | }; | 401 | } |
395 | 402 | ||
396 | spin_unlock(&vport->stats_lock); | 403 | spin_unlock(&vport->stats_lock); |
397 | } | 404 | } |