diff options
author | David Ahern <dsa@cumulusnetworks.com> | 2017-03-31 17:13:59 +0300 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2017-04-02 06:21:44 +0300 |
commit | 39eb8cd1758886072ceb93607827722a11592ba2 (patch) | |
tree | 9edfe97cac2f15e5c9372ecb276bef9b4a38446d /net/mpls/internal.h | |
parent | 3d8417d79e0da6a47ff29932ef80486be78af56e (diff) | |
download | linux-39eb8cd1758886072ceb93607827722a11592ba2.tar.xz |
net: mpls: rt_nhn_alive and nh_flags should be accessed using READ_ONCE
The number of alive nexthops for a route (rt->rt_nhn_alive) and the
flags for a next hop (nh->nh_flags) are modified by netdev event
handlers. The event handlers run with rtnl_lock held so updates are
always done with the lock held. The packet path accesses the fields
under the rcu lock. Since those fields can change at any moment in
the packet path, both fields should be accessed using READ_ONCE. Updates
to both fields should use WRITE_ONCE.
Update mpls_select_multipath (packet path) and mpls_ifdown and mpls_ifup
(event handlers) accordingly.
Signed-off-by: David Ahern <dsa@cumulusnetworks.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/mpls/internal.h')
-rw-r--r-- | net/mpls/internal.h | 8 |
1 files changed, 8 insertions, 0 deletions
diff --git a/net/mpls/internal.h b/net/mpls/internal.h index 62928d8fabd1..91419fe63464 100644 --- a/net/mpls/internal.h +++ b/net/mpls/internal.h @@ -83,6 +83,10 @@ enum mpls_payload_type { struct mpls_nh { /* next hop label forwarding entry */ struct net_device __rcu *nh_dev; + + /* nh_flags is accessed under RCU in the packet path; it is + * modified handling netdev events with rtnl lock held + */ unsigned int nh_flags; u32 nh_label[MAX_NEW_LABELS]; u8 nh_labels; @@ -124,6 +128,10 @@ struct mpls_route { /* next hop label forwarding entry */ u8 rt_max_alen; u8 rt_ttl_propagate; unsigned int rt_nhn; + + /* rt_nhn_alive is accessed under RCU in the packet path; it + * is modified handling netdev events with rtnl lock held + */ unsigned int rt_nhn_alive; struct mpls_nh rt_nh[0]; }; |