Date: Mon, 24 Aug 2015 10:28:53 +0300 From: Alexander V. Chernikov <melifaro@freebsd.org> To: Julian Elischer <julian@freebsd.org>, "src-committers@freebsd.org" <src-committers@freebsd.org>, "svn-src-projects@freebsd.org" <svn-src-projects@freebsd.org> Subject: Re: svn commit: r287047 - in projects/routing/sys: net netinet Message-ID: <385571440401333@web5h.yandex.ru> In-Reply-To: <55DAC6B8.7090004@freebsd.org> References: <201508231815.t7NIFJ1U042238@repo.freebsd.org> <55DAC6B8.7090004@freebsd.org>
next in thread | previous in thread | raw e-mail | index | archive | help
24.08.2015, 10:25, "Julian Elischer" <julian@freebsd.org>: > On 8/24/15 2:15 AM, Alexander V. Chernikov wrote: >> Author: melifaro >> Date: Sun Aug 23 18:15:18 2015 >> New Revision: 287047 >> URL: https://svnweb.freebsd.org/changeset/base/287047 >> >> Log: >> Rename ip_sendmbuf to fib4_sendmbuf() and move it to >> rt_nhops api. Convert IPv4 SAS to use new routing api. >> >> Modified: >> projects/routing/sys/net/rt_nhops.c >> projects/routing/sys/net/rt_nhops.h >> projects/routing/sys/netinet/in_pcb.c >> projects/routing/sys/netinet/ip_output.c > > I object to some small aspects of this. you are moving > inet specific code out of the inet files into the > protocol independent files. please don't do this.. > and if they are in Proto-indep. files htey need to be guarded by > #ifdef INET > (or whatever it is.). better to leave them in the inet files I think.. Yes, you're right. The original idea besides rt_nhops.c was just to have new file not to interfere with anything existing. Now when I have some sort of established API I plan to move all those af-dependent functions to somewhere like netinet/in_fib.c / netinet6/in6_fib.c Does this look good for you? > >> Modified: projects/routing/sys/net/rt_nhops.c >> ============================================================================== >> --- projects/routing/sys/net/rt_nhops.c Sun Aug 23 18:14:30 2015 (r287046) >> +++ projects/routing/sys/net/rt_nhops.c Sun Aug 23 18:15:18 2015 (r287047) >> @@ -315,7 +315,8 @@ fib4_lookup_prepend(uint32_t fibnum, str >> * It should be already presented if we're >> * sending data via known gateway. >> */ >> - error = arpresolve_fast(lifp, gw, m->m_flags, eh->ether_dhost); >> + error = arpresolve_fast(lifp, gw, m ? m->m_flags : 0, >> + eh->ether_dhost); >> if (error == 0) { >> memcpy(&eh->ether_shost, IF_LLADDR(lifp), ETHER_ADDR_LEN); >> eh->ether_type = htons(ETHERTYPE_IP); >> @@ -332,6 +333,46 @@ fib4_lookup_prepend(uint32_t fibnum, str >> return (0); >> } >> >> +int >> +fib4_sendmbuf(struct ifnet *ifp, struct mbuf *m, struct nhop_data *nh, >> + struct in_addr dst) >> +{ >> + int error; >> + >> + if (nh != NULL && (nh->nh_flags & NH_FLAGS_L2_INCOMPLETE) == 0) { >> + >> + /* >> + * Fast path case. Most packets should >> + * be sent from here. >> + * TODO: Make special ifnet >> + * 'if_output_frame' handler for that. >> + */ >> + struct route_compat rc; >> + struct ether_header *eh; >> + rc.ro_flags = AF_INET << 8 | RT_NHOP; >> + rc.ro_nh = nh; >> + >> + M_PREPEND(m, nh->nh_count, M_NOWAIT); >> + if (m == NULL) >> + return (ENOBUFS); >> + eh = mtod(m, struct ether_header *); >> + memcpy(eh, nh->d.data, nh->nh_count); >> + error = (*ifp->if_output)(ifp, m, >> + NULL, (struct route *)&rc); >> + } else { >> + struct sockaddr_in gw_out; >> + memset(&gw_out, 0, sizeof(gw_out)); >> + gw_out.sin_len = sizeof(gw_out); >> + gw_out.sin_family = AF_INET; >> + gw_out.sin_addr = nh ? nh->d.gw4 : dst; >> + error = (*ifp->if_output)(ifp, m, >> + (const struct sockaddr *)&gw_out, NULL); >> + } >> + >> + return (error); >> +} >> + >> + >> static void >> fib4_rte_to_nh_extended(struct rtentry *rte, struct in_addr dst, >> struct nhop4_extended *pnh4) >> >> Modified: projects/routing/sys/net/rt_nhops.h >> ============================================================================== >> --- projects/routing/sys/net/rt_nhops.h Sun Aug 23 18:14:30 2015 (r287046) >> +++ projects/routing/sys/net/rt_nhops.h Sun Aug 23 18:15:18 2015 (r287047) >> @@ -198,6 +198,9 @@ void fib4_choose_prepend(uint32_t fibnum >> int fib4_lookup_prepend(uint32_t fibnum, struct in_addr dst, struct mbuf *m, >> struct nhop_data *nh, struct nhop4_extended *nh_ext); >> >> +int fib4_sendmbuf(struct ifnet *ifp, struct mbuf *m, struct nhop_data *nh, >> + struct in_addr dst); >> + >> void fib6_free_nh(uint32_t fibnum, struct nhop_data *nh); >> void fib6_choose_prepend(uint32_t fibnum, struct nhop_data *nh_src, >> uint32_t flowid, struct nhop_data *nh, struct nhop6_extended *nh_ext); >> >> Modified: projects/routing/sys/netinet/in_pcb.c >> ============================================================================== >> --- projects/routing/sys/netinet/in_pcb.c Sun Aug 23 18:14:30 2015 (r287046) >> +++ projects/routing/sys/netinet/in_pcb.c Sun Aug 23 18:15:18 2015 (r287047) >> @@ -93,6 +93,7 @@ __FBSDID("$FreeBSD$"); >> #include <netinet6/in6_var.h> >> #include <netinet6/ip6_var.h> >> #endif /* INET6 */ >> +#include <net/rt_nhops.h> >> >> #ifdef IPSEC >> @@ -756,8 +757,10 @@ in_pcbladdr(struct inpcb *inp, struct in >> { >> struct ifaddr *ifa; >> struct sockaddr *sa; >> - struct sockaddr_in *sin; >> - struct route sro; >> + struct sockaddr_in *sin, sin_storage; >> + struct nhop_data nhd, *pnhd; >> + struct nhop4_extended nh_ext; >> + u_int fibnum; >> int error; >> >> KASSERT(laddr != NULL, ("%s: laddr NULL", __func__)); >> @@ -770,9 +773,8 @@ in_pcbladdr(struct inpcb *inp, struct in >> return (0); >> >> error = 0; >> - bzero(&sro, sizeof(sro)); >> >> - sin = (struct sockaddr_in *)&sro.ro_dst; >> + sin = &sin_storage; >> sin->sin_family = AF_INET; >> sin->sin_len = sizeof(struct sockaddr_in); >> sin->sin_addr.s_addr = faddr->s_addr; >> @@ -783,8 +785,17 @@ in_pcbladdr(struct inpcb *inp, struct in >> * >> * Find out route to destination. >> */ >> + fibnum = inp->inp_inc.inc_fibnum; >> + pnhd = &nhd; >> + memset(&nhd, 0, sizeof(nhd)); >> + memset(&nh_ext, 0, sizeof(nh_ext)); >> if ((inp->inp_socket->so_options & SO_DONTROUTE) == 0) >> - in_rtalloc_ign(&sro, 0, inp->inp_inc.inc_fibnum); >> + error = fib4_lookup_prepend(fibnum, *faddr, >> + NULL, &nhd, &nh_ext); >> + if (error != 0) { >> + pnhd = NULL; >> + error = 0; >> + } >> >> /* >> * If we found a route, use the address corresponding to >> @@ -794,7 +805,7 @@ in_pcbladdr(struct inpcb *inp, struct in >> * network and try to find a corresponding interface to take >> * the source address from. >> */ >> - if (sro.ro_rt == NULL || sro.ro_rt->rt_ifp == NULL) { >> + if (pnhd == NULL) { >> struct in_ifaddr *ia; >> struct ifnet *ifp; >> >> @@ -850,23 +861,22 @@ in_pcbladdr(struct inpcb *inp, struct in >> * belonging to this jail. If so use it. >> * 3. as a last resort return the 'default' jail address. >> */ >> - if ((sro.ro_rt->rt_ifp->if_flags & IFF_LOOPBACK) == 0) { >> + if ((nh_ext.nh_ifp->if_flags & IFF_LOOPBACK) == 0) { >> struct in_ifaddr *ia; >> struct ifnet *ifp; >> + struct in_addr addr; >> >> /* If not jailed, use the default returned. */ >> if (cred == NULL || !prison_flag(cred, PR_IP4)) { >> - ia = (struct in_ifaddr *)sro.ro_rt->rt_ifa; >> - laddr->s_addr = ia->ia_addr.sin_addr.s_addr; >> + laddr->s_addr = nh_ext.nh_src.s_addr; >> goto done; >> } >> >> /* Jailed. */ >> /* 1. Check if the iface address belongs to the jail. */ >> - sin = (struct sockaddr_in *)sro.ro_rt->rt_ifa->ifa_addr; >> - if (prison_check_ip4(cred, &sin->sin_addr) == 0) { >> - ia = (struct in_ifaddr *)sro.ro_rt->rt_ifa; >> - laddr->s_addr = ia->ia_addr.sin_addr.s_addr; >> + addr = nh_ext.nh_src; >> + if (prison_check_ip4(cred, &addr) == 0) { >> + laddr->s_addr = nh_ext.nh_src.s_addr; >> goto done; >> } >> >> @@ -875,7 +885,7 @@ in_pcbladdr(struct inpcb *inp, struct in >> * belonging to this jail. >> */ >> ia = NULL; >> - ifp = sro.ro_rt->rt_ifp; >> + ifp = nh_ext.nh_ifp; >> IF_ADDR_RLOCK(ifp); >> TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { >> sa = ifa->ifa_addr; >> @@ -908,7 +918,7 @@ in_pcbladdr(struct inpcb *inp, struct in >> * In case of jails, check that it is an address of the jail >> * and if we cannot find, fall back to the 'default' jail address. >> */ >> - if ((sro.ro_rt->rt_ifp->if_flags & IFF_LOOPBACK) != 0) { >> + if ((nh_ext.nh_ifp->if_flags & IFF_LOOPBACK) != 0) { >> struct sockaddr_in sain; >> struct in_ifaddr *ia; >> >> @@ -969,8 +979,8 @@ in_pcbladdr(struct inpcb *inp, struct in >> } >> >> done: >> - if (sro.ro_rt != NULL) >> - RTFREE(sro.ro_rt); >> + if (pnhd != NULL) >> + fib4_free_nh(fibnum, pnhd); >> return (error); >> } >> >> Modified: projects/routing/sys/netinet/ip_output.c >> ============================================================================== >> --- projects/routing/sys/netinet/ip_output.c Sun Aug 23 18:14:30 2015 (r287046) >> +++ projects/routing/sys/netinet/ip_output.c Sun Aug 23 18:15:18 2015 (r287047) >> @@ -102,9 +102,6 @@ SYSCTL_INT(_net_inet_ip, OID_AUTO, mbuf_ >> #endif >> >> static void ip_mloopback (struct ifnet *, struct mbuf *, int); >> -static inline int ip_sendmbuf(struct ifnet *ifp, struct mbuf *m, >> - struct nhop_data *nh, struct in_addr dst); >> - >> >> extern int in_mcast_loop; >> extern struct protosw inetsw[]; >> @@ -651,7 +648,7 @@ sendit: >> */ >> m_clrprotoflags(m); >> IP_PROBE(send, NULL, NULL, ip, ifp, ip, NULL); >> - error = ip_sendmbuf(ifp, m, nh, dst); >> + error = fib4_sendmbuf(ifp, m, nh, dst); >> goto done; >> } >> >> @@ -688,7 +685,7 @@ sendit: >> m_clrprotoflags(m); >> >> IP_PROBE(send, NULL, NULL, ip, ifp, ip, NULL); >> - error = ip_sendmbuf(ifp, m, nh, dst); >> + error = fib4_sendmbuf(ifp, m, nh, dst); >> } else >> m_freem(m); >> } >> @@ -706,45 +703,6 @@ bad: >> goto done; >> } >> >> -static inline int >> -ip_sendmbuf(struct ifnet *ifp, struct mbuf *m, struct nhop_data *nh, >> - struct in_addr dst) >> -{ >> - int error; >> - >> - if (nh != NULL && (nh->nh_flags & NH_FLAGS_L2_INCOMPLETE) == 0) { >> - >> - /* >> - * Fast path case. Most packets should >> - * be sent from here. >> - * TODO: Make special ifnet >> - * 'if_output_frame' handler for that. >> - */ >> - struct route_compat rc; >> - struct ether_header *eh; >> - rc.ro_flags = AF_INET << 8 | RT_NHOP; >> - rc.ro_nh = nh; >> - >> - M_PREPEND(m, nh->nh_count, M_NOWAIT); >> - if (m == NULL) >> - return (ENOBUFS); >> - eh = mtod(m, struct ether_header *); >> - memcpy(eh, nh->d.data, nh->nh_count); >> - error = (*ifp->if_output)(ifp, m, >> - NULL, (struct route *)&rc); >> - } else { >> - struct sockaddr_in gw_out; >> - memset(&gw_out, 0, sizeof(gw_out)); >> - gw_out.sin_len = sizeof(gw_out); >> - gw_out.sin_family = AF_INET; >> - gw_out.sin_addr = nh ? nh->d.gw4 : dst; >> - error = (*ifp->if_output)(ifp, m, >> - (const struct sockaddr *)&gw_out, NULL); >> - } >> - >> - return (error); >> -} >> - >> /* >> * Create a chain of fragments which fit the given mtu. m_frag points to the >> * mbuf to be fragmented; on return it points to the chain with the fragments.
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?385571440401333>