Mercurial > hg > dhcpcd
changeset 4645:7d0f6ee7b39e draft
BSD: Fix router reachability tests
dhcpcd likes to indicate an on-link route as a NULL gateway.
However, we were testing this for an AF_LINK address to ensure
reachability. As such, it was possible to log a false positive.
Instead, record the existance of a valid AF_LINK address via
RTDF_GATELINK.
While here, ensure that we only treat RTM_DELETE as unreachable
and only other messages with RTDF_GATELINK as reachable, ignoring
other states so that a new incomplete address won't make us
unreachable if we're just discovering it.
| author | Roy Marples <roy@marples.name> |
|---|---|
| date | Fri, 23 Aug 2019 18:01:24 +0100 |
| parents | 292402db994b |
| children | c83adc0e8b5f |
| files | src/if-bsd.c src/route.h |
| diffstat | 2 files changed, 16 insertions(+), 16 deletions(-) [+] |
line wrap: on
line diff
--- a/src/if-bsd.c Wed Aug 21 17:16:25 2019 +0100 +++ b/src/if-bsd.c Fri Aug 23 18:01:24 2019 +0100 @@ -674,9 +674,15 @@ if (rt->rt_netmask.sa_family == 255) /* Why? */ rt->rt_netmask.sa_family = rt->rt_dest.sa_family; } - /* dhcpcd likes an unspecified gateway to indicate via the link. */ - if (rt->rt_flags & RTF_GATEWAY && - rti_info[RTAX_GATEWAY]->sa_family != AF_LINK) + /* dhcpcd likes an unspecified gateway to indicate via the link. + * However we need to know if gateway was a link with an address. */ + if (rti_info[RTAX_GATEWAY]->sa_family == AF_LINK) { + const struct sockaddr_dl *sdl; + + sdl = (const struct sockaddr_dl*)rti_info[RTAX_GATEWAY]; + if (sdl->sdl_alen != 0) + rt->rt_dflags |= RTDF_GATELINK; + } else if (rtm->rtm_flags & RTF_GATEWAY) if_copysa(&rt->rt_gateway, rti_info[RTAX_GATEWAY]); if (rtm->rtm_addrs & RTA_IFA) if_copysa(&rt->rt_ifa, rti_info[RTAX_IFA]); @@ -1077,20 +1083,13 @@ * BSD announces host routes. * As such, we should be notified of reachability by its * existance with a hardware address. + * Ensure we don't call this for an incomplete state. */ - if (rt.rt_dest.sa_family == AF_INET6 && rt.rt_flags & RTF_HOST) { - struct sockaddr_in6 dest; - struct sockaddr_dl sdl; - - memcpy(&dest, &rt.rt_dest, rt.rt_dest.sa_len); - if (rt.rt_gateway.sa_family == AF_LINK) - memcpy(&sdl, &rt.rt_gateway, rt.rt_gateway.sa_len); - else - sdl.sdl_alen = 0; - ipv6nd_neighbour(ctx, &dest.sin6_addr, - rtm->rtm_type != RTM_DELETE && sdl.sdl_alen ? - IPV6ND_REACHABLE : 0); - } + if (rt.rt_dest.sa_family == AF_INET6 && + rt.rt_flags & RTF_HOST && + (rtm->rtm_type == RTM_DELETE || rt.rt_dflags & RTDF_GATELINK)) + ipv6nd_neighbour(ctx, &rt.rt_ss_dest.sin6.sin6_addr, + rtm->rtm_type != RTM_DELETE ? IPV6ND_REACHABLE : 0); #endif rt_recvrt(rtm->rtm_type, &rt, rtm->rtm_pid);
--- a/src/route.h Wed Aug 21 17:16:25 2019 +0100 +++ b/src/route.h Fri Aug 23 18:01:24 2019 +0100 @@ -92,6 +92,7 @@ #define RTDF_RA 0x08 /* Router Advertisement */ #define RTDF_DHCP 0x10 /* DHCP route */ #define RTDF_STATIC 0x20 /* Configured in dhcpcd */ +#define RTDF_GATELINK 0x40 /* Gateway is on link */ size_t rt_order; rb_node_t rt_tree; };
