Module Name: src
Committed By: rmind
Date: Fri Sep 20 03:03:52 UTC 2013
Modified Files:
src/usr.sbin/npf/npfctl: npf.conf.5 npf_build.c npf_parse.y npf_scan.l
npf_show.c npfctl.h
Log Message:
- NPF: change the group/ruleset syntax - simplify. Update npf.conf(5) manual.
- Add support for the inline pcap-filter(7) syntax in the rule, e.g.:
block out final pcap-filter "tcp and dst 10.1.1.252"
To generate a diff of this commit:
cvs rdiff -u -r1.30 -r1.31 src/usr.sbin/npf/npfctl/npf.conf.5
cvs rdiff -u -r1.26 -r1.27 src/usr.sbin/npf/npfctl/npf_build.c
cvs rdiff -u -r1.25 -r1.26 src/usr.sbin/npf/npfctl/npf_parse.y
cvs rdiff -u -r1.12 -r1.13 src/usr.sbin/npf/npfctl/npf_scan.l
cvs rdiff -u -r1.1 -r1.2 src/usr.sbin/npf/npfctl/npf_show.c
cvs rdiff -u -r1.32 -r1.33 src/usr.sbin/npf/npfctl/npfctl.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/usr.sbin/npf/npfctl/npf.conf.5
diff -u src/usr.sbin/npf/npfctl/npf.conf.5:1.30 src/usr.sbin/npf/npfctl/npf.conf.5:1.31
--- src/usr.sbin/npf/npfctl/npf.conf.5:1.30 Thu Sep 19 12:05:11 2013
+++ src/usr.sbin/npf/npfctl/npf.conf.5 Fri Sep 20 03:03:52 2013
@@ -1,4 +1,4 @@
-.\" $NetBSD: npf.conf.5,v 1.30 2013/09/19 12:05:11 rmind Exp $
+.\" $NetBSD: npf.conf.5,v 1.31 2013/09/20 03:03:52 rmind Exp $
.\"
.\" Copyright (c) 2009-2013 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 September 19, 2013
+.Dd September 20, 2013
.Dt NPF.CONF 5
.Os
.Sh NAME
@@ -236,19 +236,21 @@ proc = "procedure" proc-name "{" *( pro
proc-opts = key " " val [ "," proc-opts ]
proc-call = call-name ":" proc-opts new-line
-; Group definition and the ruleset.
+; Group definition and the rule list.
-group = "group" "(" ( "default" | group-opts ) ")" "{" ruleset "}"
-group-opts = [ "name" string ] [ "interface" interface ] [ "in" | "out" ]
-ruleset = [ rule new-line ] [ ruleset ]
-
-rule = ( "block" [ block-opts ] | "pass" ) [ "stateful" ]
- [ "in" | out" ] [ "final" ] [ "on" iface ]
- [ "family" fam-opt ] [ "proto" protocol [ proto-opts ] ]
+group = "group" ( "default" | group-opts ) "{" rule-list "}"
+group-opts = name-string [ "in" | "out" ] [ "on" interface ]
+rule-list = [ rule new-line ] rule-list
+
+static-rule = ( "block" [ block-opts ] | "pass" ) [ "stateful" ]
+ [ "in" | out" ] [ "final" ] [ "on" interface ]
+ [ "family" family-opt ] [ "proto" protocol [ proto-opts ] ]
( "all" | filt-opts ) [ "apply" proc-name ]
+dynamic-ruleset = "ruleset" group-opts
+rule = static-rule | dynamic-ruleset
block-opts = "return-rst" | "return-icmp" | "return"
-fam-opt = "inet" | "inet6"
+family-opt = "inet" | "inet6"
proto-opts = "flags" tcp-flags [ "/" tcp-flag-mask ] |
"icmp-type" type [ "code" icmp-code ]
@@ -291,7 +293,7 @@ procedure "log" {
log: npflog0
}
-group (name "external", interface $ext_if) {
+group "external" on $ext_if {
pass stateful out final all
block in final from \*[Lt]1\*[Gt]
@@ -302,13 +304,16 @@ group (name "external", interface $ext_i
pass stateful in final proto udp to $ext_if port 33434-33600 # Traceroute
}
-group (name "internal", interface $int_if) {
+group "internal" on $int_if {
block in all
- pass in final from \*[Lt]2\*[Gt]
+ block in final from \*[Lt]2\*[Gt]
+
+ # Ingress filtering as per RFC 2827.
+ pass in final from $localnet
pass out final all
}
-group (default) {
+group default {
pass final on lo0 all
block all
}
Index: src/usr.sbin/npf/npfctl/npf_build.c
diff -u src/usr.sbin/npf/npfctl/npf_build.c:1.26 src/usr.sbin/npf/npfctl/npf_build.c:1.27
--- src/usr.sbin/npf/npfctl/npf_build.c:1.26 Thu Sep 19 12:05:11 2013
+++ src/usr.sbin/npf/npfctl/npf_build.c Fri Sep 20 03:03:52 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: npf_build.c,v 1.26 2013/09/19 12:05:11 rmind Exp $ */
+/* $NetBSD: npf_build.c,v 1.27 2013/09/20 03:03:52 rmind Exp $ */
/*-
* Copyright (c) 2011-2013 The NetBSD Foundation, Inc.
@@ -34,7 +34,7 @@
*/
#include <sys/cdefs.h>
-__RCSID("$NetBSD: npf_build.c,v 1.26 2013/09/19 12:05:11 rmind Exp $");
+__RCSID("$NetBSD: npf_build.c,v 1.27 2013/09/20 03:03:52 rmind Exp $");
#include <sys/types.h>
#include <sys/ioctl.h>
@@ -59,6 +59,8 @@ static nl_rule_t * current_group[MAX_RU
static unsigned rule_nesting_level = 0;
static nl_rule_t * defgroup = NULL;
+static void npfctl_dump_bpf(struct bpf_program *);
+
void
npfctl_config_init(bool debug)
{
@@ -273,7 +275,7 @@ npfctl_build_proto(npf_bpf_t *ctx, sa_fa
static bool
npfctl_build_code(nl_rule_t *rl, sa_family_t family, const opt_proto_t *op,
- const filt_opts_t *fopts, bool invert)
+ const filt_opts_t *fopts)
{
const addr_port_t *apfrom = &fopts->fo_from;
const addr_port_t *apto = &fopts->fo_to;
@@ -306,21 +308,18 @@ npfctl_build_code(nl_rule_t *rl, sa_fami
}
}
- const int srcflag = invert ? MATCH_DST : MATCH_SRC;
- const int dstflag = invert ? MATCH_SRC : MATCH_DST;
-
bc = npfctl_bpf_create();
/* Build layer 4 protocol blocks. */
npfctl_build_proto(bc, family, op);
/* Build IP address blocks. */
- npfctl_build_vars(bc, family, apfrom->ap_netaddr, srcflag);
- npfctl_build_vars(bc, family, apto->ap_netaddr, dstflag);
+ npfctl_build_vars(bc, family, apfrom->ap_netaddr, MATCH_SRC);
+ npfctl_build_vars(bc, family, apto->ap_netaddr, MATCH_DST);
/* Build port-range blocks. */
- npfctl_build_vars(bc, family, apfrom->ap_portrange, srcflag);
- npfctl_build_vars(bc, family, apto->ap_portrange, dstflag);
+ npfctl_build_vars(bc, family, apfrom->ap_portrange, MATCH_SRC);
+ npfctl_build_vars(bc, family, apto->ap_portrange, MATCH_DST);
/* Set the byte-code marks, if any. */
const void *bmarks = npfctl_bpf_bmarks(bc, &len);
@@ -330,24 +329,38 @@ npfctl_build_code(nl_rule_t *rl, sa_fami
/* Complete BPF byte-code and pass to the rule. */
struct bpf_program *bf = npfctl_bpf_complete(bc);
- if (npf_debug) {
- extern char *yytext;
- extern int yylineno;
-
- printf("\nRULE AT LINE %d\n", yylineno - (int)(*yytext == '\n'));
- bpf_dump(bf, 0);
- }
len = bf->bf_len * sizeof(struct bpf_insn);
if (npf_rule_setcode(rl, NPF_CODE_BPF, bf->bf_insns, len) == -1) {
errx(EXIT_FAILURE, "npf_rule_setcode failed");
}
+ npfctl_dump_bpf(bf);
npfctl_bpf_destroy(bc);
return true;
}
static void
+npfctl_build_pcap(nl_rule_t *rl, const char *filter)
+{
+ const size_t maxsnaplen = 64 * 1024;
+ struct bpf_program bf;
+ size_t len;
+
+ if (pcap_compile_nopcap(maxsnaplen, DLT_RAW, &bf,
+ filter, 1, PCAP_NETMASK_UNKNOWN) == -1) {
+ yyerror("invalid pcap-filter(7) syntax");
+ }
+ len = bf.bf_len * sizeof(struct bpf_insn);
+
+ if (npf_rule_setcode(rl, NPF_CODE_BPF, bf.bf_insns, len) == -1) {
+ errx(EXIT_FAILURE, "npf_rule_setcode failed");
+ }
+ npfctl_dump_bpf(&bf);
+ pcap_freecode(&bf);
+}
+
+static void
npfctl_build_rpcall(nl_rproc_t *rp, const char *name, npfvar_t *args)
{
npf_extmod_t *extmod;
@@ -468,14 +481,20 @@ npfctl_build_group_end(void)
*/
void
npfctl_build_rule(uint32_t attr, u_int if_idx, sa_family_t family,
- const opt_proto_t *op, const filt_opts_t *fopts, const char *rproc)
+ const opt_proto_t *op, const filt_opts_t *fopts,
+ const char *pcap_filter, const char *rproc)
{
nl_rule_t *rl;
attr |= (npf_conf ? 0 : NPF_RULE_DYNAMIC);
rl = npf_rule_create(NULL, attr, if_idx);
- npfctl_build_code(rl, family, op, fopts, false);
+ if (pcap_filter) {
+ npfctl_build_pcap(rl, pcap_filter);
+ } else {
+ npfctl_build_code(rl, family, op, fopts);
+ }
+
if (rproc) {
npf_rule_setproc(rl, rproc);
}
@@ -547,7 +566,7 @@ npfctl_build_nat(int type, u_int if_idx,
assert(false);
}
- npfctl_build_code(nat, family, &op, fopts, false);
+ npfctl_build_code(nat, family, &op, fopts);
npf_nat_insert(npf_conf, nat, NPF_PRI_LAST);
}
@@ -672,3 +691,16 @@ npfctl_build_alg(const char *al_name)
errx(EXIT_FAILURE, "ALG '%s' already loaded", al_name);
}
}
+
+static void
+npfctl_dump_bpf(struct bpf_program *bf)
+{
+ if (npf_debug) {
+ extern char *yytext;
+ extern int yylineno;
+
+ int rule_line = yylineno - (int)(*yytext == '\n');
+ printf("\nRULE AT LINE %d\n", rule_line);
+ bpf_dump(bf, 0);
+ }
+}
Index: src/usr.sbin/npf/npfctl/npf_parse.y
diff -u src/usr.sbin/npf/npfctl/npf_parse.y:1.25 src/usr.sbin/npf/npfctl/npf_parse.y:1.26
--- src/usr.sbin/npf/npfctl/npf_parse.y:1.25 Thu Sep 19 01:04:45 2013
+++ src/usr.sbin/npf/npfctl/npf_parse.y Fri Sep 20 03:03:52 2013
@@ -1,11 +1,11 @@
-/* $NetBSD: npf_parse.y,v 1.25 2013/09/19 01:04:45 rmind Exp $ */
+/* $NetBSD: npf_parse.y,v 1.26 2013/09/20 03:03:52 rmind Exp $ */
/*-
- * Copyright (c) 2011-2012 The NetBSD Foundation, Inc.
+ * Copyright (c) 2011-2013 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
- * by Martin Husemann and Christos Zoulas.
+ * by Martin Husemann, Christos Zoulas and Mindaugas Rasiukevicius.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -123,6 +123,7 @@ yyerror(const char *fmt, ...)
%token PAR_CLOSE
%token PAR_OPEN
%token PASS
+%token PCAP_FILTER
%token PORT
%token PROCEDURE
%token PROTO
@@ -158,7 +159,7 @@ yyerror(const char *fmt, ...)
%type <str> proc_param_val, opt_apply
%type <num> ifindex, port, opt_final, on_ifindex, number
%type <num> afamily, opt_family
-%type <num> block_or_pass, rule_dir, block_opts
+%type <num> block_or_pass, rule_dir, group_dir, block_opts
%type <num> opt_stateful, icmp_type, table_type, map_sd, map_type
%type <var> ifnet, addr_or_ifnet, port_range, icmp_type_and_code
%type <var> filt_addr, addr_and_mask, tcp_flags, tcp_flags_and_mask
@@ -166,7 +167,7 @@ yyerror(const char *fmt, ...)
%type <addrport> mapseg
%type <filtopts> filt_opts, all_or_filt_opts
%type <optproto> opt_proto
-%type <rulegroup> group_attr, group_opt
+%type <rulegroup> group_opts
%union {
char * str;
@@ -313,9 +314,9 @@ map
{
npfctl_build_natseg($3, $5, $2, &$4, &$6, NULL);
}
- | MAP RULESET PAR_OPEN group_attr PAR_CLOSE
+ | MAP RULESET group_opts
{
- npfctl_build_maprset($4.rg_name, $4.rg_attr, $4.rg_ifnum);
+ npfctl_build_maprset($3.rg_name, $3.rg_attr, $3.rg_ifnum);
}
;
@@ -384,11 +385,11 @@ proc_param_val
;
group
- : GROUP PAR_OPEN group_attr PAR_CLOSE
+ : GROUP group_opts
{
/* Build a group. Increases the nesting level. */
- npfctl_build_group($3.rg_name, $3.rg_attr,
- $3.rg_ifnum, $3.rg_default);
+ npfctl_build_group($2.rg_name, $2.rg_attr,
+ $2.rg_ifnum, $2.rg_default);
}
ruleset_block
{
@@ -398,70 +399,32 @@ group
;
ruleset
- : RULESET PAR_OPEN group_attr PAR_CLOSE
+ : RULESET group_opts
{
/* Ruleset is a dynamic group. */
- npfctl_build_group($3.rg_name, $3.rg_attr | NPF_RULE_DYNAMIC,
- $3.rg_ifnum, $3.rg_default);
+ npfctl_build_group($2.rg_name, $2.rg_attr | NPF_RULE_DYNAMIC,
+ $2.rg_ifnum, $2.rg_default);
npfctl_build_group_end();
}
+ ;
-group_attr
- : group_opt COMMA group_attr
- {
- $$ = $3;
-
- if (($1.rg_name && $$.rg_name) ||
- ($1.rg_ifnum && $$.rg_ifnum) ||
- ($1.rg_attr & $$.rg_attr) != 0)
- yyerror("duplicate group option");
-
- if ($1.rg_name) {
- $$.rg_name = $1.rg_name;
- }
- if ($1.rg_attr) {
- $$.rg_attr |= $1.rg_attr;
- }
- if ($1.rg_ifnum) {
- $$.rg_ifnum = $1.rg_ifnum;
- }
- if ($1.rg_default) {
- $$.rg_default = $1.rg_default;
- }
- }
- | group_opt { $$ = $1; }
+group_dir
+ : FORW { $$ = NPF_RULE_FORW; }
+ | rule_dir
;
-group_opt
+group_opts
: DEFAULT
{
memset(&$$, 0, sizeof(rule_group_t));
$$.rg_default = true;
}
- | NAME STRING
- {
- memset(&$$, 0, sizeof(rule_group_t));
- $$.rg_name = $2;
- }
- | INTERFACE ifindex
+ | STRING group_dir on_ifindex
{
memset(&$$, 0, sizeof(rule_group_t));
- $$.rg_ifnum = $2;
- }
- | TDYNAMIC
- {
- memset(&$$, 0, sizeof(rule_group_t));
- $$.rg_attr = NPF_RULE_DYNAMIC;
- }
- | FORW
- {
- memset(&$$, 0, sizeof(rule_group_t));
- $$.rg_attr = NPF_RULE_FORW;
- }
- | rule_dir
- {
- memset(&$$, 0, sizeof(rule_group_t));
- $$.rg_attr = $1;
+ $$.rg_name = $1;
+ $$.rg_attr = $2;
+ $$.rg_ifnum = $3;
}
;
@@ -486,7 +449,13 @@ rule
opt_family opt_proto all_or_filt_opts opt_apply
{
npfctl_build_rule($1 | $2 | $3 | $4, $5,
- $6, &$7, &$8, $9);
+ $6, &$7, &$8, NULL, $9);
+ }
+ | block_or_pass opt_stateful rule_dir opt_final on_ifindex
+ PCAP_FILTER STRING opt_apply
+ {
+ npfctl_build_rule($1 | $2 | $3 | $4, $5,
+ AF_UNSPEC, NULL, NULL, $7, $8);
}
;
Index: src/usr.sbin/npf/npfctl/npf_scan.l
diff -u src/usr.sbin/npf/npfctl/npf_scan.l:1.12 src/usr.sbin/npf/npfctl/npf_scan.l:1.13
--- src/usr.sbin/npf/npfctl/npf_scan.l:1.12 Wed Mar 20 00:29:47 2013
+++ src/usr.sbin/npf/npfctl/npf_scan.l Fri Sep 20 03:03:52 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: npf_scan.l,v 1.12 2013/03/20 00:29:47 christos Exp $ */
+/* $NetBSD: npf_scan.l,v 1.13 2013/09/20 03:03:52 rmind Exp $ */
/*-
* Copyright (c) 2011-2012 The NetBSD Foundation, Inc.
@@ -113,6 +113,7 @@ interface return INTERFACE;
all return ALL;
block return BLOCK;
pass return PASS;
+pcap-filter return PCAP_FILTER;
stateful return STATEFUL;
apply return APPLY;
final return FINAL;
Index: src/usr.sbin/npf/npfctl/npf_show.c
diff -u src/usr.sbin/npf/npfctl/npf_show.c:1.1 src/usr.sbin/npf/npfctl/npf_show.c:1.2
--- src/usr.sbin/npf/npfctl/npf_show.c:1.1 Thu Sep 19 01:04:45 2013
+++ src/usr.sbin/npf/npfctl/npf_show.c Fri Sep 20 03:03:52 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: npf_show.c,v 1.1 2013/09/19 01:04:45 rmind Exp $ */
+/* $NetBSD: npf_show.c,v 1.2 2013/09/20 03:03:52 rmind Exp $ */
/*-
* Copyright (c) 2013 The NetBSD Foundation, Inc.
@@ -36,7 +36,7 @@
*/
#include <sys/cdefs.h>
-__RCSID("$NetBSD: npf_show.c,v 1.1 2013/09/19 01:04:45 rmind Exp $");
+__RCSID("$NetBSD: npf_show.c,v 1.2 2013/09/20 03:03:52 rmind Exp $");
#include <sys/socket.h>
#include <netinet/in.h>
@@ -482,7 +482,6 @@ npfctl_ruleset_show(int fd, const char *
return error;
}
while ((rl = npf_rule_iterate(ncf, &level)) != NULL) {
- print_indent(ctx, level);
npfctl_print_rule(ctx, rl);
}
npf_config_destroy(ncf);
Index: src/usr.sbin/npf/npfctl/npfctl.h
diff -u src/usr.sbin/npf/npfctl/npfctl.h:1.32 src/usr.sbin/npf/npfctl/npfctl.h:1.33
--- src/usr.sbin/npf/npfctl/npfctl.h:1.32 Thu Sep 19 12:05:11 2013
+++ src/usr.sbin/npf/npfctl/npfctl.h Fri Sep 20 03:03:52 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: npfctl.h,v 1.32 2013/09/19 12:05:11 rmind Exp $ */
+/* $NetBSD: npfctl.h,v 1.33 2013/09/20 03:03:52 rmind Exp $ */
/*-
* Copyright (c) 2009-2013 The NetBSD Foundation, Inc.
@@ -188,7 +188,8 @@ void npfctl_build_rproc(const char *, n
void npfctl_build_group(const char *, int, u_int, bool);
void npfctl_build_group_end(void);
void npfctl_build_rule(uint32_t, u_int, sa_family_t,
- const opt_proto_t *, const filt_opts_t *, const char *);
+ const opt_proto_t *, const filt_opts_t *,
+ const char *, const char *);
void npfctl_build_natseg(int, int, u_int, const addr_port_t *,
const addr_port_t *, const filt_opts_t *);
void npfctl_build_maprset(const char *, int, u_int);