Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 23 Aug 2015 18:12:12 +0000 (UTC)
From:      "Alexander V. Chernikov" <melifaro@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r287044 - in projects/routing/sys: conf net netpfil/ipfw netpfil/pf
Message-ID:  <201508231812.t7NICCSE041966@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: melifaro
Date: Sun Aug 23 18:12:11 2015
New Revision: 287044
URL: https://svnweb.freebsd.org/changeset/base/287044

Log:
  Implement fib*_lookup_nh_basic to provide fast
   non-refcounted way to determine egress ifp / mtu.

Added:
  projects/routing/sys/net/rt_nhops.c   (contents, props changed)
  projects/routing/sys/net/rt_nhops.h   (contents, props changed)
Modified:
  projects/routing/sys/conf/files
  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	Sun Aug 23 18:04:37 2015	(r287043)
+++ projects/routing/sys/conf/files	Sun Aug 23 18:12:11 2015	(r287044)
@@ -3426,6 +3426,7 @@ net/raw_cb.c			standard
 net/raw_usrreq.c		standard
 net/route.c			standard
 net/rss_config.c		optional inet rss | inet6 rss
+net/rt_nhops.c			standard
 net/rtsock.c			standard
 net/slcompress.c		optional netgraph_vjc | sppp | \
 					 netgraph_sppp

