Skip to content

Commit 1fd1c76

Browse files
dsaherndavem330
authored andcommitted
ipv4: nexthop version of fib_info_nh_uses_dev
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]>
1 parent af7888a commit 1fd1c76

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
@@ -447,6 +447,16 @@ static inline int fib_num_tclassid_users(struct net *net)
447447
#endif
448448
int fib_unmerge(struct net *net);
449449

450+
static inline bool nhc_l3mdev_matches_dev(const struct fib_nh_common *nhc,
451+
const struct net_device *dev)
452+
{
453+
if (nhc->nhc_dev == dev ||
454+
l3mdev_master_ifindex_rcu(nhc->nhc_dev) == dev->ifindex)
455+
return true;
456+
457+
return false;
458+
}
459+
450460
/* Exported by fib_semantics.c */
451461
int ip_fib_check_default(__be32 gw, struct net_device *dev);
452462
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
@@ -266,6 +266,31 @@ struct fib_nh_common *nexthop_get_nhc_lookup(const struct nexthop *nh,
266266
return NULL;
267267
}
268268

269+
static inline bool nexthop_uses_dev(const struct nexthop *nh,
270+
const struct net_device *dev)
271+
{
272+
struct nh_info *nhi;
273+
274+
if (nh->is_group) {
275+
struct nh_group *nhg = rcu_dereference(nh->nh_grp);
276+
int i;
277+
278+
for (i = 0; i < nhg->num_nh; i++) {
279+
struct nexthop *nhe = nhg->nh_entries[i].nh;
280+
281+
nhi = rcu_dereference(nhe->nh_info);
282+
if (nhc_l3mdev_matches_dev(&nhi->fib_nhc, dev))
283+
return true;
284+
}
285+
} else {
286+
nhi = rcu_dereference(nh->nh_info);
287+
if (nhc_l3mdev_matches_dev(&nhi->fib_nhc, dev))
288+
return true;
289+
}
290+
291+
return false;
292+
}
293+
269294
static inline unsigned int fib_info_num_path(const struct fib_info *fi)
270295
{
271296
if (unlikely(fi->nh))

net/ipv4/fib_frontend.c

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -309,17 +309,18 @@ bool fib_info_nh_uses_dev(struct fib_info *fi, const struct net_device *dev)
309309
{
310310
bool dev_match = false;
311311
#ifdef CONFIG_IP_ROUTE_MULTIPATH
312-
int ret;
312+
if (unlikely(fi->nh)) {
313+
dev_match = nexthop_uses_dev(fi->nh, dev);
314+
} else {
315+
int ret;
313316

314-
for (ret = 0; ret < fib_info_num_path(fi); ret++) {
315-
const struct fib_nh_common *nhc = fib_info_nhc(fi, ret);
317+
for (ret = 0; ret < fib_info_num_path(fi); ret++) {
318+
const struct fib_nh_common *nhc = fib_info_nhc(fi, ret);
316319

317-
if (nhc->nhc_dev == dev) {
318-
dev_match = true;
319-
break;
320-
} else if (l3mdev_master_ifindex_rcu(nhc->nhc_dev) == dev->ifindex) {
321-
dev_match = true;
322-
break;
320+
if (nhc_l3mdev_matches_dev(nhc, dev)) {
321+
dev_match = true;
322+
break;
323+
}
323324
}
324325
}
325326
#else

0 commit comments

Comments
 (0)