Date: Mon, 7 Sep 2015 07:03:41 +0000 (UTC) From: "Alexander V. Chernikov" <melifaro@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r287530 - in projects/routing/sys: conf contrib/ipfilter/netinet dev/cxgb/ulp/iw_cxgb dev/cxgb/ulp/tom dev/cxgbe/iw_cxgbe dev/cxgbe/tom fs/nfsclient net netgraph/netflow netinet netinet... Message-ID: <201509070703.t8773f1w096223@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: melifaro Date: Mon Sep 7 07:03:40 2015 New Revision: 287530 URL: https://svnweb.freebsd.org/changeset/base/287530 Log: Move fib[46] from rt_nhops.[ch] to netinet/in_fib.[ch] and netinet6/in6_fib.[ch] Retain rt_nhops.c as a placeholder for future single/multipath nexthops construction. Added: projects/routing/sys/netinet/in_fib.c (contents, props changed) projects/routing/sys/netinet/in_fib.h (contents, props changed) projects/routing/sys/netinet6/in6_fib.c (contents, props changed) projects/routing/sys/netinet6/in6_fib.h (contents, props changed) Modified: projects/routing/sys/conf/files projects/routing/sys/contrib/ipfilter/netinet/ip_fil_freebsd.c projects/routing/sys/dev/cxgb/ulp/iw_cxgb/iw_cxgb_cm.c projects/routing/sys/dev/cxgb/ulp/tom/cxgb_cpl_io.c projects/routing/sys/dev/cxgb/ulp/tom/cxgb_listen.c projects/routing/sys/dev/cxgbe/iw_cxgbe/cm.c projects/routing/sys/dev/cxgbe/tom/t4_connect.c projects/routing/sys/dev/cxgbe/tom/t4_listen.c projects/routing/sys/fs/nfsclient/nfs_clport.c projects/routing/sys/net/if_stf.c projects/routing/sys/net/rt_nhops.c projects/routing/sys/net/rt_nhops.h projects/routing/sys/netgraph/netflow/netflow.c projects/routing/sys/netinet/if_ether.c projects/routing/sys/netinet/in.c projects/routing/sys/netinet/in_gif.c projects/routing/sys/netinet/in_mcast.c projects/routing/sys/netinet/in_pcb.c projects/routing/sys/netinet/ip_fastfwd.c projects/routing/sys/netinet/ip_icmp.c projects/routing/sys/netinet/ip_input.c projects/routing/sys/netinet/ip_options.c projects/routing/sys/netinet/ip_output.c projects/routing/sys/netinet/tcp_offload.c projects/routing/sys/netinet/tcp_output.c projects/routing/sys/netinet/tcp_subr.c projects/routing/sys/netinet6/icmp6.c projects/routing/sys/netinet6/in6.c projects/routing/sys/netinet6/in6_gif.c projects/routing/sys/netinet6/in6_mcast.c projects/routing/sys/netinet6/in6_src.c projects/routing/sys/netinet6/ip6_output.c projects/routing/sys/netpfil/ipfw/ip_fw2.c projects/routing/sys/netpfil/pf/pf.c Modified: projects/routing/sys/conf/files ============================================================================== --- projects/routing/sys/conf/files Mon Sep 7 02:00:05 2015 (r287529) +++ projects/routing/sys/conf/files Mon Sep 7 07:03:40 2015 (r287530) @@ -3636,6 +3636,7 @@ netinet/in.c optional inet netinet/in_debug.c optional inet ddb netinet/in_kdtrace.c optional inet | inet6 netinet/ip_carp.c optional inet carp | inet6 carp +netinet/in_fib.c optional inet netinet/in_gif.c optional gif inet | netgraph_gif inet netinet/ip_gre.c optional gre inet netinet/ip_id.c optional inet @@ -3643,6 +3644,7 @@ netinet/in_mcast.c optional inet netinet/in_pcb.c optional inet | inet6 netinet/in_pcbgroup.c optional inet pcbgroup | inet6 pcbgroup netinet/in_proto.c optional inet | inet6 +netinet/in_fib.c optional inet netinet/in_rmx.c optional inet netinet/in_rss.c optional inet rss netinet/ip_divert.c optional inet ipdivert ipfirewall @@ -3701,6 +3703,7 @@ netinet6/frag6.c optional inet6 netinet6/icmp6.c optional inet6 netinet6/in6.c optional inet6 netinet6/in6_cksum.c optional inet6 +netinet6/in6_fib.c optional inet6 netinet6/in6_gif.c optional gif inet6 | netgraph_gif inet6 netinet6/in6_ifattach.c optional inet6 netinet6/in6_mcast.c optional inet6 Modified: projects/routing/sys/contrib/ipfilter/netinet/ip_fil_freebsd.c ============================================================================== --- projects/routing/sys/contrib/ipfilter/netinet/ip_fil_freebsd.c Mon Sep 7 02:00:05 2015 (r287529) +++ projects/routing/sys/contrib/ipfilter/netinet/ip_fil_freebsd.c Mon Sep 7 07:03:40 2015 (r287530) @@ -53,6 +53,7 @@ static const char rcsid[] = "@(#)$Id$"; #include <netinet/in_var.h> #include <netinet/in_systm.h> #include <netinet/ip.h> +#include <netinet/in_fib.h> #include <netinet/ip_var.h> #include <netinet/tcp.h> #if defined(__FreeBSD_version) && (__FreeBSD_version >= 800000) @@ -71,7 +72,6 @@ static const char rcsid[] = "@(#)$Id$"; #ifdef USE_INET6 # include <netinet/icmp6.h> #endif -#include <net/rt_nhops.h> #include "netinet/ip_fil.h" #include "netinet/ip_nat.h" #include "netinet/ip_frag.h" Modified: projects/routing/sys/dev/cxgb/ulp/iw_cxgb/iw_cxgb_cm.c ============================================================================== --- projects/routing/sys/dev/cxgb/ulp/iw_cxgb/iw_cxgb_cm.c Mon Sep 7 02:00:05 2015 (r287529) +++ projects/routing/sys/dev/cxgb/ulp/iw_cxgb/iw_cxgb_cm.c Mon Sep 7 07:03:40 2015 (r287530) @@ -63,13 +63,12 @@ __FBSDID("$FreeBSD$"); #include <netinet/in.h> #include <netinet/in_pcb.h> #include <netinet/ip.h> +#include <netinet/in_fib.h> #include <netinet/ip_var.h> #include <netinet/tcp_var.h> #include <netinet/tcp.h> #include <netinet/tcpip.h> -#include <net/rt_nhops.h> - #include <rdma/ib_verbs.h> #include <linux/idr.h> #include <ulp/iw_cxgb/iw_cxgb_ib_intfc.h> Modified: projects/routing/sys/dev/cxgb/ulp/tom/cxgb_cpl_io.c ============================================================================== --- projects/routing/sys/dev/cxgb/ulp/tom/cxgb_cpl_io.c Mon Sep 7 02:00:05 2015 (r287529) +++ projects/routing/sys/dev/cxgb/ulp/tom/cxgb_cpl_io.c Mon Sep 7 07:03:40 2015 (r287530) @@ -62,6 +62,7 @@ __FBSDID("$FreeBSD$"); #include <netinet/in_var.h> #include <netinet/ip.h> +#include <netinet/in_fib.h> #include <netinet/tcp_var.h> #define TCPSTATES #include <netinet/tcp_fsm.h> @@ -69,7 +70,6 @@ __FBSDID("$FreeBSD$"); #include <netinet/tcp_seq.h> #include <netinet/tcp_timer.h> #include <net/route.h> -#include <net/rt_nhops.h> #include "cxgb_include.h" #include "ulp/tom/cxgb_l2t.h" Modified: projects/routing/sys/dev/cxgb/ulp/tom/cxgb_listen.c ============================================================================== --- projects/routing/sys/dev/cxgb/ulp/tom/cxgb_listen.c Mon Sep 7 02:00:05 2015 (r287529) +++ projects/routing/sys/dev/cxgb/ulp/tom/cxgb_listen.c Mon Sep 7 07:03:40 2015 (r287530) @@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$"); #include <net/route.h> #include <netinet/in.h> #include <netinet/ip.h> +#include <netinet/in_fib.h> #include <netinet/in_pcb.h> #include <netinet/in_var.h> #include <netinet/tcp_timer.h> @@ -47,7 +48,6 @@ __FBSDID("$FreeBSD$"); #define TCPSTATES #include <netinet/tcp_fsm.h> #include <netinet/toecore.h> -#include <net/rt_nhops.h> #include "cxgb_include.h" #include "ulp/tom/cxgb_tom.h" Modified: projects/routing/sys/dev/cxgbe/iw_cxgbe/cm.c ============================================================================== --- projects/routing/sys/dev/cxgbe/iw_cxgbe/cm.c Mon Sep 7 02:00:05 2015 (r287529) +++ projects/routing/sys/dev/cxgbe/iw_cxgbe/cm.c Mon Sep 7 07:03:40 2015 (r287530) @@ -47,13 +47,12 @@ __FBSDID("$FreeBSD$"); #include <netinet/in_systm.h> #include <netinet/in_pcb.h> #include <netinet/ip.h> +#include <netinet/in_fib.h> #include <netinet/ip_var.h> #include <netinet/tcp_var.h> #include <netinet/tcp.h> #include <netinet/tcpip.h> -#include <net/rt_nhops.h> - #include <netinet/toecore.h> struct sge_iq; Modified: projects/routing/sys/dev/cxgbe/tom/t4_connect.c ============================================================================== --- projects/routing/sys/dev/cxgbe/tom/t4_connect.c Mon Sep 7 02:00:05 2015 (r287529) +++ projects/routing/sys/dev/cxgbe/tom/t4_connect.c Mon Sep 7 07:03:40 2015 (r287530) @@ -49,11 +49,11 @@ __FBSDID("$FreeBSD$"); #include <netinet/in.h> #include <netinet/in_pcb.h> #include <netinet/ip.h> +#include <netinet/in_fib.h> #include <netinet/tcp_var.h> #define TCPSTATES #include <netinet/tcp_fsm.h> #include <netinet/toecore.h> -#include <net/rt_nhops.h> #include "common/common.h" #include "common/t4_msg.h" Modified: projects/routing/sys/dev/cxgbe/tom/t4_listen.c ============================================================================== --- projects/routing/sys/dev/cxgbe/tom/t4_listen.c Mon Sep 7 02:00:05 2015 (r287529) +++ projects/routing/sys/dev/cxgbe/tom/t4_listen.c Mon Sep 7 07:03:40 2015 (r287530) @@ -51,6 +51,8 @@ __FBSDID("$FreeBSD$"); #include <netinet/in.h> #include <netinet/in_pcb.h> #include <netinet/ip.h> +#include <netinet/in_fib.h> +#include <netinet6/in6_fib.h> #include <netinet/ip6.h> #include <netinet6/scope6_var.h> #include <netinet/tcp_timer.h> @@ -58,7 +60,6 @@ __FBSDID("$FreeBSD$"); #define TCPSTATES #include <netinet/tcp_fsm.h> #include <netinet/toecore.h> -#include <net/rt_nhops.h> #include "common/common.h" #include "common/t4_msg.h" Modified: projects/routing/sys/fs/nfsclient/nfs_clport.c ============================================================================== --- projects/routing/sys/fs/nfsclient/nfs_clport.c Mon Sep 7 02:00:05 2015 (r287529) +++ projects/routing/sys/fs/nfsclient/nfs_clport.c Mon Sep 7 07:03:40 2015 (r287530) @@ -47,10 +47,10 @@ __FBSDID("$FreeBSD$"); #include <sys/sysctl.h> #include <fs/nfs/nfsport.h> #include <netinet/if_ether.h> +#include <netinet/in_fib.h> #include <netinet6/scope6_var.h> #include <netinet6/ip6_var.h> #include <net/if_types.h> -#include <net/rt_nhops.h> #include <fs/nfsclient/nfs_kdtrace.h> Modified: projects/routing/sys/net/if_stf.c ============================================================================== --- projects/routing/sys/net/if_stf.c Mon Sep 7 02:00:05 2015 (r287529) +++ projects/routing/sys/net/if_stf.c Mon Sep 7 07:03:40 2015 (r287530) @@ -104,6 +104,7 @@ #include <netinet/in.h> #include <netinet/in_systm.h> #include <netinet/ip.h> +#include <netinet/in_fib.h> #include <netinet/ip_var.h> #include <netinet/in_var.h> @@ -114,8 +115,6 @@ #include <netinet/ip_encap.h> -#include <net/rt_nhops.h> - #include <machine/stdarg.h> #include <net/bpf.h> Modified: projects/routing/sys/net/rt_nhops.c ============================================================================== --- projects/routing/sys/net/rt_nhops.c Mon Sep 7 02:00:05 2015 (r287529) +++ projects/routing/sys/net/rt_nhops.c Mon Sep 7 07:03:40 2015 (r287530) @@ -27,11 +27,6 @@ * SUCH DAMAGE. */ -/* - * Temporary file. In future it should be split between net/route.c - * and per-AF files like netinet/in_rmx.c | netinet6/in6_rmx.c - */ - #include "opt_inet.h" #include "opt_inet6.h" #include "opt_route.h" @@ -119,29 +114,6 @@ int fwd_destroy_fib(struct fwd_module *f #endif static inline uint16_t fib_rte_to_nh_flags(int rt_flags); -#ifdef INET -static void rib4_rte_to_nh_extended(struct rtentry *rte, struct in_addr dst, - struct rt4_extended *prt4); -static void fib4_rte_to_nh_extended(struct rtentry *rte, struct in_addr dst, - struct nhop4_extended *pnh4); -static void fib4_rte_to_nh_basic(struct rtentry *rte, struct in_addr dst, - struct nhop4_basic *pnh4); -#endif -#ifdef INET6 -static void fib6_rte_to_nh_extended(struct rtentry *rte, struct in6_addr *dst, - struct nhop6_extended *pnh6); -static void fib6_rte_to_nh_basic(struct rtentry *rte, const struct in6_addr *dst, - struct nhop6_basic *pnh6); -static int fib6_storelladdr(struct ifnet *ifp, struct in6_addr *dst, - int mm_flags, u_char *desten); -static uint16_t fib6_get_ifa(struct rtentry *rte); -static int fib6_lla_to_nh_basic(const struct in6_addr *dst, uint32_t scopeid, - struct nhop6_basic *pnh6); -static int fib6_lla_to_nh_extended(struct in6_addr *dst, uint32_t scopeid, - struct nhop6_extended *pnh6); -static int fib6_lla_to_nh(struct in6_addr *dst, uint32_t scopeid, - struct nhop_prepend *nh, struct ifnet **lifp); -#endif MALLOC_DEFINE(M_RTFIB, "rtfib", "routing fwd"); @@ -169,1183 +141,17 @@ MALLOC_DEFINE(M_RTFIB, "rtfib", "routing */ //#define NHOP_DIRECT -#define RNTORT(p) ((struct rtentry *)(p)) -/* - * Copies proper nexthop data based on @nh_src nexthop. - * - * For non-ECMP nexthop function simply copies @nh_src. - * For ECMP nexthops flowid is used to select proper - * nexthop. - * - */ -static inline void -fib_choose_prepend(uint32_t fibnum, struct nhop_prepend *nh_src, - uint32_t flowid, struct nhop_prepend *nh, int af) -{ - struct nhop_multi *nh_multi; - int idx; - - if ((nh_src->nh_flags & NHF_RECURSE) != 0) { - - /* - * Recursive nexthop. Choose direct nexthop - * based on flowid. - */ - nh_multi = (struct nhop_multi *)nh_src; - idx = nh_multi->nh_nhops[flowid % nh_multi->nh_count]; #if 0 - KASSERT((fibnum < rt_numfibs), ("fib4_lookup_prependĀ§: bad fibnum")); - rh = rt_tables_get_rnh(fibnum, AF_INET); - //nh_src = &rh->nhops[i]; -#endif - } - - *nh = *nh_src; - /* TODO: Do some light-weight refcounting on egress ifp's */ -} - static inline void fib_free_nh_prepend(uint32_t fibnum, struct nhop_prepend *nh, int af) { /* TODO: Do some light-weight refcounting on egress ifp's */ } - -#ifdef INET -void -fib4_free_nh_prepend(uint32_t fibnum, struct nhop_prepend *nh) -{ - - fib_free_nh_prepend(fibnum, nh, AF_INET); -} - -void -fib4_choose_prepend(uint32_t fibnum, struct nhop_prepend *nh_src, - uint32_t flowid, struct nhop_prepend *nh, struct nhop4_extended *nh_ext) -{ - - fib_choose_prepend(fibnum, nh_src, flowid, nh, AF_INET); - if (nh_ext == NULL) - return; - - nh_ext->nh_ifp = NH_LIFP(nh); - nh_ext->nh_mtu = nh->nh_mtu; - nh_ext->nh_flags = nh->nh_flags; -#if 0 - /* TODO: copy source/gw address from extended nexthop data */ - nh_ext->nh_addr = ; - nh_ext->nh_src= ; #endif -} - -/* - * Function performs lookup in IPv4 table fib @fibnum. - * - * In case of successful lookup @nh header is filled with - * appropriate interface info and full L2 header to prepend. - * - * If no valid ARP record is present, NHF_L2_INCOMPLETE flag - * is set and gateway address is stored into nh->d.gw4 - * - * If @nh_ext is not NULL, additional nexthop data is stored there. - * - * Returns 0 on success. - * - */ -int -fib4_lookup_prepend(uint32_t fibnum, struct in_addr dst, struct mbuf *m, - struct nhop_prepend *nh, struct nhop4_extended *nh_ext) -{ - struct rib_head *rh; - struct radix_node *rn; - struct sockaddr_in *gw_sa, sin; - struct ifnet *lifp; - struct in_addr gw; - struct ether_header *eh; - int error, flags; - struct rtentry *rte; - RIB_LOCK_READER; - - KASSERT((fibnum < rt_numfibs), ("fib4_lookup_prepend: bad fibnum")); - rh = rt_tables_get_rnh(fibnum, AF_INET); - if (rh == NULL) - return (EHOSTUNREACH); - - /* Prepare lookup key */ - memset(&sin, 0, sizeof(sin)); - sin.sin_len = sizeof(struct sockaddr_in); - sin.sin_addr = dst; - - RIB_RLOCK(rh); - rn = rh->rnh_matchaddr((void *)&sin, &rh->head); - rte = RNTORT(rn); - if (rn == NULL || ((rn->rn_flags & RNF_ROOT) != 0) || - RT_LINK_IS_UP(rte->rt_ifp) == 0) { - RIB_RUNLOCK(rh); - return (EHOSTUNREACH); - } - - /* - * Currently we fill in @nh ourselves. - * In near future rte will have nhop index to copy from. - */ - - /* Calculate L3 info */ - flags = 0; - nh->nh_mtu = min(rte->rt_mtu, rte->rt_ifp->if_mtu); - if (rte->rt_flags & RTF_GATEWAY) { - gw_sa = (struct sockaddr_in *)rte->rt_gateway; - gw = gw_sa->sin_addr; - } else - gw = dst; - /* Set flags */ - flags = fib_rte_to_nh_flags(rte->rt_flags); - gw_sa = (struct sockaddr_in *)rt_key(rte); - if (gw_sa->sin_addr.s_addr == 0) - flags |= NHF_DEFAULT; - - /* - * TODO: nh L2/L3 resolve. - * Currently all we have is rte ifp. - * Simply use it. - */ - /* Save interface address ifp */ - lifp = rte->rt_ifa->ifa_ifp; - nh->aifp_idx = lifp->if_index; - /* Save both logical and transmit interface indexes */ - lifp = rte->rt_ifp; - nh->lifp_idx = lifp->if_index; - nh->i.ifp_idx = nh->lifp_idx; - - if (nh_ext != NULL) { - /* Fill in extended info */ - fib4_rte_to_nh_extended(rte, dst, nh_ext); - } - - RIB_RUNLOCK(rh); - - nh->nh_flags = flags; - /* - * Try to lookup L2 info. - * Do this using separate LLE locks. - * TODO: move this under radix lock. - */ - if (lifp->if_type == IFT_ETHER) { - eh = (struct ether_header *)nh->d.data; - - /* - * Fill in ethernet header. - * It should be already presented if we're - * sending data via known gateway. - */ - error = arpresolve_fast(lifp, gw, m ? m->m_flags : 0, - eh->ether_dhost); - printf("Resolve for ifp %s returned %d\n", lifp->if_xname, error); - if (error == 0) { - memcpy(&eh->ether_shost, IF_LLADDR(lifp), ETHER_ADDR_LEN); - eh->ether_type = htons(ETHERTYPE_IP); - nh->nh_count = ETHER_HDR_LEN; - return (0); - } - } - - printf("Incomplete for ifp %s ()\n", lifp->if_xname); - /* Notify caller that no L2 info is linked */ - nh->nh_count = 0; - nh->nh_flags |= NHF_L2_INCOMPLETE; - /* ..And save gateway address */ - nh->d.gw4 = gw; - return (0); -} - -int -fib4_sendmbuf(struct ifnet *ifp, struct mbuf *m, struct nhop_prepend *nh, - struct in_addr dst) -{ - int error; - - if (nh != NULL && (nh->nh_flags & NHF_L2_INCOMPLETE) == 0) { - - /* - * Fast path case. Most packets should - * be sent from here. - * TODO: Make special ifnet - * 'if_output_frame' handler for that. - */ - struct nhop_info ni; - struct ether_header *eh; - bzero(&ni, sizeof(ni)); - ni.ni_flags = RT_NHOP; - ni.ni_family = AF_INET; - ni.ni_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); - printf("FP %s\n", ifp->if_xname); - error = (*ifp->if_output)(ifp, m, NULL, &ni); - } 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; - printf("SLOW %s\n", ifp->if_xname); - error = (*ifp->if_output)(ifp, m, - (const struct sockaddr *)&gw_out, NULL); - } - - return (error); -} - -static inline uint16_t -fib_rte_to_nh_flags(int rt_flags) -{ - uint16_t res; - - res = (rt_flags & RTF_REJECT) ? NHF_REJECT : 0; - res |= (rt_flags & RTF_BLACKHOLE) ? NHF_BLACKHOLE : 0; - res |= (rt_flags & (RTF_DYNAMIC|RTF_MODIFIED)) ? NHF_REDIRECT : 0; - res |= (rt_flags & RTF_BROADCAST) ? NHF_BROADCAST : 0; - res |= (rt_flags & RTF_GATEWAY) ? NHF_GATEWAY : 0; - - return (res); -} - -static void -fib4_rte_to_nh_basic(struct rtentry *rte, struct in_addr dst, - struct nhop4_basic *pnh4) -{ - struct sockaddr_in *gw; - - pnh4->nh_ifp = rte->rt_ifa->ifa_ifp; - pnh4->nh_mtu = min(rte->rt_mtu, rte->rt_ifp->if_mtu); - if (rte->rt_flags & RTF_GATEWAY) { - gw = (struct sockaddr_in *)rte->rt_gateway; - pnh4->nh_addr = gw->sin_addr; - } else - pnh4->nh_addr = dst; - /* Set flags */ - pnh4->nh_flags = fib_rte_to_nh_flags(rte->rt_flags); - gw = (struct sockaddr_in *)rt_key(rte); - if (gw->sin_addr.s_addr == 0) - pnh4->nh_flags |= NHF_DEFAULT; - /* XXX: Set RTF_BROADCAST if GW address is broadcast */ -} - -static void -fib4_rte_to_nh_extended(struct rtentry *rte, struct in_addr dst, - struct nhop4_extended *pnh4) -{ - struct sockaddr_in *gw; - struct in_ifaddr *ia; - - pnh4->nh_ifp = rte->rt_ifa->ifa_ifp; - pnh4->nh_mtu = min(rte->rt_mtu, rte->rt_ifp->if_mtu); - if (rte->rt_flags & RTF_GATEWAY) { - gw = (struct sockaddr_in *)rte->rt_gateway; - pnh4->nh_addr = gw->sin_addr; - } else - pnh4->nh_addr = dst; - /* Set flags */ - pnh4->nh_flags = fib_rte_to_nh_flags(rte->rt_flags); - gw = (struct sockaddr_in *)rt_key(rte); - if (gw->sin_addr.s_addr == 0) - pnh4->nh_flags |= NHF_DEFAULT; - /* XXX: Set RTF_BROADCAST if GW address is broadcast */ - - ia = ifatoia(rte->rt_ifa); - pnh4->nh_src = IA_SIN(ia)->sin_addr; -} - -static void -rib4_rte_to_nh_extended(struct rtentry *rte, struct in_addr dst, - struct rt4_extended *prt4) -{ - struct sockaddr_in *gw; - struct in_ifaddr *ia; - - /* Do explicit nexthop zero unless we're copying it */ - memset(prt4, 0, sizeof(*prt4)); - - gw = ((struct sockaddr_in *)rt_key(rte)); - prt4->rt_addr = gw->sin_addr; - gw = ((struct sockaddr_in *)rt_mask(rte)); - prt4->rt_mask.s_addr = (gw != NULL) ? - gw->sin_addr.s_addr : INADDR_BROADCAST; - - if (rte->rt_flags & RTF_GATEWAY) { - gw = (struct sockaddr_in *)rte->rt_gateway; - prt4->rt_gateway = gw->sin_addr; - } else - prt4->rt_gateway = dst; - - prt4->rt_lifp = rte->rt_ifp; - prt4->rt_aifp = rte->rt_ifa->ifa_ifp; - prt4->rt_flags = rte->rt_flags; - prt4->rt_mtu = min(rte->rt_mtu, rte->rt_ifp->if_mtu); - - prt4->rt_nhop = 0; /* XXX: fill real nexthop */ - - ia = ifatoia(rte->rt_ifa); - prt4->rt_src = IA_SIN(ia)->sin_addr; -} - -/* - * Performs IPv4 route table lookup on @dst. Returns 0 on success. - * Stores nexthop info provided @pnh4 structure. - * Note that - * - nh_ifp cannot be safely dereferenced - * - nh_ifp represents ifaddr ifp (e.g. if looking up address on - * interface "ix0" pointer to "ix0" interface will be returned instead - * of "lo0") - * - howewer mtu from "transmit" interface will be returned. - */ -int -fib4_lookup_nh_basic(uint32_t fibnum, struct in_addr dst, uint32_t flowid, - struct nhop4_basic *pnh4) -{ - struct rib_head *rh; - struct radix_node *rn; - struct sockaddr_in sin; - struct rtentry *rte; - RIB_LOCK_READER; - - KASSERT((fibnum < rt_numfibs), ("fib4_lookup_nh_basic: bad fibnum")); - rh = rt_tables_get_rnh(fibnum, AF_INET); - if (rh == NULL) - return (ENOENT); - - /* Prepare lookup key */ - memset(&sin, 0, sizeof(sin)); - sin.sin_len = sizeof(struct sockaddr_in); - sin.sin_addr = dst; - - RIB_RLOCK(rh); - rn = rh->rnh_matchaddr((void *)&sin, &rh->head); - if (rn != NULL && ((rn->rn_flags & RNF_ROOT) == 0)) { - rte = RNTORT(rn); - /* Ensure route & ifp is UP */ - if (RT_LINK_IS_UP(rte->rt_ifp)) { - fib4_rte_to_nh_basic(rte, dst, pnh4); - RIB_RUNLOCK(rh); - - return (0); - } - } - RIB_RUNLOCK(rh); - - return (ENOENT); -} - -int -fib4_lookup_nh_ifp(uint32_t fibnum, struct in_addr dst, uint32_t flowid, - struct nhop4_basic *pnh4) -{ - struct rib_head *rh; - struct radix_node *rn; - struct sockaddr_in sin; - struct rtentry *rte; - RIB_LOCK_READER; - - KASSERT((fibnum < rt_numfibs), ("fib4_lookup_nh_ifp: bad fibnum")); - rh = rt_tables_get_rnh(fibnum, AF_INET); - if (rh == NULL) - return (ENOENT); - - /* Prepare lookup key */ - memset(&sin, 0, sizeof(sin)); - sin.sin_len = sizeof(struct sockaddr_in); - sin.sin_addr = dst; - - RIB_RLOCK(rh); - rn = rh->rnh_matchaddr((void *)&sin, &rh->head); - if (rn != NULL && ((rn->rn_flags & RNF_ROOT) == 0)) { - rte = RNTORT(rn); - /* Ensure route & ifp is UP */ - if (RT_LINK_IS_UP(rte->rt_ifp)) { - fib4_rte_to_nh_basic(rte, dst, pnh4); - RIB_RUNLOCK(rh); - pnh4->nh_ifp = rte->rt_ifp; - return (0); - } - } - RIB_RUNLOCK(rh); - - return (ENOENT); -} - -/* - * Performs IPv4 route table lookup on @dst. Returns 0 on success. - * Stores extende nexthop info provided @pnh4 structure. - * Note that - * - nh_ifp cannot be safely dereferenced unless NHOP_LOOKUP_REF is specified. - * - in that case you need to call fib4_free_nh_ext() - * - nh_ifp represents logical transmit interface (rt_ifp) - * - mtu from logical transmit interface will be returned. - */ -int -fib4_lookup_nh_ext(uint32_t fibnum, struct in_addr dst, uint32_t flowid, - uint32_t flags, struct nhop4_extended *pnh4) -{ - struct rib_head *rh; - struct radix_node *rn; - struct sockaddr_in sin; - struct rtentry *rte; - RIB_LOCK_READER; - - KASSERT((fibnum < rt_numfibs), ("fib4_lookup_nh_ext: bad fibnum")); - rh = rt_tables_get_rnh(fibnum, AF_INET); - if (rh == NULL) - return (ENOENT); - - /* Prepare lookup key */ - memset(&sin, 0, sizeof(sin)); - sin.sin_len = sizeof(struct sockaddr_in); - sin.sin_addr = dst; - - RIB_RLOCK(rh); - rn = rh->rnh_matchaddr((void *)&sin, &rh->head); - if (rn != NULL && ((rn->rn_flags & RNF_ROOT) == 0)) { - rte = RNTORT(rn); - /* Ensure route & ifp is UP */ - if (RT_LINK_IS_UP(rte->rt_ifp)) { - fib4_rte_to_nh_extended(rte, dst, pnh4); - if ((flags & NHOP_LOOKUP_REF) != 0) { - /* TODO: Do lwref on egress ifp's */ - } - RIB_RUNLOCK(rh); - - return (0); - } - } - RIB_RUNLOCK(rh); - - return (ENOENT); -} - -void -fib4_free_nh_ext(uint32_t fibnum, struct nhop4_extended *pnh4) -{ - -} - -void -fib4_source_to_sa_ext(const struct nhopu_extended *pnhu, struct sockaddr_in *sin) -{ - - sin->sin_family = AF_INET; - sin->sin_len = sizeof(*sin); - sin->sin_addr = pnhu->u.nh4.nh_src; -} - -int -rib4_lookup_nh_ext(uint32_t fibnum, struct in_addr dst, uint32_t flowid, - uint32_t flags, struct rt4_extended *prt4) -{ - struct rib_head *rh; - struct radix_node *rn; - struct sockaddr_in sin; - struct rtentry *rte; - RIB_LOCK_READER; - - KASSERT((fibnum < rt_numfibs), ("rib4_lookup_nh_ext: bad fibnum")); - rh = rt_tables_get_rnh(fibnum, AF_INET); - if (rh == NULL) - return (ENOENT); - - /* Prepare lookup key */ - memset(&sin, 0, sizeof(sin)); - sin.sin_len = sizeof(struct sockaddr_in); - sin.sin_addr = dst; - - RIB_RLOCK(rh); - rn = rh->rnh_matchaddr((void *)&sin, &rh->head); - if (rn != NULL && ((rn->rn_flags & RNF_ROOT) == 0)) { - rte = RNTORT(rn); - /* Ensure route & ifp is UP */ - if (RT_LINK_IS_UP(rte->rt_ifp)) { - rib4_rte_to_nh_extended(rte, dst, prt4); - if ((flags & NHOP_LOOKUP_REF) != 0) { - /* TODO: Do lwref on egress ifp's */ - } - RIB_RUNLOCK(rh); - return (0); - } - } - RIB_RUNLOCK(rh); - - return (ENOENT); -} - -void -rib4_free_nh_ext(uint32_t fibnum, struct rt4_extended *prt4) -{ - -} - -#endif - -#ifdef INET6 -void -fib6_free_nh_prepend(uint32_t fibnum, struct nhop_prepend *nh) -{ - fib_free_nh_prepend(fibnum, nh, AF_INET6); -} - -void -fib6_choose_prepend(uint32_t fibnum, struct nhop_prepend *nh_src, - uint32_t flowid, struct nhop_prepend *nh, struct nhop6_extended *nh_ext) -{ - - fib_choose_prepend(fibnum, nh_src, flowid, nh, AF_INET6); - if (nh_ext == NULL) - return; - - nh_ext->nh_ifp = NH_LIFP(nh); - nh_ext->nh_mtu = nh->nh_mtu; - nh_ext->nh_flags = nh->nh_flags; -/* - nh_ext->nh_addr = ; - nh_ext->nh_src= ; -*/ -} - -/* - * Temporary function to copy ethernet address from valid lle - */ -static int -fib6_storelladdr(struct ifnet *ifp, struct in6_addr *dst, int mm_flags, - u_char *desten) -{ - struct llentry *ln; - struct sockaddr_in6 dst_sa; - - if (mm_flags & M_MCAST) { - ETHER_MAP_IPV6_MULTICAST(&dst, desten); - return (0); - } - - memset(&dst_sa, 0, sizeof(dst_sa)); - dst_sa.sin6_family = AF_INET6; - dst_sa.sin6_len = sizeof(dst_sa); - dst_sa.sin6_addr = *dst; - dst_sa.sin6_scope_id = ifp->if_index; - - - /* - * the entry should have been created in nd6_store_lladdr - */ - IF_AFDATA_RLOCK(ifp); - ln = lla_lookup(LLTABLE6(ifp), 0, (struct sockaddr *)&dst_sa); - - /* - * Perform fast path for the following cases: - * 1) lle state is REACHABLE - * 2) lle state is DELAY (NS message sentNS message sent) - * - * Every other case involves lle modification, so we handle - * them separately. - */ - if (ln == NULL || (ln->ln_state != ND6_LLINFO_REACHABLE && - ln->ln_state != ND6_LLINFO_DELAY)) { - if (ln != NULL) - LLE_RUNLOCK(ln); - IF_AFDATA_RUNLOCK(ifp); - return (1); - } - bcopy(&ln->ll_addr, desten, ifp->if_addrlen); - LLE_RUNLOCK(ln); - IF_AFDATA_RUNLOCK(ifp); - - return (0); -} - -int -fib6_lookup_prepend(uint32_t fibnum, struct in6_addr *dst, uint32_t scopeid, - struct mbuf *m, struct nhop_prepend *nh, struct nhop6_extended *nh_ext) -{ - struct rib_head *rh; - struct radix_node *rn; - struct sockaddr_in6 sin6, *gw_sa; - struct in6_addr gw6; - struct rtentry *rte; - struct ifnet *lifp; - struct ether_header *eh; - RIB_LOCK_READER; - uint32_t flags; - int error; - - if (IN6_IS_SCOPE_LINKLOCAL(dst)) { - /* Do not lookup link-local addresses in rtable */ - error = fib6_lla_to_nh(dst, scopeid, nh, &lifp); - if (error != 0) - return (error); - /* */ - gw6 = *dst; - goto do_l2; - } - - - KASSERT((fibnum < rt_numfibs), ("fib6_lookup_prepend: bad fibnum")); - rh = rt_tables_get_rnh(fibnum, AF_INET6); - if (rh == NULL) - return (ENOENT); - - /* Prepare lookup key */ - memset(&sin6, 0, sizeof(sin6)); - sin6.sin6_len = sizeof(struct sockaddr_in6); - sin6.sin6_addr = *dst; - sin6.sin6_scope_id = scopeid; - sa6_embedscope(&sin6, 0); - - - RIB_RLOCK(rh); - rn = rh->rnh_matchaddr((void *)&sin6, &rh->head); - rte = RNTORT(rn); - if (rn == NULL || ((rn->rn_flags & RNF_ROOT) != 0) || - RT_LINK_IS_UP(rte->rt_ifp) == 0) { - RIB_RUNLOCK(rh); - return (EHOSTUNREACH); - } - - /* Explicitly zero nexthop */ - memset(nh, 0, sizeof(*nh)); - flags = 0; - nh->nh_mtu = min(rte->rt_mtu, IN6_LINKMTU(rte->rt_ifp)); - if (rte->rt_flags & RTF_GATEWAY) { - gw_sa = (struct sockaddr_in6 *)rte->rt_gateway; - gw6 = gw_sa->sin6_addr; - in6_clearscope(&gw6); - } else - gw6 = *dst; - /* Set flags */ - flags = fib_rte_to_nh_flags(rte->rt_flags); - gw_sa = (struct sockaddr_in6 *)rt_key(rte); - if (IN6_IS_ADDR_UNSPECIFIED(&gw_sa->sin6_addr)) - flags |= NHF_DEFAULT; - - /* - * TODO: nh L2/L3 resolve. - * Currently all we have is rte ifp. - * Simply use it. - */ - /* Save interface address ifp */ - nh->aifp_idx = fib6_get_ifa(rte); - /* Save both logical and transmit interface indexes */ - lifp = rte->rt_ifp; - nh->lifp_idx = lifp->if_index; - nh->i.ifp_idx = nh->lifp_idx; - - RIB_RUNLOCK(rh); - - nh->nh_flags = flags; -do_l2: - /* - * Try to lookup L2 info. - * Do this using separate LLE locks. - * TODO: move this under radix lock. - */ - if (lifp->if_type == IFT_ETHER) { - eh = (struct ether_header *)nh->d.data; - - /* - * Fill in ethernet header. - * It should be already presented if we're - * sending data via known gateway. - */ - error = fib6_storelladdr(lifp, &gw6, 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_IPV6); - nh->nh_count = ETHER_HDR_LEN; - return (0); - } - } - - /* Notify caller that no L2 info is linked */ - nh->nh_count = 0; - nh->nh_flags |= NHF_L2_INCOMPLETE; - /* ..And save gateway address */ - nh->d.gw6 = gw6; - return (0); -} - -int -fib6_sendmbuf(struct ifnet *ifp, struct ifnet *origifp, struct mbuf *m, - struct nhop_prepend *nh) -{ - int error; - - if (nh != NULL && (nh->nh_flags & NHF_L2_INCOMPLETE) == 0) { - - /* - * Fast path case. Most packets should - * be sent from here. - * TODO: Make special ifnet - * 'if_output_frame' handler for that. - */ - struct nhop_info ni; - struct ether_header *eh; - bzero(&ni, sizeof(ni)); - ni.ni_family = AF_INET6; - ni.ni_flags = RT_NHOP; - ni.ni_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, &ni); - } else { - /* We need to perform ND lookup */ - struct sockaddr_in6 gw_out; - - memset(&gw_out, 0, sizeof(gw_out)); - gw_out.sin6_family = AF_INET6; - gw_out.sin6_len = sizeof(gw_out); - gw_out.sin6_addr = nh->d.gw6; - gw_out.sin6_scope_id = ifp->if_index; - sa6_embedscope(&gw_out, 0); - - error = nd6_output(ifp, origifp, m, &gw_out, NULL); - } - - return (error); -} - -static uint16_t -fib6_get_ifa(struct rtentry *rte) -{ - struct ifnet *ifp; - struct sockaddr_dl *sdl; - - ifp = rte->rt_ifp; - if ((ifp->if_flags & IFF_LOOPBACK) && - rte->rt_gateway->sa_family == AF_LINK) { - sdl = (struct sockaddr_dl *)rte->rt_gateway; - return (sdl->sdl_index); - } - - return (ifp->if_index); -#if 0 - /* IPv6 case */ - /* Alternative way to get interface address ifp */ - /* - * Adjust the "outgoing" interface. If we're going to loop *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201509070703.t8773f1w096223>