Added: projects/routing/sys/net/rt_nhops.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ projects/routing/sys/net/rt_nhops.c	Sun Aug 23 18:12:11 2015	(r287044)
@@ -0,0 +1,240 @@
+/*-
+ * Copyright (c) 2014
+ * 	Alexander V. Chernikov <melifaro@FreeBSD.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * 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"
+#include "opt_mpath.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/syslog.h>
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/socket.h>
+#include <sys/sysctl.h>
+#include <sys/syslog.h>
+#include <sys/sysproto.h>
+#include <sys/proc.h>
+#include <sys/domain.h>
+#include <sys/kernel.h>
+#include <sys/sbuf.h>
+
+#include <net/if.h>
+#include <net/if_var.h>
+#include <net/if_dl.h>
+#include <net/route.h>
+#include <net/vnet.h>
+
+#ifdef RADIX_MPATH
+#include <net/radix_mpath.h>
+#endif
+
+#include <netinet/in.h>
+#include <netinet/ip_mroute.h>
+#include <netinet/ip6.h>
+
+#include <net/rt_nhops.h>
+
+#include <vm/uma.h>
+
+struct fwd_info {
+	fib_lookup_t	*lookup;
+	void		*state;
+};
+
+#define	FWD_FSM_NONE	0
+#define	FWD_FSM_INIT	1
+#define	FWD_FSM_FWD	2
+struct fwd_control {
+	int		fwd_state;	/* FSM */
+	struct fwd_module	*fm;
+};
+
+#if 0
+static struct fwd_info *fwd_db[FWD_SIZE];
+static struct fwd_control *fwd_ctl[FWD_SIZE];
+
+static TAILQ_HEAD(fwd_module_list, fwd_module)	modulehead = TAILQ_HEAD_INITIALIZER(modulehead);
+static struct fwd_module_list fwd_modules[FWD_SIZE];
+
+static uint8_t fwd_map_af[] = {
+	AF_INET,
+	AF_INET6,
+};
+
+static struct rwlock fwd_lock;
+#define	FWD_LOCK_INIT()	rw_init(&fwd_lock, "fwd_lock")
+#define	FWD_RLOCK()	rw_rlock(&fwd_lock)
+#define	FWD_RUNLOCK()	rw_runlock(&fwd_lock)
+#define	FWD_WLOCK()	rw_wlock(&fwd_lock)
+#define	FWD_WUNLOCK()	rw_wunlock(&fwd_lock)
+
+int fwd_attach_fib(struct fwd_module *fm, u_int fib);
+int fwd_destroy_fib(struct fwd_module *fm, u_int fib);
+#endif
+MALLOC_DEFINE(M_RTFIB, "rtfib", "routing fwd");
+
+
+
+/*
+ * Per-AF fast routines returning minimal needed info.
+ * It is not safe to dereference any pointers since it
+ * may end up with use-after-free case.
+ * Typically it may be used to check if outgoing
+ * interface matches or to calculate proper MTU.
+ *
+ * Note that returned interface pointer is logical one,
+ * e.g. actual transmit ifp may be different.
+ * Difference may be triggered by
+ * 1) loopback routes installed for interface addresses.
+ *  e.g. for address 10.0.0.1 with prefix /24 bound to
+ *  interface ix0, "logical" interface will be "ix0",
+ *  while "trasmit" interface will be "lo0" since this is
+ *  loopback route. You should consider using other
+ *  functions if you need "transmit" interface or both.
+ *
+ *
+ * Returns 0 on match, error code overwise.
+ */
+
+#define	NHOP_FLAGS_MASK	(RTF_REJECT|RTF_BLACKHOLE)
+//#define	NHOP_DIRECT	
+#define RNTORT(p)	((struct rtentry *)(p))
+#ifdef INET
+int
+fib4_lookup_nh_basic(uint32_t fibnum, struct in_addr dst, uint32_t flowid,
+    struct nhop4_basic *pnh4)
+{
+	struct radix_node_head *rnh;
+	struct radix_node *rn;
+	struct sockaddr_in *gw, sin;
+	struct rtentry *rte;
+
+	KASSERT((fibnum < rt_numfibs), ("fib4_lookup_nh_basic: bad fibnum"));
+	rnh = rt_tables_get_rnh(fibnum, AF_INET);
+	if (rnh == NULL)
+		return (ENOENT);
+
+	/* Prepare lookup key */
+	memset(&sin, 0, sizeof(sin));
+	sin.sin_addr = dst;
+
+	RADIX_NODE_HEAD_RLOCK(rnh);
+	rn = rnh->rnh_matchaddr((void *)&sin, rnh);
+	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)) {
+			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 = rte->rt_flags & NHOP_FLAGS_MASK;
+			gw = (struct sockaddr_in *)rt_key(rte);
+			if (gw->sin_addr.s_addr == 0)
+				pnh4->nh_flags |= NHOP_DEFAULT;
+			RADIX_NODE_HEAD_RUNLOCK(rnh);
+
+			return (0);
+		}
+	}
+	RADIX_NODE_HEAD_RUNLOCK(rnh);
+
+	return (ENOENT);
+}
+#endif
+
+#ifdef INET6
+int
+fib6_lookup_nh_basic(uint32_t fibnum, struct in6_addr dst, uint32_t flowid,
+    struct nhop6_basic *pnh6)
+{
+	struct radix_node_head *rnh;
+	struct radix_node *rn;
+	struct sockaddr_in6 *gw, sin6;
+	struct rtentry *rte;
+
+	KASSERT((fibnum < rt_numfibs), ("fib6_lookup_nh_basic: bad fibnum"));
+	rnh = rt_tables_get_rnh(fibnum, AF_INET);
+	if (rnh == NULL)
+		return (ENOENT);
+
+	/* Prepare lookup key */
+	memset(&sin6, 0, sizeof(sin6));
+	sin6.sin6_addr = dst;
+
+	RADIX_NODE_HEAD_RLOCK(rnh);
+	rn = rnh->rnh_matchaddr((void *)&sin6, rnh);
+	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)) {
+			pnh6->nh_ifp = rte->rt_ifa->ifa_ifp;
+			pnh6->nh_mtu = min(rte->rt_mtu, rte->rt_ifp->if_mtu);
+			if (rte->rt_flags & RTF_GATEWAY) {
+				gw = (struct sockaddr_in6 *)rte->rt_gateway;
+				pnh6->nh_addr = gw->sin6_addr;
+			} else
+				pnh6->nh_addr = dst;
+			/* Set flags */
+			pnh6->nh_flags = rte->rt_flags & NHOP_FLAGS_MASK;
+			gw = (struct sockaddr_in6 *)rt_key(rte);
+			if (IN6_IS_ADDR_UNSPECIFIED(&gw->sin6_addr))
+				pnh6->nh_flags |= NHOP_DEFAULT;
+			RADIX_NODE_HEAD_RUNLOCK(rnh);
+			return (0);
+		}
+	}
+	RADIX_NODE_HEAD_RUNLOCK(rnh);
+
+	return (ENOENT);
+}
+#endif
+
+
+
+
+
+
+
+
+
+
+
+

Added: projects/routing/sys/net/rt_nhops.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ projects/routing/sys/net/rt_nhops.h	Sun Aug 23 18:12:11 2015	(r287044)
@@ -0,0 +1,178 @@
+/*-
+ * Copyright (c) 2014
+ * 	Alexander V. Chernikov <melifaro@FreeBSD.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _NET_RT_NHOPS_H_
+#define	_NET_RT_NHOPS_H_
+
+#define	MAX_PREPEND_LEN		64	/* Max data that can be prepended */
+
+
+#define	NH_TYPE_DIRECT		1	/* Directly reachable, no data */
+#define	NH_TYPE_BLACKHOLE	2	/* Blackhole route */
+#define	NH_TYPE_REJECT		3	/* Send reject  */
+#define	NH_TYPE_L2		4	/* Provides full prepend header */
+#define	NH_TYPE_MUTATOR		5	/* NH+callback function  */
+#define	NH_TYPE_MULTIPATH	6	/* Multipath route */
+
+struct nhop_info {
+	uint64_t	refcnt;		/* Use references */
+	uint64_t	flags;		/* Options */
+
+};
+
+/* Multipath nhop info */
+struct nhop_mpath_info {
+	uint16_t	nhop;		/* Netxthop id */
+};
+
+/* mutator info */
+struct nhop_mutator_info;
+struct nhop_data;
+
+typedef int nhop_mutate_t(struct mbuf **, struct nhop_data *nd, void *storage);
+struct nhop_mutator_info {
+	nhop_mutate_t	*func;
+	char		data[];
+};
+
+/* Structure used for forwarding purposes */
+struct nhop_data {
+	uint8_t		flags;	/* NH flags */
+	uint8_t		count;	/* Number of nexthops or data length */
+	uint16_t	mtu;
+	uint16_t	lifp_idx;	/* Logical interface index */
+	uint16_t	ifp_idx;	/* Transmit interface index */
+	union {
+		struct nhop_mpath_info mp[32];	/* Multipath info */
+		struct nhop_mutator_info mm;	/* mutator info */
+		char	data[MAX_PREPEND_LEN - 8];	/* data to prepend */
+	} d;
+};
+
+/* Per-AF per-fib nhop table */
+struct nhops_descr {
+	uint32_t	nhop_size;	/* Nehthop data size */
+	uint32_t	nhops_max;	/* Max number of nhops */
+	void		*nhops_data;	/* Pointer to nhop data table */
+	void		*nhops_info;	/* Pointer to nhop info table */
+};
+
+
+#if 0
+typedef int nhop_resolve_t(struct sockaddr *dst, u_int fib, struct nhop_data *nd, struct nhop_info *nf);
+
+
+
+int
+lla_create_notify(struct sockaddr *dst, u_int fib, lla_notify_t *func, void *state, int flags);
+#endif
+
+/* Basic nexthop info used for uRPF/mtu checks */
+struct nhop4_basic {
+	struct ifnet	*nh_ifp;	/* Logical egress interface */
+	uint16_t	nh_mtu;		/* nexthop mtu */
+	uint16_t	nh_flags;	/* nhop flags */
+	struct in_addr	nh_addr;	/* GW/DST IPv4 address */
+};
+
+struct nhop6_basic {
+	struct ifnet	*nh_ifp;	/* Logical egress interface */
+	uint16_t	nh_mtu;		/* nexthop mtu */
+	uint16_t	nh_flags;	/* nhop flags */
+	struct in6_addr	nh_addr;	/* GW/DST IPv4 address */
+};
+
+struct nhop64_basic {
+	union {
+		struct nhop4_basic	nh4;
+		struct nhop6_basic	nh6;
+	} u;
+};
+
+int fib4_lookup_nh_basic(uint32_t fibnum, struct in_addr dst, uint32_t flowid,
+    struct nhop4_basic *pnh4);
+int fib6_lookup_nh_basic(uint32_t fibnum, struct in6_addr dst, uint32_t flowid,
+    struct nhop6_basic *pnh6);
+
+#define	NHOP_REJECT	RTF_REJECT
+#define	NHOP_BLACKHOLE	RTF_BLACKHOLE
+#define	NHOP_DEFAULT	0x80	/* Default route */
+
+#define	FWD_INET	0
+#define	FWD_INET6	1
+
+#define	FWD_SIZE	2
+
+#define	FWD_NAME_MAX	15
+
+#define	FWD_MULTIPATH	0x0001	/* has multipath support */
+#define	FWD_OLDMASKS	0x0002	/* has support for non-contig masks */
+#define	FWD_DEFAULT	0x0004	/* installs as default fib mechanism */
+#define	FWD_MANAGELOCK	0x0004	/* manage its own locking */
+
+typedef void *fib_init_t(u_int fibnum);
+typedef void fib_destroy_t(void *state);
+typedef int fib_dump_t(void *state, struct radix_node_head *rnh);
+typedef	int fib_change_t(void *state, int req, struct rtentry *rte,
+    struct rt_addrinfo *info);
+typedef int fib_lookup_t(void *state, void *key, uint64_t *attr, u_int flowid,
+    void *nhop);
+
+/* Structure used by external module */
+struct fwd_module_info {
+	uint8_t		fwd_family;	/* family we're registering to */
+	char		name[FWD_NAME_MAX];	/* fwd module name */
+	uint32_t	capabilities;
+	fib_init_t	*fib_init;
+	fib_destroy_t	*fib_destroy;
+	fib_dump_t	*fib_dump;
+	fib_change_t	*fib_change;
+	fib_lookup_t	*fib_lookup;
+};
+
+/* Internal version of previous structure */
+struct fwd_module {
+	TAILQ_ENTRY(fwd_module)	list;
+	uint8_t		fwd_family;
+	char		name[FWD_NAME_MAX];
+	uint32_t	capabilities;
+	fib_init_t	*fib_init;
+	fib_destroy_t	*fib_destroy;
+	fib_dump_t	*fib_dump;
+	fib_change_t	*fib_change;
+	fib_lookup_t	*fib_lookup;
+};
+
+int fwd_attach_module(struct fwd_module_info *m, void **);
+int fwd_destroy_module(void *state);
+int fwd_change_fib(struct radix_node_head *rnh, int req, struct rtentry *rte,
+    struct rt_addrinfo *info);
+
+#endif
+

