Commit 0b5e2e39 authored by David Ahern's avatar David Ahern Committed by David S. Miller

nexthop: Expand nexthop_is_multipath in a few places

I got too fancy consolidating checks on multipath type. The result
is that path lookups can access 2 different nh_grp structs as exposed
by Nik's torture tests. Expand nexthop_is_multipath within nexthop.h to
avoid multiple, nh_grp dereferences and make decisions based on the
consistent struct.

Only 2 places left using nexthop_is_multipath are within IPv6, both
only check that the nexthop is a multipath for a branching decision
which are acceptable.

Fixes: 430a0491 ("nexthop: Add support for nexthop groups")
Signed-off-by: default avatarDavid Ahern <dsahern@gmail.com>
Acked-by: default avatarNikolay Aleksandrov <nikolay@cumulusnetworks.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 90f33bff
...@@ -137,10 +137,11 @@ static inline unsigned int nexthop_num_path(const struct nexthop *nh) ...@@ -137,10 +137,11 @@ static inline unsigned int nexthop_num_path(const struct nexthop *nh)
{ {
unsigned int rc = 1; unsigned int rc = 1;
if (nexthop_is_multipath(nh)) { if (nh->is_group) {
struct nh_group *nh_grp; struct nh_group *nh_grp;
nh_grp = rcu_dereference_rtnl(nh->nh_grp); nh_grp = rcu_dereference_rtnl(nh->nh_grp);
if (nh_grp->mpath)
rc = nh_grp->num_nh; rc = nh_grp->num_nh;
} }
...@@ -148,10 +149,8 @@ static inline unsigned int nexthop_num_path(const struct nexthop *nh) ...@@ -148,10 +149,8 @@ static inline unsigned int nexthop_num_path(const struct nexthop *nh)
} }
static inline static inline
struct nexthop *nexthop_mpath_select(const struct nexthop *nh, int nhsel) struct nexthop *nexthop_mpath_select(const struct nh_group *nhg, int nhsel)
{ {
const struct nh_group *nhg = rcu_dereference_rtnl(nh->nh_grp);
/* for_nexthops macros in fib_semantics.c grabs a pointer to /* for_nexthops macros in fib_semantics.c grabs a pointer to
* the nexthop before checking nhsel * the nexthop before checking nhsel
*/ */
...@@ -186,12 +185,14 @@ static inline bool nexthop_is_blackhole(const struct nexthop *nh) ...@@ -186,12 +185,14 @@ static inline bool nexthop_is_blackhole(const struct nexthop *nh)
{ {
const struct nh_info *nhi; const struct nh_info *nhi;
if (nexthop_is_multipath(nh)) { if (nh->is_group) {
if (nexthop_num_path(nh) > 1) struct nh_group *nh_grp;
return false;
nh = nexthop_mpath_select(nh, 0); nh_grp = rcu_dereference_rtnl(nh->nh_grp);
if (!nh) if (nh_grp->num_nh > 1)
return false; return false;
nh = nh_grp->nh_entries[0].nh;
} }
nhi = rcu_dereference_rtnl(nh->nh_info); nhi = rcu_dereference_rtnl(nh->nh_info);
...@@ -217,11 +218,16 @@ struct fib_nh_common *nexthop_fib_nhc(struct nexthop *nh, int nhsel) ...@@ -217,11 +218,16 @@ struct fib_nh_common *nexthop_fib_nhc(struct nexthop *nh, int nhsel)
BUILD_BUG_ON(offsetof(struct fib_nh, nh_common) != 0); BUILD_BUG_ON(offsetof(struct fib_nh, nh_common) != 0);
BUILD_BUG_ON(offsetof(struct fib6_nh, nh_common) != 0); BUILD_BUG_ON(offsetof(struct fib6_nh, nh_common) != 0);
if (nexthop_is_multipath(nh)) { if (nh->is_group) {
nh = nexthop_mpath_select(nh, nhsel); struct nh_group *nh_grp;
nh_grp = rcu_dereference_rtnl(nh->nh_grp);
if (nh_grp->mpath) {
nh = nexthop_mpath_select(nh_grp, nhsel);
if (!nh) if (!nh)
return NULL; return NULL;
} }
}
nhi = rcu_dereference_rtnl(nh->nh_info); nhi = rcu_dereference_rtnl(nh->nh_info);
return &nhi->fib_nhc; return &nhi->fib_nhc;
...@@ -264,8 +270,11 @@ static inline struct fib6_nh *nexthop_fib6_nh(struct nexthop *nh) ...@@ -264,8 +270,11 @@ static inline struct fib6_nh *nexthop_fib6_nh(struct nexthop *nh)
{ {
struct nh_info *nhi; struct nh_info *nhi;
if (nexthop_is_multipath(nh)) { if (nh->is_group) {
nh = nexthop_mpath_select(nh, 0); struct nh_group *nh_grp;
nh_grp = rcu_dereference_rtnl(nh->nh_grp);
nh = nexthop_mpath_select(nh_grp, 0);
if (!nh) if (!nh)
return NULL; return NULL;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment