summaryrefslogtreecommitdiff
path: root/net/mpls/internal.h
diff options
context:
space:
mode:
authorDavid Ahern <dsa@cumulusnetworks.com>2017-03-31 17:13:59 +0300
committerDavid S. Miller <davem@davemloft.net>2017-04-02 06:21:44 +0300
commit39eb8cd1758886072ceb93607827722a11592ba2 (patch)
tree9edfe97cac2f15e5c9372ecb276bef9b4a38446d /net/mpls/internal.h
parent3d8417d79e0da6a47ff29932ef80486be78af56e (diff)
downloadlinux-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.h8
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];
};