diff options
| author | Roy Marples <roy@marples.name> | 2019-08-23 18:01:24 +0100 |
|---|---|---|
| committer | Roy Marples <roy@marples.name> | 2019-08-23 18:01:24 +0100 |
| commit | 0bec93e409a8ba10b3192d6d70e6f11f6674a278 (patch) | |
| tree | fb838859b9ffad00af55e0907a63dea26ac9aa50 /src/if-bsd.c | |
| parent | 3f69fdec4e0456a8f6751fc6a89cf3b79a4f3c9e (diff) | |
| download | dhcpcd-0bec93e409a8ba10b3192d6d70e6f11f6674a278.tar.xz | |
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.
Diffstat (limited to 'src/if-bsd.c')
| -rw-r--r-- | src/if-bsd.c | 31 |
1 files changed, 15 insertions, 16 deletions
diff --git a/src/if-bsd.c b/src/if-bsd.c index 6d5531cb..83a2f169 100644 --- a/src/if-bsd.c +++ b/src/if-bsd.c @@ -674,9 +674,15 @@ if_copyrt(struct dhcpcd_ctx *ctx, struct rt *rt, const struct rt_msghdr *rtm) 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 @@ if_rtm(struct dhcpcd_ctx *ctx, const struct rt_msghdr *rtm) * 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); |
