Module Name: src Committed By: ozaki-r Date: Tue May 17 12:58:21 UTC 2016
Modified Files: src/sys/net: rtsock.c Log Message: Tidy up route_output Avoid jumping into the middle of a switch statement, use a function instead. To generate a diff of this commit: cvs rdiff -u -r1.186 -r1.187 src/sys/net/rtsock.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/net/rtsock.c diff -u src/sys/net/rtsock.c:1.186 src/sys/net/rtsock.c:1.187 --- src/sys/net/rtsock.c:1.186 Thu May 12 02:24:16 2016 +++ src/sys/net/rtsock.c Tue May 17 12:58:21 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: rtsock.c,v 1.186 2016/05/12 02:24:16 ozaki-r Exp $ */ +/* $NetBSD: rtsock.c,v 1.187 2016/05/17 12:58:21 ozaki-r Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -61,7 +61,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: rtsock.c,v 1.186 2016/05/12 02:24:16 ozaki-r Exp $"); +__KERNEL_RCSID(0, "$NetBSD: rtsock.c,v 1.187 2016/05/17 12:58:21 ozaki-r Exp $"); #ifdef _KERNEL_OPT #include "opt_inet.h" @@ -480,13 +480,72 @@ route_get_sdl(const struct ifnet *ifp, c } } +static int +route_output_report(struct rtentry *rt, struct rt_addrinfo *info, + struct rt_xmsghdr *rtm, struct rt_xmsghdr **new_rtm) +{ + int len; + struct ifnet *ifp; + + if ((rtm->rtm_addrs & (RTA_IFP | RTA_IFA)) == 0) + ; + else if ((ifp = rt->rt_ifp) != NULL) { + const struct ifaddr *rtifa; + info->rti_info[RTAX_IFP] = ifp->if_dl->ifa_addr; + /* rtifa used to be simply rt->rt_ifa. + * If rt->rt_ifa != NULL, then + * rt_get_ifa() != NULL. So this + * ought to still be safe. --dyoung + */ + rtifa = rt_get_ifa(rt); + info->rti_info[RTAX_IFA] = rtifa->ifa_addr; +#ifdef RTSOCK_DEBUG + if (info->rti_info[RTAX_IFA]->sa_family == AF_INET) { + char ibuf[INET_ADDRSTRLEN]; + char abuf[INET_ADDRSTRLEN]; + printf("%s: copying out RTAX_IFA %s " + "for info->rti_info[RTAX_DST] %s " + "ifa_getifa %p ifa_seqno %p\n", + __func__, + RT_IN_PRINT(ibuf, RTAX_IFA), + RT_IN_PRINT(abuf, RTAX_DST), + (void *)rtifa->ifa_getifa, + rtifa->ifa_seqno); + } +#endif /* RTSOCK_DEBUG */ + if (ifp->if_flags & IFF_POINTOPOINT) + info->rti_info[RTAX_BRD] = rtifa->ifa_dstaddr; + else + info->rti_info[RTAX_BRD] = NULL; + rtm->rtm_index = ifp->if_index; + } else { + info->rti_info[RTAX_IFP] = NULL; + info->rti_info[RTAX_IFA] = NULL; + } + (void)rt_msg2(rtm->rtm_type, info, NULL, NULL, &len); + if (len > rtm->rtm_msglen) { + struct rt_xmsghdr *old_rtm = rtm; + R_Malloc(*new_rtm, struct rt_xmsghdr *, len); + if (*new_rtm == NULL) + return ENOBUFS; + (void)memcpy(*new_rtm, old_rtm, old_rtm->rtm_msglen); + rtm = *new_rtm; + } + (void)rt_msg2(rtm->rtm_type, info, rtm, NULL, 0); + rtm->rtm_flags = rt->rt_flags; + rtm_setmetrics(rt, rtm); + rtm->rtm_addrs = info->rti_addrs; + + return 0; +} + /*ARGSUSED*/ int COMPATNAME(route_output)(struct mbuf *m, struct socket *so) { struct sockproto proto = { .sp_family = PF_XROUTE, }; struct rt_xmsghdr *rtm = NULL; - struct rt_xmsghdr *old_rtm = NULL; + struct rt_xmsghdr *old_rtm = NULL, *new_rtm = NULL; struct rtentry *rt = NULL; struct rtentry *saved_nrt = NULL; struct rt_addrinfo info; @@ -494,8 +553,6 @@ COMPATNAME(route_output)(struct mbuf *m, struct ifnet *ifp = NULL; struct ifaddr *ifa = NULL; sa_family_t family; - bool is_ll = false; - int ll_flags = 0; struct sockaddr_dl sdl; #define senderr(e) do { error = e; goto flush;} while (/*CONSTCOND*/ 0) @@ -621,9 +678,20 @@ COMPATNAME(route_output)(struct mbuf *m, } #endif /* INET */ error = rtrequest1(rtm->rtm_type, &info, &saved_nrt); - if (error == 0) { - rt = saved_nrt; - goto report; + if (error != 0) + break; + + rt = saved_nrt; + info.rti_info[RTAX_DST] = rt_getkey(rt); + info.rti_info[RTAX_GATEWAY] = rt->rt_gateway; + info.rti_info[RTAX_NETMASK] = rt_mask(rt); + info.rti_info[RTAX_TAG] = rt_gettag(rt); + error = route_output_report(rt, &info, rtm, &new_rtm); + if (error) + senderr(error); + if (new_rtm != NULL) { + old_rtm = rtm; + rtm = new_rtm; } break; @@ -661,73 +729,34 @@ COMPATNAME(route_output)(struct mbuf *m, (rtm->rtm_flags & RTF_UP) == 0) && rtm->rtm_type == RTM_GET && sockaddr_cmp(rt_getkey(rt), info.rti_info[RTAX_DST]) != 0) { + int ll_flags = 0; route_get_sdl(rt->rt_ifp, info.rti_info[RTAX_DST], &sdl, &ll_flags); info.rti_info[RTAX_GATEWAY] = sstocsa(&sdl); - is_ll = true; - goto skip; + error = route_output_report(rt, &info, rtm, &new_rtm); + if (error) + senderr(error); + if (new_rtm != NULL) { + old_rtm = rtm; + rtm = new_rtm; + } + rtm->rtm_flags |= RTF_LLDATA; + rtm->rtm_flags |= (ll_flags & LLE_STATIC) ? RTF_STATIC : 0; + break; } switch (rtm->rtm_type) { case RTM_GET: - report: info.rti_info[RTAX_DST] = rt_getkey(rt); info.rti_info[RTAX_GATEWAY] = rt->rt_gateway; info.rti_info[RTAX_NETMASK] = rt_mask(rt); info.rti_info[RTAX_TAG] = rt_gettag(rt); - skip: - if ((rtm->rtm_addrs & (RTA_IFP | RTA_IFA)) == 0) - ; - else if ((ifp = rt->rt_ifp) != NULL) { - const struct ifaddr *rtifa; - info.rti_info[RTAX_IFP] = ifp->if_dl->ifa_addr; - /* rtifa used to be simply rt->rt_ifa. - * If rt->rt_ifa != NULL, then - * rt_get_ifa() != NULL. So this - * ought to still be safe. --dyoung - */ - rtifa = rt_get_ifa(rt); - info.rti_info[RTAX_IFA] = rtifa->ifa_addr; -#ifdef RTSOCK_DEBUG - if (info.rti_info[RTAX_IFA]->sa_family == - AF_INET) { - char ibuf[INET_ADDRSTRLEN]; - char abuf[INET_ADDRSTRLEN]; - printf("%s: copying out RTAX_IFA %s " - "for info.rti_info[RTAX_DST] %s " - "ifa_getifa %p ifa_seqno %p\n", - __func__, - RT_IN_PRINT(ibuf, RTAX_IFA), - RT_IN_PRINT(abuf, RTAX_DST), - (void *)rtifa->ifa_getifa, - rtifa->ifa_seqno); - } -#endif /* RTSOCK_DEBUG */ - if (ifp->if_flags & IFF_POINTOPOINT) { - info.rti_info[RTAX_BRD] = - rtifa->ifa_dstaddr; - } else - info.rti_info[RTAX_BRD] = NULL; - rtm->rtm_index = ifp->if_index; - } else { - info.rti_info[RTAX_IFP] = NULL; - info.rti_info[RTAX_IFA] = NULL; - } - (void)rt_msg2(rtm->rtm_type, &info, NULL, NULL, &len); - if (len > rtm->rtm_msglen) { + error = route_output_report(rt, &info, rtm, &new_rtm); + if (error) + senderr(error); + if (new_rtm != NULL) { old_rtm = rtm; - R_Malloc(rtm, struct rt_xmsghdr *, len); - if (rtm == NULL) - senderr(ENOBUFS); - (void)memcpy(rtm, old_rtm, old_rtm->rtm_msglen); - } - (void)rt_msg2(rtm->rtm_type, &info, rtm, NULL, 0); - rtm->rtm_flags = rt->rt_flags; - rtm_setmetrics(rt, rtm); - rtm->rtm_addrs = info.rti_addrs; - if (is_ll) { - rtm->rtm_flags |= RTF_LLDATA; - rtm->rtm_flags |= (ll_flags & LLE_STATIC) ? RTF_STATIC : 0; + rtm = new_rtm; } break;