npfctl: dynamic interface address handling; update npf.conf(8). trunk
authorrmind <rmind@NetBSD.org>
Tue, 03 Jan 2017 01:29:49 +0000
branchtrunk
changeset 247301 3dc65643915b
parent 247300 27f15c3cac16
child 247302 e2ac449f0ecd
npfctl: dynamic interface address handling; update npf.conf(8).
usr.sbin/npf/npfctl/npf.conf.5
usr.sbin/npf/npfctl/npf_build.c
usr.sbin/npf/npfctl/npf_parse.y
usr.sbin/npf/npfctl/npf_scan.l
usr.sbin/npf/npfctl/npfctl.h
--- a/usr.sbin/npf/npfctl/npf.conf.5	Tue Jan 03 00:59:31 2017 +0000
+++ b/usr.sbin/npf/npfctl/npf.conf.5	Tue Jan 03 01:29:49 2017 +0000
@@ -1,6 +1,6 @@
-.\"    $NetBSD: npf.conf.5,v 1.45 2016/12/27 22:35:33 rmind Exp $
+.\"    $NetBSD: npf.conf.5,v 1.46 2017/01/03 01:29:49 rmind Exp $
 .\"
-.\" Copyright (c) 2009-2015 The NetBSD Foundation, Inc.
+.\" Copyright (c) 2009-2017 The NetBSD Foundation, Inc.
 .\" All rights reserved.
 .\"
 .\" This material is based upon work partially supported by The
@@ -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 December 28, 2016
+.Dd January 3, 2017
 .Dt NPF.CONF 5
 .Os
 .Sh NAME
@@ -110,6 +110,24 @@
 $pub_if4 = inet4(wm0)
 $pub_if46 = { inet4(wm0), inet6(wm0) }
 .Ed
+.Pp
+In the above examples, NPF will statically capture the interface
+addresses on configuration load.
+.Pp
+The following can be used for dynamic handling of the interface addresses:
+.Bd -literal
+$pub_if = ifaddrs(wm0)
+.Ed
+.Pp
+In this case, the expression will represent the runtime list of addresses,
+reflecting any changes to the interface, including the attach and detach.
+Marking the interface as ``down'' has no effect, i.e. all addresses will
+remain present.
+.Pp
+The dynamic address list represents both the IPv4 and IPv6 addresses,
+therefore the
+.Cd family
+keyword can be used in combination to make the filtering more narrow.
 .Ss Groups
 Groups may have the following options: name, interface, and direction.
 They are defined in the following form:
--- a/usr.sbin/npf/npfctl/npf_build.c	Tue Jan 03 00:59:31 2017 +0000
+++ b/usr.sbin/npf/npfctl/npf_build.c	Tue Jan 03 01:29:49 2017 +0000
@@ -1,7 +1,7 @@
-/*	$NetBSD: npf_build.c,v 1.42 2016/12/27 22:35:33 rmind Exp $	*/
+/*	$NetBSD: npf_build.c,v 1.43 2017/01/03 01:29:49 rmind Exp $	*/
 
 /*-
- * Copyright (c) 2011-2014 The NetBSD Foundation, Inc.
+ * Copyright (c) 2011-2017 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This material is based upon work partially supported by The
@@ -34,7 +34,7 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: npf_build.c,v 1.42 2016/12/27 22:35:33 rmind Exp $");
+__RCSID("$NetBSD: npf_build.c,v 1.43 2017/01/03 01:29:49 rmind Exp $");
 
 #include <sys/types.h>
 #include <sys/mman.h>
@@ -65,6 +65,7 @@
 static nl_rule_t *		current_group[MAX_RULE_NESTING];
 static unsigned			rule_nesting_level = 0;
 static nl_rule_t *		defgroup = NULL;
+static unsigned			npfctl_tid_counter = 0;
 
 static void			npfctl_dump_bpf(struct bpf_program *);
 
@@ -797,10 +798,9 @@
 void
 npfctl_build_table(const char *tname, u_int type, const char *fname)
 {
-	static unsigned tid = 0;
 	nl_table_t *tl;
 
-	tl = npf_table_create(tname, tid++, type);
+	tl = npf_table_create(tname, npfctl_tid_counter++, type);
 	assert(tl != NULL);
 
 	if (npf_table_insert(npf_conf, tl)) {
@@ -814,6 +814,24 @@
 	}
 }
 
+npfvar_t *
+npfctl_ifnet_table(const char *ifname)
+{
+	char tname[NPF_TABLE_MAXNAMELEN];
+	nl_table_t *tl;
+	u_int tid;
+
+	snprintf(tname, sizeof(tname), ".ifnet-%s", ifname);
+
+	tid = npfctl_table_getid(tname);
+	if (tid == (unsigned)-1) {
+		tid = npfctl_tid_counter++;
+		tl = npf_table_create(tname, tid, NPF_TABLE_TREE);
+		(void)npf_table_insert(npf_conf, tl);
+	}
+	return npfvar_create_element(NPFVAR_TABLE, &tid, sizeof(u_int));
+}
+
 /*
  * npfctl_build_alg: create an NPF application level gateway and add it
  * to the configuration.
--- a/usr.sbin/npf/npfctl/npf_parse.y	Tue Jan 03 00:59:31 2017 +0000
+++ b/usr.sbin/npf/npfctl/npf_parse.y	Tue Jan 03 01:29:49 2017 +0000
@@ -1,7 +1,7 @@
-/*	$NetBSD: npf_parse.y,v 1.39 2016/12/27 22:35:33 rmind Exp $	*/
+/*	$NetBSD: npf_parse.y,v 1.40 2017/01/03 01:29:49 rmind Exp $	*/
 
 /*-
- * Copyright (c) 2011-2014 The NetBSD Foundation, Inc.
+ * Copyright (c) 2011-2017 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This code is derived from software contributed to The NetBSD Foundation
@@ -116,6 +116,7 @@
 %token			IN
 %token			INET4
 %token			INET6
+%token			IFADDRS
 %token			INTERFACE
 %token			MAP
 %token			MINUS
@@ -161,13 +162,14 @@
 %token	<str>		TABLE_ID
 %token	<str>		VAR_ID
 
-%type	<str>		addr, some_name, table_store
+%type	<str>		addr, some_name, table_store, dynamic_ifaddrs
 %type	<str>		proc_param_val, opt_apply, ifname, on_ifname, ifref
 %type	<num>		port, opt_final, number, afamily, opt_family
 %type	<num>		block_or_pass, rule_dir, group_dir, block_opts
 %type	<num>		maybe_not, opt_stateful, icmp_type, table_type
 %type	<num>		map_sd, map_algo, map_type
-%type	<var>		ifaddrs, addr_or_ifaddr, port_range, icmp_type_and_code
+%type	<var>		static_ifaddrs, addr_or_ifaddr
+%type	<var>		port_range, icmp_type_and_code
 %type	<var>		filt_addr, addr_and_mask, tcp_flags, tcp_flags_and_mask
 %type	<var>		procs, proc_call, proc_param_list, proc_param
 %type	<var>		element, list_elems, list, value
@@ -288,7 +290,8 @@
 		$$ = npfvar_create_from_string(NPFVAR_VAR_ID, $1);
 	}
 	| TABLE_ID		{ $$ = npfctl_parse_table_id($1); }
-	| ifaddrs		{ $$ = $1; }
+	| dynamic_ifaddrs	{ $$ = npfctl_ifnet_table($1); }
+	| static_ifaddrs	{ $$ = $1; }
 	| addr_and_mask		{ $$ = $1; }
 	;
 
@@ -634,6 +637,7 @@
 filt_addr
 	: list			{ $$ = $1; }
 	| addr_or_ifaddr	{ $$ = $1; }
+	| dynamic_ifaddrs	{ $$ = npfctl_ifnet_table($1); }
 	| TABLE_ID		{ $$ = npfctl_parse_table_id($1); }
 	| ANY			{ $$ = NULL; }
 	;
@@ -659,7 +663,7 @@
 		assert($1 != NULL);
 		$$ = $1;
 	}
-	| ifaddrs
+	| static_ifaddrs
 	{
 		ifnet_addr_t *ifna = npfvar_get_data($1, NPFVAR_INTERFACE, 0);
 		$$ = ifna->ifna_addrs;
@@ -679,6 +683,7 @@
 			type = npfvar_get_type(vp, 0);
 			goto again;
 		case NPFVAR_FAM:
+		case NPFVAR_TABLE:
 			$$ = vp;
 			break;
 		case NPFVAR_INTERFACE:
@@ -814,16 +819,24 @@
 	}
 	;
 
-ifaddrs
+static_ifaddrs
 	: afamily PAR_OPEN ifname PAR_CLOSE
 	{
 		$$ = npfctl_parse_ifnet($3, $1);
 	}
 	;
 
+dynamic_ifaddrs
+	: IFADDRS PAR_OPEN ifname PAR_CLOSE
+	{
+		$$ = $3;
+	}
+	;
+
 ifref
 	: ifname
-	| ifaddrs
+	| dynamic_ifaddrs
+	| static_ifaddrs
 	{
 		ifnet_addr_t *ifna = npfvar_get_data($1, NPFVAR_INTERFACE, 0);
 		npfctl_note_interface(ifna->ifna_name);
--- a/usr.sbin/npf/npfctl/npf_scan.l	Tue Jan 03 00:59:31 2017 +0000
+++ b/usr.sbin/npf/npfctl/npf_scan.l	Tue Jan 03 01:29:49 2017 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_scan.l,v 1.24 2016/12/27 22:35:33 rmind Exp $	*/
+/*	$NetBSD: npf_scan.l,v 1.25 2017/01/03 01:29:49 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2011-2012 The NetBSD Foundation, Inc.
@@ -129,6 +129,7 @@
 bpf.jit			return BPFJIT;
 inet6			return INET6;
 inet4			return INET4;
+ifaddrs			return IFADDRS;
 proto			return PROTO;
 family			return FAMILY;
 tcp			return TCP;
--- a/usr.sbin/npf/npfctl/npfctl.h	Tue Jan 03 00:59:31 2017 +0000
+++ b/usr.sbin/npf/npfctl/npfctl.h	Tue Jan 03 01:29:49 2017 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: npfctl.h,v 1.42 2016/12/27 22:35:33 rmind Exp $	*/
+/*	$NetBSD: npfctl.h,v 1.43 2017/01/03 01:29:49 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2009-2013 The NetBSD Foundation, Inc.
@@ -121,6 +121,7 @@
 in_port_t	npfctl_portno(const char *);
 uint8_t		npfctl_icmpcode(int, uint8_t, const char *);
 uint8_t		npfctl_icmptype(int, const char *);
+npfvar_t *	npfctl_ifnet_table(const char *);
 npfvar_t *	npfctl_parse_ifnet(const char *, const int);
 npfvar_t *	npfctl_parse_tcpflag(const char *);
 npfvar_t *	npfctl_parse_table_id(const char *);