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