Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src NPF: add support for static (stateless) NAT.
details: https://anonhg.NetBSD.org/src/rev/0ac8d0b3dc89
branches: trunk
changeset: 326627:0ac8d0b3dc89
user: rmind <rmind%NetBSD.org@localhost>
date: Fri Feb 07 23:45:22 2014 +0000
description:
NPF: add support for static (stateless) NAT.
diffstat:
lib/libnpf/npf.c | 14 ++-
lib/libnpf/npf.h | 3 +-
sys/net/npf/npf.h | 5 +-
sys/net/npf/npf_nat.c | 113 ++++++++++++++----------
usr.sbin/npf/npfctl/npf_build.c | 68 ++++++--------
usr.sbin/npf/npfctl/npf_show.c | 13 +-
usr.sbin/npf/npftest/libnpftest/npf_nat_test.c | 19 +++-
usr.sbin/npf/npftest/libnpftest/npf_test.h | 7 +-
usr.sbin/npf/npftest/npftest.conf | 7 +-
9 files changed, 150 insertions(+), 99 deletions(-)
diffs (truncated from 512 to 300 lines):
diff -r 6e6cf278b27d -r 0ac8d0b3dc89 lib/libnpf/npf.c
--- a/lib/libnpf/npf.c Fri Feb 07 23:18:04 2014 +0000
+++ b/lib/libnpf/npf.c Fri Feb 07 23:45:22 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: npf.c,v 1.26 2014/02/06 02:51:28 rmind Exp $ */
+/* $NetBSD: npf.c,v 1.27 2014/02/07 23:45:22 rmind Exp $ */
/*-
* Copyright (c) 2010-2014 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf.c,v 1.26 2014/02/06 02:51:28 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf.c,v 1.27 2014/02/07 23:45:22 rmind Exp $");
#include <sys/types.h>
#include <netinet/in_systm.h>
@@ -874,6 +874,16 @@
return type;
}
+u_int
+npf_nat_getflags(nl_nat_t *nt)
+{
+ prop_dictionary_t rldict = nt->nrl_dict;
+ unsigned flags = 0;
+
+ prop_dictionary_get_uint32(rldict, "flags", &flags);
+ return flags;
+}
+
void
npf_nat_getmap(nl_nat_t *nt, npf_addr_t *addr, size_t *alen, in_port_t *port)
{
diff -r 6e6cf278b27d -r 0ac8d0b3dc89 lib/libnpf/npf.h
--- a/lib/libnpf/npf.h Fri Feb 07 23:18:04 2014 +0000
+++ b/lib/libnpf/npf.h Fri Feb 07 23:45:22 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: npf.h,v 1.23 2014/02/06 02:51:28 rmind Exp $ */
+/* $NetBSD: npf.h,v 1.24 2014/02/07 23:45:22 rmind Exp $ */
/*-
* Copyright (c) 2011-2013 The NetBSD Foundation, Inc.
@@ -136,6 +136,7 @@
nl_nat_t * npf_nat_iterate(nl_config_t *);
int npf_nat_gettype(nl_nat_t *);
+unsigned npf_nat_getflags(nl_nat_t *);
void npf_nat_getmap(nl_nat_t *, npf_addr_t *, size_t *, in_port_t *);
nl_rproc_t * npf_rproc_iterate(nl_config_t *);
diff -r 6e6cf278b27d -r 0ac8d0b3dc89 sys/net/npf/npf.h
--- a/sys/net/npf/npf.h Fri Feb 07 23:18:04 2014 +0000
+++ b/sys/net/npf/npf.h Fri Feb 07 23:45:22 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: npf.h,v 1.35 2014/02/06 02:51:28 rmind Exp $ */
+/* $NetBSD: npf.h,v 1.36 2014/02/07 23:45:22 rmind Exp $ */
/*-
* Copyright (c) 2009-2013 The NetBSD Foundation, Inc.
@@ -87,7 +87,7 @@
#include <netinet/ip_icmp.h>
#include <netinet/icmp6.h>
-#define NPC_IP4 0x01 /* Indicates fetched IPv4 header. */
+#define NPC_IP4 0x01 /* Indicates IPv4 header. */
#define NPC_IP6 0x02 /* Indicates IPv6 header. */
#define NPC_IPFRAG 0x04 /* IPv4/IPv6 fragment. */
#define NPC_LAYER4 0x08 /* Layer 4 has been fetched. */
@@ -235,6 +235,7 @@
#define NPF_NAT_PORTS 0x01
#define NPF_NAT_PORTMAP 0x02
+#define NPF_NAT_STATIC 0x04
/* Table types. */
#define NPF_TABLE_HASH 1
diff -r 6e6cf278b27d -r 0ac8d0b3dc89 sys/net/npf/npf_nat.c
--- a/sys/net/npf/npf_nat.c Fri Feb 07 23:18:04 2014 +0000
+++ b/sys/net/npf/npf_nat.c Fri Feb 07 23:45:22 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: npf_nat.c,v 1.23 2013/12/06 01:33:37 rmind Exp $ */
+/* $NetBSD: npf_nat.c,v 1.24 2014/02/07 23:45:22 rmind Exp $ */
/*-
* Copyright (c) 2010-2013 The NetBSD Foundation, Inc.
@@ -70,7 +70,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_nat.c,v 1.23 2013/12/06 01:33:37 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_nat.c,v 1.24 2014/02/07 23:45:22 rmind Exp $");
#include <sys/param.h>
#include <sys/types.h>
@@ -423,8 +423,8 @@
{
/*
* Outbound NAT rewrites:
- * - Source on "forwards" stream.
- * - Destination on "backwards" stream.
+ * - Source (NPF_SRC) on "forwards" stream.
+ * - Destination (NPF_DST) on "backwards" stream.
* Inbound NAT is other way round.
*/
if (type == NPF_NATOUT) {
@@ -433,7 +433,7 @@
KASSERT(type == NPF_NATIN);
}
CTASSERT(NPF_SRC == 0 && NPF_DST == 1);
- KASSERT(forw == 0 || forw == 1);
+ KASSERT(forw == NPF_SRC || forw == NPF_DST);
return (u_int)forw;
}
@@ -528,14 +528,56 @@
}
/*
- * npf_nat_translate: perform address and/or port translation.
+ * npf_nat_rwr: perform address and/or port translation.
+ */
+static int
+npf_nat_rwr(npf_cache_t *npc, const npf_natpolicy_t *np,
+ const npf_addr_t *addr, const in_addr_t port, bool forw)
+{
+ const unsigned proto = npc->npc_proto;
+ const u_int which = npf_nat_which(np->n_type, forw);
+
+ /*
+ * Rewrite IP and/or TCP/UDP checksums first, since we need the
+ * current (old) address/port for the calculations. Then perform
+ * the address translation i.e. rewrite source or destination.
+ */
+ if (!npf_rwrcksum(npc, which, addr, port)) {
+ return EINVAL;
+ }
+ if (!npf_rwrip(npc, which, addr)) {
+ return EINVAL;
+ }
+ if ((np->n_flags & NPF_NAT_PORTS) == 0) {
+ /* Done. */
+ return 0;
+ }
+
+ switch (proto) {
+ case IPPROTO_TCP:
+ case IPPROTO_UDP:
+ /* Rewrite source/destination port. */
+ if (!npf_rwrport(npc, which, port)) {
+ return EINVAL;
+ }
+ break;
+ case IPPROTO_ICMP:
+ KASSERT(npf_iscached(npc, NPC_ICMP));
+ /* Nothing. */
+ break;
+ default:
+ return ENOTSUP;
+ }
+ return 0;
+}
+
+/*
+ * npf_nat_translate: perform translation given the state data.
*/
int
npf_nat_translate(npf_cache_t *npc, nbuf_t *nbuf, npf_nat_t *nt, bool forw)
{
- const int proto = npc->npc_proto;
const npf_natpolicy_t *np = nt->nt_natpolicy;
- const u_int which = npf_nat_which(np->n_type, forw);
const npf_addr_t *addr;
in_port_t port;
@@ -560,39 +602,8 @@
npf_alg_exec(npc, nbuf, nt, forw);
}
- /*
- * Rewrite IP and/or TCP/UDP checksums first, since we need the
- * current (old) address/port for the calculations. Then perform
- * the address translation i.e. rewrite source or destination.
- */
- if (!npf_rwrcksum(npc, which, addr, port)) {
- return EINVAL;
- }
- if (!npf_rwrip(npc, which, addr)) {
- return EINVAL;
- }
-
- if ((np->n_flags & NPF_NAT_PORTS) == 0) {
- /* Done. */
- return 0;
- }
-
- switch (proto) {
- case IPPROTO_TCP:
- case IPPROTO_UDP:
- /* Rewrite source/destination port. */
- if (!npf_rwrport(npc, which, port)) {
- return EINVAL;
- }
- break;
- case IPPROTO_ICMP:
- KASSERT(npf_iscached(npc, NPC_ICMP));
- /* Nothing. */
- break;
- default:
- return ENOTSUP;
- }
- return 0;
+ /* Finally, perform the translation. */
+ return npf_nat_rwr(npc, np, addr, port, forw);
}
/*
@@ -640,6 +651,16 @@
}
forw = true;
+ /* Static NAT - just perform the translation. */
+ if (np->n_flags & NPF_NAT_STATIC) {
+ if (nbuf_cksum_barrier(nbuf, di)) {
+ npf_recache(npc, nbuf);
+ }
+ error = npf_nat_rwr(npc, np, &np->n_taddr, np->n_tport, forw);
+ atomic_dec_uint(&np->n_refcnt);
+ return error;
+ }
+
/*
* If there is no local session (no "stateful" rule - unusual, but
* possible configuration), establish one before translation. Note
@@ -688,11 +709,11 @@
/* Perform the translation. */
error = npf_nat_translate(npc, nbuf, nt, forw);
out:
- if (error && nse) {
- /* It created for NAT - just expire. */
- npf_session_expire(nse);
- }
- if (nse) {
+ if (__predict_false(nse)) {
+ if (error) {
+ /* It created for NAT - just expire. */
+ npf_session_expire(nse);
+ }
npf_session_release(nse);
}
return error;
diff -r 6e6cf278b27d -r 0ac8d0b3dc89 usr.sbin/npf/npfctl/npf_build.c
--- a/usr.sbin/npf/npfctl/npf_build.c Fri Feb 07 23:18:04 2014 +0000
+++ b/usr.sbin/npf/npfctl/npf_build.c Fri Feb 07 23:45:22 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: npf_build.c,v 1.34 2014/02/06 18:48:09 christos Exp $ */
+/* $NetBSD: npf_build.c,v 1.35 2014/02/07 23:45:22 rmind Exp $ */
/*-
* Copyright (c) 2011-2014 The NetBSD Foundation, Inc.
@@ -34,7 +34,7 @@
*/
#include <sys/cdefs.h>
-__RCSID("$NetBSD: npf_build.c,v 1.34 2014/02/06 18:48:09 christos Exp $");
+__RCSID("$NetBSD: npf_build.c,v 1.35 2014/02/07 23:45:22 rmind Exp $");
#include <sys/types.h>
#include <sys/mman.h>
@@ -535,7 +535,7 @@
*/
static void
npfctl_build_nat(int type, const char *ifname, sa_family_t family,
- const addr_port_t *ap, const filt_opts_t *fopts, bool binat)
+ const addr_port_t *ap, const filt_opts_t *fopts, u_int flags)
{
const opt_proto_t op = { .op_proto = -1, .op_opts = NULL };
fam_addr_mask_t *am;
@@ -551,36 +551,16 @@
yyerror("IPv6 NAT is not supported");
}
- switch (type) {
- case NPF_NATOUT:
- /*
- * Outbound NAT (or source NAT) policy, usually used for the
- * traditional NAPT. If it is a half for bi-directional NAT,
- * then no port translation with mapping.
- */
- nat = npf_nat_create(NPF_NATOUT, !binat ?
- (NPF_NAT_PORTS | NPF_NAT_PORTMAP) : 0,
- ifname, &am->fam_addr, am->fam_family, 0);
- break;
- case NPF_NATIN:
- /*
- * Inbound NAT (or destination NAT). Unless bi-NAT, a port
- * must be specified, since it has to be redirection.
- */
+ if (ap->ap_portrange) {
Home |
Main Index |
Thread Index |
Old Index