summaryrefslogtreecommitdiffstats
path: root/src/if-bsd.c
diff options
context:
space:
mode:
authorRoy Marples <roy@marples.name>2019-08-23 18:01:24 +0100
committerRoy Marples <roy@marples.name>2019-08-23 18:01:24 +0100
commit0bec93e409a8ba10b3192d6d70e6f11f6674a278 (patch)
treefb838859b9ffad00af55e0907a63dea26ac9aa50 /src/if-bsd.c
parent3f69fdec4e0456a8f6751fc6a89cf3b79a4f3c9e (diff)
downloaddhcpcd-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.c31
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);