diff --git a/src/dhcp.c b/src/dhcp.c index 2733e91c..fe9c40cd 100644 --- a/src/dhcp.c +++ b/src/dhcp.c @@ -434,9 +434,9 @@ decode_rfc3442_rt(rb_tree_t *routes, struct interface *ifp, const uint8_t *data, if (netmask.s_addr == INADDR_BROADCAST) rt->rt_flags = RTF_HOST; - sa_in_init(&rt->rt_dest, &dest); - sa_in_init(&rt->rt_netmask, &netmask); - sa_in_init(&rt->rt_gateway, &gateway); + sa_in_init(rt->rt_dest, &dest); + sa_in_init(rt->rt_netmask, &netmask); + sa_in_init(rt->rt_gateway, &gateway); if (rt_proto_add(routes, rt)) n = 1; } @@ -614,9 +614,9 @@ get_option_routes(rb_tree_t *routes, struct interface *ifp, if (netmask.s_addr == INADDR_BROADCAST) rt->rt_flags = RTF_HOST; - sa_in_init(&rt->rt_dest, &dest); - sa_in_init(&rt->rt_netmask, &netmask); - sa_in_init(&rt->rt_gateway, &gateway); + sa_in_init(rt->rt_dest, &dest); + sa_in_init(rt->rt_netmask, &netmask); + sa_in_init(rt->rt_gateway, &gateway); if (rt_proto_add(routes, rt)) n++; } @@ -636,9 +636,9 @@ get_option_routes(rb_tree_t *routes, struct interface *ifp, return -1; memcpy(&gateway.s_addr, p, sizeof(gateway.s_addr)); p += 4; - sa_in_init(&rt->rt_dest, &dest); - sa_in_init(&rt->rt_netmask, &netmask); - sa_in_init(&rt->rt_gateway, &gateway); + sa_in_init(rt->rt_dest, &dest); + sa_in_init(rt->rt_netmask, &netmask); + sa_in_init(rt->rt_gateway, &gateway); if (rt_proto_add(routes, rt)) n++; } diff --git a/src/dhcpcd.c b/src/dhcpcd.c index f065c733..ab853a8f 100644 --- a/src/dhcpcd.c +++ b/src/dhcpcd.c @@ -2201,7 +2201,7 @@ main(int argc, char **argv, char **envp) ctx.ifc = argc - optind; ctx.ifv = argv + optind; - rt_init(&ctx); + rt_init_routes(&ctx); ifo = read_config(&ctx, NULL, NULL, NULL); if (ifo == NULL) { diff --git a/src/if-bsd.c b/src/if-bsd.c index 72d573b7..f017b510 100644 --- a/src/if-bsd.c +++ b/src/if-bsd.c @@ -751,15 +751,15 @@ if_route(unsigned char cmd, const struct rt *rt) rtm->rtm_flags |= RTF_PINNED; #endif - gateway_unspec = sa_is_unspecified(&rt->rt_gateway); + gateway_unspec = sa_is_unspecified(rt->rt_gateway); if (cmd == RTM_ADD || cmd == RTM_CHANGE) { - bool netmask_bcast = sa_is_allones(&rt->rt_netmask); + bool netmask_bcast = sa_is_allones(rt->rt_netmask); rtm->rtm_flags |= RTF_UP; rtm->rtm_addrs |= RTA_GATEWAY; if (!(rtm->rtm_flags & RTF_REJECT) && - !sa_is_loopback(&rt->rt_gateway)) { + !sa_is_loopback(rt->rt_gateway)) { rtm->rtm_index = (unsigned short)rt->rt_ifp->index; /* * OpenBSD rejects this for on-link routes when there is no default route @@ -770,10 +770,10 @@ if_route(unsigned char cmd, const struct rt *rt) #ifdef __OpenBSD__ #warning kernel does not allow IPv6 address sharing if (!gateway_unspec || - rt->rt_dest.sa_family != AF_INET6) + rt->rt_dest->sa_family != AF_INET6) #endif rtm->rtm_addrs |= RTA_IFP; - if (!sa_is_unspecified(&rt->rt_ifa)) + if (!sa_is_unspecified(rt->rt_ifa)) rtm->rtm_addrs |= RTA_IFA; } if (netmask_bcast) @@ -822,31 +822,32 @@ if_route(unsigned char cmd, const struct rt *rt) if_linkaddr(&sdl, rt->rt_ifp); - ADDSA(&rt->rt_dest); + ADDSA(rt->rt_dest); if (rtm->rtm_addrs & RTA_GATEWAY) { if (gateway_unspec) ADDSA((struct sockaddr *)&sdl); else { - union sa_ss gateway; + struct sockaddr_storage gss; + struct sockaddr *gsa = (struct sockaddr *)&gss; - if_copysa(&gateway.sa, &rt->rt_gateway); + if_copysa(gsa, rt->rt_gateway); #ifdef INET6 - if (gateway.sa.sa_family == AF_INET6) - ipv6_setscope(&gateway.sin6, rt->rt_ifp->index); + if (gss.ss_family == AF_INET6) + ipv6_setscope((struct sockaddr_in6 *)&gss, rt->rt_ifp->index); #endif - ADDSA(&gateway.sa); + ADDSA(gsa); } } if (rtm->rtm_addrs & RTA_NETMASK) - ADDSA(&rt->rt_netmask); + ADDSA(rt->rt_netmask); if (rtm->rtm_addrs & RTA_IFP) ADDSA((struct sockaddr *)&sdl); if (rtm->rtm_addrs & RTA_IFA) - ADDSA(&rt->rt_ifa); + ADDSA(rt->rt_ifa); #undef ADDSA @@ -903,13 +904,13 @@ if_copyrt(struct dhcpcd_ctx *ctx, struct rt *rt, const struct rt_msghdr *rtm) if (get_addrs(rtm->rtm_addrs, (const char *)rtm + sizeof(*rtm), rtm->rtm_msglen - sizeof(*rtm), rti_info) == -1) return -1; - memset(rt, 0, sizeof(*rt)); + rt_init(rt); rt->rt_flags = (unsigned int)rtm->rtm_flags; - if_copysa(&rt->rt_dest, rti_info[RTAX_DST]); + if_copysa(rt->rt_dest, rti_info[RTAX_DST]); if (rtm->rtm_addrs & RTA_NETMASK) { - if_copysa(&rt->rt_netmask, rti_info[RTAX_NETMASK]); + if_copysa(rt->rt_netmask, rti_info[RTAX_NETMASK]); /* * Netmask family and length are ignored by traditional * userland tools such as route and netstat and are assumed @@ -921,8 +922,8 @@ if_copyrt(struct dhcpcd_ctx *ctx, struct rt *rt, const struct rt_msghdr *rtm) * * This is currently true for all BSD kernels. */ - rt->rt_netmask.sa_family = rt->rt_dest.sa_family; - rt->rt_netmask.sa_len = rt->rt_dest.sa_len; + rt->rt_netmask->sa_family = rt->rt_dest->sa_family; + rt->rt_netmask->sa_len = rt->rt_dest->sa_len; } /* dhcpcd likes an unspecified gateway to indicate via the link. @@ -936,11 +937,11 @@ if_copyrt(struct dhcpcd_ctx *ctx, struct rt *rt, const struct rt_msghdr *rtm) 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_copysa(rt->rt_gateway, rti_info[RTAX_GATEWAY]); } if (rtm->rtm_addrs & RTA_IFA) - if_copysa(&rt->rt_ifa, rti_info[RTAX_IFA]); + if_copysa(rt->rt_ifa, rti_info[RTAX_IFA]); rt->rt_mtu = (unsigned int)rtm->rtm_rmx.rmx_mtu; @@ -1018,7 +1019,7 @@ if_initrt(struct dhcpcd_ctx *ctx, rb_tree_t *kroutes, int af) logerr(__func__); break; } - memcpy(rtn, &rt, sizeof(*rtn)); + rt_copy(rtn, &rt); if (rb_tree_insert_node(kroutes, rtn) != rtn) rt_free(rtn); } @@ -1332,15 +1333,16 @@ if_rtm(struct dhcpcd_ctx *ctx, const struct rt_msghdr *rtm) * existance with a hardware address. * Ensure we don't call this for a newly incomplete state. */ - if (rt.rt_dest.sa_family == AF_INET6 && + if (rt.rt_dest->sa_family == AF_INET6 && (rt.rt_flags & RTF_HOST || rtm->rtm_type == RTM_MISS) && !(rtm->rtm_type == RTM_ADD && !(rt.rt_dflags & RTDF_GATELINK))) { bool reachable; + struct sockaddr_in6 *dest = (struct sockaddr_in6 *)&rt.rt_ss_dest; reachable = (rtm->rtm_type == RTM_ADD || rtm->rtm_type == RTM_CHANGE) && rt.rt_dflags & RTDF_GATELINK; - ipv6nd_neighbour(ctx, &rt.rt_ss_dest.sin6.sin6_addr, reachable); + ipv6nd_neighbour(ctx, &dest->sin6_addr, reachable); } #endif diff --git a/src/if-linux.c b/src/if-linux.c index 3f678d29..5fa5505e 100644 --- a/src/if-linux.c +++ b/src/if-linux.c @@ -689,7 +689,7 @@ if_copyrt(struct dhcpcd_ctx *ctx, struct rt *rt, struct nlmsghdr *nlm) if (rtm->rtm_table != RT_TABLE_MAIN) return -1; - memset(rt, 0, sizeof(*rt)); + rt_init(rt); if (rtm->rtm_type == RTN_UNREACHABLE) rt->rt_flags |= RTF_REJECT; @@ -699,11 +699,11 @@ if_copyrt(struct dhcpcd_ctx *ctx, struct rt *rt, struct nlmsghdr *nlm) sa = NULL; switch (rta->rta_type) { case RTA_DST: - sa = &rt->rt_dest; + sa = rt->rt_dest; break; case RTA_SRC: { - union sa_ss ssa; - struct sockaddr *psa = (struct sockaddr *)&ssa; + struct sockaddr_storage ss; + struct sockaddr *psa = (struct sockaddr *)&ss; socklen_t salen; psa->sa_family = rtm->rtm_family; @@ -722,10 +722,10 @@ if_copyrt(struct dhcpcd_ctx *ctx, struct rt *rt, struct nlmsghdr *nlm) break; } case RTA_GATEWAY: - sa = &rt->rt_gateway; + sa = rt->rt_gateway; break; case RTA_PREFSRC: - sa = &rt->rt_ifa; + sa = rt->rt_ifa; break; case RTA_OIF: ifindex = *(unsigned int *)RTA_DATA(rta); @@ -784,20 +784,18 @@ if_copyrt(struct dhcpcd_ctx *ctx, struct rt *rt, struct nlmsghdr *nlm) sa->sa_family = rtm->rtm_family; salen = sa_addrlen(sa); - /* sa is a union where sockaddr_in6 is the biggest. */ - /* coverity[overrun-buffer-arg] */ memcpy((char *)sa + sa_addroffset(sa), RTA_DATA(rta), MIN(salen, RTA_PAYLOAD(rta))); } } /* If no RTA_DST set the unspecified address for the family. */ - if (rt->rt_dest.sa_family == AF_UNSPEC) - rt->rt_dest.sa_family = rtm->rtm_family; + if (rt->rt_dest->sa_family == AF_UNSPEC) + rt->rt_dest->sa_family = rtm->rtm_family; - rt->rt_netmask.sa_family = rtm->rtm_family; - sa_fromprefix(&rt->rt_netmask, rtm->rtm_dst_len); - if (sa_is_allones(&rt->rt_netmask)) + rt->rt_netmask->sa_family = rtm->rtm_family; + sa_fromprefix(rt->rt_netmask, rtm->rtm_dst_len); + if (sa_is_allones(rt->rt_netmask)) rt->rt_flags |= RTF_HOST; #if 0 @@ -1662,10 +1660,10 @@ if_route(unsigned char cmd, const struct rt *rt) break; } nlm.hdr.nlmsg_flags |= NLM_F_REQUEST; - nlm.rt.rtm_family = (unsigned char)rt->rt_dest.sa_family; + nlm.rt.rtm_family = (unsigned char)rt->rt_dest->sa_family; nlm.rt.rtm_table = RT_TABLE_MAIN; - gateway_unspec = sa_is_unspecified(&rt->rt_gateway); + gateway_unspec = sa_is_unspecified(rt->rt_gateway); if (cmd == RTM_DELETE) { nlm.rt.rtm_scope = RT_SCOPE_NOWHERE; @@ -1702,22 +1700,18 @@ if_route(unsigned char cmd, const struct rt *rt) add_attr_l(&nlm.hdr, sizeof(nlm), (type), \ (const char *)(sa) + sa_addroffset((sa)), \ (unsigned short)sa_addrlen((sa))); - nlm.rt.rtm_dst_len = (unsigned char)sa_toprefix(&rt->rt_netmask); - /* rt->rt_dest and rt->gateway are unions where sockaddr_in6 - * is the biggest member. However, we access them as the - * generic sockaddr and coverity thinks this will overrun. */ - /* coverity[overrun-buffer-arg] */ - ADDSA(RTA_DST, &rt->rt_dest); + nlm.rt.rtm_dst_len = (unsigned char)sa_toprefix(rt->rt_netmask); + ADDSA(RTA_DST, rt->rt_dest); if (cmd == RTM_ADD || cmd == RTM_CHANGE) { if (!gateway_unspec) { /* coverity[overrun-buffer-arg] */ - ADDSA(RTA_GATEWAY, &rt->rt_gateway); + ADDSA(RTA_GATEWAY, rt->rt_gateway); } /* Cannot add tentative source addresses. * We don't know this here, so just skip INET6 ifa's.*/ - if (!sa_is_unspecified(&rt->rt_ifa) && - rt->rt_ifa.sa_family != AF_INET6) - ADDSA(RTA_PREFSRC, &rt->rt_ifa); + if (!sa_is_unspecified(rt->rt_ifa) && + rt->rt_ifa->sa_family != AF_INET6) + ADDSA(RTA_PREFSRC, rt->rt_ifa); if (rt->rt_mtu) { char metricsbuf[32]; struct rtattr *metrics = (void *)metricsbuf; @@ -1754,7 +1748,7 @@ if_route(unsigned char cmd, const struct rt *rt) #endif } - if (!sa_is_loopback(&rt->rt_gateway)) + if (!sa_is_loopback(rt->rt_gateway)) add_attr_32(&nlm.hdr, sizeof(nlm), RTA_OIF, rt->rt_ifp->index); #ifdef HAVE_ROUTE_LIFETIME @@ -1785,7 +1779,7 @@ _if_initrt(struct dhcpcd_ctx *ctx, void *arg, struct nlmsghdr *nlm) logerr(__func__); return 0; } - memcpy(rtn, &rt, sizeof(*rtn)); + rt_copy(rtn, &rt); if (rb_tree_insert_node(kroutes, rtn) != rtn) rt_free(rtn); return 0; diff --git a/src/if-options.c b/src/if-options.c index 54e048bf..cb4321d6 100644 --- a/src/if-options.c +++ b/src/if-options.c @@ -1330,9 +1330,9 @@ parse_option(struct dhcpcd_ctx *ctx, const char *ifname, struct if_options *ifo, *fp = ' '; if ((rt = rt_new0(ctx)) == NULL) return -1; - sa_in_init(&rt->rt_dest, &addr); - sa_in_init(&rt->rt_netmask, &addr2); - sa_in_init(&rt->rt_gateway, &addr3); + sa_in_init(rt->rt_dest, &addr); + sa_in_init(rt->rt_netmask, &addr2); + sa_in_init(rt->rt_gateway, &addr3); if (rt_proto_add_ctx(&ifo->routes, rt, ctx)) add_environ(&ifo->config, arg, 0); #else @@ -1351,9 +1351,9 @@ parse_option(struct dhcpcd_ctx *ctx, const char *ifname, struct if_options *ifo, if ((rt = rt_new0(ctx)) == NULL) return -1; addr2.s_addr = INADDR_ANY; - sa_in_init(&rt->rt_dest, &addr2); - sa_in_init(&rt->rt_netmask, &addr2); - sa_in_init(&rt->rt_gateway, &addr); + sa_in_init(rt->rt_dest, &addr2); + sa_in_init(rt->rt_netmask, &addr2); + sa_in_init(rt->rt_gateway, &addr); if (rt_proto_add_ctx(&ifo->routes, rt, ctx)) add_environ(&ifo->config, arg, 0); #else diff --git a/src/if-sun.c b/src/if-sun.c index 0a974769..37659bce 100644 --- a/src/if-sun.c +++ b/src/if-sun.c @@ -572,21 +572,21 @@ if_route0(struct dhcpcd_ctx *ctx, struct rtm *rtmsg, unsigned char cmd, rtm->rtm_flags = rt->rt_flags; rtm->rtm_addrs = RTA_DST | RTA_GATEWAY; - gateway_unspec = sa_is_unspecified(&rt->rt_gateway); + gateway_unspec = sa_is_unspecified(rt->rt_gateway); if (cmd == RTM_ADD || cmd == RTM_CHANGE) { - bool netmask_bcast = sa_is_allones(&rt->rt_netmask); + bool netmask_bcast = sa_is_allones(rt->rt_netmask); rtm->rtm_flags |= RTF_UP; if (!(rtm->rtm_flags & RTF_REJECT) && - !sa_is_loopback(&rt->rt_gateway)) { + !sa_is_loopback(rt->rt_gateway)) { rtm->rtm_addrs |= RTA_IFP; /* RTA_IFA is currently ignored by the kernel. * RTA_SRC and RTF_SETSRC look like what we want, * but they don't work with RTF_GATEWAY. * We set RTA_IFA just in the hope that the * kernel will one day support this. */ - if (!sa_is_unspecified(&rt->rt_ifa)) + if (!sa_is_unspecified(rt->rt_ifa)) rtm->rtm_addrs |= RTA_IFA; } @@ -607,15 +607,15 @@ if_route0(struct dhcpcd_ctx *ctx, struct rtm *rtmsg, unsigned char cmd, if (!(rtm->rtm_flags & RTF_HOST)) rtm->rtm_addrs |= RTA_NETMASK; - ADDSA(&rt->rt_dest); + ADDSA(rt->rt_dest); if (gateway_unspec) - ADDSA(&rt->rt_ifa); + ADDSA(rt->rt_ifa); else - ADDSA(&rt->rt_gateway); + ADDSA(rt->rt_gateway); if (rtm->rtm_addrs & RTA_NETMASK) - ADDSA(&rt->rt_netmask); + ADDSA(rt->rt_netmask); if (rtm->rtm_addrs & RTA_IFP) { struct sockaddr_dl sdl; @@ -625,11 +625,11 @@ if_route0(struct dhcpcd_ctx *ctx, struct rtm *rtmsg, unsigned char cmd, } if (rtm->rtm_addrs & RTA_IFA) - ADDSA(&rt->rt_ifa); + ADDSA(rt->rt_ifa); #if 0 if (rtm->rtm_addrs & RTA_SRC) - ADDSA(&rt->rt_ifa); + ADDSA(rt->rt_ifa); #endif rtm->rtm_msglen = (unsigned short)(bp - (char *)rtm); @@ -662,12 +662,12 @@ if_copyrt(struct dhcpcd_ctx *ctx, struct rt *rt, const struct rt_msghdr *rtm) rtm->rtm_msglen - sizeof(*rtm), rti_info) == -1) return -1; - memset(rt, 0, sizeof(*rt)); - + rt_init(rt); rt->rt_flags = (unsigned int)rtm->rtm_flags; - COPYSA(&rt->rt_dest, rti_info[RTAX_DST]); + + COPYSA(rt->rt_dest, rti_info[RTAX_DST]); if (rtm->rtm_addrs & RTA_NETMASK) - COPYSA(&rt->rt_netmask, rti_info[RTAX_NETMASK]); + COPYSA(rt->rt_netmask, rti_info[RTAX_NETMASK]); /* dhcpcd likes an unspecified gateway to indicate via the link. * However we need to know if gateway was a link with an address. */ @@ -680,11 +680,11 @@ if_copyrt(struct dhcpcd_ctx *ctx, struct rt *rt, const struct rt_msghdr *rtm) if (sdl->sdl_alen != 0) rt->rt_dflags |= RTDF_GATELINK; } else if (rtm->rtm_flags & RTF_GATEWAY) - COPYSA(&rt->rt_gateway, rti_info[RTAX_GATEWAY]); + COPYSA(rt->rt_gateway, rti_info[RTAX_GATEWAY]); } if (rtm->rtm_addrs & RTA_SRC) - COPYSA(&rt->rt_ifa, rti_info[RTAX_SRC]); + COPYSA(rt->rt_ifa, rti_info[RTAX_SRC]); rt->rt_mtu = (unsigned int)rtm->rtm_rmx.rmx_mtu; if (rtm->rtm_index) @@ -748,14 +748,14 @@ if_finishrt(struct dhcpcd_ctx *ctx, struct rt *rt) * of the owning address. * dhcpcd has a blank gateway here to indicate a * subnet route. */ - if (!sa_is_unspecified(&rt->rt_dest) && - !sa_is_unspecified(&rt->rt_gateway)) { - switch (rt->rt_gateway.sa_family) { + if (!sa_is_unspecified(rt->rt_dest) && + !sa_is_unspecified(rt->rt_gateway)) { + switch (rt->rt_gateway->sa_family) { #ifdef INET case AF_INET: { struct in_addr *in; - in = &satosin(&rt->rt_gateway)->sin_addr; + in = &satosin(rt->rt_gateway)->sin_addr; if (ipv4_findaddr(ctx, in)) in->s_addr = INADDR_ANY; break; @@ -765,7 +765,7 @@ if_finishrt(struct dhcpcd_ctx *ctx, struct rt *rt) case AF_INET6: { struct in6_addr *in6; - in6 = &satosin6(&rt->rt_gateway)->sin6_addr; + in6 = &satosin6(rt->rt_gateway)->sin6_addr; if (ipv6_findaddr(ctx, in6, 0)) *in6 = in6addr_any; break; @@ -839,15 +839,16 @@ if_rtm(struct dhcpcd_ctx *ctx, const struct rt_msghdr *rtm) * existance with a hardware address. * Ensure we don't call this for a newly incomplete state. */ - if (rt.rt_dest.sa_family == AF_INET6 && + if (rt.rt_dest->sa_family == AF_INET6 && (rt.rt_flags & RTF_HOST || rtm->rtm_type == RTM_MISS) && !(rtm->rtm_type == RTM_ADD && !(rt.rt_dflags & RTDF_GATELINK))) { bool reachable; + struct sockaddr_in6 *dest = (struct sockaddr_in6 *)rt.rt_dest; reachable = (rtm->rtm_type == RTM_ADD || rtm->rtm_type == RTM_CHANGE) && rt.rt_dflags & RTDF_GATELINK; - ipv6nd_neighbour(ctx, &rt.rt_ss_dest.sin6.sin6_addr, reachable); + ipv6nd_neighbour(ctx, &dest->sin6_addr, reachable); } #endif @@ -1392,16 +1393,16 @@ if_walkrt(struct dhcpcd_ctx *ctx, rb_tree_t *routes, char *data, size_t len) break; } - memset(&rt, 0, sizeof(rt)); + rt_init(&rt); in.s_addr = re->ipRouteDest; - sa_in_init(&rt.rt_dest, &in); + sa_in_init(rt.rt_dest, &in); in.s_addr = re->ipRouteMask; - sa_in_init(&rt.rt_netmask, &in); + sa_in_init(rt.rt_netmask, &in); in.s_addr = re->ipRouteNextHop; - sa_in_init(&rt.rt_gateway, &in); + sa_in_init(rt.rt_gateway, &in); rt.rt_flags = re->ipRouteInfo.re_flags; in.s_addr = re->ipRouteInfo.re_src_addr; - sa_in_init(&rt.rt_ifa, &in); + sa_in_init(rt.rt_ifa, &in); rt.rt_mtu = re->ipRouteInfo.re_max_frag; if_octetstr(ifname, &re->ipRouteIfIndex, sizeof(ifname)); rt.rt_ifp = if_find(ctx->ifaces, ifname); @@ -1413,7 +1414,7 @@ if_walkrt(struct dhcpcd_ctx *ctx, rb_tree_t *routes, char *data, size_t len) logerr(__func__); break; } - memcpy(rtn, &rt, sizeof(*rtn)); + rt_copy(rtn, &rt); if (rb_tree_insert_node(routes, rtn) != rtn) rt_free(rtn); } while (++re < e); @@ -1451,12 +1452,12 @@ if_walkrt6(struct dhcpcd_ctx *ctx, rb_tree_t *routes, char *data, size_t len) break; } - memset(&rt, 0, sizeof(rt)); - sa_in6_init(&rt.rt_dest, &re->ipv6RouteDest); + rt_init(&rt); + sa_in6_init(rt.rt_dest, &re->ipv6RouteDest); ipv6_mask(&in6, re->ipv6RoutePfxLength); - sa_in6_init(&rt.rt_netmask, &in6); - sa_in6_init(&rt.rt_gateway, &re->ipv6RouteNextHop); - sa_in6_init(&rt.rt_ifa, &re->ipv6RouteInfo.re_src_addr); + sa_in6_init(rt.rt_netmask, &in6); + sa_in6_init(rt.rt_gateway, &re->ipv6RouteNextHop); + sa_in6_init(rt.rt_ifa, &re->ipv6RouteInfo.re_src_addr); rt.rt_mtu = re->ipv6RouteInfo.re_max_frag; if_octetstr(ifname, &re->ipv6RouteIfIndex, sizeof(ifname)); rt.rt_ifp = if_find(ctx->ifaces, ifname); @@ -1468,7 +1469,7 @@ if_walkrt6(struct dhcpcd_ctx *ctx, rb_tree_t *routes, char *data, size_t len) logerr(__func__); break; } - memcpy(rtn, &rt, sizeof(*rtn)); + rt_copy(rtn, &rt); if (rb_tree_insert_node(routes, rtn) != rtn) rt_free(rtn); } while (++re < e); diff --git a/src/ipv4.c b/src/ipv4.c index d77bfb46..6461d52a 100644 --- a/src/ipv4.c +++ b/src/ipv4.c @@ -308,12 +308,12 @@ inet_dhcproutes(rb_tree_t *routes, struct interface *ifp, bool *have_default) return -1; rt->rt_dflags |= RTDF_IFA_ROUTE; in.s_addr = state->addr->addr.s_addr & state->addr->mask.s_addr; - sa_in_init(&rt->rt_dest, &in); + sa_in_init(rt->rt_dest, &in); in.s_addr = state->addr->mask.s_addr; - sa_in_init(&rt->rt_netmask, &in); + sa_in_init(rt->rt_netmask, &in); // in.s_addr = INADDR_ANY; - // sa_in_init(&rt->rt_gateway, &in); - rt->rt_gateway.sa_family = AF_UNSPEC; + // sa_in_init(rt->rt_gateway, &in); + rt->rt_gateway->sa_family = AF_UNSPEC; rt_proto_add(&nroutes, rt); } @@ -321,11 +321,11 @@ inet_dhcproutes(rb_tree_t *routes, struct interface *ifp, bool *have_default) if (RB_TREE_MIN(&ifp->options->routes)) { RB_TREE_FOREACH(r, &ifp->options->routes) { - if (sa_is_unspecified(&r->rt_gateway)) + if (sa_is_unspecified(r->rt_gateway)) break; if ((rt = rt_new0(ifp->ctx)) == NULL) return -1; - memcpy(rt, r, sizeof(*rt)); + rt_copy(rt, r); rt_setif(rt, ifp); rt->rt_dflags = RTDF_STATIC; rt_proto_add(&nroutes, rt); @@ -342,10 +342,10 @@ inet_dhcproutes(rb_tree_t *routes, struct interface *ifp, bool *have_default) if ((rt = rt_new(ifp)) == NULL) return -1; in.s_addr = INADDR_ANY; - sa_in_init(&rt->rt_dest, &in); - sa_in_init(&rt->rt_netmask, &in); - sa_in_init(&rt->rt_gateway, &state->addr->brd); - sa_in_init(&rt->rt_ifa, &state->addr->addr); + sa_in_init(rt->rt_dest, &in); + sa_in_init(rt->rt_netmask, &in); + sa_in_init(rt->rt_gateway, &state->addr->brd); + sa_in_init(rt->rt_ifa, &state->addr->addr); rt_proto_add(&nroutes, rt); } @@ -359,7 +359,7 @@ inet_dhcproutes(rb_tree_t *routes, struct interface *ifp, bool *have_default) rt->rt_dflags |= RTDF_DHCP; if (state->added & STATE_FAKE) rt->rt_dflags |= RTDF_FAKE; - sa_in_init(&rt->rt_ifa, &state->addr->addr); + sa_in_init(rt->rt_ifa, &state->addr->addr); if (rb_tree_insert_node(routes, rt) != rt) { rt_free(rt); continue; @@ -393,26 +393,26 @@ inet_routerhostroute(rb_tree_t *routes, struct interface *ifp) RB_TREE_FOREACH(rt, routes) { - if (rt->rt_dest.sa_family != AF_INET) + if (rt->rt_dest->sa_family != AF_INET) continue; - if (!sa_is_unspecified(&rt->rt_dest) || - sa_is_unspecified(&rt->rt_gateway)) + if (!sa_is_unspecified(rt->rt_dest) || + sa_is_unspecified(rt->rt_gateway)) continue; - gateway = satosin(&rt->rt_gateway); + gateway = satosin(rt->rt_gateway); /* Scan for a route to match */ RB_TREE_FOREACH(rth, routes) { if (rth == rt) break; /* match host */ - if (sa_cmp(&rth->rt_dest, &rt->rt_gateway) == 0) + if (sa_cmp(rth->rt_dest, rt->rt_gateway) == 0) break; /* match subnet */ /* XXX ADD TO RT_COMARE? XXX */ cp = (const char *)&gateway->sin_addr.s_addr; - dest = satosin(&rth->rt_dest); + dest = satosin(rth->rt_dest); cp2 = (const char *)&dest->sin_addr.s_addr; - netmask = satosin(&rth->rt_netmask); + netmask = satosin(rth->rt_netmask); cp3 = (const char *)&netmask->sin_addr.s_addr; cplim = cp3 + sizeof(netmask->sin_addr.s_addr); while (cp3 < cplim) { @@ -436,7 +436,7 @@ inet_routerhostroute(rb_tree_t *routes, struct interface *ifp) logwarnx("%s: forcing router %s through " "interface", ifp->name, - sa_addrtop(&rt->rt_gateway, buf, + sa_addrtop(rt->rt_gateway, buf, sizeof(buf))); } gateway->sin_addr.s_addr = INADDR_ANY; @@ -449,22 +449,22 @@ inet_routerhostroute(rb_tree_t *routes, struct interface *ifp) ifo->options |= DHCPCD_ROUTER_HOST_ROUTE_WARNED; logwarnx("%s: router %s requires a host route", ifp->name, - sa_addrtop(&rt->rt_gateway, buf, sizeof(buf))); + sa_addrtop(rt->rt_gateway, buf, sizeof(buf))); } if ((rth = rt_new(ifp)) == NULL) return -1; rth->rt_flags |= RTF_HOST; - sa_in_init(&rth->rt_dest, &gateway->sin_addr); + sa_in_init(rth->rt_dest, &gateway->sin_addr); in.s_addr = INADDR_BROADCAST; - sa_in_init(&rth->rt_netmask, &in); + sa_in_init(rth->rt_netmask, &in); in.s_addr = INADDR_ANY; - sa_in_init(&rth->rt_gateway, &in); + sa_in_init(rth->rt_gateway, &in); rth->rt_mtu = dhcp_get_mtu(ifp); if (state->addr != NULL) - sa_in_init(&rth->rt_ifa, &state->addr->addr); + sa_in_init(rth->rt_ifa, &state->addr->addr); else - rth->rt_ifa.sa_family = AF_UNSPEC; + rth->rt_ifa->sa_family = AF_UNSPEC; /* We need to insert the host route just before the router. */ while ((rtp = RB_TREE_MAX(routes)) != NULL) { diff --git a/src/ipv4ll.c b/src/ipv4ll.c index eabe10b1..8ee02264 100644 --- a/src/ipv4ll.c +++ b/src/ipv4ll.c @@ -102,12 +102,12 @@ ipv4ll_subnetroute(rb_tree_t *routes, struct interface *ifp) return -1; in.s_addr = state->addr->addr.s_addr & state->addr->mask.s_addr; - sa_in_init(&rt->rt_dest, &in); + sa_in_init(rt->rt_dest, &in); in.s_addr = state->addr->mask.s_addr; - sa_in_init(&rt->rt_netmask, &in); + sa_in_init(rt->rt_netmask, &in); in.s_addr = INADDR_ANY; - sa_in_init(&rt->rt_gateway, &in); - sa_in_init(&rt->rt_ifa, &state->addr->addr); + sa_in_init(rt->rt_gateway, &in); + sa_in_init(rt->rt_ifa, &state->addr->addr); rt->rt_dflags |= RTDF_IPV4LL; return rt_proto_add(routes, rt) ? 1 : 0; } @@ -117,7 +117,7 @@ ipv4ll_defaultroute(rb_tree_t *routes, struct interface *ifp) { struct ipv4ll_state *state; struct rt *rt; - struct in_addr in; + struct in_addr in = { .s_addr = INADDR_ANY }; assert(ifp != NULL); if ((state = IPV4LL_STATE(ifp)) == NULL || state->addr == NULL) @@ -126,11 +126,10 @@ ipv4ll_defaultroute(rb_tree_t *routes, struct interface *ifp) if ((rt = rt_new(ifp)) == NULL) return -1; - in.s_addr = INADDR_ANY; - sa_in_init(&rt->rt_dest, &in); - sa_in_init(&rt->rt_netmask, &in); - sa_in_init(&rt->rt_gateway, &in); - sa_in_init(&rt->rt_ifa, &state->addr->addr); + sa_in_init(rt->rt_dest, &in); + sa_in_init(rt->rt_netmask, &in); + sa_in_init(rt->rt_gateway, &in); + sa_in_init(rt->rt_ifa, &state->addr->addr); rt->rt_dflags |= RTDF_IPV4LL; #ifdef HAVE_ROUTE_METRIC rt->rt_metric += RTMETRIC_IPV4LL; @@ -510,7 +509,7 @@ ipv4ll_recvrt(__unused int cmd, const struct rt *rt) struct interface *ifp; /* Only interested in default route changes. */ - if (sa_is_unspecified(&rt->rt_dest)) + if (!sa_is_unspecified(rt->rt_dest)) return 0; /* If any interface is running IPv4LL, rebuild our routing table. */ diff --git a/src/ipv6.c b/src/ipv6.c index 263fb6a0..1ff3fa69 100644 --- a/src/ipv6.c +++ b/src/ipv6.c @@ -2211,20 +2211,20 @@ inet6_makeprefix(struct interface *ifp, const struct ra *rap, if ((rt = inet6_makeroute(ifp, rap)) == NULL) return NULL; - sa_in6_init(&rt->rt_dest, &addr->prefix); + sa_in6_init(rt->rt_dest, &addr->prefix); ipv6_mask(&netmask, addr->prefix_len); - sa_in6_init(&rt->rt_netmask, &netmask); + sa_in6_init(rt->rt_netmask, &netmask); if (addr->flags & IPV6_AF_PFXDELEGATION) { rt->rt_flags |= RTF_REJECT; /* Linux does not like a gateway for a reject route. */ #ifndef __linux__ - sa_in6_init(&rt->rt_gateway, &in6addr_loopback); + sa_in6_init(rt->rt_gateway, &in6addr_loopback); #endif } else if (!(addr->flags & IPV6_AF_ONLINK)) - sa_in6_init(&rt->rt_gateway, &rap->from); + sa_in6_init(rt->rt_gateway, &rap->from); else - rt->rt_gateway.sa_family = AF_UNSPEC; - sa_in6_init(&rt->rt_ifa, &addr->addr); + rt->rt_gateway->sa_family = AF_UNSPEC; + sa_in6_init(rt->rt_ifa, &addr->addr); return rt; } @@ -2235,9 +2235,9 @@ inet6_makerouter(struct ra *rap) if ((rt = inet6_makeroute(rap->iface, rap)) == NULL) return NULL; - sa_in6_init(&rt->rt_dest, &in6addr_any); - sa_in6_init(&rt->rt_netmask, &in6addr_any); - sa_in6_init(&rt->rt_gateway, &rap->from); + sa_in6_init(rt->rt_dest, &in6addr_any); + sa_in6_init(rt->rt_netmask, &in6addr_any); + sa_in6_init(rt->rt_gateway, &rap->from); return rt; } @@ -2293,9 +2293,9 @@ inet6_raroutes(rb_tree_t *routes, struct dhcpcd_ctx *ctx) in6_addr_fromprefix(&netmask, rinfo->prefix_len); - sa_in6_init(&rt->rt_dest, &rinfo->prefix); - sa_in6_init(&rt->rt_netmask, &netmask); - sa_in6_init(&rt->rt_gateway, &rap->from); + sa_in6_init(rt->rt_dest, &rinfo->prefix); + sa_in6_init(rt->rt_netmask, &netmask); + sa_in6_init(rt->rt_gateway, &rap->from); rt->rt_dflags |= RTDF_RA; #ifdef HAVE_ROUTE_PREF rt->rt_pref = ipv6nd_rtpref(rinfo->flags); diff --git a/src/route.c b/src/route.c index 804b1e25..5a3957fc 100644 --- a/src/route.c +++ b/src/route.c @@ -114,19 +114,21 @@ rt_cmp_netmask(const struct rt *rt1, const struct rt *rt2) { if (rt1->rt_flags & RTF_HOST && rt2->rt_flags & RTF_HOST) return 0; - return sa_cmp(&rt1->rt_netmask, &rt2->rt_netmask); + return sa_cmp(rt1->rt_netmask, rt2->rt_netmask); } int rt_cmp_dest(const struct rt *rt1, const struct rt *rt2) { - union sa_ss ma1 = { .sa.sa_family = AF_UNSPEC }; - union sa_ss ma2 = { .sa.sa_family = AF_UNSPEC }; + struct sockaddr_storage ss1 = { .ss_family = AF_UNSPEC }; + struct sockaddr_storage ss2 = { .ss_family = AF_UNSPEC }; + struct sockaddr *ma1 = (struct sockaddr *)&ss1; + struct sockaddr *ma2 = (struct sockaddr *)&ss2; int c; - rt_maskedaddr(&ma1.sa, &rt1->rt_dest, &rt1->rt_netmask); - rt_maskedaddr(&ma2.sa, &rt2->rt_dest, &rt2->rt_netmask); - c = sa_cmp(&ma1.sa, &ma2.sa); + rt_maskedaddr(ma1, rt1->rt_dest, rt1->rt_netmask); + rt_maskedaddr(ma2, rt2->rt_dest, rt2->rt_netmask); + c = sa_cmp(ma1, ma2); if (c != 0) return c; @@ -243,7 +245,7 @@ static const rb_tree_ops_t rt_compare_free_ops = { #endif void -rt_init(struct dhcpcd_ctx *ctx) +rt_init_routes(struct dhcpcd_ctx *ctx) { rb_tree_init(&ctx->routes, &rt_compare_os_ops); #ifdef RT_FREE_ROUTE_TABLE @@ -254,8 +256,8 @@ rt_init(struct dhcpcd_ctx *ctx) bool rt_is_default(const struct rt *rt) { - return sa_is_unspecified(&rt->rt_dest) && - sa_is_unspecified(&rt->rt_netmask); + return sa_is_unspecified(rt->rt_dest) && + sa_is_unspecified(rt->rt_netmask); } static void @@ -269,10 +271,10 @@ rt_desc(int loglevel, const char *cmd, const struct rt *rt) assert(cmd != NULL); assert(rt != NULL); - sa_addrtop(&rt->rt_dest, dest, sizeof(dest)); - prefix = sa_toprefix(&rt->rt_netmask); - sa_addrtop(&rt->rt_gateway, gateway, sizeof(gateway)); - gateway_unspec = sa_is_unspecified(&rt->rt_gateway); + sa_addrtop(rt->rt_dest, dest, sizeof(dest)); + prefix = sa_toprefix(rt->rt_netmask); + sa_addrtop(rt->rt_gateway, gateway, sizeof(gateway)); + gateway_unspec = sa_is_unspecified(rt->rt_gateway); ifname = rt->rt_ifp == NULL ? "(null)" : rt->rt_ifp->name; if (rt->rt_flags & RTF_HOST) { @@ -312,8 +314,8 @@ rt_headclear0(struct dhcpcd_ctx *ctx, rb_tree_t *rts, int af) RB_TREE_FOREACH_SAFE(rt, rts, rtn) { - if (af != AF_UNSPEC && rt->rt_dest.sa_family != af && - rt->rt_gateway.sa_family != af) + if (af != AF_UNSPEC && rt->rt_dest->sa_family != af && + rt->rt_gateway->sa_family != af) continue; rb_tree_remove_node(rts, rt); rt_free(rt); @@ -356,6 +358,29 @@ rt_dispose(struct dhcpcd_ctx *ctx) #endif } +static void +rt_setup_sa(struct rt *rt) +{ + rt->rt_dest = (struct sockaddr *)&rt->rt_ss_dest; + rt->rt_netmask = (struct sockaddr *)&rt->rt_ss_netmask; + rt->rt_gateway = (struct sockaddr *)&rt->rt_ss_gateway; + rt->rt_ifa = (struct sockaddr *)&rt->rt_ss_ifa; +} + +void +rt_init(struct rt *rt) +{ + memset(rt, 0, sizeof(*rt)); + rt_setup_sa(rt); +} + +void +rt_copy(struct rt *dst, const struct rt *src) +{ + memcpy(dst, src, sizeof(*dst)); + rt_setup_sa(dst); +} + struct rt * rt_new0(struct dhcpcd_ctx *ctx) { @@ -375,7 +400,7 @@ rt_new0(struct dhcpcd_ctx *ctx) logerr(__func__); return NULL; } - memset(rt, 0, sizeof(*rt)); + rt_init(rt); return rt; } @@ -495,7 +520,7 @@ rt_recvrt(int cmd, const struct rt *rt, pid_t pid) } #if defined(IPV4LL) && defined(HAVE_ROUTE_METRIC) - if (rt->rt_dest.sa_family == AF_INET) + if (rt->rt_dest->sa_family == AF_INET) ipv4ll_recvrt(cmd, rt); #endif } @@ -571,8 +596,8 @@ rt_add(rb_tree_t *kroutes, struct rt *nrt, struct rt *ort) if (((nrt->rt_ifp->active && !(nrt->rt_ifp->options->options & DHCPCD_GATEWAY)) || (!nrt->rt_ifp->active && !(ctx->options & DHCPCD_GATEWAY))) && - sa_is_unspecified(&nrt->rt_dest) && - sa_is_unspecified(&nrt->rt_netmask)) + sa_is_unspecified(nrt->rt_dest) && + sa_is_unspecified(nrt->rt_netmask)) return false; krt = rb_tree_find_node(kroutes, nrt); @@ -582,9 +607,9 @@ rt_add(rb_tree_t *kroutes, struct rt *nrt, struct rt *ort) #ifdef HAVE_ROUTE_METRIC krt->rt_metric == nrt->rt_metric && #endif - sa_cmp(&krt->rt_dest, &nrt->rt_dest) == 0 && + sa_cmp(krt->rt_dest, nrt->rt_dest) == 0 && rt_cmp_netmask(krt, nrt) == 0 && - sa_cmp(&krt->rt_gateway, &nrt->rt_gateway) == 0 && + sa_cmp(krt->rt_gateway, nrt->rt_gateway) == 0 && (nrt->rt_ifp->flags & IFF_LOOPBACK || rt_cmp_mtu(krt, nrt) == 0)) { #ifdef HAVE_ROUTE_LIFETIME if (rt_cmp_lifetime(krt, nrt) == 0) { @@ -702,7 +727,7 @@ rt_cmp(const struct rt *r1, const struct rt *r2) #ifdef HAVE_ROUTE_METRIC r1->rt_metric == r2->rt_metric && #endif - sa_cmp(&r1->rt_gateway, &r2->rt_gateway) == 0) + sa_cmp(r1->rt_gateway, r2->rt_gateway) == 0) return 0; return 1; } @@ -720,8 +745,8 @@ rt_doroute(rb_tree_t *kroutes, struct rt *rt) if (rt->rt_dflags & RTDF_FAKE) return true; if (or->rt_dflags & RTDF_FAKE || rt_cmp(rt, or) != 0 || - (rt->rt_ifa.sa_family != AF_UNSPEC && - sa_cmp(&or->rt_ifa, &rt->rt_ifa) != 0) || + (rt->rt_ifa->sa_family != AF_UNSPEC && + sa_cmp(or->rt_ifa, rt->rt_ifa) != 0) || #ifdef HAVE_ROUTE_LIFETIME rt_cmp_lifetime(rt, or) != 0 || #endif @@ -791,13 +816,13 @@ rt_build(struct dhcpcd_ctx *ctx, int af) continue; #ifdef BSD if (rt_is_default(rt) && - if_missfilter(rt->rt_ifp, &rt->rt_gateway) == -1) + if_missfilter(rt->rt_ifp, rt->rt_gateway) == -1) logerr("if_missfilter"); #endif - if ((rt->rt_dest.sa_family != af && - rt->rt_dest.sa_family != AF_UNSPEC) || - (rt->rt_gateway.sa_family != af && - rt->rt_gateway.sa_family != AF_UNSPEC)) + if ((rt->rt_dest->sa_family != af && + rt->rt_dest->sa_family != AF_UNSPEC) || + (rt->rt_gateway->sa_family != af && + rt->rt_gateway->sa_family != AF_UNSPEC)) continue; /* Is this route already in our table? */ if (rb_tree_find_node(&added, rt) != NULL) @@ -821,10 +846,10 @@ rt_build(struct dhcpcd_ctx *ctx, int af) /* Remove old routes we used to manage. */ RB_TREE_FOREACH_REVERSE_SAFE(rt, &ctx->routes, rtn) { - if ((rt->rt_dest.sa_family != af && - rt->rt_dest.sa_family != AF_UNSPEC) || - (rt->rt_gateway.sa_family != af && - rt->rt_gateway.sa_family != AF_UNSPEC)) + if ((rt->rt_dest->sa_family != af && + rt->rt_dest->sa_family != AF_UNSPEC) || + (rt->rt_gateway->sa_family != af && + rt->rt_gateway->sa_family != AF_UNSPEC)) continue; rb_tree_remove_node(&ctx->routes, rt); if (rb_tree_find_node(&added, rt) == NULL) { diff --git a/src/route.h b/src/route.h index bfe1d8ee..62bfa511 100644 --- a/src/route.h +++ b/src/route.h @@ -85,17 +85,21 @@ #endif struct rt { - union sa_ss rt_ss_dest; -#define rt_dest rt_ss_dest.sa - union sa_ss rt_ss_netmask; -#define rt_netmask rt_ss_netmask.sa - union sa_ss rt_ss_gateway; -#define rt_gateway rt_ss_gateway.sa + struct sockaddr *rt_dest; + struct sockaddr *rt_netmask; + struct sockaddr *rt_gateway; struct interface *rt_ifp; - union sa_ss rt_ss_ifa; -#define rt_ifa rt_ss_ifa.sa + struct sockaddr *rt_ifa; + + /* Storage for the above sockaddrs */ + struct sockaddr_storage rt_ss_dest; + struct sockaddr_storage rt_ss_netmask; + struct sockaddr_storage rt_ss_gateway; + struct sockaddr_storage rt_ss_ifa; + unsigned int rt_flags; unsigned int rt_mtu; + #ifdef HAVE_ROUTE_METRIC unsigned int rt_metric; #endif @@ -108,6 +112,7 @@ struct rt { #define RTMETRIC_WIRELESS 2000U #define RTMETRIC_IPV4LL 1000000U #define RTMETRIC_ROAM 2000000U + #ifdef HAVE_ROUTE_PREF int rt_pref; #endif @@ -116,6 +121,7 @@ struct rt { #define RTPREF_LOW (-1) #define RTPREF_RESERVED (-2) #define RTPREF_INVALID (-3) /* internal */ + unsigned int rt_dflags; #define RTDF_IFA_ROUTE 0x01 /* Address generated route */ #define RTDF_FAKE 0x02 /* Maybe us on lease reboot */ @@ -124,8 +130,10 @@ struct rt { #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; + #ifdef HAVE_ROUTE_LIFETIME struct timespec rt_aquired; /* timestamp of aquisition */ uint32_t rt_lifetime; /* current lifetime of route */ @@ -136,7 +144,7 @@ struct rt { extern const rb_tree_ops_t rt_compare_list_ops; extern const rb_tree_ops_t rt_compare_proto_ops; -void rt_init(struct dhcpcd_ctx *); +void rt_init_routes(struct dhcpcd_ctx *); void rt_dispose(struct dhcpcd_ctx *); void rt_free(struct rt *); void rt_freeif(struct interface *); @@ -144,6 +152,8 @@ bool rt_is_default(const struct rt *); void rt_headclear0(struct dhcpcd_ctx *, rb_tree_t *, int); void rt_headclear(rb_tree_t *, int); void rt_headfreeif(rb_tree_t *); +void rt_init(struct rt *); +void rt_copy(struct rt *, const struct rt *); struct rt *rt_new0(struct dhcpcd_ctx *); void rt_setif(struct rt *, struct interface *); struct rt *rt_new(struct interface *); diff --git a/src/sa.c b/src/sa.c index b2554099..b91ff79e 100644 --- a/src/sa.c +++ b/src/sa.c @@ -281,11 +281,12 @@ sa_toprefix(const struct sockaddr *sa) #ifndef NDEBUG /* Ensure the calculation is correct */ if (!sa_inprefix) { - union sa_ss ss = { .sa = { .sa_family = sa->sa_family } }; + struct sockaddr_storage ss = { .ss_family = sa->sa_family }; + struct sockaddr *ss_sa = (struct sockaddr *)&ss; sa_inprefix = true; - sa_fromprefix(&ss.sa, prefix); - assert(sa_cmp(sa, &ss.sa) == 0); + sa_fromprefix(ss_sa, prefix); + assert(sa_cmp(sa, ss_sa) == 0); sa_inprefix = false; } #endif diff --git a/src/sa.h b/src/sa.h index e40d68fe..99031250 100644 --- a/src/sa.h +++ b/src/sa.h @@ -33,13 +33,6 @@ #include -union sa_ss { - struct sockaddr sa; - struct sockaddr_in sin; - struct sockaddr_in6 sin6; -// struct sockaddr_storage ss; /* avoids memory overrun */ -}; - #ifdef BSD #define HAVE_SA_LEN #endif