From owner-svn-src-projects@FreeBSD.ORG Sun Oct 12 11:22:27 2014 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 60455411; Sun, 12 Oct 2014 11:22:27 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 4AE43A3C; Sun, 12 Oct 2014 11:22:27 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id s9CBMRGt092462; Sun, 12 Oct 2014 11:22:27 GMT (envelope-from melifaro@FreeBSD.org) Received: (from melifaro@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id s9CBMQ4J092457; Sun, 12 Oct 2014 11:22:26 GMT (envelope-from melifaro@FreeBSD.org) Message-Id: <201410121122.s9CBMQ4J092457@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: melifaro set sender to melifaro@FreeBSD.org using -f From: "Alexander V. Chernikov" Date: Sun, 12 Oct 2014 11:22:26 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r272982 - in projects/routing/sys: conf net netpfil/ipfw netpfil/pf X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 12 Oct 2014 11:22:27 -0000 Author: melifaro Date: Sun Oct 12 11:22:25 2014 New Revision: 272982 URL: https://svnweb.freebsd.org/changeset/base/272982 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 Oct 12 10:39:59 2014 (r272981) +++ projects/routing/sys/conf/files Sun Oct 12 11:22:25 2014 (r272982) @@ -3254,6 +3254,7 @@ net/radix_mpath.c standard net/raw_cb.c standard net/raw_usrreq.c standard net/route.c standard +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 Oct 12 11:22:25 2014 (r272982) @@ -0,0 +1,240 @@ +/*- + * Copyright (c) 2014 + * Alexander V. Chernikov + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#ifdef RADIX_MPATH +#include +#endif + +#include +#include +#include + +#include + +#include + +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 Oct 12 11:22:25 2014 (r272982) @@ -0,0 +1,178 @@ +/*- + * Copyright (c) 2014 + * Alexander V. Chernikov + * + * 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 Oct 12 10:39:59 2014 (r272981) +++ projects/routing/sys/netpfil/ipfw/ip_fw2.c Sun Oct 12 11:22:25 2014 (r272982) @@ -89,6 +89,7 @@ __FBSDID("$FreeBSD$"); #include #include #endif +#include #include @@ -434,19 +435,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. @@ -455,27 +447,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__ */ } @@ -530,49 +513,24 @@ search_ip6_addr_net (struct in6_addr * i 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 Oct 12 10:39:59 2014 (r272981) +++ projects/routing/sys/netpfil/pf/pf.c Sun Oct 12 11:22:25 2014 (r272982) @@ -96,6 +96,8 @@ __FBSDID("$FreeBSD$"); #include #endif /* INET6 */ +#include + #include #include @@ -2906,15 +2908,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; @@ -2922,34 +2916,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); @@ -5105,37 +5084,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: /* @@ -5143,66 +5099,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