svn commit: r272982 - in projects/routing/sys: conf net netpfil/ipfw netpfil/pf
Alexander V. Chernikov
melifaro at FreeBSD.org
Sun Oct 12 11:22:27 UTC 2014
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 <melifaro at 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 Oct 12 11:22:25 2014 (r272982)
@@ -0,0 +1,178 @@
+/*-
+ * Copyright (c) 2014
+ * Alexander V. Chernikov <melifaro at 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 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 <netinet6/scope6_var.h>
#include <netinet6/ip6_var.h>
#endif
+#include <net/rt_nhops.h>
#include <netpfil/ipfw/ip_fw_private.h>
@@ -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 <netinet6/in6_pcb.h>
#endif /* INET6 */
+#include <net/rt_nhops.h>
+
#include <machine/in_cksum.h>
#include <security/mac/mac_framework.h>
@@ -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
More information about the svn-src-projects
mailing list