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