aboutsummaryrefslogtreecommitdiff
path: root/sys/netpfil
diff options
context:
space:
mode:
authorAlexander V. Chernikov <melifaro@FreeBSD.org>2015-12-08 10:50:03 +0000
committerAlexander V. Chernikov <melifaro@FreeBSD.org>2015-12-08 10:50:03 +0000
commit65ff3638df7d7d993e284971e2c78b3ca9613c8d (patch)
tree6ca921174b94c73570e52b7776a5a84068f7a02f /sys/netpfil
parentb2a78a9d85e5c7c0ede74119a2515adda06be635 (diff)
downloadsrc-65ff3638df7d7d993e284971e2c78b3ca9613c8d.tar.gz
src-65ff3638df7d7d993e284971e2c78b3ca9613c8d.zip
Merge helper fib* functions used for basic lookups.
Vast majority of rtalloc(9) users require only basic info from route table (e.g. "does the rtentry interface match with the interface I have?". "what is the MTU?", "Give me the IPv4 source address to use", etc..). Instead of hand-rolling lookups, checking if rtentry is up, valid, dealing with IPv6 mtu, finding "address" ifp (almost never done right), provide easy-to-use API hiding all the complexity and returning the needed info into small on-stack structure. This change also helps hiding route subsystem internals (locking, direct rtentry accesses). Additionaly, using this API improves lookup performance since rtentry is not locked. (This is safe, since all the rtentry changes happens under both radix WLOCK and rtentry WLOCK). Sponsored by: Yandex LLC
Notes
Notes: svn path=/head/; revision=291993
Diffstat (limited to 'sys/netpfil')
-rw-r--r--sys/netpfil/ipfw/ip_fw2.c82
1 files changed, 23 insertions, 59 deletions
diff --git a/sys/netpfil/ipfw/ip_fw2.c b/sys/netpfil/ipfw/ip_fw2.c
index 73a27dfe3e2b..3a17c3c5ac2e 100644
--- a/sys/netpfil/ipfw/ip_fw2.c
+++ b/sys/netpfil/ipfw/ip_fw2.c
@@ -84,7 +84,9 @@ __FBSDID("$FreeBSD$");
#include <netinet/ip6.h>
#include <netinet/icmp6.h>
+#include <netinet/in_fib.h>
#ifdef INET6
+#include <netinet6/in6_fib.h>
#include <netinet6/in6_pcb.h>
#include <netinet6/scope6_var.h>
#include <netinet6/ip6_var.h>
@@ -437,19 +439,10 @@ verify_path(struct in_addr src, struct ifnet *ifp, u_int fib)
#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, NHR_IFAIF, 0, &nh4) != 0)
+ return (0);
/*
* If ifp is provided, check for equality with rtentry.
@@ -458,26 +451,18 @@ verify_path(struct in_addr src, struct ifnet *ifp, u_int fib)
* 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 & NHF_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 & (NHF_REJECT|NHF_BLACKHOLE)) != 0)
+ return (0);
/* found valid route */
- RTFREE(ro.ro_rt);
return 1;
#endif /* __FreeBSD__ */
}
@@ -537,49 +522,28 @@ 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));
+ struct nhop6_basic nh6;
- dst = (struct sockaddr_in6 * )&(ro.ro_dst);
- dst->sin6_family = AF_INET6;
- dst->sin6_len = sizeof(*dst);
- dst->sin6_addr = *src;
+ if (IN6_IS_SCOPE_LINKLOCAL(src))
+ return (1);
- in6_rtalloc_ign(&ro, 0, fib);
- if (ro.ro_rt == NULL)
- return 0;
+ if (fib6_lookup_nh_basic(fib, src, 0, NHR_IFAIF, 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 & NHF_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 && (nh6.nh_flags & (NHF_REJECT|NHF_BLACKHOLE)) != 0)
+ return (0);
/* found valid route */
- RTFREE(ro.ro_rt);
return 1;
-
}
static int