ipv4: fib: Notify about nexthop status changes
When a multipath route is hit the kernel doesn't consider nexthops that are DEAD or LINKDOWN when IN_DEV_IGNORE_ROUTES_WITH_LINKDOWN is set. Devices that offload multipath routes need to be made aware of nexthop status changes. Otherwise, the device will keep forwarding packets to non-functional nexthops. Add the FIB_EVENT_NH_{ADD,DEL} events to the fib notification chain, which notify capable devices when they should add or delete a nexthop from their tables. Cc: Roopa Prabhu <roopa@cumulusnetworks.com> Cc: David Ahern <dsa@cumulusnetworks.com> Cc: Andy Gospodarek <andy@greyhouse.net> Signed-off-by: Ido Schimmel <idosch@mellanox.com> Signed-off-by: Jiri Pirko <jiri@mellanox.com> Reviewed-by: Andy Gospodarek <gospo@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
70ad35067c
commit
982acb9756
2 changed files with 40 additions and 0 deletions
|
@ -214,11 +214,18 @@ struct fib_entry_notifier_info {
|
||||||
u32 nlflags;
|
u32 nlflags;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct fib_nh_notifier_info {
|
||||||
|
struct fib_notifier_info info; /* must be first */
|
||||||
|
struct fib_nh *fib_nh;
|
||||||
|
};
|
||||||
|
|
||||||
enum fib_event_type {
|
enum fib_event_type {
|
||||||
FIB_EVENT_ENTRY_ADD,
|
FIB_EVENT_ENTRY_ADD,
|
||||||
FIB_EVENT_ENTRY_DEL,
|
FIB_EVENT_ENTRY_DEL,
|
||||||
FIB_EVENT_RULE_ADD,
|
FIB_EVENT_RULE_ADD,
|
||||||
FIB_EVENT_RULE_DEL,
|
FIB_EVENT_RULE_DEL,
|
||||||
|
FIB_EVENT_NH_ADD,
|
||||||
|
FIB_EVENT_NH_DEL,
|
||||||
};
|
};
|
||||||
|
|
||||||
int register_fib_notifier(struct notifier_block *nb,
|
int register_fib_notifier(struct notifier_block *nb,
|
||||||
|
|
|
@ -1355,6 +1355,36 @@ int fib_sync_down_addr(struct net_device *dev, __be32 local)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int call_fib_nh_notifiers(struct fib_nh *fib_nh,
|
||||||
|
enum fib_event_type event_type)
|
||||||
|
{
|
||||||
|
struct in_device *in_dev = __in_dev_get_rtnl(fib_nh->nh_dev);
|
||||||
|
struct fib_nh_notifier_info info = {
|
||||||
|
.fib_nh = fib_nh,
|
||||||
|
};
|
||||||
|
|
||||||
|
switch (event_type) {
|
||||||
|
case FIB_EVENT_NH_ADD:
|
||||||
|
if (fib_nh->nh_flags & RTNH_F_DEAD)
|
||||||
|
break;
|
||||||
|
if (IN_DEV_IGNORE_ROUTES_WITH_LINKDOWN(in_dev) &&
|
||||||
|
fib_nh->nh_flags & RTNH_F_LINKDOWN)
|
||||||
|
break;
|
||||||
|
return call_fib_notifiers(dev_net(fib_nh->nh_dev), event_type,
|
||||||
|
&info.info);
|
||||||
|
case FIB_EVENT_NH_DEL:
|
||||||
|
if ((IN_DEV_IGNORE_ROUTES_WITH_LINKDOWN(in_dev) &&
|
||||||
|
fib_nh->nh_flags & RTNH_F_LINKDOWN) ||
|
||||||
|
(fib_nh->nh_flags & RTNH_F_DEAD))
|
||||||
|
return call_fib_notifiers(dev_net(fib_nh->nh_dev),
|
||||||
|
event_type, &info.info);
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NOTIFY_DONE;
|
||||||
|
}
|
||||||
|
|
||||||
/* Event force Flags Description
|
/* Event force Flags Description
|
||||||
* NETDEV_CHANGE 0 LINKDOWN Carrier OFF, not for scope host
|
* NETDEV_CHANGE 0 LINKDOWN Carrier OFF, not for scope host
|
||||||
* NETDEV_DOWN 0 LINKDOWN|DEAD Link down, not for scope host
|
* NETDEV_DOWN 0 LINKDOWN|DEAD Link down, not for scope host
|
||||||
|
@ -1396,6 +1426,8 @@ int fib_sync_down_dev(struct net_device *dev, unsigned long event, bool force)
|
||||||
nexthop_nh->nh_flags |= RTNH_F_LINKDOWN;
|
nexthop_nh->nh_flags |= RTNH_F_LINKDOWN;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
call_fib_nh_notifiers(nexthop_nh,
|
||||||
|
FIB_EVENT_NH_DEL);
|
||||||
dead++;
|
dead++;
|
||||||
}
|
}
|
||||||
#ifdef CONFIG_IP_ROUTE_MULTIPATH
|
#ifdef CONFIG_IP_ROUTE_MULTIPATH
|
||||||
|
@ -1550,6 +1582,7 @@ int fib_sync_up(struct net_device *dev, unsigned int nh_flags)
|
||||||
continue;
|
continue;
|
||||||
alive++;
|
alive++;
|
||||||
nexthop_nh->nh_flags &= ~nh_flags;
|
nexthop_nh->nh_flags &= ~nh_flags;
|
||||||
|
call_fib_nh_notifiers(nexthop_nh, FIB_EVENT_NH_ADD);
|
||||||
} endfor_nexthops(fi)
|
} endfor_nexthops(fi)
|
||||||
|
|
||||||
if (alive > 0) {
|
if (alive > 0) {
|
||||||
|
|
Loading…
Reference in a new issue