diff options
author | Jiri Benc <jbenc@redhat.com> | 2015-03-28 14:13:23 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-03-31 13:28:33 -0400 |
commit | 2afa650ce297bc2048bc3d059774be9c39734565 (patch) | |
tree | 0447b56128f826e76df43fee1d690ab359e93c27 | |
parent | 27705f7085ce2e124fac4c280ce824962cc90bb6 (diff) |
ipvlan: protect against concurrent link removal
Adding and removing to the 'ipvlans' list is already done using _rcu list
operations.
Signed-off-by: Jiri Benc <jbenc@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ipvlan/ipvlan_core.c | 4 |
1 files changed, 3 insertions, 1 deletions
diff --git a/drivers/net/ipvlan/ipvlan_core.c b/drivers/net/ipvlan/ipvlan_core.c index 8a542b9340c4..568628f95aa2 100644 --- a/drivers/net/ipvlan/ipvlan_core.c +++ b/drivers/net/ipvlan/ipvlan_core.c | |||
@@ -193,7 +193,8 @@ static void ipvlan_multicast_frame(struct ipvl_port *port, struct sk_buff *skb, | |||
193 | if (skb->protocol == htons(ETH_P_PAUSE)) | 193 | if (skb->protocol == htons(ETH_P_PAUSE)) |
194 | return; | 194 | return; |
195 | 195 | ||
196 | list_for_each_entry(ipvlan, &port->ipvlans, pnode) { | 196 | rcu_read_lock(); |
197 | list_for_each_entry_rcu(ipvlan, &port->ipvlans, pnode) { | ||
197 | if (local && (ipvlan == in_dev)) | 198 | if (local && (ipvlan == in_dev)) |
198 | continue; | 199 | continue; |
199 | 200 | ||
@@ -220,6 +221,7 @@ static void ipvlan_multicast_frame(struct ipvl_port *port, struct sk_buff *skb, | |||
220 | mcast_acct: | 221 | mcast_acct: |
221 | ipvlan_count_rx(ipvlan, len, ret == NET_RX_SUCCESS, true); | 222 | ipvlan_count_rx(ipvlan, len, ret == NET_RX_SUCCESS, true); |
222 | } | 223 | } |
224 | rcu_read_unlock(); | ||
223 | 225 | ||
224 | /* Locally generated? ...Forward a copy to the main-device as | 226 | /* Locally generated? ...Forward a copy to the main-device as |
225 | * well. On the RX side we'll ignore it (wont give it to any | 227 | * well. On the RX side we'll ignore it (wont give it to any |