| From foo@baz Wed 22 May 2019 08:37:51 AM CEST |
| From: Pieter Jansen van Vuuren <pieter.jansenvanvuuren@netronome.com> |
| Date: Tue, 14 May 2019 14:28:19 -0700 |
| Subject: nfp: flower: add rcu locks when accessing netdev for tunnels |
| |
| From: Pieter Jansen van Vuuren <pieter.jansenvanvuuren@netronome.com> |
| |
| [ Upstream commit cb07d915bf278a7a3938b983bbcb4921366b5eff ] |
| |
| Add rcu locks when accessing netdev when processing route request |
| and tunnel keep alive messages received from hardware. |
| |
| Fixes: 8e6a9046b66a ("nfp: flower vxlan neighbour offload") |
| Fixes: 856f5b135758 ("nfp: flower vxlan neighbour keep-alive") |
| Signed-off-by: Pieter Jansen van Vuuren <pieter.jansenvanvuuren@netronome.com> |
| Reviewed-by: Jakub Kicinski <jakub.kicinski@netronome.com> |
| Reviewed-by: John Hurley <john.hurley@netronome.com> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c | 17 ++++++++++------ |
| 1 file changed, 11 insertions(+), 6 deletions(-) |
| |
| --- a/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c |
| +++ b/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c |
| @@ -194,6 +194,7 @@ void nfp_tunnel_keep_alive(struct nfp_ap |
| return; |
| } |
| |
| + rcu_read_lock(); |
| for (i = 0; i < count; i++) { |
| ipv4_addr = payload->tun_info[i].ipv4; |
| port = be32_to_cpu(payload->tun_info[i].egress_port); |
| @@ -209,6 +210,7 @@ void nfp_tunnel_keep_alive(struct nfp_ap |
| neigh_event_send(n, NULL); |
| neigh_release(n); |
| } |
| + rcu_read_unlock(); |
| } |
| |
| static bool nfp_tun_is_netdev_to_offload(struct net_device *netdev) |
| @@ -404,9 +406,10 @@ void nfp_tunnel_request_route(struct nfp |
| |
| payload = nfp_flower_cmsg_get_data(skb); |
| |
| + rcu_read_lock(); |
| netdev = nfp_app_repr_get(app, be32_to_cpu(payload->ingress_port)); |
| if (!netdev) |
| - goto route_fail_warning; |
| + goto fail_rcu_unlock; |
| |
| flow.daddr = payload->ipv4_addr; |
| flow.flowi4_proto = IPPROTO_UDP; |
| @@ -416,21 +419,23 @@ void nfp_tunnel_request_route(struct nfp |
| rt = ip_route_output_key(dev_net(netdev), &flow); |
| err = PTR_ERR_OR_ZERO(rt); |
| if (err) |
| - goto route_fail_warning; |
| + goto fail_rcu_unlock; |
| #else |
| - goto route_fail_warning; |
| + goto fail_rcu_unlock; |
| #endif |
| |
| /* Get the neighbour entry for the lookup */ |
| n = dst_neigh_lookup(&rt->dst, &flow.daddr); |
| ip_rt_put(rt); |
| if (!n) |
| - goto route_fail_warning; |
| - nfp_tun_write_neigh(n->dev, app, &flow, n, GFP_KERNEL); |
| + goto fail_rcu_unlock; |
| + nfp_tun_write_neigh(n->dev, app, &flow, n, GFP_ATOMIC); |
| neigh_release(n); |
| + rcu_read_unlock(); |
| return; |
| |
| -route_fail_warning: |
| +fail_rcu_unlock: |
| + rcu_read_unlock(); |
| nfp_flower_cmsg_warn(app, "Requested route not found.\n"); |
| } |
| |