From: Roy Marples Date: Mon, 22 Sep 2014 10:50:30 +0000 (+0000) Subject: Detect IPv6 route deletion on Linux. X-Git-Tag: v6.4.6~18 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=6c666347cd5f9e01fd387a724c4c7278ba2b91a0;p=thirdparty%2Fdhcpcd.git Detect IPv6 route deletion on Linux. --- diff --git a/if-linux.c b/if-linux.c index f418d108..26f66e1a 100644 --- a/if-linux.c +++ b/if-linux.c @@ -407,8 +407,12 @@ link_route(struct dhcpcd_ctx *ctx, __unused struct interface *ifp, unsigned int metric; struct rtattr *rta; struct rtmsg *rtm; +#ifdef INET struct rt rt; - char ifn[IF_NAMESIZE + 1]; +#endif +#ifdef INET6 + struct rt6 rt6; +#endif if (nlm->nlmsg_type != RTM_DELROUTE) return 0; @@ -421,7 +425,7 @@ link_route(struct dhcpcd_ctx *ctx, __unused struct interface *ifp, rtm = NLMSG_DATA(nlm); if (rtm->rtm_type != RTN_UNICAST || rtm->rtm_table != RT_TABLE_MAIN || - rtm->rtm_family != AF_INET) + (rtm->rtm_family != AF_INET && rtm->rtm_family != AF_INET6)) return 1; /* Ignore messages generated by us. * For some reason we get messages generated by us @@ -438,32 +442,65 @@ link_route(struct dhcpcd_ctx *ctx, __unused struct interface *ifp, rt.gate.s_addr = INADDR_ANY; metric = 0; while (RTA_OK(rta, len)) { - switch (rta->rta_type) { - case RTA_DST: - memcpy(&rt.dest.s_addr, RTA_DATA(rta), - sizeof(rt.dest.s_addr)); - break; - case RTA_GATEWAY: - memcpy(&rt.gate.s_addr, RTA_DATA(rta), - sizeof(rt.gate.s_addr)); + switch (rtm->rtm_family) { + case AF_INET: + switch (rta->rta_type) { + case RTA_DST: + memcpy(&rt.dest.s_addr, RTA_DATA(rta), + sizeof(rt.dest.s_addr)); + break; + case RTA_GATEWAY: + memcpy(&rt.gate.s_addr, RTA_DATA(rta), + sizeof(rt.gate.s_addr)); + break; + case RTA_OIF: + rt.iface = if_findindex(ctx, + *(unsigned int *)RTA_DATA(rta)); + break; + } break; - case RTA_OIF: - rt.iface = if_findindex(ctx, - *(unsigned int *)RTA_DATA(rta)); + case AF_INET6: + switch (rta->rta_type) { + case RTA_DST: + memcpy(&rt6.dest.s6_addr, RTA_DATA(rta), + sizeof(rt6.dest.s6_addr)); + break; + case RTA_GATEWAY: + memcpy(&rt6.gate.s6_addr, RTA_DATA(rta), + sizeof(rt6.gate.s6_addr)); + break; + case RTA_OIF: + rt6.iface = if_findindex(ctx, + *(unsigned int *)RTA_DATA(rta)); + break; + } break; + } + switch (rta->rta_type) { case RTA_PRIORITY: metric = *(unsigned int *)RTA_DATA(rta); break; } rta = RTA_NEXT(rta, len); } - if (rt.iface != NULL) { - if (metric == rt.iface->metric) { + + switch (rtm->rtm_family) { #ifdef INET - inet_cidrtoaddr(rtm->rtm_dst_len, &rt.net); - ipv4_routedeleted(ctx, &rt); + case AF_INET: + if (rt.iface != NULL && metric == rt.iface->metric) { + inet_cidrtoaddr(rtm->rtm_dst_len, &rt.net); + ipv4_routedeleted(ctx, &rt); + } + break; +#endif +#ifdef INET6 + case AF_INET6: + if (rt6.iface != NULL && metric == rt6.iface->metric) { + ipv6_mask(&rt6.net, rtm->rtm_dst_len); + ipv6_routedeleted(ctx, &rt6); + } + break; #endif - } } return 1; }