Date: Sun, 23 Aug 2015 18:15:19 +0000 (UTC) From: "Alexander V. Chernikov" <melifaro@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r287047 - in projects/routing/sys: net netinet Message-ID: <201508231815.t7NIFJ1U042238@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
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 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?201508231815.t7NIFJ1U042238>