Modified: projects/routing/sys/netpfil/ipfw/ip_fw2.c
==============================================================================
--- projects/routing/sys/netpfil/ipfw/ip_fw2.c	Sun Aug 23 18:04:37 2015	(r287043)
+++ projects/routing/sys/netpfil/ipfw/ip_fw2.c	Sun Aug 23 18:12:11 2015	(r287044)
@@ -89,6 +89,7 @@ __FBSDID("$FreeBSD$");
 #include <netinet6/scope6_var.h>
 #include <netinet6/ip6_var.h>
 #endif
+#include <net/rt_nhops.h>
 
 #include <netpfil/ipfw/ip_fw_private.h>
 
@@ -437,19 +438,10 @@ verify_path(struct in_addr src, struct i
 #if defined(USERSPACE) || !defined(__FreeBSD__)
 	return 0;
 #else
-	struct route ro;
-	struct sockaddr_in *dst;
+	struct nhop4_basic nh4;
 
-	bzero(&ro, sizeof(ro));
-
-	dst = (struct sockaddr_in *)&(ro.ro_dst);
-	dst->sin_family = AF_INET;
-	dst->sin_len = sizeof(*dst);
-	dst->sin_addr = src;
-	in_rtalloc_ign(&ro, 0, fib);
-
-	if (ro.ro_rt == NULL)
-		return 0;
+	if (fib4_lookup_nh_basic(fib, src, 0, &nh4) != 0)
+		return (0);
 
 	/*
 	 * If ifp is provided, check for equality with rtentry.
@@ -458,27 +450,18 @@ verify_path(struct in_addr src, struct i
 	 * routing entry (via lo0) for our own address
 	 * may exist, so we need to handle routing assymetry.
 	 */
-	if (ifp != NULL && ro.ro_rt->rt_ifa->ifa_ifp != ifp) {
-		RTFREE(ro.ro_rt);
-		return 0;
-	}
+	if (ifp != NULL && ifp != nh4.nh_ifp)
+		return (0);
 
 	/* if no ifp provided, check if rtentry is not default route */
-	if (ifp == NULL &&
-	     satosin(rt_key(ro.ro_rt))->sin_addr.s_addr == INADDR_ANY) {
-		RTFREE(ro.ro_rt);
-		return 0;
-	}
+	if (ifp == NULL && (nh4.nh_flags & NHOP_DEFAULT) != 0)
+		return (0);
 
 	/* or if this is a blackhole/reject route */
-	if (ifp == NULL && ro.ro_rt->rt_flags & (RTF_REJECT|RTF_BLACKHOLE)) {
-		RTFREE(ro.ro_rt);
-		return 0;
-	}
+	if (ifp == NULL && (nh4.nh_flags & (NHOP_REJECT|NHOP_BLACKHOLE)) != 0)
+		return (0);
 
-	/* found valid route */
-	RTFREE(ro.ro_rt);
-	return 1;
+	return (1);
 #endif /* __FreeBSD__ */
 }
 
