Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src - Rework NPF NAT syntax to be more structured and support fu...



details:   https://anonhg.NetBSD.org/src/rev/bf4355cd51fb
branches:  trunk
changeset: 779752:bf4355cd51fb
user:      rmind <rmind%NetBSD.org@localhost>
date:      Fri Jun 15 23:24:08 2012 +0000

description:
- Rework NPF NAT syntax to be more structured and support future additions
  of different types and configurations of NAT.
- npfctl: improve disassemble and show-config command functionality.
- Fix custom ICMP code and type filtering.

diffstat:

 sys/net/npf/npf_ncode.h               |   11 +-
 usr.sbin/npf/npfctl/npf.conf.5        |   24 +-
 usr.sbin/npf/npfctl/npf_build.c       |  118 +++++++---
 usr.sbin/npf/npfctl/npf_data.c        |    6 +-
 usr.sbin/npf/npfctl/npf_disassemble.c |  351 +++++++++++++++++++--------------
 usr.sbin/npf/npfctl/npf_ncgen.c       |   21 +-
 usr.sbin/npf/npfctl/npf_parse.y       |   88 ++++---
 usr.sbin/npf/npfctl/npf_scan.l        |   12 +-
 usr.sbin/npf/npfctl/npfctl.c          |    8 +-
 usr.sbin/npf/npfctl/npfctl.h          |   42 ++-
 10 files changed, 405 insertions(+), 276 deletions(-)

diffs (truncated from 1299 to 300 lines):

