Home | History | Annotate | Line # | Download | only in npfctl
npf_parse.y revision 1.16
      1 /*	$NetBSD: npf_parse.y,v 1.16 2012/11/15 22:20:27 rmind Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 2011-2012 The NetBSD Foundation, Inc.
      5  * All rights reserved.
      6  *
      7  * This code is derived from software contributed to The NetBSD Foundation
      8  * by Martin Husemann and Christos Zoulas.
      9  *
     10  * Redistribution and use in source and binary forms, with or without
     11  * modification, are permitted provided that the following conditions
     12  * are met:
     13  * 1. Redistributions of source code must retain the above copyright
     14  *    notice, this list of conditions and the following disclaimer.
     15  * 2. Redistributions in binary form must reproduce the above copyright
     16  *    notice, this list of conditions and the following disclaimer in the
     17  *    documentation and/or other materials provided with the distribution.
     18  *
     19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     29  * POSSIBILITY OF SUCH DAMAGE.
     30  */
     31 
     32 %{
     33 
     34 #include <stdio.h>
     35 #include <err.h>
     36 #include <vis.h>
     37 #include <netdb.h>
     38 
     39 #include "npfctl.h"
     40 
     41 #define	YYSTACKSIZE	4096
     42 
     43 const char *		yyfilename;
     44 
     45 extern int		yylineno, yycolumn;
     46 extern int		yylex(void);
     47 
     48 /* Variable under construction (bottom up). */
     49 static npfvar_t *	cvar;
     50 
     51 void
     52 yyerror(const char *fmt, ...)
     53 {
     54 	extern int yyleng;
     55 	extern char *yytext;
     56 
     57 	char *msg, *context = estrndup(yytext, yyleng);
     58 	bool eol = (*context == '\n');
     59 	va_list ap;
     60 
     61 	va_start(ap, fmt);
     62 	vasprintf(&msg, fmt, ap);
     63 	va_end(ap);
     64 
     65 	fprintf(stderr, "%s:%d:%d: %s", yyfilename,
     66 	    yylineno - (int)eol, yycolumn, msg);
     67 	if (!eol) {
     68 		size_t len = strlen(context);
     69 		char *dst = ecalloc(1, len * 4 + 1);
     70 
     71 		strvisx(dst, context, len, VIS_WHITE|VIS_CSTYLE);
     72 		fprintf(stderr, " near '%s'", dst);
     73 	}
     74 	fprintf(stderr, "\n");
     75 	exit(EXIT_FAILURE);
     76 }
     77 
     78 %}
     79 
     80 %token			ALL
     81 %token			ANY
     82 %token			APPLY
     83 %token			ARROWBOTH
     84 %token			ARROWLEFT
     85 %token			ARROWRIGHT
     86 %token			BLOCK
     87 %token			CURLY_CLOSE
     88 %token			CURLY_OPEN
     89 %token			CODE
     90 %token			COLON
     91 %token			COMMA
     92 %token			DEFAULT
     93 %token			TDYNAMIC
     94 %token			TSTATIC
     95 %token			EQ
     96 %token			TFILE
     97 %token			FLAGS
     98 %token			FROM
     99 %token			GROUP
    100 %token			HASH
    101 %token			ICMPTYPE
    102 %token			ID
    103 %token			IN
    104 %token			INET
    105 %token			INET6
    106 %token			INTERFACE
    107 %token			MAP
    108 %token			MINUS
    109 %token			NAME
    110 %token			ON
    111 %token			OUT
    112 %token			PAR_CLOSE
    113 %token			PAR_OPEN
    114 %token			PASS
    115 %token			PORT
    116 %token			PROCEDURE
    117 %token			PROTO
    118 %token			FAMILY
    119 %token			FINAL
    120 %token			RETURN
    121 %token			RETURNICMP
    122 %token			RETURNRST
    123 %token			SEPLINE
    124 %token			SLASH
    125 %token			STATEFUL
    126 %token			TABLE
    127 %token			TCP
    128 %token			TO
    129 %token			TREE
    130 %token			TYPE
    131 %token	<num>		ICMP
    132 %token	<num>		ICMP6
    133 
    134 %token	<num>		HEX
    135 %token	<str>		IDENTIFIER
    136 %token	<str>		IPV4ADDR
    137 %token	<str>		IPV6ADDR
    138 %token	<num>		NUM
    139 %token	<fpnum>		FPNUM
    140 %token	<str>		STRING
    141 %token	<str>		TABLE_ID
    142 %token	<str>		VAR_ID
    143 
    144 %type	<str>		addr, some_name, list_elem, table_store
    145 %type	<str>		proc_param_val, opt_apply
    146 %type	<num>		ifindex, port, opt_final, on_iface
    147 %type	<num>		block_or_pass, rule_dir, block_opts, opt_family
    148 %type	<num>		opt_stateful, icmp_type, table_type, map_sd, map_type
    149 %type	<var>		addr_or_iface, port_range, icmp_type_and_code
    150 %type	<var>		filt_addr, addr_and_mask, tcp_flags, tcp_flags_and_mask
    151 %type	<var>		procs, proc_call, proc_param_list, proc_param
    152 %type	<addrport>	mapseg
    153 %type	<filtopts>	filt_opts, all_or_filt_opts
    154 %type	<optproto>	opt_proto
    155 %type	<rulegroup>	group_attr, group_opt
    156 
    157 %union {
    158 	char *		str;
    159 	unsigned long	num;
    160 	double		fpnum;
    161 	addr_port_t	addrport;
    162 	filt_opts_t	filtopts;
    163 	npfvar_t *	var;
    164 	opt_proto_t	optproto;
    165 	rule_group_t	rulegroup;
    166 }
    167 
    168 %%
    169 
    170 input
    171 	: lines
    172 	;
    173 
    174 lines
    175 	: line SEPLINE lines
    176 	| line
    177 	;
    178 
    179 line
    180 	: def
    181 	| table
    182 	| map
    183 	| group
    184 	| rproc
    185 	|
    186 	;
    187 
    188 def
    189 	: VAR_ID
    190 	{
    191 		cvar = npfvar_create($1);
    192 		npfvar_add(cvar);
    193 	}
    194 	  EQ definition
    195 	{
    196 		cvar = NULL;
    197 	}
    198 	;
    199 
    200 definition
    201 	: list_elem
    202 	| listdef
    203 	;
    204 
    205 listdef
    206 	: CURLY_OPEN list_elems CURLY_CLOSE
    207 	;
    208 
    209 list_elems
    210 	: list_elem COMMA list_elems
    211 	| list_elem
    212 	;
    213 
    214 list_elem
    215 	: IDENTIFIER
    216 	{
    217 		npfvar_t *vp = npfvar_create(".identifier");
    218 		npfvar_add_element(vp, NPFVAR_IDENTIFIER, $1, strlen($1) + 1);
    219 		npfvar_add_elements(cvar, vp);
    220 	}
    221 	| STRING
    222 	{
    223 		npfvar_t *vp = npfvar_create(".string");
    224 		npfvar_add_element(vp, NPFVAR_STRING, $1, strlen($1) + 1);
    225 		npfvar_add_elements(cvar, vp);
    226 	}
    227 	| NUM MINUS NUM
    228 	{
    229 		npfvar_t *vp = npfctl_parse_port_range($1, $3);
    230 		npfvar_add_elements(cvar, vp);
    231 	}
    232 	| NUM
    233 	{
    234 		npfvar_t *vp = npfvar_create(".num");
    235 		npfvar_add_element(vp, NPFVAR_NUM, &$1, sizeof($1));
    236 		npfvar_add_elements(cvar, vp);
    237 	}
    238 	| VAR_ID
    239 	{
    240 		npfvar_t *vp = npfvar_create(".var_id");
    241 		npfvar_add_element(vp, NPFVAR_VAR_ID, $1, strlen($1) + 1);
    242 		npfvar_add_elements(cvar, vp);
    243 	}
    244 	| addr_and_mask
    245 	{
    246 		npfvar_add_elements(cvar, $1);
    247 	}
    248 	;
    249 
    250 table
    251 	: TABLE TABLE_ID TYPE table_type table_store
    252 	{
    253 		npfctl_build_table($2, $4, $5);
    254 	}
    255 	;
    256 
    257 table_type
    258 	: HASH		{ $$ = NPF_TABLE_HASH; }
    259 	| TREE		{ $$ = NPF_TABLE_TREE; }
    260 	;
    261 
    262 table_store
    263 	: TDYNAMIC	{ $$ = NULL; }
    264 	| TFILE STRING	{ $$ = $2; }
    265 	;
    266 
    267 map_sd
    268 	: TSTATIC	{ $$ = NPFCTL_NAT_STATIC; }
    269 	| TDYNAMIC	{ $$ = NPFCTL_NAT_DYNAMIC; }
    270 	|		{ $$ = NPFCTL_NAT_DYNAMIC; }
    271 	;
    272 
    273 map_type
    274 	: ARROWBOTH	{ $$ = NPF_NATIN | NPF_NATOUT; }
    275 	| ARROWLEFT	{ $$ = NPF_NATIN; }
    276 	| ARROWRIGHT	{ $$ = NPF_NATOUT; }
    277 	;
    278 
    279 mapseg
    280 	: addr_or_iface port_range
    281 	{
    282 		$$.ap_netaddr = $1;
    283 		$$.ap_portrange = $2;
    284 	}
    285 	;
    286 
    287 map
    288 	: MAP ifindex map_sd mapseg map_type mapseg PASS filt_opts
    289 	{
    290 		npfctl_build_natseg($3, $5, $2, &$4, &$6, &$8);
    291 	}
    292 	| MAP ifindex map_sd mapseg map_type mapseg
    293 	{
    294 		npfctl_build_natseg($3, $5, $2, &$4, &$6, NULL);
    295 	}
    296 	;
    297 
    298 rproc
    299 	: PROCEDURE STRING CURLY_OPEN procs CURLY_CLOSE
    300 	{
    301 		npfctl_build_rproc($2, $4);
    302 	}
    303 	;
    304 
    305 procs
    306 	: proc_call SEPLINE procs
    307 	{
    308 		$$ = npfvar_add_elements($1, $3);
    309 	}
    310 	| proc_call	{ $$ = $1; }
    311 	;
    312 
    313 proc_call
    314 	: IDENTIFIER COLON proc_param_list
    315 	{
    316 		proc_call_t pc;
    317 
    318 		pc.pc_name = estrdup($1);
    319 		pc.pc_opts = $3;
    320 		$$ = npfvar_create(".proc_call");
    321 		npfvar_add_element($$, NPFVAR_PROC, &pc, sizeof(pc));
    322 	}
    323 	|	{ $$ = NULL; }
    324 	;
    325 
    326 proc_param_list
    327 	: proc_param COMMA proc_param_list
    328 	{
    329 		$$ = npfvar_add_elements($1, $3);
    330 	}
    331 	| proc_param	{ $$ = $1; }
    332 	|		{ $$ = NULL; }
    333 	;
    334 
    335 proc_param
    336 	/* Key and value pair. */
    337 	: some_name proc_param_val
    338 	{
    339 		proc_param_t pp;
    340 
    341 		pp.pp_param = estrdup($1);
    342 		pp.pp_value = $2 ? estrdup($2) : NULL;
    343 		$$ = npfvar_create(".proc_param");
    344 		npfvar_add_element($$, NPFVAR_PROC_PARAM, &pp, sizeof(pp));
    345 	}
    346 	;
    347 
    348 proc_param_val
    349 	: some_name	{ $$ = $1; }
    350 	| NUM		{ (void)asprintf(&$$, "%ld", $1); }
    351 	| FPNUM		{ (void)asprintf(&$$, "%lf", $1); }
    352 	|		{ $$ = NULL; }
    353 	;
    354 
    355 group
    356 	: GROUP PAR_OPEN group_attr PAR_CLOSE
    357 	{
    358 		npfctl_build_group($3.rg_name, $3.rg_attr, $3.rg_ifnum);
    359 	}
    360 	  ruleset
    361 	;
    362 
    363 group_attr
    364 	: group_opt COMMA group_attr
    365 	{
    366 		$$ = $3;
    367 
    368 		if (($1.rg_name && $$.rg_name) ||
    369 		    ($1.rg_ifnum && $$.rg_ifnum) ||
    370 		    ($1.rg_attr & $$.rg_attr) != 0)
    371 			yyerror("duplicate group option");
    372 
    373 		if ($1.rg_name) {
    374 			$$.rg_name = $1.rg_name;
    375 		}
    376 		if ($1.rg_attr) {
    377 			$$.rg_attr |= $1.rg_attr;
    378 		}
    379 		if ($1.rg_ifnum) {
    380 			$$.rg_ifnum = $1.rg_ifnum;
    381 		}
    382 	}
    383 	| group_opt		{ $$ = $1; }
    384 	;
    385 
    386 group_opt
    387 	: DEFAULT
    388 	{
    389 		$$.rg_name = NULL;
    390 		$$.rg_ifnum = 0;
    391 		$$.rg_attr = NPF_RULE_DEFAULT;
    392 	}
    393 	| NAME STRING
    394 	{
    395 		$$.rg_name = $2;
    396 		$$.rg_ifnum = 0;
    397 		$$.rg_attr = 0;
    398 	}
    399 	| INTERFACE ifindex
    400 	{
    401 		$$.rg_name = NULL;
    402 		$$.rg_ifnum = $2;
    403 		$$.rg_attr = 0;
    404 	}
    405 	| rule_dir
    406 	{
    407 		$$.rg_name = NULL;
    408 		$$.rg_ifnum = 0;
    409 		$$.rg_attr = $1;
    410 	}
    411 	;
    412 
    413 ruleset
    414 	: CURLY_OPEN rules CURLY_CLOSE
    415 	;
    416 
    417 rules
    418 	: rule SEPLINE rules
    419 	| rule
    420 	;
    421 
    422 rule
    423 	: block_or_pass opt_stateful rule_dir opt_final on_iface opt_family
    424 	  opt_proto all_or_filt_opts opt_apply
    425 	{
    426 		/*
    427 		 * Arguments: attributes, interface index, address
    428 		 * family, protocol options, filter options.
    429 		 */
    430 		npfctl_build_rule($1 | $2 | $3 | $4, $5,
    431 		    $6, &$7, &$8, $9);
    432 	}
    433 	|
    434 	;
    435 
    436 block_or_pass
    437 	: BLOCK block_opts	{ $$ = $2; }
    438 	| PASS			{ $$ = NPF_RULE_PASS; }
    439 	;
    440 
    441 rule_dir
    442 	: IN			{ $$ = NPF_RULE_IN; }
    443 	| OUT			{ $$ = NPF_RULE_OUT; }
    444 	|			{ $$ = NPF_RULE_IN | NPF_RULE_OUT; }
    445 	;
    446 
    447 opt_final
    448 	: FINAL			{ $$ = NPF_RULE_FINAL; }
    449 	|			{ $$ = 0; }
    450 	;
    451 
    452 on_iface
    453 	: ON ifindex		{ $$ = $2; }
    454 	|			{ $$ = 0; }
    455 	;
    456 
    457 opt_family
    458 	: FAMILY INET		{ $$ = AF_INET; }
    459 	| FAMILY INET6		{ $$ = AF_INET6; }
    460 	|			{ $$ = AF_UNSPEC; }
    461 	;
    462 
    463 opt_proto
    464 	: PROTO TCP tcp_flags_and_mask
    465 	{
    466 		$$.op_proto = IPPROTO_TCP;
    467 		$$.op_opts = $3;
    468 	}
    469 	| PROTO ICMP icmp_type_and_code
    470 	{
    471 		$$.op_proto = IPPROTO_ICMP;
    472 		$$.op_opts = $3;
    473 	}
    474 	| PROTO ICMP6 icmp_type_and_code
    475 	{
    476 		$$.op_proto = IPPROTO_ICMPV6;
    477 		$$.op_opts = $3;
    478 	}
    479 	| PROTO some_name
    480 	{
    481 		$$.op_proto = npfctl_protono($2);
    482 		$$.op_opts = NULL;
    483 	}
    484 	| PROTO NUM
    485 	{
    486 		$$.op_proto = $2;
    487 		$$.op_opts = NULL;
    488 	}
    489 	|
    490 	{
    491 		$$.op_proto = -1;
    492 		$$.op_opts = NULL;
    493 	}
    494 	;
    495 
    496 all_or_filt_opts
    497 	: ALL
    498 	{
    499 		$$.fo_from.ap_netaddr = NULL;
    500 		$$.fo_from.ap_portrange = NULL;
    501 		$$.fo_to.ap_netaddr = NULL;
    502 		$$.fo_to.ap_portrange = NULL;
    503 	}
    504 	| filt_opts	{ $$ = $1; }
    505 	;
    506 
    507 opt_stateful
    508 	: STATEFUL	{ $$ = NPF_RULE_STATEFUL; }
    509 	|		{ $$ = 0; }
    510 	;
    511 
    512 opt_apply
    513 	: APPLY STRING	{ $$ = $2; }
    514 	|		{ $$ = NULL; }
    515 	;
    516 
    517 block_opts
    518 	: RETURNRST	{ $$ = NPF_RULE_RETRST; }
    519 	| RETURNICMP	{ $$ = NPF_RULE_RETICMP; }
    520 	| RETURN	{ $$ = NPF_RULE_RETRST | NPF_RULE_RETICMP; }
    521 	|		{ $$ = 0; }
    522 	;
    523 
    524 filt_opts
    525 	: FROM filt_addr port_range TO filt_addr port_range
    526 	{
    527 		$$.fo_from.ap_netaddr = $2;
    528 		$$.fo_from.ap_portrange = $3;
    529 		$$.fo_to.ap_netaddr = $5;
    530 		$$.fo_to.ap_portrange = $6;
    531 	}
    532 	| FROM filt_addr port_range
    533 	{
    534 		$$.fo_from.ap_netaddr = $2;
    535 		$$.fo_from.ap_portrange = $3;
    536 		$$.fo_to.ap_netaddr = NULL;
    537 		$$.fo_to.ap_portrange = NULL;
    538 	}
    539 	| TO filt_addr port_range
    540 	{
    541 		$$.fo_from.ap_netaddr = NULL;
    542 		$$.fo_from.ap_portrange = NULL;
    543 		$$.fo_to.ap_netaddr = $2;
    544 		$$.fo_to.ap_portrange = $3;
    545 	}
    546 	;
    547 
    548 filt_addr
    549 	: addr_or_iface		{ $$ = $1; }
    550 	| TABLE_ID		{ $$ = npfctl_parse_table_id($1); }
    551 	| ANY			{ $$ = NULL; }
    552 	;
    553 
    554 addr_and_mask
    555 	: addr SLASH NUM
    556 	{
    557 		$$ = npfctl_parse_fam_addr_mask($1, NULL, &$3);
    558 	}
    559 	| addr SLASH HEX
    560 	{
    561 		$$ = npfctl_parse_fam_addr_mask($1, NULL, &$3);
    562 	}
    563 	| addr SLASH addr
    564 	{
    565 		$$ = npfctl_parse_fam_addr_mask($1, $3, NULL);
    566 	}
    567 	| addr
    568 	{
    569 		$$ = npfctl_parse_fam_addr_mask($1, NULL, NULL);
    570 	}
    571 	;
    572 
    573 addr_or_iface
    574 	: addr_and_mask
    575 	{
    576 		assert($1 != NULL);
    577 		$$ = $1;
    578 	}
    579 	| some_name
    580 	{
    581 		$$ = npfctl_parse_iface($1);
    582 	}
    583 	| VAR_ID
    584 	{
    585 		npfvar_t *vp = npfvar_lookup($1);
    586 		const int type = npfvar_get_type(vp, 0);
    587 
    588 		switch (type) {
    589 		case NPFVAR_VAR_ID:
    590 		case NPFVAR_STRING:
    591 			$$ = npfctl_parse_iface(npfvar_expand_string(vp));
    592 			break;
    593 		case NPFVAR_FAM:
    594 			$$ = vp;
    595 			break;
    596 		case -1:
    597 			yyerror("undefined variable '%s' for interface", $1);
    598 			break;
    599 		default:
    600 			yyerror("wrong variable '%s' type '%s' or interface",
    601 			    $1, npfvar_type(type));
    602 			$$ = NULL;
    603 			break;
    604 		}
    605 	}
    606 	;
    607 
    608 addr
    609 	: IPV4ADDR	{ $$ = $1; }
    610 	| IPV6ADDR	{ $$ = $1; }
    611 	;
    612 
    613 port_range
    614 	: PORT port		/* just port */
    615 	{
    616 		$$ = npfctl_parse_port_range($2, $2);
    617 	}
    618 	| PORT port MINUS port	/* port from-to */
    619 	{
    620 		$$ = npfctl_parse_port_range($2, $4);
    621 	}
    622 	| PORT VAR_ID
    623 	{
    624 		$$ = npfctl_parse_port_range_variable($2);
    625 	}
    626 	|
    627 	{
    628 		$$ = NULL;
    629 	}
    630 	;
    631 
    632 port
    633 	: NUM		{ $$ = $1; }
    634 	| IDENTIFIER	{ $$ = npfctl_portno($1); }
    635 	;
    636 
    637 icmp_type_and_code
    638 	: ICMPTYPE icmp_type
    639 	{
    640 		$$ = npfctl_parse_icmp($<num>0, $2, -1);
    641 	}
    642 	| ICMPTYPE icmp_type CODE NUM
    643 	{
    644 		$$ = npfctl_parse_icmp($<num>0, $2, $4);
    645 	}
    646 	| ICMPTYPE icmp_type CODE IDENTIFIER
    647 	{
    648 		$$ = npfctl_parse_icmp($<num>0, $2, npfctl_icmpcode($<num>0, $2, $4));
    649 	}
    650 	| ICMPTYPE icmp_type CODE VAR_ID
    651 	{
    652 		char *s = npfvar_expand_string(npfvar_lookup($4));
    653 		$$ = npfctl_parse_icmp($<num>0, $2, npfctl_icmpcode($<num>0, $2, s));
    654 	}
    655 	|
    656 	{
    657 		$$ = npfctl_parse_icmp($<num>0, -1, -1);
    658 	}
    659 	;
    660 
    661 tcp_flags_and_mask
    662 	: FLAGS tcp_flags SLASH tcp_flags
    663 	{
    664 		npfvar_add_elements($2, $4);
    665 		$$ = $2;
    666 	}
    667 	| FLAGS tcp_flags
    668 	{
    669 		char *s = npfvar_get_data($2, NPFVAR_TCPFLAG, 0);
    670 		npfvar_add_elements($2, npfctl_parse_tcpflag(s));
    671 		$$ = $2;
    672 	}
    673 	|		{ $$ = NULL; }
    674 	;
    675 
    676 tcp_flags
    677 	: IDENTIFIER	{ $$ = npfctl_parse_tcpflag($1); }
    678 	;
    679 
    680 icmp_type
    681 	: NUM		{ $$ = $1; }
    682 	| IDENTIFIER	{ $$ = npfctl_icmptype($<num>-1, $1); }
    683 	| VAR_ID
    684 	{
    685 		char *s = npfvar_expand_string(npfvar_lookup($1));
    686 		$$ = npfctl_icmptype($<num>-1, s);
    687 	}
    688 	;
    689 
    690 ifindex
    691 	: some_name
    692 	{
    693 		$$ = npfctl_find_ifindex($1);
    694 	}
    695 	| VAR_ID
    696 	{
    697 		npfvar_t *vp = npfvar_lookup($1);
    698 		const int type = npfvar_get_type(vp, 0);
    699 
    700 		switch (type) {
    701 		case NPFVAR_VAR_ID:
    702 		case NPFVAR_STRING:
    703 			$$ = npfctl_find_ifindex(npfvar_expand_string(vp));
    704 			break;
    705 		case -1:
    706 			yyerror("undefined variable '%s' for interface", $1);
    707 			break;
    708 		default:
    709 			yyerror("wrong variable '%s' type '%s' for interface",
    710 			    $1, npfvar_type(type));
    711 			$$ = -1;
    712 			break;
    713 		}
    714 	}
    715 	;
    716 
    717 some_name
    718 	: IDENTIFIER	{ $$ = $1; }
    719 	| STRING	{ $$ = $1; }
    720 	;
    721 
    722 %%
    723