@@ -537,49 +520,24 @@ ipfw_localip6(struct in6_addr *in6)
 static int
 verify_path6(struct in6_addr *src, struct ifnet *ifp, u_int fib)
 {
-	struct route_in6 ro;
-	struct sockaddr_in6 *dst;
-
-	bzero(&ro, sizeof(ro));
-
-	dst = (struct sockaddr_in6 * )&(ro.ro_dst);
-	dst->sin6_family = AF_INET6;
-	dst->sin6_len = sizeof(*dst);
-	dst->sin6_addr = *src;
+	struct nhop6_basic nh6;
 
-	in6_rtalloc_ign(&ro, 0, fib);
-	if (ro.ro_rt == NULL)
-		return 0;
+	if (fib6_lookup_nh_basic(fib, *src, 0, &nh6) != 0)
+		return (0);
 
-	/* 
-	 * if ifp is provided, check for equality with rtentry
-	 * We should use rt->rt_ifa->ifa_ifp, instead of rt->rt_ifp,
-	 * to support the case of sending packets to an address of our own.
-	 * (where the former interface is the first argument of if_simloop()
-	 *  (=ifp), the latter is lo0)
-	 */
-	if (ifp != NULL && ro.ro_rt->rt_ifa->ifa_ifp != ifp) {
-		RTFREE(ro.ro_rt);
-		return 0;
-	}
+	/* If ifp is provided, check for equality with route table. */
+	if (ifp != NULL && ifp != nh6.nh_ifp)
+		return (0);
 
 	/* if no ifp provided, check if rtentry is not default route */
-	if (ifp == NULL &&
-	    IN6_IS_ADDR_UNSPECIFIED(&satosin6(rt_key(ro.ro_rt))->sin6_addr)) {
-		RTFREE(ro.ro_rt);
-		return 0;
-	}
+	if (ifp == NULL && (nh6.nh_flags & NHOP_DEFAULT) != 0)
+		return (0);
 
 	/* or if this is a blackhole/reject route */
-	if (ifp == NULL && ro.ro_rt->rt_flags & (RTF_REJECT|RTF_BLACKHOLE)) {
-		RTFREE(ro.ro_rt);
-		return 0;
-	}
-
-	/* found valid route */
-	RTFREE(ro.ro_rt);
-	return 1;
+	if (ifp == NULL && (nh6.nh_flags & (NHOP_REJECT|NHOP_BLACKHOLE)) != 0)
+		return (0);
 
+	return (1);
 }
 
 static int

