diff options
-rw-r--r-- | include/net/geneve.h | 2 | ||||
-rw-r--r-- | net/ipv4/geneve.c | 26 |
2 files changed, 8 insertions, 20 deletions
diff --git a/include/net/geneve.h b/include/net/geneve.h index b40f4affc4cb..03aa2adb5bab 100644 --- a/include/net/geneve.h +++ b/include/net/geneve.h | |||
@@ -68,7 +68,7 @@ struct geneve_sock; | |||
68 | typedef void (geneve_rcv_t)(struct geneve_sock *gs, struct sk_buff *skb); | 68 | typedef void (geneve_rcv_t)(struct geneve_sock *gs, struct sk_buff *skb); |
69 | 69 | ||
70 | struct geneve_sock { | 70 | struct geneve_sock { |
71 | struct hlist_node hlist; | 71 | struct list_head list; |
72 | geneve_rcv_t *rcv; | 72 | geneve_rcv_t *rcv; |
73 | void *rcv_data; | 73 | void *rcv_data; |
74 | struct socket *sock; | 74 | struct socket *sock; |
diff --git a/net/ipv4/geneve.c b/net/ipv4/geneve.c index ad8dbae11d01..4fe5a592821c 100644 --- a/net/ipv4/geneve.c +++ b/net/ipv4/geneve.c | |||
@@ -26,7 +26,6 @@ | |||
26 | #include <linux/etherdevice.h> | 26 | #include <linux/etherdevice.h> |
27 | #include <linux/if_ether.h> | 27 | #include <linux/if_ether.h> |
28 | #include <linux/if_vlan.h> | 28 | #include <linux/if_vlan.h> |
29 | #include <linux/hash.h> | ||
30 | #include <linux/ethtool.h> | 29 | #include <linux/ethtool.h> |
31 | #include <linux/mutex.h> | 30 | #include <linux/mutex.h> |
32 | #include <net/arp.h> | 31 | #include <net/arp.h> |
@@ -54,12 +53,9 @@ | |||
54 | /* Protects sock_list and refcounts. */ | 53 | /* Protects sock_list and refcounts. */ |
55 | static DEFINE_MUTEX(geneve_mutex); | 54 | static DEFINE_MUTEX(geneve_mutex); |
56 | 55 | ||
57 | #define PORT_HASH_BITS 8 | ||
58 | #define PORT_HASH_SIZE (1<<PORT_HASH_BITS) | ||
59 | |||
60 | /* per-network namespace private data for this module */ | 56 | /* per-network namespace private data for this module */ |
61 | struct geneve_net { | 57 | struct geneve_net { |
62 | struct hlist_head sock_list[PORT_HASH_SIZE]; | 58 | struct list_head sock_list; |
63 | }; | 59 | }; |
64 | 60 | ||
65 | static int geneve_net_id; | 61 | static int geneve_net_id; |
@@ -69,19 +65,13 @@ static inline struct genevehdr *geneve_hdr(const struct sk_buff *skb) | |||
69 | return (struct genevehdr *)(udp_hdr(skb) + 1); | 65 | return (struct genevehdr *)(udp_hdr(skb) + 1); |
70 | } | 66 | } |
71 | 67 | ||
72 | static struct hlist_head *gs_head(struct net *net, __be16 port) | ||
73 | { | ||
74 | struct geneve_net *gn = net_generic(net, geneve_net_id); | ||
75 | |||
76 | return &gn->sock_list[hash_32(ntohs(port), PORT_HASH_BITS)]; | ||
77 | } | ||
78 | |||
79 | /* Find geneve socket based on network namespace and UDP port */ | 68 | /* Find geneve socket based on network namespace and UDP port */ |
80 | static struct geneve_sock *geneve_find_sock(struct net *net, __be16 port) | 69 | static struct geneve_sock *geneve_find_sock(struct net *net, __be16 port) |
81 | { | 70 | { |
71 | struct geneve_net *gn = net_generic(net, geneve_net_id); | ||
82 | struct geneve_sock *gs; | 72 | struct geneve_sock *gs; |
83 | 73 | ||
84 | hlist_for_each_entry(gs, gs_head(net, port), hlist) { | 74 | list_for_each_entry(gs, &gn->sock_list, list) { |
85 | if (inet_sk(gs->sock->sk)->inet_sport == port) | 75 | if (inet_sk(gs->sock->sk)->inet_sport == port) |
86 | return gs; | 76 | return gs; |
87 | } | 77 | } |
@@ -339,6 +329,7 @@ static struct geneve_sock *geneve_socket_create(struct net *net, __be16 port, | |||
339 | geneve_rcv_t *rcv, void *data, | 329 | geneve_rcv_t *rcv, void *data, |
340 | bool ipv6) | 330 | bool ipv6) |
341 | { | 331 | { |
332 | struct geneve_net *gn = net_generic(net, geneve_net_id); | ||
342 | struct geneve_sock *gs; | 333 | struct geneve_sock *gs; |
343 | struct socket *sock; | 334 | struct socket *sock; |
344 | struct udp_tunnel_sock_cfg tunnel_cfg; | 335 | struct udp_tunnel_sock_cfg tunnel_cfg; |
@@ -371,7 +362,7 @@ static struct geneve_sock *geneve_socket_create(struct net *net, __be16 port, | |||
371 | tunnel_cfg.encap_destroy = NULL; | 362 | tunnel_cfg.encap_destroy = NULL; |
372 | setup_udp_tunnel_sock(net, sock, &tunnel_cfg); | 363 | setup_udp_tunnel_sock(net, sock, &tunnel_cfg); |
373 | 364 | ||
374 | hlist_add_head(&gs->hlist, gs_head(net, port)); | 365 | list_add(&gs->list, &gn->sock_list); |
375 | 366 | ||
376 | return gs; | 367 | return gs; |
377 | } | 368 | } |
@@ -407,7 +398,7 @@ void geneve_sock_release(struct geneve_sock *gs) | |||
407 | if (--gs->refcnt) | 398 | if (--gs->refcnt) |
408 | goto unlock; | 399 | goto unlock; |
409 | 400 | ||
410 | hlist_del(&gs->hlist); | 401 | list_del(&gs->list); |
411 | geneve_notify_del_rx_port(gs); | 402 | geneve_notify_del_rx_port(gs); |
412 | udp_tunnel_sock_release(gs->sock); | 403 | udp_tunnel_sock_release(gs->sock); |
413 | kfree_rcu(gs, rcu); | 404 | kfree_rcu(gs, rcu); |
@@ -420,17 +411,14 @@ EXPORT_SYMBOL_GPL(geneve_sock_release); | |||
420 | static __net_init int geneve_init_net(struct net *net) | 411 | static __net_init int geneve_init_net(struct net *net) |
421 | { | 412 | { |
422 | struct geneve_net *gn = net_generic(net, geneve_net_id); | 413 | struct geneve_net *gn = net_generic(net, geneve_net_id); |
423 | unsigned int h; | ||
424 | 414 | ||
425 | for (h = 0; h < PORT_HASH_SIZE; ++h) | 415 | INIT_LIST_HEAD(&gn->sock_list); |
426 | INIT_HLIST_HEAD(&gn->sock_list[h]); | ||
427 | 416 | ||
428 | return 0; | 417 | return 0; |
429 | } | 418 | } |
430 | 419 | ||
431 | static struct pernet_operations geneve_net_ops = { | 420 | static struct pernet_operations geneve_net_ops = { |
432 | .init = geneve_init_net, | 421 | .init = geneve_init_net, |
433 | .exit = NULL, | ||
434 | .id = &geneve_net_id, | 422 | .id = &geneve_net_id, |
435 | .size = sizeof(struct geneve_net), | 423 | .size = sizeof(struct geneve_net), |
436 | }; | 424 | }; |