diff -r 57a9427362f3 -r bf4355cd51fb sys/net/npf/npf_ncode.h
--- a/sys/net/npf/npf_ncode.h   Fri Jun 15 23:01:16 2012 +0000
+++ b/sys/net/npf/npf_ncode.h   Fri Jun 15 23:24:08 2012 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: npf_ncode.h,v 1.7 2012/04/14 19:01:21 rmind Exp $      */
+/*     $NetBSD: npf_ncode.h,v 1.8 2012/06/15 23:24:08 rmind Exp $      */
 
 /*-
  * Copyright (c) 2009-2010 The NetBSD Foundation, Inc.
@@ -143,9 +143,9 @@
 # define       NPF_OPERAND_PORT_RANGE          14
 
 static const struct npf_instruction {
-       const char *name;
-       uint8_t op[4];
-} npf_instructions[256] = {
+       const char *    name;
+       uint8_t         op[4];
+} npf_instructions[] = {
        [NPF_OPCODE_RET] = {
                .name = "ret",
                .op = {
@@ -247,7 +247,8 @@
                        [1] = NPF_OPERAND_REGISTER,
                },
        },
-       [NPF_OPCODE_DIV] = { .name = "div",
+       [NPF_OPCODE_DIV] = {
+               .name = "div",
                .op = {
                        [0] = NPF_OPERAND_VALUE,
                        [1] = NPF_OPERAND_REGISTER,
diff -r 57a9427362f3 -r bf4355cd51fb usr.sbin/npf/npfctl/npf.conf.5
--- a/usr.sbin/npf/npfctl/npf.conf.5    Fri Jun 15 23:01:16 2012 +0000
+++ b/usr.sbin/npf/npfctl/npf.conf.5    Fri Jun 15 23:24:08 2012 +0000
@@ -1,4 +1,4 @@
-.\"    $NetBSD: npf.conf.5,v 1.11 2012/05/30 22:00:44 wiz Exp $
+.\"    $NetBSD: npf.conf.5,v 1.12 2012/06/15 23:24:08 rmind Exp $
 .\"
 .\" Copyright (c) 2009-2012 The NetBSD Foundation, Inc.
 .\" All rights reserved.
@@ -27,7 +27,7 @@
 .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 .\" POSSIBILITY OF SUCH DAMAGE.
 .\"
-.Dd May 27, 2012
+.Dd June 14, 2012
 .Dt NPF.CONF 5
 .Os
 .Sh NAME
@@ -132,7 +132,7 @@
 .\" -----
 .Sh GRAMMAR
 .Bd -literal
-line           = ( def | table | nat | group | rproc )
+line           = ( def | table | map | group | rproc )
 
 def            = ( \*[Lt]name\*[Gt] "=" "{ a, b, ... }" | "\*[Lt]text\*[Gt]" | "$\*[Lt]interface\*[Gt]" )
 iface          = ( \*[Lt]interface\*[Gt] | def )
@@ -140,9 +140,9 @@
 table          = "table" \*[Lt]tid\*[Gt] "type" ( "hash" | "tree" )
                  ( "dynamic" | "file" \*[Lt]path\*[Gt] )
 
-nat            = "nat" iface filt-opts "->" \*[Lt]addr\*[Gt]
-binat          = "binat" iface filt-opts "->" \*[Lt]addr\*[Gt]
-rdr            = "rdr" iface filt-opts "->" \*[Lt]addr\*[Gt] port-opts
+map-di         = ( "->" | "<-" | "<->" )
+map-type       = ( "static" | "dynamic" )
+map            = "map" iface maptype \*[Lt]seg1\*[Gt] mapdi \*[Lt]seg2\*[Gt] [ "pass" filt-opts ]
 
 rproc          = "procedure" \*[Lt]name\*[Gt] procs
 procs          = "{" op1 \*[Lt]newline\*[Gt], op2 \*[Lt]newline\*[Gt], ... "}"
@@ -179,13 +179,15 @@
 $ext_if = "wm0"
 $int_if = "wm1"
 
-$services_tcp = { http, https, smtp, domain, 6000 }
-$services_udp = { domain, ntp, 6000 }
-
 table <1> type hash file "/etc/npf_blacklist"
 table <2> type tree dynamic
 
-nat $ext_if from 192.168.0.0/24 to any -> $ext_if
+$services_tcp = { http, https, smtp, domain, 6000, 9022 }
+$services_udp = { domain, ntp, 6000 }
+$localnet = { 10.1.1.0/24 }
+
+map $ext_if dynamic 10.1.1.0/24 -> $ext_if
+map $ext_if dynamic 10.1.1.2 port 22 <- $ext_if 9022
 
 procedure "log" {
        log: npflog0
@@ -196,9 +198,9 @@
 }
 
 group (name "external", interface $ext_if) {
-       block in final from \*[Lt]1\*[Gt]
        pass stateful out final from $ext_if apply "rid"
 
+       block in final from \*[Lt]1\*[Gt]
        pass in final family inet proto tcp to $ext_if port ssh apply "log"
        pass in final proto tcp to $ext_if port $services_tcp
        pass in final proto udp to $ext_if port $services_udp
diff -r 57a9427362f3 -r bf4355cd51fb usr.sbin/npf/npfctl/npf_build.c
--- a/usr.sbin/npf/npfctl/npf_build.c   Fri Jun 15 23:01:16 2012 +0000
+++ b/usr.sbin/npf/npfctl/npf_build.c   Fri Jun 15 23:24:08 2012 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: npf_build.c,v 1.6 2012/02/26 21:50:05 christos Exp $   */
+/*     $NetBSD: npf_build.c,v 1.7 2012/06/15 23:24:08 rmind Exp $      */
 
 /*-
  * Copyright (c) 2011-2012 The NetBSD Foundation, Inc.
@@ -34,7 +34,7 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: npf_build.c,v 1.6 2012/02/26 21:50:05 christos Exp $");
+__RCSID("$NetBSD: npf_build.c,v 1.7 2012/06/15 23:24:08 rmind Exp $");
 
 #include <sys/types.h>
 #include <sys/ioctl.h>
@@ -90,10 +90,11 @@
        return npf_table_exists_p(npf_conf, atoi(id));
 }
 
-static in_port_t *
+static in_port_t
 npfctl_get_singleport(const npfvar_t *vp)
 {
        port_range_t *pr;
+       in_port_t *port;
 
        if (npfvar_get_count(vp) > 1) {
                yyerror("multiple ports are not valid");
@@ -102,7 +103,8 @@
        if (pr->pr_start != pr->pr_end) {
                yyerror("port range is not valid");
        }
-       return &pr->pr_start;
+       port = &pr->pr_start;
+       return *port;
 }
 
 static fam_addr_mask_t *
@@ -247,13 +249,15 @@
 npfctl_build_ncode(nl_rule_t *rl, sa_family_t family, const opt_proto_t *op,
     const filt_opts_t *fopts, bool invert)
 {
+       const addr_port_t *apfrom = &fopts->fo_from;
+       const addr_port_t *apto = &fopts->fo_to;
        nc_ctx_t *nc;
        void *code;
        size_t len;
 
        if (family == AF_UNSPEC && op->op_proto == -1 &&
-           op->op_opts == NULL && !fopts->fo_from && !fopts->fo_to &&
-           !fopts->fo_from_port_range && !fopts->fo_to_port_range)
+           op->op_opts == NULL && !apfrom->ap_netaddr && !apto->ap_netaddr &&
+           !apfrom->ap_portrange && !apto->ap_portrange)
                return false;
 
        int srcflag = NC_MATCH_SRC;
@@ -267,19 +271,19 @@
        nc = npfctl_ncgen_create();
 
        /* Build IP address blocks. */
-       npfctl_build_vars(nc, family, fopts->fo_from, srcflag);
-       npfctl_build_vars(nc, family, fopts->fo_to, dstflag);
+       npfctl_build_vars(nc, family, apfrom->ap_netaddr, srcflag);
+       npfctl_build_vars(nc, family, apto->ap_netaddr, dstflag);
 
        /* Build layer 4 protocol blocks. */
        int pflag = npfctl_build_proto(nc, op);
 
        /* Build port-range blocks. */
