Module Name: src Committed By: riz Date: Tue Dec 11 04:31:53 UTC 2012
Modified Files: src/share/examples/npf [netbsd-6]: host-npf.conf soho_gw-npf.conf src/sys/net/npf [netbsd-6]: npf_tableset.c src/usr.sbin/npf/npfctl [netbsd-6]: npf.conf.5 npf_build.c npf_data.c npf_parse.y npf_scan.l npf_var.h npfctl.h Log Message: Pull up following revision(s) (requested by rmind in ticket #736): usr.sbin/npf/npfctl/npf_parse.y: revision 1.17 sys/net/npf/npf_tableset.c: revision 1.16 usr.sbin/npf/npfctl/npfctl.h: revision 1.23 usr.sbin/npf/npfctl/npf_data.c: revision 1.19 usr.sbin/npf/npfctl/npf_build.c: revision 1.15 share/examples/npf/host-npf.conf: revision 1.3 usr.sbin/npf/npfctl/npf_scan.l: revision 1.9 share/examples/npf/soho_gw-npf.conf: revision 1.3 usr.sbin/npf/npfctl/npf_var.h: revision 1.6 usr.sbin/npf/npfctl/npf.conf.5: revision 1.24 npfctl: extend syntax for extracting interface IP address(es) by the family. adjust to current npf.conf syntax npf_table_list: avoid triggering assert on diagnostic. To generate a diff of this commit: cvs rdiff -u -r1.2.4.2 -r1.2.4.3 src/share/examples/npf/host-npf.conf \ src/share/examples/npf/soho_gw-npf.conf cvs rdiff -u -r1.9.2.6 -r1.9.2.7 src/sys/net/npf/npf_tableset.c cvs rdiff -u -r1.9.2.4 -r1.9.2.5 src/usr.sbin/npf/npfctl/npf.conf.5 cvs rdiff -u -r1.4.2.7 -r1.4.2.8 src/usr.sbin/npf/npfctl/npf_build.c cvs rdiff -u -r1.10.2.5 -r1.10.2.6 src/usr.sbin/npf/npfctl/npf_data.c cvs rdiff -u -r1.3.2.9 -r1.3.2.10 src/usr.sbin/npf/npfctl/npf_parse.y cvs rdiff -u -r1.1.2.5 -r1.1.2.6 src/usr.sbin/npf/npfctl/npf_scan.l cvs rdiff -u -r1.1.2.4 -r1.1.2.5 src/usr.sbin/npf/npfctl/npf_var.h cvs rdiff -u -r1.11.2.9 -r1.11.2.10 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/share/examples/npf/host-npf.conf diff -u src/share/examples/npf/host-npf.conf:1.2.4.2 src/share/examples/npf/host-npf.conf:1.2.4.3 --- src/share/examples/npf/host-npf.conf:1.2.4.2 Mon Oct 1 20:15:34 2012 +++ src/share/examples/npf/host-npf.conf Tue Dec 11 04:31:53 2012 @@ -1,4 +1,4 @@ -# $NetBSD: host-npf.conf,v 1.2.4.2 2012/10/01 20:15:34 riz Exp $ +# $NetBSD: host-npf.conf,v 1.2.4.3 2012/12/11 04:31:53 riz Exp $ # # this is an example of NPF rules for a host (i.e., not routing) with # two network interfaces, wired and wifi @@ -7,7 +7,12 @@ # it also does IPSEC on the wifi # $wired_if = "wm0" +$wired_v4 = { inet4(wm0) } +$wired_v6 = { inet6(wm0) } + $wifi_if = "iwn0" +$wifi_v4 = { inet4(iwn0) } +$wifi_v6 = { inet6(iwn0) } $dhcpserver = { 198.51.100.1 } @@ -37,38 +42,38 @@ group (name "wired", interface $wired_if pass in final family inet proto icmp all pass in final family inet proto tcp \ - from $dhcpserver port bootps to $wired_if port bootpc + from $dhcpserver port bootps to $wired_v4 port bootpc pass in final family inet proto udp \ - from $dhcpserver port bootps to $wired_if port bootpc + from $dhcpserver port bootps to $wired_v4 port bootpc - pass in final family inet6 proto tcp to $wired_if port ssh + pass in final family inet6 proto tcp to $wired_v6 port ssh pass in final family inet proto tcp flags S/SA \ - from $backupsrv_v4 to $wired_if port $backup_port + from $backupsrv_v4 to $wired_v4 port $backup_port pass in final family inet proto udp \ - from $backupsrv_v4 to $wired_if port $backup_port + from $backupsrv_v4 to $wired_v4 port $backup_port pass in final family inet6 proto tcp flags S/SA \ - from $backupsrv_v6 to $wired_if port $backup_port + from $backupsrv_v6 to $wired_v6 port $backup_port pass in final family inet6 proto udp \ - from $backupsrv_v6 to $wired_if port $backup_port + from $backupsrv_v6 to $wired_v6 port $backup_port - pass stateful in final family inet6 proto udp to $wired_if \ + pass stateful in final family inet6 proto udp to $wired_v6 \ port $services_udp - pass stateful in final family inet proto udp to $wired_if \ + pass stateful in final family inet proto udp to $wired_v6 \ port $services_udp # only SYN packets need to generate state pass stateful out final family inet6 proto tcp flags S/SA \ - from $wired_if apply "rid" + from $wired_v6 apply "rid" pass stateful out final family inet proto tcp flags S/SA \ - from $wired_if apply "rid" + from $wired_v4 apply "rid" # pass the other tcp packets without generating extra state - pass out final family inet6 proto tcp from $wired_if apply "rid" - pass out final family inet proto tcp from $wired_if apply "rid" + pass out final family inet6 proto tcp from $wired_v6 apply "rid" + pass out final family inet proto tcp from $wired_v4 apply "rid" # all other types of traffic, generate state per packet - pass stateful out final family inet6 from $wired_if apply "rid" - pass stateful out final family inet from $wired_if apply "rid" + pass stateful out final family inet6 from $wired_v6 apply "rid" + pass stateful out final family inet from $wired_v4 apply "rid" } @@ -81,37 +86,37 @@ group (name "wifi", interface $wifi_if) pass in final family inet6 proto ipv6-icmp to ff00::/10 pass out final family inet6 proto ipv6-icmp from ff00::/10 - pass in final family inet6 proto ipv6-icmp to $wifi_if - pass in final family inet proto icmp to $wifi_if + pass in final family inet6 proto ipv6-icmp to $wifi_v6 + pass in final family inet proto icmp to $wifi_v6 pass in final family inet proto tcp \ - from any port bootps to $wifi_if port bootpc + from any port bootps to $wifi_v4 port bootpc pass in final family inet proto udp \ - from any port bootps to $wifi_if port bootpc + from any port bootps to $wifi_v4 port bootpc - pass in final family inet6 proto tcp flags S/SA to $wifi_if port ssh + pass in final family inet6 proto tcp flags S/SA to $wifi_v6 port ssh - pass in final family inet6 proto udp to $wifi_if port $services_udp - pass in final family inet proto udp to $wifi_if port $services_udp + pass in final family inet6 proto udp to $wifi_v6 port $services_udp + pass in final family inet proto udp to $wifi_v4 port $services_udp # IPSEC - pass in final family inet6 proto udp to $wifi_if port isakmp - pass in final family inet proto udp to $wifi_if port isakmp + pass in final family inet6 proto udp to $wifi_v6 port isakmp + pass in final family inet proto udp to $wifi_v4 port isakmp pass in family inet6 proto esp all pass in family inet proto esp all # only SYN packets need to generate state pass stateful out final family inet6 proto tcp flags S/SA \ - from $wifi_if apply "rid" + from $wifi_v6 apply "rid" pass stateful out final family inet proto tcp flags S/SA \ - from $wifi_if apply "rid" + from $wifi_v4 apply "rid" # pass the other tcp packets without generating extra state - pass out final family inet6 proto tcp from $wifi_if apply "rid" - pass out final family inet proto tcp from $wifi_if apply "rid" + pass out final family inet6 proto tcp from $wifi_v6 apply "rid" + pass out final family inet proto tcp from $wifi_v4 apply "rid" # all other types of traffic, generate state per packet - pass stateful out final family inet6 from $wifi_if apply "rid" - pass stateful out final family inet from $wifi_if apply "rid" + pass stateful out final family inet6 from $wifi_v6 apply "rid" + pass stateful out final family inet from $wifi_v4 apply "rid" } group (default) { Index: src/share/examples/npf/soho_gw-npf.conf diff -u src/share/examples/npf/soho_gw-npf.conf:1.2.4.2 src/share/examples/npf/soho_gw-npf.conf:1.2.4.3 --- src/share/examples/npf/soho_gw-npf.conf:1.2.4.2 Mon Oct 1 20:15:34 2012 +++ src/share/examples/npf/soho_gw-npf.conf Tue Dec 11 04:31:53 2012 @@ -1,4 +1,4 @@ -# $NetBSD: soho_gw-npf.conf,v 1.2.4.2 2012/10/01 20:15:34 riz Exp $ +# $NetBSD: soho_gw-npf.conf,v 1.2.4.3 2012/12/11 04:31:53 riz Exp $ # # SOHO border # @@ -6,6 +6,9 @@ # IPv4 only # $ext_if = "wm0" +$ext_v4 = inet4(wm0) +$ext_addrs = { ifnet(wm0) } + $int_if = "wm1" # a table to house e.g. block candidates in @@ -20,11 +23,11 @@ $localnet = { 198.51.100.0/24 } # NAT outgoing to the address of the external interface # Note: if $ext_if has multiple IP addresses (e.g. IPv6 as well), # then the translation address has to be specified explicitly. -map $ext_if dynamic 198.51.100.0/24 -> $ext_if +map $ext_if dynamic 198.51.100.0/24 -> $ext_v4 # NAT traffic arriving on port 9022 of the external interface address # to host 198.51.100.2 port 22 -map $ext_if dynamic 198.51.100.2 port 22 <- $ext_if 9022 +map $ext_if dynamic 198.51.100.2 port 22 <- $ext_v4 9022 procedure "log" { log: npflog0 @@ -35,18 +38,18 @@ procedure "rid" { } group (name "external", interface $ext_if) { - pass stateful out final from $ext_if apply "rid" + pass stateful out final from $ext_addrs apply "rid" block in final from <1> - pass stateful in final family inet proto tcp to $ext_if port ssh \ + pass stateful in final family inet proto tcp to $ext_v4 port ssh \ apply "log" - pass stateful in final proto tcp to $ext_if port $services_tcp - pass stateful in final proto udp to $ext_if port $services_udp + pass stateful in final proto tcp to $ext_addrs port $services_tcp + pass stateful in final proto udp to $ext_addrs port $services_udp # Passive FTP - pass stateful in final proto tcp to $ext_if port 49151-65535 + pass stateful in final proto tcp to $ext_addrs port 49151-65535 # Traceroute - pass stateful in final proto udp to $ext_if port 33434-33600 + pass stateful in final proto udp to $ext_addrs port 33434-33600 } group (name "internal", interface $int_if) { Index: src/sys/net/npf/npf_tableset.c diff -u src/sys/net/npf/npf_tableset.c:1.9.2.6 src/sys/net/npf/npf_tableset.c:1.9.2.7 --- src/sys/net/npf/npf_tableset.c:1.9.2.6 Sat Nov 24 04:34:41 2012 +++ src/sys/net/npf/npf_tableset.c Tue Dec 11 04:31:53 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: npf_tableset.c,v 1.9.2.6 2012/11/24 04:34:41 riz Exp $ */ +/* $NetBSD: npf_tableset.c,v 1.9.2.7 2012/12/11 04:31:53 riz Exp $ */ /*- * Copyright (c) 2009-2012 The NetBSD Foundation, Inc. @@ -41,7 +41,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: npf_tableset.c,v 1.9.2.6 2012/11/24 04:34:41 riz Exp $"); +__KERNEL_RCSID(0, "$NetBSD: npf_tableset.c,v 1.9.2.7 2012/12/11 04:31:53 riz Exp $"); #include <sys/param.h> #include <sys/types.h> @@ -575,8 +575,7 @@ npf_table_list(npf_tableset_t *tset, u_i if (error) break; error = table_tree_list(&t->t_tree[1], 128, ubuf, len, &off); - if (error) - break; + break; default: KASSERT(false); } Index: src/usr.sbin/npf/npfctl/npf.conf.5 diff -u src/usr.sbin/npf/npfctl/npf.conf.5:1.9.2.4 src/usr.sbin/npf/npfctl/npf.conf.5:1.9.2.5 --- src/usr.sbin/npf/npfctl/npf.conf.5:1.9.2.4 Mon Oct 1 20:05:56 2012 +++ src/usr.sbin/npf/npfctl/npf.conf.5 Tue Dec 11 04:31:53 2012 @@ -1,4 +1,4 @@ -.\" $NetBSD: npf.conf.5,v 1.9.2.4 2012/10/01 20:05:56 riz Exp $ +.\" $NetBSD: npf.conf.5,v 1.9.2.5 2012/12/11 04:31:53 riz 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 September 30, 2012 +.Dd November 26, 2012 .Dt NPF.CONF 5 .Os .Sh NAME @@ -96,6 +96,18 @@ The file should contain a list of IP add .Ed .Pp Tables of type "hash" can only contain IP addresses. +.Ss Interfaces +Interfaces can be specified as the values of the variables: +.Bd -literal +$pub_if_list = { ifnet(wm0), ifnet(wm1) } +.Ed +In the context of filtering, an interface provides a list of its +all IP addresses, including IPv4 and IPv6. +Specific interface addresses can be selected by the family, e.g.: +.Bd -literal +$pub_if4 = inet4(wm0) +$pub_if6 = { inet6(wm0) } +.Ed .Ss Groups Groups may have the following options: name, interface, and direction. They are defined in the following form: @@ -151,7 +163,7 @@ bi-directional NAT (combination of inbou The following would translate the source to the IP address specified by the $pub_ip for the packets on the interface $ext_if. .Bd -literal -map $ext_if dynamic 10.1.1.0/24 -> $pub_if +map $ext_if dynamic 10.1.1.0/24 -> $pub_ip .Ed .Pp Translations are implicitly filtered by limiting the operation to the @@ -256,8 +268,8 @@ directory containing further examples .\" ----- .Sh EXAMPLES .Bd -literal -$ext_if = "wm0" -$int_if = "wm1" +$ext_if = ifnet(wm0) +$int_if = ifnet(wm1) table <1> type hash file "/etc/npf_blacklist" table <2> type tree dynamic Index: src/usr.sbin/npf/npfctl/npf_build.c diff -u src/usr.sbin/npf/npfctl/npf_build.c:1.4.2.7 src/usr.sbin/npf/npfctl/npf_build.c:1.4.2.8 --- src/usr.sbin/npf/npfctl/npf_build.c:1.4.2.7 Sun Nov 18 22:38:28 2012 +++ src/usr.sbin/npf/npfctl/npf_build.c Tue Dec 11 04:31:52 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: npf_build.c,v 1.4.2.7 2012/11/18 22:38:28 riz Exp $ */ +/* $NetBSD: npf_build.c,v 1.4.2.8 2012/12/11 04:31:52 riz Exp $ */ /*- * Copyright (c) 2011-2012 The NetBSD Foundation, Inc. @@ -34,7 +34,7 @@ */ #include <sys/cdefs.h> -__RCSID("$NetBSD: npf_build.c,v 1.4.2.7 2012/11/18 22:38:28 riz Exp $"); +__RCSID("$NetBSD: npf_build.c,v 1.4.2.8 2012/12/11 04:31:52 riz Exp $"); #include <sys/types.h> #include <sys/ioctl.h> @@ -145,7 +145,7 @@ npfctl_build_fam(nc_ctx_t *nc, sa_family * Otherwise, address of invalid family was passed manually. */ if (family != AF_UNSPEC && family != fam->fam_family) { - if (!fam->fam_interface) { + if (!fam->fam_ifindex) { yyerror("specified address is not of the required " "family %d", family); } Index: src/usr.sbin/npf/npfctl/npf_data.c diff -u src/usr.sbin/npf/npfctl/npf_data.c:1.10.2.5 src/usr.sbin/npf/npfctl/npf_data.c:1.10.2.6 --- src/usr.sbin/npf/npfctl/npf_data.c:1.10.2.5 Mon Aug 13 17:49:52 2012 +++ src/usr.sbin/npf/npfctl/npf_data.c Tue Dec 11 04:31:52 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: npf_data.c,v 1.10.2.5 2012/08/13 17:49:52 riz Exp $ */ +/* $NetBSD: npf_data.c,v 1.10.2.6 2012/12/11 04:31:52 riz Exp $ */ /*- * Copyright (c) 2009-2012 The NetBSD Foundation, Inc. @@ -31,7 +31,7 @@ */ #include <sys/cdefs.h> -__RCSID("$NetBSD: npf_data.c,v 1.10.2.5 2012/08/13 17:49:52 riz Exp $"); +__RCSID("$NetBSD: npf_data.c,v 1.10.2.6 2012/12/11 04:31:52 riz Exp $"); #include <sys/types.h> #include <sys/null.h> @@ -273,63 +273,60 @@ npfctl_parse_port_range_variable(const c } npfvar_t * -npfctl_parse_iface(const char *ifname) +npfctl_parse_ifnet(const char *ifname, const int family) { - npfvar_t *vp = npfvar_create(".iface"); + npfvar_t *vpa, *vp; struct ifaddrs *ifa; - fam_addr_mask_t fam; - bool gotif = false; + ifnet_addr_t ifna; if (ifs_list == NULL && getifaddrs(&ifs_list) == -1) { err(EXIT_FAILURE, "getifaddrs"); } - memset(&fam, 0, sizeof(fam)); - npfvar_t *ip = npfvar_create(".ifname"); - if (!npfvar_add_element(ip, NPFVAR_STRING, ifname, strlen(ifname) + 1)) - goto out; + vpa = npfvar_create(".ifaddrs"); + ifna.ifna_addrs = vpa; + ifna.ifna_index = npfctl_find_ifindex(ifname); + assert(ifna.ifna_index != 0); for (ifa = ifs_list; ifa != NULL; ifa = ifa->ifa_next) { + fam_addr_mask_t fam; struct sockaddr *sa; - sa_family_t family; if (strcmp(ifa->ifa_name, ifname) != 0) continue; - gotif = true; if ((ifa->ifa_flags & IFF_UP) == 0) warnx("interface '%s' is down", ifname); sa = ifa->ifa_addr; - family = sa->sa_family; - if (family != AF_INET && family != AF_INET6) + if (sa->sa_family != AF_INET && sa->sa_family != AF_INET6) + continue; + if (family != AF_UNSPEC && sa->sa_family != family) continue; - fam.fam_family = family; - fam.fam_interface = ip; + memset(&fam, 0, sizeof(fam)); + fam.fam_family = sa->sa_family; + fam.fam_ifindex = ifna.ifna_index; - if (!npfctl_copy_address(family, &fam.fam_addr, sa)) + if (!npfctl_copy_address(sa->sa_family, &fam.fam_addr, sa)) goto out; if (!npfctl_parse_mask(NULL, fam.fam_family, &fam.fam_mask)) goto out; - if (!npfvar_add_element(vp, NPFVAR_FAM, &fam, sizeof(fam))) + if (!npfvar_add_element(vpa, NPFVAR_FAM, &fam, sizeof(fam))) goto out; - } - if (!gotif) { - yyerror("interface '%s' not found", ifname); - goto out; - } - if (npfvar_get_count(vp) == 0) { + if (npfvar_get_count(vpa) == 0) { yyerror("no addresses matched for interface '%s'", ifname); goto out; } + + vp = npfvar_create(".interface"); + npfvar_add_element(vp, NPFVAR_INTERFACE, &ifna, sizeof(ifna)); return vp; out: - npfvar_destroy(vp); - npfvar_destroy(ip); + npfvar_destroy(ifna.ifna_addrs); return NULL; } Index: src/usr.sbin/npf/npfctl/npf_parse.y diff -u src/usr.sbin/npf/npfctl/npf_parse.y:1.3.2.9 src/usr.sbin/npf/npfctl/npf_parse.y:1.3.2.10 --- src/usr.sbin/npf/npfctl/npf_parse.y:1.3.2.9 Mon Nov 26 17:39:29 2012 +++ src/usr.sbin/npf/npfctl/npf_parse.y Tue Dec 11 04:31:52 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: npf_parse.y,v 1.3.2.9 2012/11/26 17:39:29 riz Exp $ */ +/* $NetBSD: npf_parse.y,v 1.3.2.10 2012/12/11 04:31:52 riz Exp $ */ /*- * Copyright (c) 2011-2012 The NetBSD Foundation, Inc. @@ -100,6 +100,7 @@ yyerror(const char *fmt, ...) %token HASH %token ICMPTYPE %token ID +%token IFNET %token IN %token INET %token INET6 @@ -143,10 +144,11 @@ yyerror(const char *fmt, ...) %type <str> addr, some_name, list_elem, table_store %type <str> proc_param_val, opt_apply -%type <num> ifindex, port, opt_final, on_iface -%type <num> block_or_pass, rule_dir, block_opts, opt_family +%type <num> ifindex, port, opt_final, on_ifindex +%type <num> afamily, opt_family +%type <num> block_or_pass, rule_dir, block_opts %type <num> opt_stateful, icmp_type, table_type, map_sd, map_type -%type <var> addr_or_iface, port_range, icmp_type_and_code +%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 %type <var> procs, proc_call, proc_param_list, proc_param %type <addrport> mapseg @@ -158,9 +160,9 @@ yyerror(const char *fmt, ...) char * str; unsigned long num; double fpnum; + npfvar_t * var; addr_port_t addrport; filt_opts_t filtopts; - npfvar_t * var; opt_proto_t optproto; rule_group_t rulegroup; } @@ -241,6 +243,10 @@ list_elem npfvar_add_element(vp, NPFVAR_VAR_ID, $1, strlen($1) + 1); npfvar_add_elements(cvar, vp); } + | ifnet + { + npfvar_add_elements(cvar, $1); + } | addr_and_mask { npfvar_add_elements(cvar, $1); @@ -277,7 +283,7 @@ map_type ; mapseg - : addr_or_iface port_range + : addr_or_ifnet port_range { $$.ap_netaddr = $1; $$.ap_portrange = $2; @@ -420,8 +426,8 @@ rules ; rule - : block_or_pass opt_stateful rule_dir opt_final on_iface opt_family - opt_proto all_or_filt_opts opt_apply + : block_or_pass opt_stateful rule_dir opt_final on_ifindex + opt_family opt_proto all_or_filt_opts opt_apply { /* * Arguments: attributes, interface index, address @@ -449,14 +455,18 @@ opt_final | { $$ = 0; } ; -on_iface +on_ifindex : ON ifindex { $$ = $2; } | { $$ = 0; } ; +afamily + : INET { $$ = AF_INET; } + | INET6 { $$ = AF_INET6; } + ; + opt_family - : FAMILY INET { $$ = AF_INET; } - | FAMILY INET6 { $$ = AF_INET6; } + : FAMILY afamily { $$ = $2; } | { $$ = AF_UNSPEC; } ; @@ -546,7 +556,7 @@ filt_opts ; filt_addr - : addr_or_iface { $$ = $1; } + : addr_or_ifnet { $$ = $1; } | TABLE_ID { $$ = npfctl_parse_table_id($1); } | ANY { $$ = NULL; } ; @@ -570,36 +580,37 @@ addr_and_mask } ; -addr_or_iface +addr_or_ifnet : addr_and_mask { assert($1 != NULL); $$ = $1; } - | some_name + | ifnet { - $$ = npfctl_parse_iface($1); + ifnet_addr_t *ifna = npfvar_get_data($1, NPFVAR_INTERFACE, 0); + $$ = ifna->ifna_addrs; } | VAR_ID { npfvar_t *vp = npfvar_lookup($1); const int type = npfvar_get_type(vp, 0); + ifnet_addr_t *ifna; switch (type) { - case NPFVAR_VAR_ID: - case NPFVAR_STRING: - $$ = npfctl_parse_iface(npfvar_expand_string(vp)); - break; case NPFVAR_FAM: $$ = vp; break; + case NPFVAR_INTERFACE: + ifna = npfvar_get_data(vp, type, 0); + $$ = ifna->ifna_addrs; + break; case -1: - yyerror("undefined variable '%s' for interface", $1); + yyerror("undefined variable '%s'", $1); break; default: - yyerror("wrong variable '%s' type '%s' or interface", - $1, npfvar_type(type)); - $$ = NULL; + yyerror("wrong variable '%s' type '%s' for address " + "or interface", $1, npfvar_type(type)); break; } } @@ -645,12 +656,14 @@ icmp_type_and_code } | ICMPTYPE icmp_type CODE IDENTIFIER { - $$ = npfctl_parse_icmp($<num>0, $2, npfctl_icmpcode($<num>0, $2, $4)); + $$ = npfctl_parse_icmp($<num>0, $2, + npfctl_icmpcode($<num>0, $2, $4)); } | ICMPTYPE icmp_type CODE VAR_ID { char *s = npfvar_expand_string(npfvar_lookup($4)); - $$ = npfctl_parse_icmp($<num>0, $2, npfctl_icmpcode($<num>0, $2, s)); + $$ = npfctl_parse_icmp($<num>0, $2, + npfctl_icmpcode($<num>0, $2, s)); } | { @@ -687,28 +700,47 @@ icmp_type } ; +ifnet + : IFNET PAR_OPEN IDENTIFIER PAR_CLOSE + { + $$ = npfctl_parse_ifnet($3, AF_UNSPEC); + } + | afamily PAR_OPEN IDENTIFIER PAR_CLOSE + { + $$ = npfctl_parse_ifnet($3, $1); + } + ifindex : some_name { $$ = npfctl_find_ifindex($1); } + | ifnet + { + ifnet_addr_t *ifna = npfvar_get_data($1, NPFVAR_INTERFACE, 0); + $$ = ifna->ifna_index; + } | VAR_ID { npfvar_t *vp = npfvar_lookup($1); const int type = npfvar_get_type(vp, 0); + ifnet_addr_t *ifna; switch (type) { - case NPFVAR_VAR_ID: case NPFVAR_STRING: + case NPFVAR_IDENTIFIER: $$ = npfctl_find_ifindex(npfvar_expand_string(vp)); break; + case NPFVAR_INTERFACE: + ifna = npfvar_get_data(vp, type, 0); + $$ = ifna->ifna_index; + break; case -1: yyerror("undefined variable '%s' for interface", $1); break; default: yyerror("wrong variable '%s' type '%s' for interface", $1, npfvar_type(type)); - $$ = -1; break; } } Index: src/usr.sbin/npf/npfctl/npf_scan.l diff -u src/usr.sbin/npf/npfctl/npf_scan.l:1.1.2.5 src/usr.sbin/npf/npfctl/npf_scan.l:1.1.2.6 --- src/usr.sbin/npf/npfctl/npf_scan.l:1.1.2.5 Mon Nov 26 17:39:29 2012 +++ src/usr.sbin/npf/npfctl/npf_scan.l Tue Dec 11 04:31:52 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: npf_scan.l,v 1.1.2.5 2012/11/26 17:39:29 riz Exp $ */ +/* $NetBSD: npf_scan.l,v 1.1.2.6 2012/12/11 04:31:52 riz Exp $ */ /*- * Copyright (c) 2011-2012 The NetBSD Foundation, Inc. @@ -80,6 +80,7 @@ apply return APPLY; final return FINAL; quick return FINAL; on return ON; +ifnet return IFNET; inet6 return INET6; inet4 return INET; inet return INET; Index: src/usr.sbin/npf/npfctl/npf_var.h diff -u src/usr.sbin/npf/npfctl/npf_var.h:1.1.2.4 src/usr.sbin/npf/npfctl/npf_var.h:1.1.2.5 --- src/usr.sbin/npf/npfctl/npf_var.h:1.1.2.4 Mon Nov 19 18:16:18 2012 +++ src/usr.sbin/npf/npfctl/npf_var.h Tue Dec 11 04:31:52 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: npf_var.h,v 1.1.2.4 2012/11/19 18:16:18 riz Exp $ */ +/* $NetBSD: npf_var.h,v 1.1.2.5 2012/12/11 04:31:52 riz Exp $ */ /*- * Copyright (c) 2011-2012 The NetBSD Foundation, Inc. @@ -49,6 +49,7 @@ #define NPFVAR_TCPFLAG 9 #define NPFVAR_ICMP 10 #define NPFVAR_ICMP6 11 +#define NPFVAR_INTERFACE 12 #ifdef _NPFVAR_PRIVATE static const char *npfvar_types[ ] = { @@ -63,7 +64,8 @@ static const char *npfvar_types[ ] = { [NPFVAR_PROC_PARAM] = "procedure-parameter", [NPFVAR_TCPFLAG] = "tcp-flag", [NPFVAR_ICMP] = "icmp", - [NPFVAR_ICMP6] = "icmp6" + [NPFVAR_ICMP6] = "icmp6", + [NPFVAR_INTERFACE] = "interface" }; #endif Index: src/usr.sbin/npf/npfctl/npfctl.h diff -u src/usr.sbin/npf/npfctl/npfctl.h:1.11.2.9 src/usr.sbin/npf/npfctl/npfctl.h:1.11.2.10 --- src/usr.sbin/npf/npfctl/npfctl.h:1.11.2.9 Mon Nov 26 17:39:29 2012 +++ src/usr.sbin/npf/npfctl/npfctl.h Tue Dec 11 04:31:52 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: npfctl.h,v 1.11.2.9 2012/11/26 17:39:29 riz Exp $ */ +/* $NetBSD: npfctl.h,v 1.11.2.10 2012/12/11 04:31:52 riz Exp $ */ /*- * Copyright (c) 2009-2012 The NetBSD Foundation, Inc. @@ -52,9 +52,16 @@ typedef struct fam_addr_mask { sa_family_t fam_family; npf_addr_t fam_addr; npf_netmask_t fam_mask; - npfvar_t * fam_interface; + unsigned long fam_ifindex; } fam_addr_mask_t; +typedef struct ifnet_addr { + unsigned long ifna_index; + sa_family_t ifna_family; + npfvar_t * ifna_filter; + npfvar_t * ifna_addrs; +} ifnet_addr_t; + typedef struct port_range { in_port_t pr_start; in_port_t pr_end; @@ -101,10 +108,10 @@ in_port_t npfctl_portno(const char *); uint8_t npfctl_icmpcode(int, uint8_t, const char *); uint8_t npfctl_icmptype(int, const char *); unsigned long npfctl_find_ifindex(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 *); npfvar_t * npfctl_parse_icmp(int, int, int); -npfvar_t * npfctl_parse_iface(const char *); npfvar_t * npfctl_parse_port_range(in_port_t, in_port_t); npfvar_t * npfctl_parse_port_range_variable(const char *); npfvar_t * npfctl_parse_fam_addr_mask(const char *, const char *,