Skip to content

Commit d3d97da

Browse files
dsahernmarcelocerri
authored andcommitted
ipv4: nexthop version of fib_info_nh_uses_dev
BugLink: https://bugs.launchpad.net/bugs/1881927 commit 1fd1c76 upstream. 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: 430a049 ("nexthop: Add support for nexthop groups") Signed-off-by: David Ahern <[email protected]> Acked-by: Nikolay Aleksandrov <[email protected]> Signed-off-by: David S. Miller <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]> Signed-off-by: Kamal Mostafa <[email protected]> Signed-off-by: Khalid Elmously <[email protected]>
1 parent 9ee0603 commit d3d97da

File tree

3 files changed

+45
-9
lines changed

3 files changed

+45
-9
lines changed

include/net/ip_fib.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,16 @@ static inline int fib_num_tclassid_users(struct net *net)
422422
#endif
423423
int fib_unmerge(struct net *net);
424424

425+
static inline bool nhc_l3mdev_matches_dev(const struct fib_nh_common *nhc,
426+
const struct net_device *dev)
427+
{
428+
if (nhc->nhc_dev == dev ||
429+
l3mdev_master_ifindex_rcu(nhc->nhc_dev) == dev->ifindex)
430+
return true;
431+
432+
return false;
433+
}
434+
425435
/* Exported by fib_semantics.c */
426436
int ip_fib_check_default(__be32 gw, struct net_device *dev);
427437
int fib_sync_down_dev(struct net_device *dev, unsigned long event, bool force);

include/net/nexthop.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,31 @@ struct fib_nh_common *nexthop_fib_nhc(struct nexthop *nh, int nhsel)
233233
return &nhi->fib_nhc;
234234
}
235235

236+
static inline bool nexthop_uses_dev(const struct nexthop *nh,
237+
const struct net_device *dev)
238+
{
239+
struct nh_info *nhi;
240+
241+
if (nh->is_group) {
242+
struct nh_group *nhg = rcu_dereference(nh->nh_grp);
243+
int i;
244+
245+
for (i = 0; i < nhg->num_nh; i++) {
246+
struct nexthop *nhe = nhg->nh_entries[i].nh;
247+
248+
nhi = rcu_dereference(nhe->nh_info);
249+
if (nhc_l3mdev_matches_dev(&nhi->fib_nhc, dev))
250+
return true;
251+
}
252+
} else {
253+
nhi = rcu_dereference(nh->nh_info);
254+
if (nhc_l3mdev_matches_dev(&nhi->fib_nhc, dev))
255+
return true;
256+
}
257+
258+
return false;
259+
}
260+
236261
static inline unsigned int fib_info_num_path(const struct fib_info *fi)
237262
{
238263
if (unlikely(fi->nh))

net/ipv4/fib_frontend.c

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -319,17 +319,18 @@ bool fib_info_nh_uses_dev(struct fib_info *fi, const struct net_device *dev)
319319
{
320320
bool dev_match = false;
321321
#ifdef CONFIG_IP_ROUTE_MULTIPATH
322-
int ret;
322+
if (unlikely(fi->nh)) {
323+
dev_match = nexthop_uses_dev(fi->nh, dev);
324+
} else {
325+
int ret;
323326

324-
for (ret = 0; ret < fib_info_num_path(fi); ret++) {
325-
const struct fib_nh_common *nhc = fib_info_nhc(fi, ret);
327+
for (ret = 0; ret < fib_info_num_path(fi); ret++) {
328+
const struct fib_nh_common *nhc = fib_info_nhc(fi, ret);
326329

327-
if (nhc->nhc_dev == dev) {
328-
dev_match = true;
329-
break;
330-
} else if (l3mdev_master_ifindex_rcu(nhc->nhc_dev) == dev->ifindex) {
331-
dev_match = true;
332-
break;
330+
if (nhc_l3mdev_matches_dev(nhc, dev)) {
331+
dev_match = true;
332+
break;
333+
}
333334
}
334335
}
335336
#else

0 commit comments

Comments
 (0)