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 IPv6-to-IPv6 Network Prefix Translation...
details: https://anonhg.NetBSD.org/src/rev/1fbe6b1acaa1
branches: trunk
changeset: 326687:1fbe6b1acaa1
user: rmind <rmind%NetBSD.org@localhost>
date: Thu Feb 13 03:34:40 2014 +0000
description:
NPF: add support for IPv6-to-IPv6 Network Prefix Translation (NPTv6),
as per RFC 6296. Add a unit test. Also, bump NPF_VERSION.
Thanks to S.P.Zeidler for the help with NPTv6 work!
diffstat:
lib/libnpf/npf.c | 30 ++++++-
lib/libnpf/npf.h | 9 +-
sys/net/npf/npf.h | 8 +-
sys/net/npf/npf_impl.h | 6 +-
sys/net/npf/npf_inet.c | 79 +++++++++++++++++++-
sys/net/npf/npf_nat.c | 64 +++++++++++++--
usr.sbin/npf/npfctl/npf_build.c | 75 +++++++++++++-----
usr.sbin/npf/npfctl/npf_data.c | 52 ++++++++++++-
usr.sbin/npf/npfctl/npf_parse.y | 22 +++-
usr.sbin/npf/npfctl/npf_scan.l | 4 +-
usr.sbin/npf/npfctl/npfctl.h | 6 +-
usr.sbin/npf/npftest/libnpftest/npf_mbuf_subr.c | 9 ++
usr.sbin/npf/npftest/libnpftest/npf_nat_test.c | 97 +++++++++++++++++-------
usr.sbin/npf/npftest/libnpftest/npf_test.h | 12 ++-
usr.sbin/npf/npftest/libnpftest/npf_test_subr.c | 29 ++++++-
usr.sbin/npf/npftest/npftest.c | 4 +-
usr.sbin/npf/npftest/npftest.conf | 10 ++-
usr.sbin/npf/npftest/npftest.h | 4 +-
18 files changed, 420 insertions(+), 100 deletions(-)
diffs (truncated from 1109 to 300 lines):
diff -r e3641265ee84 -r 1fbe6b1acaa1 lib/libnpf/npf.c
--- a/lib/libnpf/npf.c Thu Feb 13 00:42:01 2014 +0000
+++ b/lib/libnpf/npf.c Thu Feb 13 03:34:40 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: npf.c,v 1.27 2014/02/07 23:45:22 rmind Exp $ */
+/* $NetBSD: npf.c,v 1.28 2014/02/13 03:34:41 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.27 2014/02/07 23:45:22 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf.c,v 1.28 2014/02/13 03:34:41 rmind Exp $");
#include <sys/types.h>
#include <netinet/in_systm.h>
@@ -802,7 +802,7 @@
nl_nat_t *
npf_nat_create(int type, u_int flags, const char *ifname,
- npf_addr_t *addr, int af, in_port_t port)
+ int af, npf_addr_t *addr, npf_netmask_t mask, in_port_t port)
{
nl_rule_t *rl;
prop_dictionary_t rldict;
@@ -832,13 +832,14 @@
prop_dictionary_set_int32(rldict, "type", type);
prop_dictionary_set_uint32(rldict, "flags", flags);
- /* Translation IP. */
+ /* Translation IP and mask. */
addrdat = prop_data_create_data(addr, sz);
if (addrdat == NULL) {
npf_rule_destroy(rl);
return NULL;
}
prop_dictionary_set(rldict, "translation-ip", addrdat);
+ prop_dictionary_set_uint32(rldict, "translation-mask", mask);
prop_object_release(addrdat);
/* Translation port (for redirect case). */
@@ -865,6 +866,27 @@
}
int
+npf_nat_setalgo(nl_nat_t *nt, u_int algo)
+{
+ prop_dictionary_t rldict = nt->nrl_dict;
+ prop_dictionary_set_uint32(rldict, "translation-algo", algo);
+ return 0;
+}
+
+int
+npf_nat_setnpt66(nl_nat_t *nt, uint16_t adj)
+{
+ prop_dictionary_t rldict = nt->nrl_dict;
+ int error;
+
+ if ((error = npf_nat_setalgo(nt, NPF_ALGO_NPT66)) != 0) {
+ return error;
+ }
+ prop_dictionary_set_uint16(rldict, "npt66-adjustment", adj);
+ return 0;
+}
+
+int
npf_nat_gettype(nl_nat_t *nt)
{
prop_dictionary_t rldict = nt->nrl_dict;
diff -r e3641265ee84 -r 1fbe6b1acaa1 lib/libnpf/npf.h
--- a/lib/libnpf/npf.h Thu Feb 13 00:42:01 2014 +0000
+++ b/lib/libnpf/npf.h Thu Feb 13 03:34:40 2014 +0000
@@ -1,7 +1,7 @@
-/* $NetBSD: npf.h,v 1.24 2014/02/07 23:45:22 rmind Exp $ */
+/* $NetBSD: npf.h,v 1.25 2014/02/13 03:34:41 rmind Exp $ */
/*-
- * Copyright (c) 2011-2013 The NetBSD Foundation, Inc.
+ * Copyright (c) 2011-2014 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This material is based upon work partially supported by The
@@ -105,7 +105,7 @@
int npf_rproc_insert(nl_config_t *, nl_rproc_t *);
nl_nat_t * npf_nat_create(int, u_int, const char *,
- npf_addr_t *, int, in_port_t);
+ int, npf_addr_t *, npf_netmask_t, in_port_t);
int npf_nat_insert(nl_config_t *, nl_nat_t *, pri_t);
nl_table_t * npf_table_create(const char *, u_int, int);
@@ -139,6 +139,9 @@
unsigned npf_nat_getflags(nl_nat_t *);
void npf_nat_getmap(nl_nat_t *, npf_addr_t *, size_t *, in_port_t *);
+int npf_nat_setalgo(nl_nat_t *, u_int);
+int npf_nat_setnpt66(nl_nat_t *, uint16_t);
+
nl_rproc_t * npf_rproc_iterate(nl_config_t *);
const char * npf_rproc_getname(nl_rproc_t *);
diff -r e3641265ee84 -r 1fbe6b1acaa1 sys/net/npf/npf.h
--- a/sys/net/npf/npf.h Thu Feb 13 00:42:01 2014 +0000
+++ b/sys/net/npf/npf.h Thu Feb 13 03:34:40 2014 +0000
@@ -1,7 +1,7 @@
-/* $NetBSD: npf.h,v 1.36 2014/02/07 23:45:22 rmind Exp $ */
+/* $NetBSD: npf.h,v 1.37 2014/02/13 03:34:40 rmind Exp $ */
/*-
- * Copyright (c) 2009-2013 The NetBSD Foundation, Inc.
+ * Copyright (c) 2009-2014 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This material is based upon work partially supported by The
@@ -45,7 +45,7 @@
#include <netinet/in_systm.h>
#include <netinet/in.h>
-#define NPF_VERSION 12
+#define NPF_VERSION 13
/*
* Public declarations and definitions.
@@ -237,6 +237,8 @@
#define NPF_NAT_PORTMAP 0x02
#define NPF_NAT_STATIC 0x04
+#define NPF_ALGO_NPT66 1
+
/* Table types. */
#define NPF_TABLE_HASH 1
#define NPF_TABLE_TREE 2
diff -r e3641265ee84 -r 1fbe6b1acaa1 sys/net/npf/npf_impl.h
--- a/sys/net/npf/npf_impl.h Thu Feb 13 00:42:01 2014 +0000
+++ b/sys/net/npf/npf_impl.h Thu Feb 13 03:34:40 2014 +0000
@@ -1,7 +1,7 @@
-/* $NetBSD: npf_impl.h,v 1.46 2014/02/06 02:51:28 rmind Exp $ */
+/* $NetBSD: npf_impl.h,v 1.47 2014/02/13 03:34:40 rmind Exp $ */
/*-
- * Copyright (c) 2009-2013 The NetBSD Foundation, Inc.
+ * Copyright (c) 2009-2014 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This material is based upon work partially supported by The
@@ -192,6 +192,8 @@
bool npf_rwrport(const npf_cache_t *, u_int, const in_port_t);
bool npf_rwrcksum(const npf_cache_t *, u_int,
const npf_addr_t *, const in_port_t);
+int npf_npt66_rwr(const npf_cache_t *, u_int, const npf_addr_t *,
+ npf_netmask_t, uint16_t);
uint16_t npf_fixup16_cksum(uint16_t, uint16_t, uint16_t);
uint16_t npf_fixup32_cksum(uint16_t, uint32_t, uint32_t);
diff -r e3641265ee84 -r 1fbe6b1acaa1 sys/net/npf/npf_inet.c
--- a/sys/net/npf/npf_inet.c Thu Feb 13 00:42:01 2014 +0000
+++ b/sys/net/npf/npf_inet.c Thu Feb 13 03:34:40 2014 +0000
@@ -1,7 +1,7 @@
-/* $NetBSD: npf_inet.c,v 1.28 2013/12/06 01:33:37 rmind Exp $ */
+/* $NetBSD: npf_inet.c,v 1.29 2014/02/13 03:34:40 rmind Exp $ */
/*-
- * Copyright (c) 2009-2012 The NetBSD Foundation, Inc.
+ * Copyright (c) 2009-2014 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This material is based upon work partially supported by The
@@ -39,7 +39,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_inet.c,v 1.28 2013/12/06 01:33:37 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_inet.c,v 1.29 2014/02/13 03:34:40 rmind Exp $");
#include <sys/param.h>
#include <sys/types.h>
@@ -616,6 +616,79 @@
return true;
}
+/*
+ * IPv6-to-IPv6 Network Prefix Translation (NPTv6), as per RFC 6296.
+ */
+
+int
+npf_npt66_rwr(const npf_cache_t *npc, u_int which, const npf_addr_t *pref,
+ npf_netmask_t len, uint16_t adj)
+{
+ npf_addr_t *addr = npc->npc_ips[which];
+ unsigned remnant, word, preflen = len >> 4;
+ uint32_t sum;
+
+ KASSERT(which == NPF_SRC || which == NPF_DST);
+
+ if (!npf_iscached(npc, NPC_IP6)) {
+ return EINVAL;
+ }
+ if (len <= 48) {
+ /*
+ * The word to adjust. Cannot translate the 0xffff
+ * subnet if /48 or shorter.
+ */
+ word = 3;
+ if (addr->s6_addr16[word] == 0xffff) {
+ return EINVAL;
+ }
+ } else {
+ /*
+ * Also, all 0s or 1s in the host part are disallowed for
+ * longer than /48 prefixes.
+ */
+ if ((addr->s6_addr32[2] == 0 && addr->s6_addr32[3] == 0) ||
+ (addr->s6_addr32[2] == ~0U && addr->s6_addr32[3] == ~0U))
+ return EINVAL;
+
+ /* Determine the 16-bit word to adjust. */
+ for (word = 4; word < 8; word++)
+ if (addr->s6_addr16[word] != 0xffff)
+ break;
+ }
+
+ /* Rewrite the prefix. */
+ for (unsigned i = 0; i < preflen; i++) {
+ addr->s6_addr16[i] = pref->s6_addr16[i];
+ }
+
+ /*
+ * If prefix length is within a 16-bit word (not dividable by 16),
+ * then prepare a mask, determine the word and adjust it.
+ */
+ if ((remnant = len - (preflen << 4)) != 0) {
+ const uint16_t wordmask = (1U << remnant) - 1;
+ const unsigned i = preflen;
+
+ addr->s6_addr16[i] = (pref->s6_addr16[i] & wordmask) |
+ (addr->s6_addr16[i] & ~wordmask);
+ }
+
+ /*
+ * Performing 1's complement sum/difference.
+ */
+ sum = addr->s6_addr16[word] + adj;
+ while (sum >> 16) {
+ sum = (sum >> 16) + (sum & 0xffff);
+ }
+ if (sum == 0xffff) {
+ /* RFC 1071. */
+ sum = 0x0000;
+ }
+ addr->s6_addr16[word] = sum;
+ return 0;
+}
+
#if defined(DDB) || defined(_NPF_TESTING)
void
diff -r e3641265ee84 -r 1fbe6b1acaa1 sys/net/npf/npf_nat.c
--- a/sys/net/npf/npf_nat.c Thu Feb 13 00:42:01 2014 +0000
+++ b/sys/net/npf/npf_nat.c Thu Feb 13 03:34:40 2014 +0000
@@ -1,6 +1,7 @@
-/* $NetBSD: npf_nat.c,v 1.24 2014/02/07 23:45:22 rmind Exp $ */
+/* $NetBSD: npf_nat.c,v 1.25 2014/02/13 03:34:40 rmind Exp $ */
/*-
+ * Copyright (c) 2014 Mindaugas Rasiukevicius <rmind at netbsd org>
* Copyright (c) 2010-2013 The NetBSD Foundation, Inc.
* All rights reserved.
*
@@ -70,7 +71,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_nat.c,v 1.24 2014/02/07 23:45:22 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_nat.c,v 1.25 2014/02/13 03:34:40 rmind Exp $");
#include <sys/param.h>
#include <sys/types.h>
@@ -100,7 +101,7 @@
/* Portmap range: [ 1024 .. 65535 ] */
#define PORTMAP_FIRST (1024)
#define PORTMAP_SIZE ((65536 - PORTMAP_FIRST) / 32)
-#define PORTMAP_FILLED ((uint32_t)~0)
+#define PORTMAP_FILLED ((uint32_t)~0U)
#define PORTMAP_MASK (31)
#define PORTMAP_SHIFT (5)
@@ -121,7 +122,12 @@
u_int n_flags;
size_t n_addr_sz;
npf_addr_t n_taddr;
+ npf_netmask_t n_tmask;
in_port_t n_tport;
+ u_int n_algo;
+ union {
+ uint16_t n_npt66_adj;
+ };
};
Home |
Main Index |
Thread Index |
Old Index