tech-net archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
"route" extension for npf
Attached are a few patches that add a "route-to"-like procedure to npf.
(Currently only implemented for IPv6.)
Jonathan Kollasch
Index: sys/net/npf/npf.h
===================================================================
RCS file: /cvsroot/src/sys/net/npf/npf.h,v
retrieving revision 1.38
diff -d -u -a -p -r1.38 npf.h
--- sys/net/npf/npf.h 14 Mar 2014 11:29:44 -0000 1.38
+++ sys/net/npf/npf.h 19 May 2014 18:02:38 -0000
@@ -188,7 +188,7 @@ typedef struct {
void * ctx;
int (*ctor)(npf_rproc_t *, prop_dictionary_t);
void (*dtor)(npf_rproc_t *, void *);
- void (*proc)(npf_cache_t *, nbuf_t *, void *, int *);
+ bool (*proc)(npf_cache_t *, nbuf_t *, void *, int *);
} npf_ext_ops_t;
void * npf_ext_register(const char *, const npf_ext_ops_t *);
Index: sys/net/npf/npf_ext_log.c
===================================================================
RCS file: /cvsroot/src/sys/net/npf/npf_ext_log.c,v
retrieving revision 1.6
diff -d -u -a -p -r1.6 npf_ext_log.c
--- sys/net/npf/npf_ext_log.c 11 Mar 2013 17:03:55 -0000 1.6
+++ sys/net/npf/npf_ext_log.c 19 May 2014 18:02:38 -0000
@@ -78,7 +78,7 @@ npf_log_dtor(npf_rproc_t *rp, void *meta
kmem_free(meta, sizeof(npf_ext_log_t));
}
-static void
+static bool
npf_log(npf_cache_t *npc, nbuf_t *nbuf, void *meta, int *decision)
{
struct mbuf *m = nbuf_head_mbuf(nbuf);
@@ -102,7 +102,7 @@ npf_log(npf_cache_t *npc, nbuf_t *nbuf,
if (ifp == NULL) {
/* No interface. */
KERNEL_UNLOCK_ONE(NULL);
- return;
+ return true;
}
/* Pass through BPF. */
@@ -110,6 +110,8 @@ npf_log(npf_cache_t *npc, nbuf_t *nbuf,
ifp->if_obytes += m->m_pkthdr.len;
bpf_mtap_af(ifp, family, m);
KERNEL_UNLOCK_ONE(NULL);
+
+ return true;
}
/*
Index: sys/net/npf/npf_ext_normalize.c
===================================================================
RCS file: /cvsroot/src/sys/net/npf/npf_ext_normalize.c,v
retrieving revision 1.1
diff -d -u -a -p -r1.1 npf_ext_normalize.c
--- sys/net/npf/npf_ext_normalize.c 12 Mar 2013 20:47:48 -0000 1.1
+++ sys/net/npf/npf_ext_normalize.c 19 May 2014 18:02:39 -0000
@@ -140,7 +140,7 @@ npf_normalize_ip4(npf_cache_t *npc, npf_
/*
* npf_normalize: the main routine to normalize IPv4 and/or TCP headers.
*/
-static void
+static bool
npf_normalize(npf_cache_t *npc, nbuf_t *nbuf, void *params, int *decision)
{
npf_normalize_t *np = params;
@@ -150,7 +150,7 @@ npf_normalize(npf_cache_t *npc, nbuf_t *
/* Skip, if already blocking. */
if (*decision == NPF_DECISION_BLOCK) {
- return;
+ return true;
}
/* Normalise IPv4. Nothing to do for IPv6. */
@@ -165,15 +165,15 @@ npf_normalize(npf_cache_t *npc, nbuf_t *
if (maxmss == 0 || !npf_iscached(npc, NPC_TCP) ||
(th->th_flags & TH_SYN) == 0) {
/* Not required; done. */
- return;
+ return true;
}
mss = 0;
if (!npf_fetch_tcpopts(npc, nbuf, &mss, &wscale)) {
- return;
+ return true;
}
if (ntohs(mss) <= maxmss) {
/* Nothing else to do. */
- return;
+ return true;
}
maxmss = htons(maxmss);
@@ -182,6 +182,8 @@ npf_normalize(npf_cache_t *npc, nbuf_t *
cksum = npf_fixup16_cksum(th->th_sum, mss, maxmss);
th->th_sum = cksum;
}
+
+ return true;
}
static int
Index: sys/net/npf/npf_ext_rndblock.c
===================================================================
RCS file: /cvsroot/src/sys/net/npf/npf_ext_rndblock.c,v
retrieving revision 1.3
diff -d -u -a -p -r1.3 npf_ext_rndblock.c
--- sys/net/npf/npf_ext_rndblock.c 11 Mar 2013 17:03:55 -0000 1.3
+++ sys/net/npf/npf_ext_rndblock.c 19 May 2014 18:02:39 -0000
@@ -96,7 +96,7 @@ npf_ext_rndblock_dtor(npf_rproc_t *rp, v
/*
* npf_ext_rndblock: main routine implementing the extension functionality.
*/
-static void
+static bool
npf_ext_rndblock(npf_cache_t *npc, nbuf_t *nbuf, void *meta, int *decision)
{
npf_ext_rndblock_t *rndblock = meta;
@@ -104,7 +104,7 @@ npf_ext_rndblock(npf_cache_t *npc, nbuf_
/* Skip, if already blocking. */
if (*decision == NPF_DECISION_BLOCK) {
- return;
+ return true;
}
/*
@@ -129,6 +129,8 @@ npf_ext_rndblock(npf_cache_t *npc, nbuf_
*decision = NPF_DECISION_BLOCK;
}
}
+
+ return true;
}
/*
Index: sys/net/npf/npf_handler.c
===================================================================
RCS file: /cvsroot/src/sys/net/npf/npf_handler.c,v
retrieving revision 1.29
diff -d -u -a -p -r1.29 npf_handler.c
--- sys/net/npf/npf_handler.c 14 Mar 2014 11:29:44 -0000 1.29
+++ sys/net/npf/npf_handler.c 19 May 2014 18:02:39 -0000
@@ -252,8 +252,13 @@ block:
* Execute the rule procedure, if any is associated.
* It may reverse the decision from pass to block.
*/
- if (rp) {
- npf_rproc_run(&npc, &nbuf, rp, &decision);
+ if (rp && !npf_rproc_run(&npc, &nbuf, rp, &decision)) {
+ if (se) {
+ npf_session_release(se);
+ }
+ npf_rproc_release(rp);
+ *mp = NULL;
+ return 0;
}
out:
/*
Index: sys/net/npf/npf_impl.h
===================================================================
RCS file: /cvsroot/src/sys/net/npf/npf_impl.h,v
retrieving revision 1.50
diff -d -u -a -p -r1.50 npf_impl.h
--- sys/net/npf/npf_impl.h 14 Mar 2014 11:29:44 -0000 1.50
+++ sys/net/npf/npf_impl.h 19 May 2014 18:02:39 -0000
@@ -298,7 +298,7 @@ void npf_rprocset_insert(npf_rprocset_t
npf_rproc_t * npf_rproc_create(prop_dictionary_t);
void npf_rproc_acquire(npf_rproc_t *);
void npf_rproc_release(npf_rproc_t *);
-void npf_rproc_run(npf_cache_t *, nbuf_t *, npf_rproc_t *, int *);
+bool npf_rproc_run(npf_cache_t *, nbuf_t *, npf_rproc_t *, int *);
/* Session handling interface. */
void npf_session_sysinit(void);
Index: sys/net/npf/npf_rproc.c
===================================================================
RCS file: /cvsroot/src/sys/net/npf/npf_rproc.c,v
retrieving revision 1.9
diff -d -u -a -p -r1.9 npf_rproc.c
--- sys/net/npf/npf_rproc.c 11 Mar 2013 01:56:37 -0000 1.9
+++ sys/net/npf/npf_rproc.c 19 May 2014 18:02:39 -0000
@@ -330,7 +330,7 @@ npf_rproc_assign(npf_rproc_t *rp, void *
*
* => Reference on the rule procedure must be held.
*/
-void
+bool
npf_rproc_run(npf_cache_t *npc, nbuf_t *nbuf, npf_rproc_t *rp, int *decision)
{
const unsigned extcount = rp->rp_ext_count;
@@ -343,10 +343,14 @@ npf_rproc_run(npf_cache_t *npc, nbuf_t *
const npf_ext_ops_t *extops = ext->ext_ops;
KASSERT(ext->ext_refcnt > 0);
- extops->proc(npc, nbuf, rp->rp_ext_meta[i], decision);
+ if (!extops->proc(npc, nbuf, rp->rp_ext_meta[i], decision)) {
+ return false;
+ }
if (nbuf_flag_p(nbuf, NBUF_DATAREF_RESET)) {
npf_recache(npc, nbuf);
}
}
+
+ return true;
}
Index: lib/libnpf/npf.c
===================================================================
RCS file: /cvsroot/src/lib/libnpf/npf.c,v
retrieving revision 1.28
diff -d -u -a -p -r1.28 npf.c
--- lib/libnpf/npf.c 13 Feb 2014 03:34:41 -0000 1.28
+++ lib/libnpf/npf.c 19 May 2014 18:04:25 -0000
@@ -432,6 +432,13 @@ npf_ext_param_bool(nl_ext_t *ext, const
prop_dictionary_set_bool(extdict, key, val);
}
+void
+npf_ext_param_string(nl_ext_t *ext, const char *key, const char *val)
+{
+ prop_dictionary_t extdict = ext->nxt_dict;
+ prop_dictionary_set_cstring(extdict, key, val);
+}
+
/*
* RULE INTERFACE.
*/
Index: lib/libnpf/npf.h
===================================================================
RCS file: /cvsroot/src/lib/libnpf/npf.h,v
retrieving revision 1.25
diff -d -u -a -p -r1.25 npf.h
--- lib/libnpf/npf.h 13 Feb 2014 03:34:41 -0000 1.25
+++ lib/libnpf/npf.h 19 May 2014 18:04:25 -0000
@@ -87,6 +87,7 @@ int npf_ruleset_flush(int, const char *
nl_ext_t * npf_ext_construct(const char *name);
void npf_ext_param_u32(nl_ext_t *, const char *, uint32_t);
void npf_ext_param_bool(nl_ext_t *, const char *, bool);
+void npf_ext_param_string(nl_ext_t *, const char *, const char *);
nl_rule_t * npf_rule_create(const char *, uint32_t, const char *);
int npf_rule_setcode(nl_rule_t *, int, const void *, size_t);
Index: sys/modules/Makefile
===================================================================
RCS file: /cvsroot/src/sys/modules/Makefile,v
retrieving revision 1.136
diff -d -u -a -p -r1.136 Makefile
--- sys/modules/Makefile 18 May 2014 11:46:23 -0000 1.136
+++ sys/modules/Makefile 19 May 2014 18:03:57 -0000
@@ -66,6 +66,7 @@ SUBDIR+= npf_alg_icmp
SUBDIR+= npf_ext_log
SUBDIR+= npf_ext_normalize
SUBDIR+= npf_ext_rndblock
+SUBDIR+= npf_ext_route
SUBDIR+= ntfs
SUBDIR+= null
SUBDIR+= onewire
Index: sys/modules/npf_ext_route/Makefile
===================================================================
RCS file: sys/modules/npf_ext_route/Makefile
diff -N sys/modules/npf_ext_route/Makefile
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ sys/modules/npf_ext_route/Makefile 19 May 2014 18:03:57 -0000
@@ -0,0 +1,11 @@
+# $NetBSD$
+
+.include "../Makefile.inc"
+
+.PATH: ${S}/net/npf
+
+KMOD= npf_ext_route
+
+SRCS= npf_ext_route.c
+
+.include <bsd.kmodule.mk>
Index: sys/net/npf/files.npf
===================================================================
RCS file: /cvsroot/src/sys/net/npf/files.npf,v
retrieving revision 1.16
diff -d -u -a -p -r1.16 files.npf
--- sys/net/npf/files.npf 8 Nov 2013 00:38:26 -0000 1.16
+++ sys/net/npf/files.npf 19 May 2014 18:03:57 -0000
@@ -34,6 +34,7 @@ file net/npf/npf_worker.c npf
file net/npf/npf_ext_log.c npf
file net/npf/npf_ext_normalize.c npf
file net/npf/npf_ext_rndblock.c npf
+file net/npf/npf_ext_route.c npf
# ALGs
file net/npf/npf_alg_icmp.c npf
Index: sys/net/npf/npf_ext_route.c
===================================================================
RCS file: sys/net/npf/npf_ext_route.c
diff -N sys/net/npf/npf_ext_route.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ sys/net/npf/npf_ext_route.c 19 May 2014 18:03:57 -0000
@@ -0,0 +1,186 @@
+/* $NetBSD$ */
+
+/*-
+ * Copyright (c) 2013 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Mindaugas Rasiukevicius.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
+ */
+
+/*
+ * NPF route extension.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD$");
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/module.h>
+
+#include <sys/conf.h>
+#include <sys/kmem.h>
+#include <sys/mbuf.h>
+#include <sys/mutex.h>
+#include <sys/queue.h>
+
+#include <net/if.h>
+#include <net/if_types.h>
+#include <net/bpf.h>
+#include <net/route.h>
+#include <netinet/in.h>
+#include <netinet/ip.h>
+#include <netinet/ip6.h>
+#include <netinet6/in6_var.h>
+#include <netinet6/nd6.h>
+
+#include "npf_impl.h"
+
+NPF_EXT_MODULE(npf_ext_route, "");
+
+#define NPFEXT_ROUTE_VER 1
+
+static void * npf_ext_route_id;
+
+typedef struct {
+ char ifname[IFNAMSIZ];
+} npf_ext_route_t;
+
+static int
+npf_route_ctor(npf_rproc_t *rp, prop_dictionary_t params)
+{
+ npf_ext_route_t *meta;
+ const char *ifname;
+
+ meta = kmem_zalloc(sizeof(npf_ext_route_t), KM_SLEEP);
+ prop_dictionary_get_cstring_nocopy(params, "route-interface", &ifname);
+ /* XXX use something like npf_ifmap */
+ strlcpy(meta->ifname, ifname, IFNAMSIZ);
+ npf_rproc_assign(rp, meta);
+ return 0;
+}
+
+static void
+npf_route_dtor(npf_rproc_t *rp, void *meta)
+{
+ kmem_free(meta, sizeof(npf_ext_route_t));
+}
+
+static bool
+npf_route(npf_cache_t *npc, nbuf_t *nbuf, void *meta, int *decision)
+{
+ struct mbuf *m = nbuf_head_mbuf(nbuf);
+ const npf_ext_route_t *route = meta;
+ struct ifnet *ifp;
+ union {
+ struct sockaddr_in v4;
+ struct sockaddr_in6 v6;
+ } dst;
+ int error = 0;
+
+ /* Skip, if already blocking. */
+ if (*decision == NPF_DECISION_BLOCK) {
+ return true;
+ }
+
+ KERNEL_LOCK(1, NULL);
+ ifp = ifunit(route->ifname);
+ if (ifp == NULL) {
+ /* XXX: oops */
+ goto bad;
+ }
+
+ if (npf_iscached(npc, NPC_IP6)) {
+ struct ip6_hdr *ip6 = npc->npc_ip.v6;
+ sockaddr_in6_init(&dst.v6, &ip6->ip6_dst, 0, 0, 0);
+
+ if (IN6_IS_SCOPE_EMBEDDABLE(&dst.v6.sin6_addr))
+ dst.v6.sin6_addr.s6_addr16[1] = htons(ifp->if_index);
+
+ if (m->m_pkthdr.len <= ifp->if_mtu) {
+ error = nd6_output(ifp, ifp, m, &dst.v6, NULL);
+ } else {
+ in6_ifstat_inc(ifp, ifs6_in_toobig);
+ icmp6_error(m, ICMP6_PACKET_TOO_BIG, 0, ifp->if_mtu);
+ }
+ } else if (npf_iscached(npc, NPC_IP4)) {
+ struct ip *ip = npc->npc_ip.v4;
+ sockaddr_in_init(&dst.v4, &ip->ip_dst, 0);
+
+ if (ntohs(ip->ip_len) <= ifp->if_mtu) {
+ }
+ goto bad;
+ }
+
+ if (error) {
+ /* XXX: statistics */
+ goto done;
+ }
+
+done:
+ KERNEL_UNLOCK_ONE(NULL);
+ return false;
+
+bad:
+ KERNEL_UNLOCK_ONE(NULL);
+ return true;
+}
+
+static int
+npf_ext_route_modcmd(modcmd_t cmd, void *arg)
+{
+ static const npf_ext_ops_t npf_route_ops = {
+ .version = NPFEXT_ROUTE_VER,
+ .ctx = NULL,
+ .ctor = npf_route_ctor,
+ .dtor = npf_route_dtor,
+ .proc = npf_route
+ };
+ int error;
+
+ switch (cmd) {
+ case MODULE_CMD_INIT:
+ npf_ext_route_id = npf_ext_register("route", &npf_route_ops);
+ if (!npf_ext_route_id) {
+ return EEXIST;
+ }
+ break;
+
+ case MODULE_CMD_FINI:
+ error = npf_ext_unregister(npf_ext_route_id);
+ if (error) {
+ return error;
+ }
+ break;
+
+ case MODULE_CMD_AUTOUNLOAD:
+ /* Allow auto-unload only if NPF permits it. */
+ return npf_autounload_p() ? 0 : EBUSY;
+
+ default:
+ return ENOTTY;
+ }
+ return 0;
+}
Index: lib/npf/Makefile
===================================================================
RCS file: /cvsroot/src/lib/npf/Makefile,v
retrieving revision 1.3
diff -d -u -a -p -r1.3 Makefile
--- lib/npf/Makefile 10 Mar 2013 21:41:05 -0000 1.3
+++ lib/npf/Makefile 19 May 2014 18:03:57 -0000
@@ -4,7 +4,7 @@
.if ${MKPIC} != "no"
-SUBDIR= ext_log ext_normalize ext_rndblock
+SUBDIR= ext_log ext_normalize ext_rndblock ext_route
.endif
Index: lib/npf/ext_route/Makefile
===================================================================
RCS file: lib/npf/ext_route/Makefile
diff -N lib/npf/ext_route/Makefile
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ lib/npf/ext_route/Makefile 19 May 2014 18:03:57 -0000
@@ -0,0 +1,4 @@
+# $NetBSD$
+
+MOD= ext_route
+.include "${.CURDIR}/../mod.mk"
Index: lib/npf/ext_route/npfext_route.c
===================================================================
RCS file: lib/npf/ext_route/npfext_route.c
diff -N lib/npf/ext_route/npfext_route.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ lib/npf/ext_route/npfext_route.c 19 May 2014 18:03:57 -0000
@@ -0,0 +1,74 @@
+/* $NetBSD$ */
+
+/*-
+ * Copyright (c) 2013 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Mindaugas Rasiukevicius.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
+ */
+
+#include <sys/cdefs.h>
+__RCSID("$NetBSD$");
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <net/if.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+#include <errno.h>
+#include <err.h>
+#include <unistd.h>
+
+#include <npf.h>
+
+int npfext_route_init(void);
+nl_ext_t * npfext_route_construct(const char *);
+int npfext_route_param(nl_ext_t *, const char *, const char *);
+
+int
+npfext_route_init(void)
+{
+ /* Nothing to initialise. */
+ return 0;
+}
+
+nl_ext_t *
+npfext_route_construct(const char *name)
+{
+ assert(strcmp(name, "route") == 0);
+ return npf_ext_construct(name);
+}
+
+int
+npfext_route_param(nl_ext_t *ext, const char *param, const char *val __unused)
+{
+
+ assert(param != NULL);
+ npf_ext_param_string(ext, "route-interface", param);
+ return 0;
+}
Index: lib/npf/ext_route/shlib_version
===================================================================
RCS file: lib/npf/ext_route/shlib_version
diff -N lib/npf/ext_route/shlib_version
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ lib/npf/ext_route/shlib_version 19 May 2014 18:03:57 -0000
@@ -0,0 +1,4 @@
+# $NetBSD$
+
+major=0
+minor=0
Home |
Main Index |
Thread Index |
Old Index