Message ID | 20200526150114.41687-6-dsahern@kernel.org |
---|---|
State | Accepted |
Delegated to: | David Miller |
Headers | show |
Series | nexthops: Fix 2 fundamental flaws with nexthop groups | expand |
On 26/05/2020 18:01, David Ahern wrote: > From: David Ahern <dsahern@gmail.com> > > Similar to the last path, need to fix fib_info_nh_uses_dev for > external nexthops to avoid referencing multiple nh_grp structs. > Move the device check in fib_info_nh_uses_dev to a helper and > create a nexthop version that is called if the fib_info uses an > external nexthop. > > Fixes: 430a049190de ("nexthop: Add support for nexthop groups") > Signed-off-by: David Ahern <dsahern@gmail.com> > --- > include/net/ip_fib.h | 10 ++++++++++ > include/net/nexthop.h | 25 +++++++++++++++++++++++++ > net/ipv4/fib_frontend.c | 19 ++++++++++--------- > 3 files changed, 45 insertions(+), 9 deletions(-) > Acked-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com> > diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h > index 1f1dd22980e4..6683558db7c9 100644 > --- a/include/net/ip_fib.h > +++ b/include/net/ip_fib.h > @@ -448,6 +448,16 @@ static inline int fib_num_tclassid_users(struct net *net) > #endif > int fib_unmerge(struct net *net); > > +static inline bool nhc_l3mdev_matches_dev(const struct fib_nh_common *nhc, > +const struct net_device *dev) > +{ > + if (nhc->nhc_dev == dev || > + l3mdev_master_ifindex_rcu(nhc->nhc_dev) == dev->ifindex) > + return true; > + > + return false; > +} > + > /* Exported by fib_semantics.c */ > int ip_fib_check_default(__be32 gw, struct net_device *dev); > int fib_sync_down_dev(struct net_device *dev, unsigned long event, bool force); > diff --git a/include/net/nexthop.h b/include/net/nexthop.h > index 9414ae46fc1c..35680a8c2a1c 100644 > --- a/include/net/nexthop.h > +++ b/include/net/nexthop.h > @@ -266,6 +266,31 @@ struct fib_nh_common *nexthop_get_nhc_lookup(const struct nexthop *nh, > return NULL; > } > > +static inline bool nexthop_uses_dev(const struct nexthop *nh, > + const struct net_device *dev) > +{ > + struct nh_info *nhi; > + > + if (nh->is_group) { > + struct nh_group *nhg = rcu_dereference(nh->nh_grp); > + int i; > + > + for (i = 0; i < nhg->num_nh; i++) { > + struct nexthop *nhe = nhg->nh_entries[i].nh; > + > + nhi = rcu_dereference(nhe->nh_info); > + if (nhc_l3mdev_matches_dev(&nhi->fib_nhc, dev)) > + return true; > + } > + } else { > + nhi = rcu_dereference(nh->nh_info); > + if (nhc_l3mdev_matches_dev(&nhi->fib_nhc, dev)) > + return true; > + } > + > + return false; > +} > + > static inline unsigned int fib_info_num_path(const struct fib_info *fi) > { > if (unlikely(fi->nh)) > diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c > index 213be9c050ad..aebb50735c68 100644 > --- a/net/ipv4/fib_frontend.c > +++ b/net/ipv4/fib_frontend.c > @@ -309,17 +309,18 @@ bool fib_info_nh_uses_dev(struct fib_info *fi, const struct net_device *dev) > { > bool dev_match = false; > #ifdef CONFIG_IP_ROUTE_MULTIPATH > - int ret; > + if (unlikely(fi->nh)) { > + dev_match = nexthop_uses_dev(fi->nh, dev); > + } else { > + int ret; > > - for (ret = 0; ret < fib_info_num_path(fi); ret++) { > - const struct fib_nh_common *nhc = fib_info_nhc(fi, ret); > + for (ret = 0; ret < fib_info_num_path(fi); ret++) { > + const struct fib_nh_common *nhc = fib_info_nhc(fi, ret); > > - if (nhc->nhc_dev == dev) { > - dev_match = true; > - break; > - } else if (l3mdev_master_ifindex_rcu(nhc->nhc_dev) == dev->ifindex) { > - dev_match = true; > - break; > + if (nhc_l3mdev_matches_dev(nhc, dev)) { > + dev_match = true; > + break; > + } > } > } > #else >
On Tue, 26 May 2020 09:01:14 -0600 David Ahern wrote: > From: David Ahern <dsahern@gmail.com> > > Similar to the last path, need to fix fib_info_nh_uses_dev for > external nexthops to avoid referencing multiple nh_grp structs. > Move the device check in fib_info_nh_uses_dev to a helper and > create a nexthop version that is called if the fib_info uses an > external nexthop. > > Fixes: 430a049190de ("nexthop: Add support for nexthop groups") > Signed-off-by: David Ahern <dsahern@gmail.com> Dave, bunch of white space problems here according to checkpatch: CHECK: Alignment should match open parenthesis #31: FILE: include/net/ip_fib.h:451: +static inline bool nhc_l3mdev_matches_dev(const struct fib_nh_common *nhc, +const struct net_device *dev) WARNING: suspect code indent for conditional statements (8, 24) #33: FILE: include/net/ip_fib.h:453: + if (nhc->nhc_dev == dev || [...] + return true; ERROR: code indent should use tabs where possible #66: FILE: include/net/nexthop.h:284: + }$ WARNING: please, no spaces at the start of a line #66: FILE: include/net/nexthop.h:284: + }$ ERROR: code indent should use tabs where possible #67: FILE: include/net/nexthop.h:285: + } else {$ WARNING: please, no spaces at the start of a line #67: FILE: include/net/nexthop.h:285: + } else {$ ERROR: code indent should use tabs where possible #71: FILE: include/net/nexthop.h:289: + }$ WARNING: please, no spaces at the start of a line #71: FILE: include/net/nexthop.h:289: + }$ total: 3 errors, 4 warnings, 1 checks, 74 lines checked
On 5/26/20 12:37 PM, Jakub Kicinski wrote: > Dave, bunch of white space problems here according to checkpatch: > ugh, the VM I used for iterations did not have the git hook to run checkpatch on commit. Will re-spin.
diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h index 1f1dd22980e4..6683558db7c9 100644 --- a/include/net/ip_fib.h +++ b/include/net/ip_fib.h @@ -448,6 +448,16 @@ static inline int fib_num_tclassid_users(struct net *net) #endif int fib_unmerge(struct net *net); +static inline bool nhc_l3mdev_matches_dev(const struct fib_nh_common *nhc, +const struct net_device *dev) +{ + if (nhc->nhc_dev == dev || + l3mdev_master_ifindex_rcu(nhc->nhc_dev) == dev->ifindex) + return true; + + return false; +} + /* Exported by fib_semantics.c */ int ip_fib_check_default(__be32 gw, struct net_device *dev); int fib_sync_down_dev(struct net_device *dev, unsigned long event, bool force); diff --git a/include/net/nexthop.h b/include/net/nexthop.h index 9414ae46fc1c..35680a8c2a1c 100644 --- a/include/net/nexthop.h +++ b/include/net/nexthop.h @@ -266,6 +266,31 @@ struct fib_nh_common *nexthop_get_nhc_lookup(const struct nexthop *nh, return NULL; } +static inline bool nexthop_uses_dev(const struct nexthop *nh, + const struct net_device *dev) +{ + struct nh_info *nhi; + + if (nh->is_group) { + struct nh_group *nhg = rcu_dereference(nh->nh_grp); + int i; + + for (i = 0; i < nhg->num_nh; i++) { + struct nexthop *nhe = nhg->nh_entries[i].nh; + + nhi = rcu_dereference(nhe->nh_info); + if (nhc_l3mdev_matches_dev(&nhi->fib_nhc, dev)) + return true; + } + } else { + nhi = rcu_dereference(nh->nh_info); + if (nhc_l3mdev_matches_dev(&nhi->fib_nhc, dev)) + return true; + } + + return false; +} + static inline unsigned int fib_info_num_path(const struct fib_info *fi) { if (unlikely(fi->nh)) diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index 213be9c050ad..aebb50735c68 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c @@ -309,17 +309,18 @@ bool fib_info_nh_uses_dev(struct fib_info *fi, const struct net_device *dev) { bool dev_match = false; #ifdef CONFIG_IP_ROUTE_MULTIPATH - int ret; + if (unlikely(fi->nh)) { + dev_match = nexthop_uses_dev(fi->nh, dev); + } else { + int ret; - for (ret = 0; ret < fib_info_num_path(fi); ret++) { - const struct fib_nh_common *nhc = fib_info_nhc(fi, ret); + for (ret = 0; ret < fib_info_num_path(fi); ret++) { + const struct fib_nh_common *nhc = fib_info_nhc(fi, ret); - if (nhc->nhc_dev == dev) { - dev_match = true; - break; - } else if (l3mdev_master_ifindex_rcu(nhc->nhc_dev) == dev->ifindex) { - dev_match = true; - break; + if (nhc_l3mdev_matches_dev(nhc, dev)) { + dev_match = true; + break; + } } } #else