Date: Sun, 23 Aug 2015 18:19:26 +0000 (UTC) From: "Alexander V. Chernikov" <melifaro@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r287053 - projects/routing/sys/netinet Message-ID: <201508231819.t7NIJQK8042769@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: melifaro Date: Sun Aug 23 18:19:25 2015 New Revision: 287053 URL: https://svnweb.freebsd.org/changeset/base/287053 Log: Convert ip_fastfwd() to use new routing api. Modified: projects/routing/sys/netinet/ip_fastfwd.c Modified: projects/routing/sys/netinet/ip_fastfwd.c ============================================================================== --- projects/routing/sys/netinet/ip_fastfwd.c Sun Aug 23 18:18:44 2015 (r287052) +++ projects/routing/sys/netinet/ip_fastfwd.c Sun Aug 23 18:19:25 2015 (r287053) @@ -106,6 +106,8 @@ __FBSDID("$FreeBSD$"); #include <netinet/ip_icmp.h> #include <netinet/ip_options.h> +#include <net/rt_nhops.h> + #include <machine/in_cksum.h> static VNET_DEFINE(int, ipfastforward_active); @@ -114,42 +116,6 @@ static VNET_DEFINE(int, ipfastforward_ac SYSCTL_INT(_net_inet_ip, OID_AUTO, fastforwarding, CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ipfastforward_active), 0, "Enable fast IP forwarding"); -static struct sockaddr_in * -ip_findroute(struct route *ro, struct in_addr dest, struct mbuf *m) -{ - struct sockaddr_in *dst; - struct rtentry *rt; - - /* - * Find route to destination. - */ - bzero(ro, sizeof(*ro)); - dst = (struct sockaddr_in *)&ro->ro_dst; - dst->sin_family = AF_INET; - dst->sin_len = sizeof(*dst); - dst->sin_addr.s_addr = dest.s_addr; - in_rtalloc_ign(ro, 0, M_GETFIB(m)); - - /* - * Route there and interface still up? - */ - rt = ro->ro_rt; - if (rt && (rt->rt_flags & RTF_UP) && - (rt->rt_ifp->if_flags & IFF_UP) && - (rt->rt_ifp->if_drv_flags & IFF_DRV_RUNNING)) { - if (rt->rt_flags & RTF_GATEWAY) - dst = (struct sockaddr_in *)rt->rt_gateway; - } else { - IPSTAT_INC(ips_noroute); - IPSTAT_INC(ips_cantforward); - if (rt) - RTFREE(rt); - icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_HOST, 0, 0); - return NULL; - } - return dst; -} - /* * Try to forward a packet based on the destination address. * This is a fast path optimized for the plain forwarding case. @@ -162,11 +128,11 @@ ip_fastforward(struct mbuf *m) { struct ip *ip; struct mbuf *m0 = NULL; - struct route ro; - struct sockaddr_in *dst = NULL; + struct nhop_data nhd, *pnhd; struct ifnet *ifp; struct in_addr odest, dest; uint16_t sum, ip_len, ip_off; + uint32_t fibnum; int error = 0; int hlen, mtu; struct m_tag *fwd_tag = NULL; @@ -180,7 +146,8 @@ ip_fastforward(struct mbuf *m) M_ASSERTVALID(m); M_ASSERTPKTHDR(m); - bzero(&ro, sizeof(ro)); + fibnum = M_GETFIB(m); + pnhd = NULL; /* * Step 1: check for packet drop conditions (and sanity checks) @@ -413,16 +380,22 @@ passin: /* * Find route to destination. */ - if ((dst = ip_findroute(&ro, dest, m)) == NULL) - return NULL; /* icmp unreach already sent */ - ifp = ro.ro_rt->rt_ifp; + fibnum = M_GETFIB(m); + if (fib4_lookup_prepend(fibnum, dest, m, &nhd, NULL) != 0) { + IPSTAT_INC(ips_noroute); + IPSTAT_INC(ips_cantforward); + icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_HOST, 0, 0); + return (NULL); + } + pnhd = &nhd; + ifp = NH_LIFP(&nhd); /* * Immediately drop blackholed traffic, and directed broadcasts * for either the all-ones or all-zero subnet addresses on * locally attached networks. */ - if ((ro.ro_rt->rt_flags & (RTF_BLACKHOLE|RTF_BROADCAST)) != 0) + if ((nhd.nh_flags & (NHOP_BLACKHOLE|RTF_BROADCAST)) != 0) goto drop; /* @@ -460,8 +433,8 @@ forwardlocal: * Return packet for processing by ip_input(). */ m->m_flags |= M_FASTFWD_OURS; - if (ro.ro_rt) - RTFREE(ro.ro_rt); + if (pnhd != NULL) + fib4_free_nh(fibnum, pnhd); return m; } /* @@ -473,10 +446,17 @@ forwardlocal: m_tag_delete(m, fwd_tag); m->m_flags &= ~M_IP_NEXTHOP; } - RTFREE(ro.ro_rt); - if ((dst = ip_findroute(&ro, dest, m)) == NULL) - return NULL; /* icmp unreach already sent */ - ifp = ro.ro_rt->rt_ifp; + fib4_free_nh(fibnum, pnhd); + + + if (fib4_lookup_prepend(fibnum, dest, m, &nhd, NULL) != 0) { + IPSTAT_INC(ips_noroute); + IPSTAT_INC(ips_cantforward); + icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_HOST, 0, 0); + return (NULL); + } + pnhd = &nhd; + ifp = NH_LIFP(&nhd); } passout: @@ -486,6 +466,7 @@ passout: ip_len = ntohs(ip->ip_len); ip_off = ntohs(ip->ip_off); +#if 0 /* * Check if route is dampned (when ARP is unable to resolve) */ @@ -494,6 +475,11 @@ passout: icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_HOST, 0, 0); goto consumed; } +#endif + if ((nhd.nh_flags & NHOP_REJECT) != 0) { + icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_HOST, 0, 0); + goto consumed; + } /* * Check if media link state of interface is not down @@ -506,10 +492,7 @@ passout: /* * Check if packet fits MTU or if hardware will fragment for us */ - if (ro.ro_rt->rt_mtu) - mtu = min(ro.ro_rt->rt_mtu, ifp->if_mtu); - else - mtu = ifp->if_mtu; + mtu = nhd.nh_mtu; if (ip_len <= mtu) { /* @@ -520,8 +503,7 @@ passout: * Send off the packet via outgoing interface */ IP_PROBE(send, NULL, NULL, ip, ifp, ip, NULL); - error = (*ifp->if_output)(ifp, m, - (struct sockaddr *)dst, &ro); + error = fib4_sendmbuf(ifp, m, &nhd, dest); } else { /* * Handle EMSGSIZE with icmp reply needfrag for TCP MTU discovery @@ -552,8 +534,7 @@ passout: m_clrprotoflags(m); IP_PROBE(send, NULL, NULL, ip, ifp, ip, NULL); - error = (*ifp->if_output)(ifp, m, - (struct sockaddr *)dst, &ro); + error = fib4_sendmbuf(ifp, m, &nhd, dest); if (error) break; } while ((m = m0) != NULL); @@ -571,17 +552,16 @@ passout: if (error != 0) IPSTAT_INC(ips_odropped); else { - counter_u64_add(ro.ro_rt->rt_pksent, 1); IPSTAT_INC(ips_forward); IPSTAT_INC(ips_fastforward); } consumed: - RTFREE(ro.ro_rt); + fib4_free_nh(fibnum, &nhd); return NULL; drop: if (m) m_freem(m); - if (ro.ro_rt) - RTFREE(ro.ro_rt); + if (pnhd != NULL) + fib4_free_nh(fibnum, pnhd); return NULL; }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201508231819.t7NIJQK8042769>