route: protect against unattached AF deep down #207

For pppoe/ng interfaces sometimes we enter ip6_tryforward() with
a NULL pointer array and IN6_LINKMTU() glancing over the fact
that this is not a valid destination since if_afdata structure
is not initialized.

While here remove the RT_LINK_IS_UP macro since nothing outside
of nhop is using it.

This is probably a side effect generator, but fixing one spot
instead of the general case would leave other holes in the stack.
Do not return a route destination if the address families were not
yet attached.
This commit is contained in:
Franco Fichtner 2025-03-02 20:54:30 +01:00
parent fade76e8b0
commit 5dc500ba7a
4 changed files with 10 additions and 10 deletions

View file

@ -376,9 +376,6 @@ struct rt_addrinfo {
#ifdef _KERNEL
#define RT_LINK_IS_UP(ifp) (!((ifp)->if_capabilities & IFCAP_LINKSTATE) \
|| (ifp)->if_link_state == LINK_STATE_UP)
#define RO_NHFREE(_ro) do { \
if ((_ro)->ro_nh) { \
NH_FREE((_ro)->ro_nh); \

View file

@ -152,7 +152,10 @@ struct nhop_object {
* with NHF_INVALID flag.
*/
#define NH_IS_VALID(_nh) RT_LINK_IS_UP((_nh)->nh_ifp)
#define NH_IS_VALID(_nh) ((!((_nh)->nh_ifp->if_capabilities & IFCAP_LINKSTATE) \
|| (_nh)->nh_ifp->if_link_state == LINK_STATE_UP) \
&& (_nh)->nh_ifp->if_afdata_initialized != 0)
#define NH_IS_NHGRP(_nh) ((_nh)->nh_flags & NHF_MULTIPATH)
#define NH_FREE(_nh) do { \

View file

@ -120,7 +120,7 @@ fib4_lookup(uint32_t fibnum, struct in_addr dst, uint32_t scopeid,
if (nh != NULL) {
nh = nhop_select(nh, flowid);
/* Ensure route & ifp is UP */
if (RT_LINK_IS_UP(nh->nh_ifp)) {
if (NH_IS_VALID(nh)) {
if (flags & NHR_REF)
nhop_ref_object(nh);
return (nh);
@ -157,7 +157,7 @@ fib4_lookup(uint32_t fibnum, struct in_addr dst, uint32_t scopeid,
if (rn != NULL && ((rn->rn_flags & RNF_ROOT) == 0)) {
nh = nhop_select((RNTORT(rn))->rt_nhop, flowid);
/* Ensure route & ifp is UP */
if (RT_LINK_IS_UP(nh->nh_ifp)) {
if (NH_IS_VALID(nh)) {
if (flags & NHR_REF)
nhop_ref_object(nh);
RIB_RUNLOCK(rh);
@ -323,7 +323,7 @@ fib4_lookup_debugnet(uint32_t fibnum, struct in_addr dst, uint32_t scopeid,
if (rt != NULL) {
struct nhop_object *nh = nhop_select(rnd.rnd_nhop, 0);
/* Ensure route & ifp is UP */
if (RT_LINK_IS_UP(nh->nh_ifp))
if (NH_IS_VALID(nh))
return (nh);
}

View file

@ -128,7 +128,7 @@ fib6_lookup(uint32_t fibnum, const struct in6_addr *dst6,
if (nh != NULL) {
nh = nhop_select(nh, flowid);
/* Ensure route & ifp is UP */
if (RT_LINK_IS_UP(nh->nh_ifp)) {
if (NH_IS_VALID(nh)) {
if (flags & NHR_REF)
nhop_ref_object(nh);
return (nh);
@ -166,7 +166,7 @@ fib6_lookup(uint32_t fibnum, const struct in6_addr *dst6,
if (rn != NULL && ((rn->rn_flags & RNF_ROOT) == 0)) {
nh = nhop_select((RNTORT(rn))->rt_nhop, flowid);
/* Ensure route & ifp is UP */
if (RT_LINK_IS_UP(nh->nh_ifp)) {
if (NH_IS_VALID(nh)) {
if (flags & NHR_REF)
nhop_ref_object(nh);
RIB_RUNLOCK(rh);
@ -338,7 +338,7 @@ fib6_lookup_debugnet(uint32_t fibnum, const struct in6_addr *dst6,
if (rt != NULL) {
struct nhop_object *nh = nhop_select(rnd.rnd_nhop, 0);
/* Ensure route & ifp is UP */
if (RT_LINK_IS_UP(nh->nh_ifp))
if (NH_IS_VALID(nh))
return (nh);
}