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...

Alexander V. Chernikov melifaro at FreeBSD.org
Mon Sep 7 07:03:44 UTC 2015


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 ***


More information about the svn-src-projects mailing list