Date: Thu, 29 Dec 2016 09:50:37 +0000 (UTC) From: "Andrey V. Elsukov" <ae@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org Subject: svn commit: r310771 - stable/11/sys/netinet Message-ID: <201612290950.uBT9obDO021596@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: ae Date: Thu Dec 29 09:50:37 2016 New Revision: 310771 URL: https://svnweb.freebsd.org/changeset/base/310771 Log: MFC r309257: Rework ip_tryforward() to use FIB4 KPI. Modified: stable/11/sys/netinet/ip_fastfwd.c Directory Properties: stable/11/ (props changed) Modified: stable/11/sys/netinet/ip_fastfwd.c ============================================================================== --- stable/11/sys/netinet/ip_fastfwd.c Thu Dec 29 09:15:27 2016 (r310770) +++ stable/11/sys/netinet/ip_fastfwd.c Thu Dec 29 09:50:37 2016 (r310771) @@ -97,6 +97,7 @@ __FBSDID("$FreeBSD$"); #include <net/vnet.h> #include <netinet/in.h> +#include <netinet/in_fib.h> #include <netinet/in_kdtrace.h> #include <netinet/in_systm.h> #include <netinet/in_var.h> @@ -107,40 +108,33 @@ __FBSDID("$FreeBSD$"); #include <machine/in_cksum.h> -static struct sockaddr_in * -ip_findroute(struct route *ro, struct in_addr dest, struct mbuf *m) +static int +ip_findroute(struct nhop4_basic *pnh, struct in_addr dest, struct mbuf *m) { - struct sockaddr_in *dst; - struct rtentry *rt; + bzero(pnh, sizeof(*pnh)); + if (fib4_lookup_nh_basic(M_GETFIB(m), dest, 0, 0, pnh) != 0) { + IPSTAT_INC(ips_noroute); + IPSTAT_INC(ips_cantforward); + icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_HOST, 0, 0); + return (EHOSTUNREACH); + } /* - * Find route to destination. + * Drop blackholed traffic and directed broadcasts. */ - 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); + if ((pnh->nh_flags & (NHF_BLACKHOLE | NHF_BROADCAST)) != 0) { + IPSTAT_INC(ips_cantforward); + m_freem(m); + return (EHOSTUNREACH); + } + + if (pnh->nh_flags & NHF_REJECT) { IPSTAT_INC(ips_cantforward); - if (rt) - RTFREE(rt); icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_HOST, 0, 0); - return NULL; + return (EHOSTUNREACH); } - return dst; + + return (0); } /* @@ -155,13 +149,11 @@ ip_tryforward(struct mbuf *m) { struct ip *ip; struct mbuf *m0 = NULL; - struct route ro; - struct sockaddr_in *dst = NULL; - struct ifnet *ifp; + struct nhop4_basic nh; + struct sockaddr_in dst; struct in_addr odest, dest; uint16_t ip_len, ip_off; int error = 0; - int mtu; struct m_tag *fwd_tag = NULL; /* @@ -171,9 +163,6 @@ ip_tryforward(struct mbuf *m) M_ASSERTVALID(m); M_ASSERTPKTHDR(m); - bzero(&ro, sizeof(ro)); - - #ifdef ALTQ /* * Is packet dropped by traffic conditioner? @@ -305,29 +294,17 @@ 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; - - /* - * 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) - goto drop; + if (ip_findroute(&nh, dest, m) != 0) + return (NULL); /* icmp unreach already sent */ /* * Step 5: outgoing firewall packet processing */ - - /* - * Run through list of hooks for output packets. - */ if (!PFIL_HOOKED(&V_inet_pfil_hook)) goto passout; - if (pfil_run_hooks(&V_inet_pfil_hook, &m, ifp, PFIL_OUT, NULL) || m == NULL) { + if (pfil_run_hooks(&V_inet_pfil_hook, &m, nh.nh_ifp, PFIL_OUT, NULL) || + m == NULL) { goto drop; } @@ -352,9 +329,7 @@ forwardlocal: * Return packet for processing by ip_input(). */ m->m_flags |= M_FASTFWD_OURS; - if (ro.ro_rt) - RTFREE(ro.ro_rt); - return m; + return (m); } /* * Redo route lookup with new destination address @@ -365,10 +340,8 @@ 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; + if (ip_findroute(&nh, dest, m) != 0) + return (NULL); /* icmp unreach already sent */ } passout: @@ -378,32 +351,15 @@ passout: ip_len = ntohs(ip->ip_len); ip_off = ntohs(ip->ip_off); - /* - * Check if route is dampned (when ARP is unable to resolve) - */ - if ((ro.ro_rt->rt_flags & RTF_REJECT) && - (ro.ro_rt->rt_expire == 0 || time_uptime < ro.ro_rt->rt_expire)) { - icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_HOST, 0, 0); - goto consumed; - } - - /* - * Check if media link state of interface is not down - */ - if (ifp->if_link_state == LINK_STATE_DOWN) { - icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_HOST, 0, 0); - goto consumed; - } + bzero(&dst, sizeof(dst)); + dst.sin_family = AF_INET; + dst.sin_len = sizeof(dst); + dst.sin_addr = nh.nh_addr; /* * 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; - - if (ip_len <= mtu) { + if (ip_len <= nh.nh_mtu) { /* * Avoid confusing lower layers. */ @@ -411,9 +367,9 @@ 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); + IP_PROBE(send, NULL, NULL, ip, nh.nh_ifp, ip, NULL); + error = (*nh.nh_ifp->if_output)(nh.nh_ifp, m, + (struct sockaddr *)&dst, NULL); } else { /* * Handle EMSGSIZE with icmp reply needfrag for TCP MTU discovery @@ -421,14 +377,15 @@ passout: if (ip_off & IP_DF) { IPSTAT_INC(ips_cantfrag); icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_NEEDFRAG, - 0, mtu); + 0, nh.nh_mtu); goto consumed; } else { /* * We have to fragment the packet */ m->m_pkthdr.csum_flags |= CSUM_IP; - if (ip_fragment(ip, &m, mtu, ifp->if_hwassist)) + if (ip_fragment(ip, &m, nh.nh_mtu, + nh.nh_ifp->if_hwassist) != 0) goto drop; KASSERT(m != NULL, ("null mbuf and no error")); /* @@ -443,9 +400,11 @@ passout: */ m_clrprotoflags(m); - IP_PROBE(send, NULL, NULL, ip, ifp, ip, NULL); - error = (*ifp->if_output)(ifp, m, - (struct sockaddr *)dst, &ro); + IP_PROBE(send, NULL, NULL, ip, nh.nh_ifp, + ip, NULL); + /* XXX: we can use cached route here */ + error = (*nh.nh_ifp->if_output)(nh.nh_ifp, m, + (struct sockaddr *)&dst, NULL); if (error) break; } while ((m = m0) != NULL); @@ -463,17 +422,13 @@ 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); return NULL; drop: if (m) m_freem(m); - if (ro.ro_rt) - RTFREE(ro.ro_rt); return NULL; }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201612290950.uBT9obDO021596>