Modified: projects/routing/sys/netpfil/pf/pf.c
==============================================================================
--- projects/routing/sys/netpfil/pf/pf.c	Sun Aug 23 18:04:37 2015	(r287043)
+++ projects/routing/sys/netpfil/pf/pf.c	Sun Aug 23 18:12:11 2015	(r287044)
@@ -96,6 +96,8 @@ __FBSDID("$FreeBSD$");
 #include <netinet6/in6_pcb.h>
 #endif /* INET6 */
 
+#include <net/rt_nhops.h>
+
 #include <machine/in_cksum.h>
 #include <security/mac/mac_framework.h>
 
@@ -2934,15 +2936,7 @@ pf_get_mss(struct mbuf *m, int off, u_in
 static u_int16_t
 pf_calc_mss(struct pf_addr *addr, sa_family_t af, int rtableid, u_int16_t offer)
 {
-#ifdef INET
-	struct sockaddr_in	*dst;
-	struct route		 ro;
-#endif /* INET */
-#ifdef INET6
-	struct sockaddr_in6	*dst6;
-	struct route_in6	 ro6;
-#endif /* INET6 */
-	struct rtentry		*rt = NULL;
+	struct nhop64_basic	 nh;
 	int			 hlen = 0;
 	u_int16_t		 mss = V_tcp_mssdflt;
 
@@ -2950,34 +2944,19 @@ pf_calc_mss(struct pf_addr *addr, sa_fam
 #ifdef INET
 	case AF_INET:
 		hlen = sizeof(struct ip);
-		bzero(&ro, sizeof(ro));
-		dst = (struct sockaddr_in *)&ro.ro_dst;
-		dst->sin_family = AF_INET;
-		dst->sin_len = sizeof(*dst);
-		dst->sin_addr = addr->v4;
-		in_rtalloc_ign(&ro, 0, rtableid);
-		rt = ro.ro_rt;
+		if (fib4_lookup_nh_basic(rtableid, addr->v4, 0, &nh.u.nh4) == 0)
+			mss = nh.u.nh4.nh_mtu - hlen - sizeof(struct tcphdr);
 		break;
 #endif /* INET */
 #ifdef INET6
 	case AF_INET6:
 		hlen = sizeof(struct ip6_hdr);
-		bzero(&ro6, sizeof(ro6));
-		dst6 = (struct sockaddr_in6 *)&ro6.ro_dst;
-		dst6->sin6_family = AF_INET6;
-		dst6->sin6_len = sizeof(*dst6);
-		dst6->sin6_addr = addr->v6;
-		in6_rtalloc_ign(&ro6, 0, rtableid);
-		rt = ro6.ro_rt;
+		if (fib6_lookup_nh_basic(rtableid, addr->v6, 0, &nh.u.nh6) == 0)
+			mss = nh.u.nh6.nh_mtu - hlen - sizeof(struct tcphdr);
 		break;
 #endif /* INET6 */
 	}
 
-	if (rt && rt->rt_ifp) {
-		mss = rt->rt_ifp->if_mtu - hlen - sizeof(struct tcphdr);
-		mss = max(V_tcp_mssdflt, mss);
-		RTFREE(rt);
-	}
 	mss = min(mss, offer);
 	mss = max(mss, 64);		/* sanity - at least max opt space */
 	return (mss);
@@ -5148,37 +5127,14 @@ int
 pf_routable(struct pf_addr *addr, sa_family_t af, struct pfi_kif *kif,
     int rtableid)
 {
-#ifdef RADIX_MPATH
-	struct radix_node_head	*rnh;
-#endif
-	struct sockaddr_in	*dst;
-	int			 ret = 1;
-	int			 check_mpath;
-#ifdef INET6
-	struct sockaddr_in6	*dst6;
-	struct route_in6	 ro;
-#else
-	struct route		 ro;
-#endif
-	struct radix_node	*rn;
-	struct rtentry		*rt;
-	struct ifnet		*ifp;
-
-	check_mpath = 0;
-#ifdef RADIX_MPATH
-	/* XXX: stick to table 0 for now */
-	rnh = rt_tables_get_rnh(0, af);
-	if (rnh != NULL && rn_mpath_capable(rnh))
-		check_mpath = 1;
-#endif
-	bzero(&ro, sizeof(ro));
+	struct nhop64_basic	nh;
+
+	/* Skip checks for ipsec interfaces */
+	if (kif != NULL && kif->pfik_ifp->if_type == IFT_ENC)
+		return (0);
+
+	bzero(&nh, sizeof(nh));
 	switch (af) {
-	case AF_INET:
-		dst = satosin(&ro.ro_dst);
-		dst->sin_family = AF_INET;
-		dst->sin_len = sizeof(*dst);
-		dst->sin_addr = addr->v4;
-		break;
 #ifdef INET6
 	case AF_INET6:
 		/*
@@ -5186,66 +5142,33 @@ pf_routable(struct pf_addr *addr, sa_fam
 		 * as they would always match anyway.
 		 */
 		if (IN6_IS_SCOPE_EMBED(&addr->v6))
-			goto out;
-		dst6 = (struct sockaddr_in6 *)&ro.ro_dst;
-		dst6->sin6_family = AF_INET6;
-		dst6->sin6_len = sizeof(*dst6);
-		dst6->sin6_addr = addr->v6;
-		break;
-#endif /* INET6 */
-	default:
-		return (0);
-	}
-
-	/* Skip checks for ipsec interfaces */
-	if (kif != NULL && kif->pfik_ifp->if_type == IFT_ENC)
-		goto out;
-
-	switch (af) {
-#ifdef INET6
-	case AF_INET6:
-		in6_rtalloc_ign(&ro, 0, rtableid);
+			return (1);
+		if (fib6_lookup_nh_basic(rtableid, addr->v6, 0, &nh.u.nh6) != 0)
+			return (0);
 		break;
 #endif
 #ifdef INET
 	case AF_INET:
-		in_rtalloc_ign((struct route *)&ro, 0, rtableid);
+		if (fib4_lookup_nh_basic(rtableid, addr->v4, 0, &nh.u.nh4) != 0)
+			return (0);
 		break;
 #endif
 	default:
-		rtalloc_ign((struct route *)&ro, 0);	/* No/default FIB. */
-		break;
+		return (0);
 	}
 
-	if (ro.ro_rt != NULL) {
-		/* No interface given, this is a no-route check */
-		if (kif == NULL)
-			goto out;
+	/* No interface given, this is a no-route check */
+	if (kif == NULL)
+		return (1);
 
-		if (kif->pfik_ifp == NULL) {
-			ret = 0;
-			goto out;
-		}
+	if (kif->pfik_ifp == NULL)
+		return (0);
 
-		/* Perform uRPF check if passed input interface */
-		ret = 0;
-		rn = (struct radix_node *)ro.ro_rt;
-		do {
-			rt = (struct rtentry *)rn;
-			ifp = rt->rt_ifp;
+	/* Perform uRPF check if passed input interface */
+	if (kif->pfik_ifp == nh.u.nh4.nh_ifp)
+		return (1);
 
-			if (kif->pfik_ifp == ifp)
-				ret = 1;
-#ifdef RADIX_MPATH
-			rn = rn_mpath_next(rn);
-#endif
-		} while (check_mpath == 1 && rn != NULL && ret == 0);
-	} else
-		ret = 0;
-out:
-	if (ro.ro_rt != NULL)
-		RTFREE(ro.ro_rt);
-	return (ret);
+	return (0);
 }
 
 #ifdef INET



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201508231812.t7NICCSE041966>