]>
Commit | Line | Data |
---|---|---|
38568109 GKH |
1 | From foo@baz Thu Mar 28 21:54:17 CET 2019 |
2 | From: Maxime Chevallier <maxime.chevallier@bootlin.com> | |
3 | Date: Sat, 16 Mar 2019 14:41:30 +0100 | |
4 | Subject: packets: Always register packet sk in the same order | |
5 | ||
6 | From: Maxime Chevallier <maxime.chevallier@bootlin.com> | |
7 | ||
8 | [ Upstream commit a4dc6a49156b1f8d6e17251ffda17c9e6a5db78a ] | |
9 | ||
10 | When using fanouts with AF_PACKET, the demux functions such as | |
11 | fanout_demux_cpu will return an index in the fanout socket array, which | |
12 | corresponds to the selected socket. | |
13 | ||
14 | The ordering of this array depends on the order the sockets were added | |
15 | to a given fanout group, so for FANOUT_CPU this means sockets are bound | |
16 | to cpus in the order they are configured, which is OK. | |
17 | ||
18 | However, when stopping then restarting the interface these sockets are | |
19 | bound to, the sockets are reassigned to the fanout group in the reverse | |
20 | order, due to the fact that they were inserted at the head of the | |
21 | interface's AF_PACKET socket list. | |
22 | ||
23 | This means that traffic that was directed to the first socket in the | |
24 | fanout group is now directed to the last one after an interface restart. | |
25 | ||
26 | In the case of FANOUT_CPU, traffic from CPU0 will be directed to the | |
27 | socket that used to receive traffic from the last CPU after an interface | |
28 | restart. | |
29 | ||
30 | This commit introduces a helper to add a socket at the tail of a list, | |
31 | then uses it to register AF_PACKET sockets. | |
32 | ||
33 | Note that this changes the order in which sockets are listed in /proc and | |
34 | with sock_diag. | |
35 | ||
36 | Fixes: dc99f600698d ("packet: Add fanout support") | |
37 | Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com> | |
38 | Acked-by: Willem de Bruijn <willemb@google.com> | |
39 | Signed-off-by: David S. Miller <davem@davemloft.net> | |
40 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
41 | --- | |
42 | include/net/sock.h | 6 ++++++ | |
43 | net/packet/af_packet.c | 2 +- | |
44 | 2 files changed, 7 insertions(+), 1 deletion(-) | |
45 | ||
46 | --- a/include/net/sock.h | |
47 | +++ b/include/net/sock.h | |
48 | @@ -710,6 +710,12 @@ static inline void sk_add_node_rcu(struc | |
49 | hlist_add_head_rcu(&sk->sk_node, list); | |
50 | } | |
51 | ||
52 | +static inline void sk_add_node_tail_rcu(struct sock *sk, struct hlist_head *list) | |
53 | +{ | |
54 | + sock_hold(sk); | |
55 | + hlist_add_tail_rcu(&sk->sk_node, list); | |
56 | +} | |
57 | + | |
58 | static inline void __sk_nulls_add_node_rcu(struct sock *sk, struct hlist_nulls_head *list) | |
59 | { | |
60 | hlist_nulls_add_head_rcu(&sk->sk_nulls_node, list); | |
61 | --- a/net/packet/af_packet.c | |
62 | +++ b/net/packet/af_packet.c | |
63 | @@ -3245,7 +3245,7 @@ static int packet_create(struct net *net | |
64 | } | |
65 | ||
66 | mutex_lock(&net->packet.sklist_lock); | |
67 | - sk_add_node_rcu(sk, &net->packet.sklist); | |
68 | + sk_add_node_tail_rcu(sk, &net->packet.sklist); | |
69 | mutex_unlock(&net->packet.sklist_lock); | |
70 | ||
71 | preempt_disable(); |