-       if (fopts->fo_from_port_range) {
-               npfctl_build_vars(nc, family, fopts->fo_from_port_range,
+       if (apfrom->ap_portrange) {
+               npfctl_build_vars(nc, family, apfrom->ap_portrange,
                    srcflag | pflag);
        }
-       if (fopts->fo_to_port_range) {
-               npfctl_build_vars(nc, family, fopts->fo_to_port_range,
+       if (apto->ap_portrange) {
+               npfctl_build_vars(nc, family, apto->ap_portrange,
                    dstflag | pflag);
        }
 
@@ -289,7 +293,7 @@
        code = npfctl_ncgen_complete(nc, &len);
        if (npf_debug) {
                extern int yylineno;
-               printf("RULE AT LINE %d\n", yylineno - 1);
+               printf("RULE AT LINE %d\n", yylineno);
                npfctl_ncgen_print(code, len);
        }
        if (npf_rule_setcode(rl, NPF_CODE_NCODE, code, len) == -1) {
@@ -430,64 +434,100 @@
  * given filter options.
  */
 void
-npfctl_build_nat(int type, u_int if_idx, const filt_opts_t *fopts,
-    npfvar_t *var1, npfvar_t *var2)
+npfctl_build_nat(int sd, int type, u_int if_idx, const addr_port_t *ap1,
+    const addr_port_t *ap2, const filt_opts_t *fopts)
 {
-       opt_proto_t op = { .op_proto = -1, .op_opts = NULL };
+       const opt_proto_t op = { .op_proto = -1, .op_opts = NULL };
+       fam_addr_mask_t *am1, *am2;
+       filt_opts_t imfopts;
+       sa_family_t family;
        nl_nat_t *nat;
-       fam_addr_mask_t *ai;
+
+       if (sd == NPFCTL_NAT_STATIC) {
+               yyerror("static NAT is not yet supported");
+       }
+       assert(sd == NPFCTL_NAT_DYNAMIC);
+       assert(if_idx != 0);
+
+       family = AF_INET;
 
-       assert(type != 0 && if_idx != 0);
-       assert(fopts != NULL && var1 != NULL);
+       if (type & NPF_NATIN) {
+               if (!ap1->ap_netaddr) {
+                       yyerror("inbound network segment is not specified");
+               }
+               am1 = npfctl_get_singlefam(ap1->ap_netaddr);
+               if (am1->fam_family != AF_INET) {
+                       yyerror("IPv6 NAT is not supported");
+               }
+               assert(am1 != NULL);
+       }
 
-       ai = npfctl_get_singlefam(var1);
-       assert(ai != NULL);
-       if (ai->fam_family != AF_INET) {
-               yyerror("IPv6 NAT is not supported");
+       if (type & NPF_NATOUT) {
+               if (!ap2->ap_netaddr) {
+                       yyerror("outbound network segment is not specified");
+               }
+               am2 = npfctl_get_singlefam(ap2->ap_netaddr);
+               if (am2->fam_family != family) {
+                       yyerror("IPv6 NAT is not supported");
+               }
+               assert(am2 != NULL);
+       }
+
+       /*
+        * If filter criteria is not specified explicitly, apply implicit
+        * filtering according to the given network segements.
+        */
+       if (!fopts) {
+               memset(&imfopts, 0, sizeof(filt_opts_t));
+               if (type & NPF_NATOUT) {
+                       memcpy(&imfopts.fo_from, ap1, sizeof(addr_port_t));
+               }
+               if (type & NPF_NATIN) {
+                       memcpy(&imfopts.fo_to, ap2, sizeof(addr_port_t));
+               }
+               fopts = &imfopts;
        }
 
        switch (type) {
-       case NPFCTL_RDR: {
+       case NPF_NATIN: {
                /*
                 * Redirection: an inbound NAT with a specific port.
                 */
-               in_port_t *port = npfctl_get_singleport(var2);
+               if (!ap1->ap_portrange) {
+                       yyerror("inbound port is not specified");
+               }
+               in_port_t port = npfctl_get_singleport(ap1->ap_portrange);
                nat = npf_nat_create(NPF_NATIN, NPF_NAT_PORTS,
-                   if_idx, &ai->fam_addr, ai->fam_family, *port);
+                   if_idx, &am1->fam_addr, am1->fam_family, port);
                break;
        }
-       case NPFCTL_BINAT: {
+       case (NPF_NATIN | NPF_NATOUT): {
                /*
                 * Bi-directional NAT: a combination of inbound NAT and
                 * outbound NAT policies.  Note that the translation address
                 * is local IP and filter criteria is inverted accordingly.
                 */
-               fam_addr_mask_t *tai = npfctl_get_singlefam(var2);
-               assert(tai != NULL);
-               if (ai->fam_family != AF_INET) {
-                       yyerror("IPv6 NAT is not supported");
-               }
                nat = npf_nat_create(NPF_NATIN, 0, if_idx,
-                   &tai->fam_addr, tai->fam_family, 0);
-               npfctl_build_ncode(nat, AF_INET, &op, fopts, true);
+                   &am1->fam_addr, am1->fam_family, 0);
+               npfctl_build_ncode(nat, family, &op, fopts, true);
                npf_nat_insert(npf_conf, nat, NPF_PRI_NEXT);
                /* FALLTHROUGH */



Home | Main Index | Thread Index | Old Index