modules/up/src/rpsl/rpsl/rpsl.y
/* [<][>][^][v][top][bottom][index][help] */
FUNCTIONS
This source file includes following functions.
- yyparse
- enable_yy_parser_debugging
- handleArgumentTypeError
- searchMethod
1 %{
2 // $Id: rpsl.y,v 1.10 2001/07/26 14:44:33 engin Exp $
3 //
4 // Copyright (c) 1994 by the University of Southern California
5 // All rights reserved.
6 //
7 // Permission to use, copy, modify, and distribute this software and its
8 // documentation in source and binary forms for lawful non-commercial
9 // purposes and without fee is hereby granted, provided that the above
10 // copyright notice appear in all copies and that both the copyright
11 // notice and this permission notice appear in supporting documentation,
12 // and that any documentation, advertising materials, and other materials
13 // related to such distribution and use acknowledge that the software was
14 // developed by the University of Southern California, Information
15 // Sciences Institute. The name of the USC may not be used to endorse or
16 // promote products derived from this software without specific prior
17 // written permission.
18 //
19 // THE UNIVERSITY OF SOUTHERN CALIFORNIA DOES NOT MAKE ANY
20 // REPRESENTATIONS ABOUT THE SUITABILITY OF THIS SOFTWARE FOR ANY
21 // PURPOSE. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
22 // IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
23 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
24 // TITLE, AND NON-INFRINGEMENT.
25 //
26 // IN NO EVENT SHALL USC, OR ANY OTHER CONTRIBUTOR BE LIABLE FOR ANY
27 // SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES, WHETHER IN CONTRACT, TORT,
28 // OR OTHER FORM OF ACTION, ARISING OUT OF OR IN CONNECTION WITH, THE USE
29 // OR PERFORMANCE OF THIS SOFTWARE.
30 //
31 // Questions concerning this software should be directed to
32 // ratoolset@isi.edu.
33 //
34 // Author(s): Cengiz Alaettinoglu <cengiz@ISI.EDU>
35
36 #include "config.h"
37 #include "time.h"
38 #include "schema.hh"
39 #include "object.hh"
40 #include "regexp.hh"
41 #include "rptype.hh"
42
43
44 #ifdef DEBUG
45 #define YYDEBUG 1
46 #endif // DEBUG
47 #if YYDEBUG != 0
48 // stdio is needed for yydebug
49 #include <cstdio>
50 #endif
51
52 extern void handle_error(char *, ...);
53 extern void handle_object_error(char *, ...);
54 extern void handle_warning(char *, ...);
55 extern int yylex();
56 char *token_name(int token_id);
57 void rpslerror(char *s, ...);
58 Attr *changeCurrentAttr(Attr *b);
59 void handleArgumentTypeError(char *attr, char *method, int position,
60 const RPType *correctType,
61 bool isOperator = false);
62 const AttrMethod *searchMethod(const AttrRPAttr *rp_attr, char *method, ItemList *args);
63
64 /* argument to yyparse result of parsing should be stored here */
65 #define YYPARSE_PARAM object
66 #define yyschema schema
67 #define enable_yy_parser_debugging enable_rpsl_parser_debugging
68
69 extern Object *current_object;
70
71 %}
72
73 %expect 1
74
75 %union {
76 long long int i;
77 double real;
78 char *string;
79 void *ptr;
80 time_t time;
81 Item *item;
82 ItemList *list;
83 regexp *re;
84 SymID sid;
85 IPAddr *ip;
86 Prefix *prfx;
87 PrefixRange *prfxrng;
88 RPType *typenode;
89
90 Filter *filter;
91 FilterMS *moreSpecOp;
92 PolicyPeering *peering;
93 PolicyActionList *actionList;
94 PolicyAction *actionNode;
95 PolicyFactor *policyFactor;
96 PolicyTerm *policyTerm;
97 PolicyExpr *policyExpr;
98 List<PolicyPeeringAction> *peeringActionList;
99
100 Attr *attr;
101 AttrAttr *rpslattr;
102 AttrMethod *method;
103 const AttrRPAttr *rp_attr;
104 const AttrProtocol *protocol;
105 AttrProtocolOption *protocol_option;
106 List<AttrProtocolOption> *protocol_option_list;
107
108 AttrPeerOption *peer_option;
109 List<AttrPeerOption> *peer_option_list;
110
111 List<RPTypeNode> *typelist;
112 List<AttrMethod> *methodlist;
113 List<WordNode> *wordlist;
114
115 List<AttrMntRoutes::MntPrfxPair> *listMntPrfxPair;
116 AttrMntRoutes::MntPrfxPair *mntPrfxPair;
117 }
118
119 %token KEYW_TRUE
120 %token KEYW_FALSE
121 %token KEYW_ACTION
122 %token KEYW_ACCEPT
123 %token KEYW_ANNOUNCE
124 %token KEYW_FROM
125 %token KEYW_TO
126 %token KEYW_AT
127 %token KEYW_ANY
128 %token KEYW_REFINE
129 %token KEYW_EXCEPT
130 %token KEYW_STATIC
131 %token KEYW_NETWORKS
132 %token KEYW_MASKLEN
133 %token KEYW_UNION
134 %token KEYW_RANGE
135 %token KEYW_LIST
136 %token KEYW_OF
137 %token KEYW_OPERATOR
138 %token KEYW_SYNTAX
139 %token KEYW_SPECIAL
140 %token KEYW_OPTIONAL
141 %token KEYW_MANDATORY
142 %token KEYW_INTERNAL
143 %token KEYW_SINGLEVALUED
144 %token KEYW_MULTIVALUED
145 %token KEYW_LOOKUP
146 %token KEYW_KEY
147 %token KEYW_DELETED
148 %token KEYW_GENERATED
149 %token KEYW_OBSOLETE
150 %token KEYW_PEERAS
151 %token KEYW_PROTOCOL
152 %token KEYW_INTO
153 %token KEYW_ATOMIC
154 %token KEYW_INBOUND
155 %token KEYW_OUTBOUND
156 %token KEYW_UPON
157 %token KEYW_HAVE_COMPONENTS
158 %token KEYW_EXCLUDE
159
160 %token KEYW_NONE
161 %token KEYW_MAILFROM
162 %token KEYW_CRYPTPW
163 %token KEYW_ASSIGNED
164 %token KEYW_ALLOCATED
165 %token KEYW_PI
166 %token KEYW_PA
167 %token KEYW_UNSPECIFIED
168 %token KEYW_EXT
169 %token KEYW_SIMPLE
170 %token KEYW_RIPE
171 %token KEYW_INTERNIC
172 %token KEYW_CLIENTADDRESS
173
174
175 %token TKN_ERROR
176 %token TKN_UNKNOWN_CLASS
177 %token TKN_EOA /* end of attribute */
178 %token TKN_EOO /* end of object */
179 %token TKN_FREETEXT
180 %token <i> TKN_INT
181 %token <real> TKN_REAL
182 %token <string> TKN_STRING
183 %token <time> TKN_TIMESTAMP
184 %token <string> TKN_BLOB
185 %token <ip> TKN_IPV4
186 %token <string> TKN_PRFXV6
187 %token <prfx> TKN_PRFXV4
188 %token <prfxrng> TKN_PRFXV4RNG
189 %token <i> TKN_ASNO
190 %token <sid> TKN_ASNAME
191 %token <sid> TKN_RSNAME
192 %token <sid> TKN_RTRSNAME
193 %token <sid> TKN_PRNGNAME
194 %token <sid> TKN_FLTRNAME
195 %token <i> TKN_BOOLEAN
196 %token <string> TKN_WORD
197 %token <rp_attr> TKN_RP_ATTR
198 %token <sid> TKN_DNS
199 %token <string> TKN_EMAIL
200 %token TKN_3DOTS
201
202 %token <string> TKN_NICHDL
203 %token <string> TKN_KEYCRTNAME
204 %token <string> TKN_CRYPTEDPW
205
206 %token <attr> ATTR_GENERIC
207 %token <attr> ATTR_BLOBS
208 %token <attr> ATTR_IMPORT
209 %token <attr> ATTR_EXPORT
210 %token <attr> ATTR_DEFAULT
211 %token <attr> ATTR_FREETEXT
212 %token <attr> ATTR_CHANGED
213 %token <attr> ATTR_IFADDR
214 %token <attr> ATTR_PEER
215 %token <attr> ATTR_INJECT
216 %token <attr> ATTR_COMPONENTS
217 %token <attr> ATTR_AGGR_MTD
218 %token <attr> ATTR_AGGR_BNDRY
219 %token <attr> ATTR_RS_MEMBERS
220 %token <attr> ATTR_RP_ATTR
221 %token <attr> ATTR_TYPEDEF
222 %token <attr> ATTR_PROTOCOL
223 %token <attr> ATTR_FILTER
224 %token <attr> ATTR_PEERING
225 %token <attr> ATTR_ATTR
226 %token <attr> ATTR_MNT_ROUTES
227
228 %token <attr> ATTR_NICHDL
229 %token <attr> ATTR_AUTH
230 %token <attr> ATTR_STATUS_INET
231 %token <attr> ATTR_PHONE
232 %token <attr> ATTR_SOURCE
233 %token <attr> ATTR_REFER
234 %token <attr> ATTR_COUNTRY
235 %token <attr> ATTR_PERSON
236
237 %left OP_OR
238 %left OP_AND
239 %right OP_NOT
240 %nonassoc<moreSpecOp> OP_MS
241 %nonassoc<string> TKN_OPERATOR
242
243 %type<list> generic_list
244 %type<list> rs_members_list
245 %type<list> opt_rs_members_list
246 %type<list> blobs_list
247 %type<list> generic_non_empty_list
248 %type<item> list_item
249 %type<item> list_item_0
250 %type<item> rs_member
251
252 %type<string> tkn_word
253 %type<string> tkn_word_from_keyw
254
255 %type<string> tkn_word_from_keyw_none
256 %type<string> tkn_word_from_keyw_mailfrom
257 %type<string> tkn_word_from_keyw_cryptpw
258 %type<string> tkn_word_from_keyw_assigned
259 %type<string> tkn_word_from_keyw_allocated
260 %type<string> tkn_word_from_keyw_pi
261 %type<string> tkn_word_from_keyw_pa
262 %type<string> tkn_word_from_keyw_unspecified
263 %type<string> tkn_word_from_keyw_ext
264 %type<string> tkn_word_from_keyw_simple
265 %type<string> tkn_word_from_keyw_ripe
266 %type<string> tkn_word_from_keyw_internic
267 %type<string> tkn_word_from_keyw_clientaddress
268
269 %type<attr> attribute
270 %type<attr> generic_attribute
271 %type<attr> blobs_attribute
272 %type<attr> changed_attribute
273 %type<attr> ifaddr_attribute
274 %type<attr> peer_attribute
275 %type<attr> components_attribute
276 %type<attr> inject_attribute
277 %type<attr> aggr_mtd_attribute
278 %type<attr> aggr_bndry_attribute
279
280 %type<attr> import_attribute
281 %type<attr> export_attribute
282 %type<attr> default_attribute
283 %type<attr> typedef_attribute
284 %type<attr> rpattr_attribute
285 %type<attr> rs_members_attribute
286 %type<attr> protocol_attribute
287 %type<attr> filter_attribute
288 %type<attr> peering_attribute
289 %type<attr> attr_attribute
290 %type<attr> freetext_attribute
291 %type<attr> mnt_routes_attribute
292
293 %type<attr> nichdl_attribute
294 %type<attr> auth_attribute
295 %type<attr> status_inet_attribute
296 %type<attr> phone_attribute
297 %type<attr> source_attribute
298 %type<attr> refer_attribute
299 %type<attr> country_attribute
300 %type<attr> person_attribute
301
302 %type<filter> filter
303 %type<filter> opt_default_filter
304 %type<filter> filter_term
305 %type<filter> filter_factor
306 %type<filter> filter_operand
307 %type<filter> filter_prefix
308 %type<filter> filter_prefix_operand
309 %type<filter> opt_filter_prefix_list
310 %type<filter> filter_prefix_list
311 %type<prfxrng> filter_prefix_list_prefix
312 %type<filter> filter_rp_attribute
313
314 %type<filter> opt_as_expr
315 %type<filter> as_expr
316 %type<filter> as_expr_term
317 %type<filter> as_expr_factor
318 %type<filter> as_expr_operand
319
320 %type<filter> opt_router_expr
321 %type<filter> opt_router_expr_with_at
322 %type<filter> router_expr
323 %type<filter> router_expr_term
324 %type<filter> router_expr_factor
325 %type<filter> router_expr_operand
326
327 %type<filter> opt_inject_expr
328 %type<filter> inject_expr
329 %type<filter> inject_expr_term
330 %type<filter> inject_expr_factor
331 %type<filter> inject_expr_operand
332
333 %type<re> filter_aspath
334 %type<re> filter_aspath_term
335 %type<re> filter_aspath_closure
336 %type<re> filter_aspath_factor
337 %type<re> filter_aspath_no
338 %type<re> filter_aspath_range
339
340 %type<actionList> action
341 %type<actionList> opt_action
342 %type<actionNode> single_action
343
344 %type<peering> peering
345
346 %type<peeringActionList> import_peering_action_list
347 %type<peeringActionList> export_peering_action_list
348 %type<policyFactor> import_factor
349 %type<policyTerm> import_factor_list
350 %type<policyTerm> import_term
351 %type<policyExpr> import_expr
352 %type<policyFactor> export_factor
353 %type<policyTerm> export_factor_list
354 %type<policyTerm> export_term
355 %type<policyExpr> export_expr
356 %type<protocol> opt_protocol_from
357 %type<protocol> opt_protocol_into
358
359 %type<wordlist> enum_list
360 %type<typenode> typedef_type
361 %type<typelist> typedef_type_list
362
363 %type<method> method
364 %type<methodlist> methods
365
366 %type<protocol_option> protocol_option
367 %type<protocol_option_list> protocol_options
368
369 %type<peer_option> peer_option
370 %type<peer_option_list> peer_options
371 %type<peer_option_list> opt_peer_options
372 %type<ip> peer_id
373
374 %type<rpslattr> opt_attr_options
375 %type<rpslattr> attr_options
376 %type<rpslattr> attr_option
377
378 %type<listMntPrfxPair> mnt_routes_list
379 %type<mntPrfxPair> mnt_routes_list_item
380
381 %type<string> int_list
382 %type<string> name_list
383
384 %%
/* [<][>][^][v][top][bottom][index][help] */
385 object: attribute_list TKN_EOO {
386 YYACCEPT;
387 }
388 | TKN_UNKNOWN_CLASS TKN_EOO {
389 YYACCEPT;
390 }
391 | error TKN_EOO {
392 handle_object_error("Error: syntax error\n");
393 YYABORT;
394 }
395 | attribute_list { // end of file
396 YYACCEPT;
397 }
398 | TKN_UNKNOWN_CLASS { // end of file
399 YYACCEPT;
400 }
401 | error { // end of file
402 handle_object_error("Error: syntax error\n");
403 YYABORT;
404 }
405 | { // end of file
406 YYABORT;
407 }
408 ;
409
410 attribute_list: attribute {
411 (*current_object) += $1;
412 }
413 | attribute_list attribute {
414 (*current_object) += $2;
415 }
416 ;
417
418 attribute: generic_attribute
419 | blobs_attribute
420 | changed_attribute
421 | import_attribute
422 | export_attribute
423 | default_attribute
424 | peer_attribute
425 | ifaddr_attribute
426 | components_attribute
427 | inject_attribute
428 | aggr_mtd_attribute
429 | aggr_bndry_attribute
430 | typedef_attribute
431 | protocol_attribute
432 | rpattr_attribute
433 | rs_members_attribute
434 | filter_attribute
435 | peering_attribute
436 | attr_attribute
437 | freetext_attribute
438 | mnt_routes_attribute
439 | nichdl_attribute
440 | auth_attribute
441 | status_inet_attribute
442 | phone_attribute
443 | source_attribute
444 | refer_attribute
445 | country_attribute
446 | person_attribute
447 | TKN_ERROR TKN_EOA { // the current line started w/ non-attribute
448 $$ = changeCurrentAttr(new Attr);
449 handle_error("Error: syntax error\n");
450 }
451 | error TKN_EOA {
452 $$ = changeCurrentAttr(new Attr);
453 handle_error("Error: syntax error\n");
454 yyerrok;
455 }
456 ;
457
458 //**** Generic Attributes ************************************************
459
460 changed_attribute: ATTR_CHANGED TKN_EMAIL TKN_INT TKN_EOA {
461 free($2);
462 $$ = $1;
463 }
464 | ATTR_CHANGED TKN_EMAIL TKN_EOA {
465 free($2);
466 $$ = $1;
467 }
468 | ATTR_CHANGED error TKN_EOA {
469 handle_error("Error: \"changed: <email> <YYYYMMDD>\" expected\n");
470 yyerrok;
471 }
472 ;
473
474
475 nichdl_attribute: ATTR_NICHDL TKN_NICHDL TKN_EOA {
476 if(yyschema.validNICHandle($2)){
477 free($2);
478 $$ = $1;
479 }else{
480 free($2);
481 handle_error("Error: Invalid NIC handle\n");
482 yyerrok;
483 }
484 }
485 | ATTR_NICHDL error TKN_EOA {
486 handle_error("Error: \"%s: <nic-handle>\" expected\n",$1->type->name());
487 yyerrok;
488 }
489
490 auth_attribute: ATTR_AUTH tkn_word_from_keyw_none TKN_EOA {
491 $$ = $1;
492 }
493 | ATTR_AUTH tkn_word_from_keyw_mailfrom TKN_EMAIL TKN_EOA {
494 free($3);
495 $$ = $1;
496 }
497 | ATTR_AUTH tkn_word_from_keyw_cryptpw TKN_CRYPTEDPW TKN_EOA {
498 free($3);
499 $$ = $1;
500 }
501 | ATTR_AUTH TKN_KEYCRTNAME TKN_EOA {
502 free($2);
503 $$ = $1;
504 }
505 | ATTR_AUTH error TKN_EOA {
506 handle_error("Error: \"auth: MAIL-FROM <regexp>\""
507 ", \"auth: NONE\", \"auth: CRYPT-PW <cryptedpaswd>\""
508 " or \"auth: PGPKEY-<pgpid>\" expected\n");
509 yyerrok;
510
511 }
512 ;
513
514
515
516 status_inet_attribute: ATTR_STATUS_INET tkn_word_from_keyw_assigned tkn_word_from_keyw_pi TKN_EOA {
517 $$ = $1;
518 }
519 | ATTR_STATUS_INET tkn_word_from_keyw_assigned tkn_word_from_keyw_pa TKN_EOA {
520 $$ = $1;
521 }
522 | ATTR_STATUS_INET tkn_word_from_keyw_allocated tkn_word_from_keyw_pi TKN_EOA {
523 $$ = $1;
524 }
525 | ATTR_STATUS_INET tkn_word_from_keyw_allocated tkn_word_from_keyw_pa TKN_EOA {
526 $$ = $1;
527 }
528 | ATTR_STATUS_INET tkn_word_from_keyw_allocated tkn_word_from_keyw_unspecified TKN_EOA {
529 $$ = $1;
530 }
531 | ATTR_STATUS_INET error TKN_EOA {
532 handle_error("Error: \"status\" attribute contains invalid keywords\n");
533 yyerrok;
534 }
535 ;
536
537 phone_attribute: ATTR_PHONE '+' int_list TKN_EOA {
538 $$ = $1;
539 }
540 | ATTR_PHONE '+' int_list '(' int_list ')' int_list TKN_EOA {
541 $$ = $1;
542 }
543 | ATTR_PHONE '+' int_list tkn_word_from_keyw_ext '.' int_list TKN_EOA {
544 $$ = $1;
545 }
546 | ATTR_PHONE '+' int_list '(' int_list ')' int_list tkn_word_from_keyw_ext '.' int_list TKN_EOA {
547 $$ = $1;
548 }
549 | ATTR_PHONE error TKN_EOA {
550 handle_error("Error: intn'l phone number expected (with a preceding '+')\n");
551 yyerrok;
552 }
553
554
555 int_list: TKN_INT {
556 //sprintf($$, "%i", $1);
557 $$ = strdup("phone"); // well, sprintf($$, "%i", $1) didn't work
558 }
559 | int_list TKN_INT{
560 $$ = $1;
561 }
562 | int_list '-' TKN_INT{
563 $$ = $1;
564 }
565 | int_list '.' TKN_INT{
566 $$ = $1;
567 }
568
569
570 source_attribute: ATTR_SOURCE tkn_word TKN_EOA {
571 if(yyschema.searchSource($2)){
572 free($2);
573 $$ = $1;
574 }else{
575 free($2);
576 handle_error("Error: No such source\n");
577 }
578 }
579 | ATTR_SOURCE error TKN_EOA {
580 handle_error("Error: invalid source attribute\n");
581 yyerrok;
582 }
583
584 refer_attribute: ATTR_REFER tkn_word_from_keyw_simple TKN_DNS TKN_EOA {
585 $$ = $1;
586 }
587 | ATTR_REFER tkn_word_from_keyw_simple TKN_DNS TKN_INT TKN_EOA {
588 $$ = $1;
589 }
590 | ATTR_REFER tkn_word_from_keyw_ripe TKN_DNS TKN_EOA {
591 $$ = $1;
592 }
593 | ATTR_REFER tkn_word_from_keyw_ripe TKN_DNS TKN_INT TKN_EOA {
594 $$ = $1;
595 }
596 | ATTR_REFER tkn_word_from_keyw_internic TKN_DNS TKN_EOA {
597 $$ = $1;
598 }
599 | ATTR_REFER tkn_word_from_keyw_internic TKN_DNS TKN_INT TKN_EOA {
600 $$ = $1;
601 }
602 | ATTR_REFER tkn_word_from_keyw_clientaddress TKN_DNS TKN_EOA {
603 $$ = $1;
604 }
605 | ATTR_REFER tkn_word_from_keyw_clientaddress TKN_DNS TKN_INT TKN_EOA {
606 $$ = $1;
607 }
608 | ATTR_REFER error TKN_EOA {
609 handle_error("Error: invalid refer attribute\n");
610 yyerrok;
611 }
612
613 country_attribute: ATTR_COUNTRY tkn_word TKN_EOA {
614 if(yyschema.searchCountry($2)){
615 free($2);
616 $$ = $1;
617 }else{
618 free($2);
619 handle_error("Error: No such country\n");
620 }
621 }
622 | ATTR_COUNTRY error TKN_EOA {
623 handle_error("Error: invalid country attribute\n");
624 yyerrok;
625 }
626
627 person_attribute: ATTR_PERSON tkn_word name_list TKN_EOA {
628 $$ = $1;
629 }
630 | ATTR_PERSON TKN_DNS name_list TKN_EOA {
631 $$ = $1;
632 }
633 | ATTR_PERSON OP_OR name_list TKN_EOA {
634 $$ = $1;
635 }
636 | ATTR_PERSON OP_AND name_list TKN_EOA {
637 $$ = $1;
638 }
639 | ATTR_PERSON error TKN_EOA {
640 handle_error("Error: invalid %s attribute\n",$1->type->name());
641 yyerrok;
642 }
643
644 name_list: tkn_word {
645 $$ = strdup($1);
646 }
647 | TKN_DNS {
648 $$ = strdup($1);
649 }
650 | OP_AND {
651 $$ = strdup("and");
652 }
653 | OP_OR {
654 $$ = strdup("or");
655 }
656 | '.' tkn_word {
657 $$ = strdup($2);
658 }
659 | '.' TKN_DNS {
660 $$ = strdup($2);
661 }
662 | '.' OP_AND {
663 $$ = strdup("and");
664 }
665 | '.' OP_OR {
666 $$ = strdup("or");
667 }
668 | '`' tkn_word {
669 $$ = strdup($2);
670 }
671 | '`' OP_OR {
672 $$ = strdup("or");
673 }
674 | '`' OP_AND {
675 $$ = strdup("and");
676 }
677 | '`' TKN_DNS {
678 $$ = strdup($2);
679 }
680 | '\'' tkn_word {
681 $$ = strdup($2);
682 }
683 | '\'' TKN_DNS {
684 $$ = strdup($2);
685 }
686 | '\'' OP_OR {
687 $$ = strdup("or");
688 }
689 | '\'' OP_AND {
690 $$ = strdup("and");
691 }
692 | '-' tkn_word {
693 $$ = strdup($2);
694 }
695 | '-' TKN_DNS {
696 $$ = strdup($2);
697 }
698 | '-' OP_OR {
699 $$ = strdup("or");
700 }
701 | '-' OP_AND {
702 $$ = strdup("and");
703 }
704 | name_list tkn_word {
705 $$ = strdup($1);
706 }
707 | name_list TKN_DNS {
708 $$ = strdup($1);
709 }
710 | name_list OP_OR {
711 $$ = strdup($1);
712 }
713 | name_list OP_AND {
714 $$ = strdup($1);
715 }
716 | name_list '.' {
717 $$ = strdup($1);
718 }
719 | name_list '`' {
720 $$ = strdup($1);
721 }
722 | name_list '\'' {
723 $$ = strdup($1);
724 }
725 | name_list '-' {
726 $$ = strdup($1);
727 }
728
729
730
731
732 freetext_attribute: ATTR_FREETEXT TKN_EOA {
733 char *start = strchr($1->object->contents + $1->offset, ':') + 1;
734 int len = $1->object->contents + $1->offset + $1->len - start;
735 ItemFREETEXT *ft = new ItemFREETEXT(start, len);
736 ItemList *il = new ItemList;
737 il->append(ft);
738
739 $$ = changeCurrentAttr(new AttrGeneric($1->type, il));
740 }
741 ;
742
743 generic_attribute: ATTR_GENERIC generic_list TKN_EOA {
744 if (!$1->type->subsyntax()->validate($2)) {
745 handle_error("Error: argument to %s should be %s.\n",
746 $1->type->name(), $1->type->subsyntax()->name());
747 delete $2;
748 $$ = changeCurrentAttr(new AttrGeneric($1->type, NULL));
749 } else
750 $$ = changeCurrentAttr(new AttrGeneric($1->type, $2));
751 }
752 | ATTR_GENERIC error TKN_EOA {
753 $$ = $1;
754 handle_error("Error: argument to %s should be %s.\n",
755 $1->type->name(), $1->type->subsyntax()->name());
756 yyerrok;
757 }
758 ;
759
760 generic_list: /* empty list */ {
761 $$ = new ItemList;
762 }
763 | generic_non_empty_list
764 ;
765
766 generic_non_empty_list: list_item {
767 $$ = new ItemList;
768 $$->append($1);
769 }
770 | generic_non_empty_list ',' list_item {
771 $$ = $1;
772 $$->append($3);
773 }
774 ;
775
776 blobs_attribute: ATTR_BLOBS blobs_list TKN_EOA {
777 $$ = changeCurrentAttr(new AttrGeneric($1->type, $2));
778 }
779 | ATTR_BLOBS error TKN_EOA {
780 $$ = $1;
781 handle_error("Error: argument to %s should be blob sequence.\n",
782 $1->type->name());
783 yyerrok;
784 }
785 ;
786
787 blobs_list: list_item {
788 $$ = new ItemList;
789 $$->append($1);
790 }
791 | blobs_list list_item {
792 $$ = $1;
793 $$->append($2);
794 }
795 ;
796
797 list_item: list_item_0 {
798 $$ = $1;
799 }
800 | list_item_0 '-' list_item_0 {
801 $$ = new ItemRange($1, $3);
802 }
803 ;
804
805 list_item_0: TKN_ASNO {
806 $$ = new ItemASNO($1);
807 }
808 | TKN_INT {
809 $$ = new ItemINT($1);
810 }
811 | TKN_REAL {
812 $$ = new ItemREAL($1);
813 }
814 | TKN_STRING {
815 $$ = new ItemSTRING($1);
816 }
817 | TKN_TIMESTAMP {
818 $$ = new ItemTimeStamp($1);
819 }
820 | TKN_IPV4 {
821 $$ = new ItemIPV4($1);
822 }
823 | TKN_PRFXV4 {
824 $$ = new ItemPRFXV4($1);
825 }
826 | TKN_PRFXV6 {
827 $$ = new ItemPRFXV6($1);
828 }
829 | TKN_PRFXV4RNG {
830 $$ = new ItemPRFXV4Range($1);
831 }
832 | TKN_IPV4 ':' TKN_INT {
833 $$ = new ItemConnection($1, $3);
834 }
835 | TKN_IPV4 ':' TKN_INT ':' TKN_INT {
836 $$ = new ItemConnection($1, $3, $5);
837 }
838 | TKN_DNS ':' TKN_INT {
839 $$ = new ItemConnection($1, $3);
840 }
841 | TKN_DNS ':' TKN_INT ':' TKN_INT {
842 $$ = new ItemConnection($1, $3, $5);
843 }
844 | TKN_ASNAME {
845 $$ = new ItemASNAME($1);
846 }
847 | TKN_RSNAME {
848 $$ = new ItemRSNAME($1);
849 }
850 | TKN_RTRSNAME {
851 $$ = new ItemRTRSNAME($1);
852 }
853 | TKN_PRNGNAME {
854 $$ = new ItemPRNGNAME($1);
855 }
856 | TKN_FLTRNAME {
857 $$ = new ItemFLTRNAME($1);
858 }
859 | TKN_BOOLEAN {
860 $$ = new ItemBOOLEAN($1);
861 }
862 | TKN_WORD {
863 $$ = new ItemWORD($1);
864 }
865 | tkn_word_from_keyw {
866 $$ = new ItemWORD($1);
867 }
868 | TKN_DNS {
869 $$ = new ItemDNS($1);
870 }
871 | TKN_EMAIL {
872 $$ = new ItemEMAIL($1);
873 }
874 | TKN_KEYCRTNAME {
875 $$ = new ItemKEYCRTNAME($1);
876 }
877 | TKN_BLOB {
878 $$ = new ItemBLOB($1);
879 }
880 | '{' generic_list '}' {
881 $$ = $2;
882 }
883 | '(' filter ')' {
884 $$ = new ItemFilter($2);
885 }
886 ;
887
888 tkn_word: TKN_WORD {
889 $$ = $1;
890 }
891 | TKN_ASNO {
892 char buffer[64];
893 sprintf(buffer, "AS%d", $1);
894 $$ = strdup(buffer);
895 }
896 | TKN_ASNAME {
897 $$ = strdup($1);
898 }
899 | TKN_RSNAME {
900 $$ = strdup($1);
901 }
902 | TKN_RTRSNAME {
903 $$ = strdup($1);
904 }
905 | TKN_PRNGNAME {
906 $$ = strdup($1);
907 }
908 | TKN_FLTRNAME {
909 $$ = strdup($1);
910 }
911 | TKN_NICHDL {
912 $$ = strdup($1);
913 }
914 | TKN_BOOLEAN {
915 if ($1)
916 $$ = strdup("true");
917 else
918 $$ = strdup("false");
919 }
920 | tkn_word_from_keyw
921 | tkn_word_from_keyw_ripe
922 | tkn_word_from_keyw_internic
923 | tkn_word_from_keyw_simple
924 | tkn_word_from_keyw_clientaddress
925 | tkn_word_from_keyw_pa
926 | tkn_word_from_keyw_pi
927 | tkn_word_from_keyw_unspecified
928 | tkn_word_from_keyw_allocated
929 | tkn_word_from_keyw_assigned
930 | tkn_word_from_keyw_mailfrom
931 | tkn_word_from_keyw_none
932 | tkn_word_from_keyw_cryptpw
933 ;
934
935 tkn_word_from_keyw: KEYW_TRUE {
936 $$ = strdup("true");
937 }
938 | KEYW_FALSE {
939 $$ = strdup("false");
940 }
941 | KEYW_ACTION {
942 $$ = strdup("action");
943 }
944 | KEYW_ACCEPT {
945 $$ = strdup("accept");
946 }
947 | KEYW_ANNOUNCE {
948 $$ = strdup("announce");
949 }
950 | KEYW_FROM {
951 $$ = strdup("from");
952 }
953 | KEYW_TO {
954 $$ = strdup("to");
955 }
956 | KEYW_AT {
957 $$ = strdup("at");
958 }
959 | KEYW_ANY {
960 $$ = strdup("any");
961 }
962 | KEYW_REFINE {
963 $$ = strdup("refine");
964 }
965 | KEYW_EXCEPT {
966 $$ = strdup("except");
967 }
968 | KEYW_STATIC {
969 $$ = strdup("static");
970 }
971 | KEYW_NETWORKS {
972 $$ = strdup("networks");
973 }
974 | KEYW_MASKLEN {
975 $$ = strdup("masklen");
976 }
977 | KEYW_UNION {
978 $$ = strdup("union");
979 }
980 | KEYW_RANGE {
981 $$ = strdup("range");
982 }
983 | KEYW_LIST {
984 $$ = strdup("list");
985 }
986 | KEYW_OF {
987 $$ = strdup("of");
988 }
989 | KEYW_OPERATOR {
990 $$ = strdup("operator");
991 }
992 | KEYW_SYNTAX {
993 $$ = strdup("syntax");
994 }
995 | KEYW_SPECIAL {
996 $$ = strdup("special");
997 }
998 | KEYW_OPTIONAL {
999 $$ = strdup("optional");
1000 }
1001 | KEYW_MANDATORY {
1002 $$ = strdup("mandatory");
1003 }
1004 | KEYW_INTERNAL {
1005 $$ = strdup("internal");
1006 }
1007 | KEYW_DELETED {
1008 $$ = strdup("deleted");
1009 }
1010 | KEYW_SINGLEVALUED {
1011 $$ = strdup("singlevalued");
1012 }
1013 | KEYW_GENERATED {
1014 $$ = strdup("generated");
1015 }
1016 | KEYW_MULTIVALUED {
1017 $$ = strdup("multivalued");
1018 }
1019 | KEYW_LOOKUP {
1020 $$ = strdup("lookup");
1021 }
1022 | KEYW_KEY {
1023 $$ = strdup("key");
1024 }
1025 | KEYW_OBSOLETE {
1026 $$ = strdup("obsolete");
1027 }
1028 | KEYW_PEERAS {
1029 $$ = strdup("peeras");
1030 }
1031 | KEYW_PROTOCOL {
1032 $$ = strdup("protocol");
1033 }
1034 | KEYW_INTO {
1035 $$ = strdup("into");
1036 }
1037 | KEYW_ATOMIC {
1038 $$ = strdup("atomic");
1039 }
1040 | KEYW_INBOUND {
1041 $$ = strdup("inbound");
1042 }
1043 | KEYW_OUTBOUND {
1044 $$ = strdup("outbound");
1045 }
1046 ;
1047
1048 tkn_word_from_keyw_none: KEYW_NONE {
1049 $$ = strdup("none");
1050 }
1051
1052 tkn_word_from_keyw_mailfrom: KEYW_MAILFROM {
1053 $$ = strdup("mail-from");
1054 }
1055
1056 tkn_word_from_keyw_cryptpw: KEYW_CRYPTPW {
1057 $$ = strdup("crypt-pw");
1058 }
1059
1060 tkn_word_from_keyw_assigned: KEYW_ASSIGNED {
1061 $$ = strdup("assigned");
1062 }
1063
1064 tkn_word_from_keyw_allocated: KEYW_ALLOCATED {
1065 $$ = strdup("allocated");
1066 }
1067
1068 tkn_word_from_keyw_pi: KEYW_PI {
1069 $$ = strdup("pi");
1070 }
1071
1072 tkn_word_from_keyw_pa: KEYW_PA {
1073 $$ = strdup("pa");
1074 }
1075
1076 tkn_word_from_keyw_unspecified: KEYW_UNSPECIFIED {
1077 $$ = strdup("unspecified");
1078 }
1079
1080 tkn_word_from_keyw_ext: KEYW_EXT {
1081 $$ = strdup("ext");
1082 }
1083
1084 tkn_word_from_keyw_simple: KEYW_SIMPLE {
1085 $$ = strdup("simple");
1086 }
1087
1088 tkn_word_from_keyw_ripe: KEYW_RIPE {
1089 $$ = strdup("ripe");
1090 }
1091
1092 tkn_word_from_keyw_internic: KEYW_INTERNIC {
1093 $$ = strdup("internic");
1094 }
1095
1096 tkn_word_from_keyw_clientaddress: KEYW_CLIENTADDRESS {
1097 $$ = strdup("clientaddress");
1098 }
1099
1100
1101 //**** aut-num class ******************************************************
1102
1103 //// as_expr ////////////////////////////////////////////////////////////
1104
1105 opt_as_expr: {
1106 $$ = new FilterASNAME(symbols.symID("AS-ANY"));
1107 }
1108 | as_expr
1109 ;
1110
1111 as_expr: as_expr OP_OR as_expr_term {
1112 $$ = new FilterOR($1, $3);
1113 }
1114 | as_expr_term
1115 ;
1116
1117 as_expr_term: as_expr_term OP_AND as_expr_factor {
1118 $$ = new FilterAND($1, $3);
1119 }
1120 | as_expr_term KEYW_EXCEPT as_expr_factor {
1121 $$ = new FilterEXCEPT($1, $3);
1122 }
1123 | as_expr_factor
1124 ;
1125
1126 as_expr_factor: '(' as_expr ')' {
1127 $$ = $2;
1128 }
1129 | as_expr_operand
1130 ;
1131
1132 as_expr_operand: TKN_ASNO {
1133 $$ = new FilterASNO($1);
1134 }
1135 | TKN_ASNAME {
1136 $$ = new FilterASNAME($1);
1137 }
1138 ;
1139
1140 //// router_expr ///////////////////////////////////////////////////////////
1141
1142 opt_router_expr: {
1143 $$ = new FilterANY;
1144 }
1145 | router_expr {
1146 $$ = $1;
1147 }
1148 ;
1149
1150 opt_router_expr_with_at: {
1151 $$ = new FilterANY;
1152 }
1153 | KEYW_AT router_expr {
1154 $$ = $2;
1155 }
1156 ;
1157
1158 router_expr: router_expr OP_OR router_expr_term {
1159 $$ = new FilterOR($1, $3);
1160 }
1161 | router_expr_term
1162 ;
1163
1164 router_expr_term: router_expr_term OP_AND router_expr_factor {
1165 $$ = new FilterAND($1, $3);
1166 }
1167 | router_expr_term KEYW_EXCEPT router_expr_factor {
1168 $$ = new FilterEXCEPT($1, $3);
1169 }
1170 | router_expr_factor
1171 ;
1172
1173 router_expr_factor: '(' router_expr ')' {
1174 $$ = $2;
1175 }
1176 | router_expr_operand
1177 ;
1178
1179 router_expr_operand: TKN_IPV4 {
1180 $$ = new FilterRouter($1);
1181 }
1182 | TKN_DNS {
1183 $$ = new FilterRouterName($1);
1184 }
1185 | TKN_RTRSNAME {
1186 $$ = new FilterRTRSNAME($1);
1187 }
1188 ;
1189
1190 //// peering ////////////////////////////////////////////////////////////
1191
1192 peering: as_expr opt_router_expr opt_router_expr_with_at {
1193 $$ = new PolicyPeering($1, $2, $3);
1194 }
1195 | TKN_PRNGNAME {
1196 $$ = new PolicyPeering($1);
1197 }
1198 ;
1199
1200 //// action /////////////////////////////////////////////////////////////
1201
1202 opt_action: {
1203 $$ = new PolicyActionList;
1204 }
1205 | KEYW_ACTION action {
1206 $$ = $2;
1207 }
1208 ;
1209
1210 action: single_action {
1211 $$ = new PolicyActionList;
1212 if ($1)
1213 $$->append($1);
1214 }
1215 | action single_action {
1216 $$ = $1;
1217 if ($2)
1218 $$->append($2);
1219 }
1220 ;
1221
1222 single_action: TKN_RP_ATTR '.' TKN_WORD '(' generic_list ')' ';' {
1223 const AttrMethod *mtd = searchMethod($1, $3, $5);
1224 if (mtd)
1225 $$ = new PolicyAction($1, mtd, $5);
1226 else {
1227 delete $5;
1228 $$ = NULL;
1229 }
1230 free($3);
1231 }
1232 | TKN_RP_ATTR TKN_OPERATOR list_item ';' {
1233 ItemList *plist = new ItemList;
1234 plist->append($3);
1235
1236 const AttrMethod *mtd = searchMethod($1, $2, plist);
1237 if (mtd)
1238 $$ = new PolicyAction($1, mtd, plist);
1239 else {
1240 delete plist;
1241 $$ = NULL;
1242 }
1243 // Added by wlee
1244 free($2);
1245 }
1246 | TKN_RP_ATTR '(' generic_list ')' ';' {
1247 const AttrMethod *mtd = searchMethod($1, "()", $3);
1248 if (mtd)
1249 $$ = new PolicyAction($1, mtd, $3);
1250 else {
1251 delete $3;
1252 $$ = NULL;
1253 }
1254 }
1255 | TKN_RP_ATTR '[' generic_list ']' ';' {
1256 const AttrMethod *mtd = searchMethod($1, "[]", $3);
1257 if (mtd)
1258 $$ = new PolicyAction($1, mtd, $3);
1259 else {
1260 delete $3;
1261 $$ = NULL;
1262 }
1263 }
1264 | ';' {
1265 $$ = NULL;
1266 }
1267 ;
1268
1269 //// filter /////////////////////////////////////////////////////////////
1270
1271 filter: filter OP_OR filter_term {
1272 $$ = new FilterOR($1, $3);
1273 }
1274 | filter filter_term %prec OP_OR {
1275 $$ = new FilterOR($1, $2);
1276 }
1277 | filter_term
1278 ;
1279
1280 filter_term : filter_term OP_AND filter_factor {
1281 $$ = new FilterAND($1, $3);
1282 }
1283 | filter_factor
1284 ;
1285
1286 filter_factor : OP_NOT filter_factor {
1287 $$ = new FilterNOT($2);
1288 }
1289 | '(' filter ')' {
1290 $$ = $2;
1291 }
1292 | filter_operand
1293 ;
1294
1295 filter_operand: KEYW_ANY {
1296 $$ = new FilterANY;
1297 }
1298 | '<' filter_aspath '>' {
1299 $$ = new FilterASPath($2);
1300 }
1301 | filter_rp_attribute {
1302 if ($1)
1303 $$ = $1;
1304 else
1305 $$ = new FilterNOT(new FilterANY);
1306 }
1307 | TKN_FLTRNAME {
1308 $$ = new FilterFLTRNAME($1);
1309 }
1310 | filter_prefix
1311 ;
1312
1313 filter_prefix: filter_prefix_operand OP_MS {
1314 $2->f1 = $1;
1315 $$ = $2;
1316 }
1317 | filter_prefix_operand
1318 ;
1319
1320 filter_prefix_operand: TKN_ASNO {
1321 $$ = new FilterASNO($1);
1322 }
1323 | KEYW_PEERAS {
1324 $$ = new FilterPeerAS;
1325 }
1326 | TKN_ASNAME {
1327 $$ = new FilterASNAME($1);
1328 }
1329 | TKN_RSNAME {
1330 $$ = new FilterRSNAME($1);
1331 }
1332 | '{' opt_filter_prefix_list '}' {
1333 $$ = $2;
1334 }
1335 ;
1336
1337 opt_filter_prefix_list: {
1338 $$ = new FilterPRFXList;
1339 }
1340 | filter_prefix_list
1341 ;
1342
1343 filter_prefix_list: filter_prefix_list_prefix {
1344 ((FilterPRFXList *) ($$ = new FilterPRFXList))->add_high(*$1);
1345 delete $1;
1346 }
1347 | filter_prefix_list ',' filter_prefix_list_prefix {
1348 $$ = $1;
1349 ((FilterPRFXList *) ($$))->add_high(*$3);
1350 delete $3;
1351 }
1352 ;
1353
1354 filter_prefix_list_prefix: TKN_PRFXV4 {
1355 $$ = $1;
1356 }
1357 | TKN_PRFXV4RNG {
1358 $$ = $1;
1359 }
1360 ;
1361
1362 filter_aspath: filter_aspath '|' filter_aspath_term {
1363 $$ = new regexp_or($1, $3);
1364 }
1365 | filter_aspath_term
1366 ;
1367
1368 filter_aspath_term: filter_aspath_term filter_aspath_closure {
1369 $$ = new regexp_cat($1, $2);
1370 }
1371 | filter_aspath_closure
1372 ;
1373
1374 filter_aspath_closure: filter_aspath_closure '*' {
1375 $$ = new regexp_star($1);
1376 }
1377 | filter_aspath_closure '?' {
1378 $$ = new regexp_question($1);
1379 }
1380 | filter_aspath_closure '+' {
1381 $$ = new regexp_plus($1);
1382 }
1383 | filter_aspath_factor
1384 ;
1385
1386 filter_aspath_factor: '^' {
1387 $$ = new regexp_bol;
1388 }
1389 | '$' {
1390 $$ = new regexp_eol;
1391 }
1392 | '(' filter_aspath ')' {
1393 $$ = $2;
1394 }
1395 | filter_aspath_no
1396 ;
1397
1398 filter_aspath_no: TKN_ASNO {
1399 $$ = new regexp_symbol($1);
1400 }
1401 | KEYW_PEERAS {
1402 $$ = new regexp_symbol(symbols.symID("PEERAS"));
1403 }
1404 | TKN_ASNAME {
1405 $$ = new regexp_symbol($1);
1406 }
1407 | '.' {
1408 $$ = new regexp_symbol(regexp_symbol::MIN_AS, regexp_symbol::MAX_AS);
1409 }
1410 | '[' filter_aspath_range ']' {
1411 $$ = $2;
1412 }
1413 | '[' '^' filter_aspath_range ']' {
1414 $$ = $3;
1415 ((regexp_symbol *) $$)->complement();
1416 }
1417 ;
1418
1419 filter_aspath_range: {
1420 $$ = new regexp_symbol;
1421 }
1422 | filter_aspath_range TKN_ASNO {
1423 ((regexp_symbol *) ($$ = $1))->add($2);
1424 }
1425 | filter_aspath_range KEYW_PEERAS {
1426 ((regexp_symbol *) ($$ = $1))->add(symbols.symID("PEERAS"));
1427 }
1428 | filter_aspath_range '.' {
1429 ((regexp_symbol *) ($$ = $1))->add(regexp_symbol::MIN_AS, regexp_symbol::MAX_AS);
1430 }
1431 | filter_aspath_range TKN_ASNO '-' TKN_ASNO {
1432 ((regexp_symbol *) ($$ = $1))->add($2, $4);
1433 }
1434 | filter_aspath_range TKN_ASNAME {
1435 ((regexp_symbol *) ($$ = $1))->add($2);
1436 }
1437 ;
1438
1439 filter_rp_attribute: TKN_RP_ATTR '.' TKN_WORD '(' generic_list ')' {
1440 const AttrMethod *mtd = searchMethod($1, $3, $5);
1441 if (mtd)
1442 $$ = new FilterRPAttribute($1, mtd, $5);
1443 else {
1444 delete $5;
1445 $$ = NULL;
1446 }
1447 free($3);
1448 }
1449 | TKN_RP_ATTR TKN_OPERATOR list_item {
1450 ItemList *plist = new ItemList;
1451 plist->append($3);
1452
1453 const AttrMethod *mtd = searchMethod($1, $2, plist);
1454 if (mtd)
1455 $$ = new FilterRPAttribute($1, mtd, plist);
1456 else {
1457 delete plist;
1458 $$ = NULL;
1459 }
1460 // Added by wlee
1461 free($2);
1462 }
1463 | TKN_RP_ATTR '(' generic_list ')' {
1464 const AttrMethod *mtd = searchMethod($1, "()", $3);
1465 if (mtd)
1466 $$ = new FilterRPAttribute($1, mtd, $3);
1467 else {
1468 delete $3;
1469 $$ = NULL;
1470 }
1471 }
1472 | TKN_RP_ATTR '[' generic_list ']' {
1473 const AttrMethod *mtd = searchMethod($1, "[]", $3);
1474 if (mtd)
1475 $$ = new FilterRPAttribute($1, mtd, $3);
1476 else {
1477 delete $3;
1478 $$ = NULL;
1479 }
1480 }
1481 ;
1482
1483 //// peering action pair ////////////////////////////////////////////////
1484
1485 import_peering_action_list: KEYW_FROM peering opt_action {
1486 $$ = new List<PolicyPeeringAction>;
1487 $$->append(new PolicyPeeringAction($2, $3));
1488 }
1489 | import_peering_action_list KEYW_FROM peering opt_action {
1490 $$ = $1;
1491 $$->append(new PolicyPeeringAction($3, $4));
1492 }
1493 ;
1494
1495 export_peering_action_list: KEYW_TO peering opt_action {
1496 $$ = new List<PolicyPeeringAction>;
1497 $$->append(new PolicyPeeringAction($2, $3));
1498 }
1499 | export_peering_action_list KEYW_TO peering opt_action {
1500 $$ = $1;
1501 $$->append(new PolicyPeeringAction($3, $4));
1502 }
1503 ;
1504
1505 //// import/export factor ///////////////////////////////////////////////
1506
1507 import_factor: import_peering_action_list KEYW_ACCEPT filter {
1508 $$ = new PolicyFactor($1, $3);
1509 }
1510 ;
1511
1512 import_factor_list: import_factor ';' {
1513 $$ = new PolicyTerm;
1514 $$->append($1);
1515 }
1516 | import_factor_list import_factor ';' {
1517 $$ = $1;
1518 $$->append($2);
1519 }
1520 ;
1521
1522 export_factor: export_peering_action_list KEYW_ANNOUNCE filter {
1523 $$ = new PolicyFactor($1, $3);
1524 }
1525 ;
1526
1527 export_factor_list: export_factor ';' {
1528 $$ = new PolicyTerm;
1529 $$->append($1);
1530 }
1531 | export_factor_list export_factor ';' {
1532 $$ = $1;
1533 $$->append($2);
1534 }
1535 ;
1536
1537 //// import/export term /////////////////////////////////////////////////
1538
1539 import_term: import_factor ';' {
1540 PolicyTerm *term = new PolicyTerm;
1541 term->append($1);
1542 $$ = term;
1543 }
1544 | '{' import_factor_list '}' {
1545 $$ = $2;
1546 }
1547 ;
1548
1549 export_term: export_factor ';' {
1550 PolicyTerm *term = new PolicyTerm;
1551 term->append($1);
1552 $$ = term;
1553 }
1554 | '{' export_factor_list '}' {
1555 $$ = $2;
1556 }
1557 ;
1558
1559 //// import/export expr /////////////////////////////////////////////////
1560
1561 import_expr: import_term {
1562 $$ = $1;
1563 }
1564 | import_term KEYW_REFINE import_expr {
1565 $$ = new PolicyRefine($1, $3);
1566 }
1567 | import_term KEYW_EXCEPT import_expr {
1568 $$ = new PolicyExcept($1, $3);
1569 }
1570 ;
1571
1572 export_expr: export_term {
1573 $$ = $1;
1574 }
1575 | export_term KEYW_REFINE export_expr {
1576 $$ = new PolicyRefine($1, $3);
1577 }
1578 | export_term KEYW_EXCEPT export_expr {
1579 $$ = new PolicyExcept($1, $3);
1580 }
1581 ;
1582
1583 //// protocol ///////////////////////////////////////////////////////////
1584
1585 opt_protocol_from: {
1586 $$ = schema.searchProtocol("BGP4");
1587 }
1588 | KEYW_PROTOCOL tkn_word {
1589 $$ = schema.searchProtocol($2);
1590 if (!$$) {
1591 handle_warning("Warning: unknown protocol %s, BGP4 assumed.\n", $2);
1592 $$ = schema.searchProtocol("BGP4");
1593 }
1594 free($2);
1595 }
1596 ;
1597
1598 opt_protocol_into: {
1599 $$ = schema.searchProtocol("BGP4");
1600 }
1601 | KEYW_INTO tkn_word {
1602 $$ = schema.searchProtocol($2);
1603 if (!$$) {
1604 handle_warning("Warning: unknown protocol %s, BGP4 assumed.\n", $2);
1605 $$ = schema.searchProtocol("BGP4");
1606 }
1607 free($2);;
1608 }
1609 ;
1610
1611 //**** import/export attributes *******************************************
1612
1613 import_attribute: ATTR_IMPORT
1614 opt_protocol_from opt_protocol_into
1615 import_expr TKN_EOA {
1616 $$ = changeCurrentAttr(new AttrImport($2, $3, $4));
1617 }
1618 | ATTR_IMPORT opt_protocol_from opt_protocol_into import_factor TKN_EOA {
1619 PolicyTerm *term = new PolicyTerm;
1620 term->append($4);
1621
1622 $$ = changeCurrentAttr(new AttrImport($2, $3, term));
1623 }
1624 | ATTR_IMPORT error TKN_EOA {
1625 $$ = $1;
1626 handle_error("Error: from <peering> expected.\n");
1627 yyerrok;
1628 }
1629 ;
1630
1631 export_attribute: ATTR_EXPORT
1632 opt_protocol_from opt_protocol_into
1633 export_expr TKN_EOA {
1634 $$ = changeCurrentAttr(new AttrExport($2, $3, $4));
1635 }
1636 | ATTR_EXPORT opt_protocol_from opt_protocol_into export_factor TKN_EOA {
1637 PolicyTerm *term = new PolicyTerm;
1638 term->append($4);
1639
1640 $$ = changeCurrentAttr(new AttrExport($2, $3, term));
1641 }
1642 | ATTR_EXPORT error TKN_EOA {
1643 $$ = $1;
1644 handle_error("Error: to <peering> expected.\n");
1645 yyerrok;
1646 }
1647 ;
1648
1649 opt_default_filter: {
1650 $$ = new FilterANY;
1651 }
1652 | KEYW_NETWORKS filter {
1653 $$ = $2;
1654 }
1655 ;
1656
1657 default_attribute: ATTR_DEFAULT KEYW_TO peering
1658 opt_action
1659 opt_default_filter TKN_EOA {
1660 $$ = changeCurrentAttr(new AttrDefault($3, $4, $5));
1661 }
1662 | ATTR_DEFAULT KEYW_TO peering error TKN_EOA {
1663 if ($3)
1664 delete $3;
1665 handle_error("Error: badly formed filter/action or keyword NETWORKS/ACTION missing.\n");
1666 yyerrok;
1667 }
1668 | ATTR_DEFAULT error TKN_EOA {
1669 handle_error("Error: TO <peer> missing.\n");
1670 yyerrok;
1671 }
1672 ;
1673
1674 filter_attribute: ATTR_FILTER filter TKN_EOA {
1675 $$ = changeCurrentAttr(new AttrFilter($2));
1676 }
1677 | ATTR_FILTER error TKN_EOA {
1678 $$ = $1;
1679 handle_error("Error: badly formed filter.\n");
1680 yyerrok;
1681 }
1682 ;
1683
1684 peering_attribute: ATTR_PEERING peering TKN_EOA {
1685 $$ = changeCurrentAttr(new AttrPeering($2));
1686 }
1687 | ATTR_PEERING error TKN_EOA {
1688 $$ = $1;
1689 handle_error("Error: badly formed filter.\n");
1690 yyerrok;
1691 }
1692 ;
1693
1694 //**** inet-rtr class *****************************************************
1695
1696 ifaddr_attribute: ATTR_IFADDR TKN_IPV4 KEYW_MASKLEN TKN_INT opt_action TKN_EOA {
1697 $$ = changeCurrentAttr(new AttrIfAddr($2->get_ipaddr(), $4, $5));
1698 delete $2;
1699 }
1700 | ATTR_IFADDR TKN_IPV4 KEYW_MASKLEN TKN_INT error TKN_EOA {
1701 delete $2;
1702 $$ = $1;
1703 handle_error("Error: in action specification.\n");
1704 yyerrok;
1705 }
1706 | ATTR_IFADDR TKN_IPV4 KEYW_MASKLEN error TKN_EOA {
1707 delete $2;
1708 $$ = $1;
1709 handle_error("Error: integer mask length expected.\n");
1710 yyerrok;
1711 }
1712 | ATTR_IFADDR TKN_IPV4 error TKN_EOA {
1713 delete $2;
1714 $$ = $1;
1715 handle_error("Error: MASKLEN <length> expected.\n");
1716 yyerrok;
1717 }
1718 | ATTR_IFADDR error TKN_EOA {
1719 $$ = $1;
1720 handle_error("Error: <ip_address> MASKLEN <length> [<action>] expected.\n");
1721 yyerrok;
1722 }
1723 ;
1724
1725 //// peer attribute /////////////////////////////////////////////////////
1726
1727 opt_peer_options: {
1728 $$ = new List<AttrPeerOption>;
1729 }
1730 | peer_options {
1731 $$ = $1;
1732 }
1733 ;
1734
1735 peer_options: peer_option {
1736 $$ = new List<AttrPeerOption>;
1737 $$->append($1);
1738 }
1739 | peer_options ',' peer_option {
1740 $$ = $1;
1741 $$->append($3);
1742 }
1743 ;
1744
1745 peer_option: tkn_word '(' generic_list ')' {
1746 $$ = new AttrPeerOption($1, $3);
1747 }
1748 ;
1749
1750 peer_id: TKN_IPV4
1751 | TKN_DNS {
1752 $$ = new IPAddr;
1753 }
1754 | TKN_RTRSNAME {
1755 $$ = new IPAddr;
1756 }
1757 | TKN_PRNGNAME {
1758 $$ = new IPAddr;
1759 }
1760 ;
1761
1762 peer_attribute: ATTR_PEER tkn_word peer_id opt_peer_options TKN_EOA {
1763 const AttrProtocol *protocol = schema.searchProtocol($2);
1764 int position;
1765 const RPType *correctType;
1766 bool error = false;
1767
1768 if (!protocol) {
1769 handle_error("Error: unknown protocol %s.\n", $2);
1770 error = true;
1771 } else {
1772 ((AttrProtocol *) protocol)->startMandatoryCheck();
1773 for (AttrPeerOption *opt = $4->head(); opt; opt = $4->next(opt)) {
1774 const AttrProtocolOption *decl = protocol->searchOption(opt->option);
1775 if (!decl) {
1776 handle_error("Error: protocol %s does not have option %s.\n",
1777 $2, opt->option);
1778 error = true;
1779 } else {
1780 for (; decl; decl = protocol->searchNextOption(decl))
1781 if (decl->option->validateArgs(opt->args, position, correctType))
1782 break;
1783 if (! decl) {
1784 handleArgumentTypeError($2, opt->option, position, correctType);
1785 error = true;
1786 }
1787 }
1788 }
1789 }
1790
1791 if (! error) {
1792 const AttrProtocolOption *missing =
1793 ((AttrProtocol *) protocol)->missingMandatoryOption();
1794 if (missing) {
1795 handle_error("Error: mandatory option %s of protocol %s is missing.\n",
1796 missing->option->name, $2);
1797 error = true;
1798 }
1799 }
1800
1801 if (!error)
1802 $$ = changeCurrentAttr(new AttrPeer(protocol, $3, $4));
1803 else {
1804 free($2);
1805 delete $3;
1806 delete $4;
1807 }
1808 }
1809 | ATTR_PEER tkn_word TKN_IPV4 error TKN_EOA {
1810 $$ = $1;
1811 free($2);
1812 delete $3;
1813 handle_error("Error: in peer option.\n");
1814 yyerrok;
1815 }
1816 | ATTR_PEER tkn_word error TKN_EOA {
1817 $$ = $1;
1818 free($2);
1819 handle_error("Error: missing peer ip_address.\n");
1820 yyerrok;
1821 }
1822 | ATTR_PEER error TKN_EOA {
1823 $$ = $1;
1824 handle_error("Error: missing protocol name.\n");
1825 yyerrok;
1826 }
1827 ;
1828
1829 //**** route class ********************************************************
1830
1831 aggr_bndry_attribute: ATTR_AGGR_BNDRY as_expr TKN_EOA {
1832 $$ = $1;
1833 delete $2;
1834 }
1835 | ATTR_AGGR_BNDRY error TKN_EOA {
1836 $$ = $1;
1837 handle_error("Error: <as-expression> expected.\n");
1838 yyerrok;
1839 }
1840 ;
1841
1842 aggr_mtd_attribute: ATTR_AGGR_MTD KEYW_INBOUND TKN_EOA {
1843 $$ = $1;
1844 }
1845 | ATTR_AGGR_MTD KEYW_OUTBOUND opt_as_expr TKN_EOA {
1846 delete $3;
1847 }
1848 | ATTR_AGGR_MTD KEYW_OUTBOUND error TKN_EOA {
1849 $$ = $1;
1850 handle_error("Error: OUTBOUND <as-expression> expected.\n");
1851 yyerrok;
1852 }
1853 | ATTR_AGGR_MTD KEYW_INBOUND error TKN_EOA {
1854 $$ = $1;
1855 handle_error("Error: INBOUND can not be followed by anything.\n");
1856 yyerrok;
1857 }
1858 | ATTR_AGGR_MTD error TKN_EOA {
1859 $$ = $1;
1860 handle_error("Error: keyword INBOUND or OUTBOUND expected.\n");
1861 yyerrok;
1862 }
1863 ;
1864
1865 //// inject attribute ///////////////////////////////////////////////////
1866
1867 opt_inject_expr: {
1868 $$ = new FilterANY;
1869 }
1870 | KEYW_UPON inject_expr {
1871 $$ = $2;
1872 }
1873 ;
1874
1875 inject_expr: inject_expr OP_OR inject_expr_term {
1876 $$ = new FilterOR($1, $3);
1877 }
1878 | inject_expr_term
1879 ;
1880
1881 inject_expr_term: inject_expr_term OP_AND inject_expr_factor {
1882 $$ = new FilterAND($1, $3);
1883 }
1884 | inject_expr_factor
1885 ;
1886
1887 inject_expr_factor: '(' inject_expr ')' {
1888 $$ = $2;
1889 }
1890 | inject_expr_operand
1891 ;
1892
1893 inject_expr_operand: KEYW_STATIC {
1894 $$ = new FilterANY;
1895 }
1896 | KEYW_HAVE_COMPONENTS '{' opt_filter_prefix_list '}' {
1897 $$ = new FilterHAVE_COMPONENTS((FilterPRFXList *) $3);
1898 }
1899 | KEYW_EXCLUDE '{' opt_filter_prefix_list '}' {
1900 $$ = new FilterEXCLUDE((FilterPRFXList *) $3);
1901 }
1902 ;
1903
1904 inject_attribute: ATTR_INJECT opt_router_expr_with_at opt_action opt_inject_expr TKN_EOA {
1905 $$ = $1;
1906 delete $2;
1907 delete $3;
1908 delete $4;
1909 }
1910 | ATTR_INJECT error TKN_EOA {
1911 $$ = $1;
1912 handle_error("Error: [at <router-exp>] [action <action>] [upon <condition>] expected.\n");
1913 yyerrok;
1914 }
1915 ;
1916
1917 //// components attribute ///////////////////////////////////////////////
1918
1919 opt_atomic:
1920 | KEYW_ATOMIC
1921 ;
1922
1923 components_list: {
1924 }
1925 | filter {
1926 delete $1;
1927 }
1928 | components_list KEYW_PROTOCOL tkn_word filter {
1929 free($3);
1930 delete $4;
1931 }
1932 ;
1933
1934 components_attribute: ATTR_COMPONENTS opt_atomic components_list TKN_EOA {
1935 $$ = $1;
1936 }
1937 | ATTR_COMPONENTS error TKN_EOA {
1938 $$ = $1;
1939 handle_error("Error: [ATOMIC] [[<filter>] [PROTOCOL <protocol> <filter>] ...] expected.\n");
1940 yyerrok;
1941 }
1942 ;
1943
1944 //**** route-set **********************************************************
1945
1946 opt_rs_members_list: /* empty list */ {
1947 $$ = new ItemList;
1948 }
1949 | rs_members_list
1950 ;
1951
1952 rs_members_list: rs_member {
1953 $$ = new ItemList;
1954 $$->append($1);
1955 }
1956 | rs_members_list ',' rs_member {
1957 $$ = $1;
1958 $$->append($3);
1959 }
1960 ;
1961
1962 rs_member: TKN_ASNO {
1963 $$ = new ItemASNO($1);
1964 }
1965 | TKN_ASNO OP_MS {
1966 $$ = new ItemMSItem(new ItemASNO($1), $2->code, $2->n, $2->m);
1967 delete $2;
1968 }
1969 | TKN_ASNAME {
1970 $$ = new ItemASNAME($1);
1971 }
1972 | TKN_ASNAME OP_MS {
1973 $$ = new ItemMSItem(new ItemASNAME($1), $2->code, $2->n, $2->m);
1974 delete $2;
1975 }
1976 | TKN_RSNAME {
1977 $$ = new ItemRSNAME($1);
1978 }
1979 | TKN_RSNAME OP_MS {
1980 $$ = new ItemMSItem(new ItemRSNAME($1), $2->code, $2->n, $2->m);
1981 delete $2;
1982 }
1983 | TKN_PRFXV4 {
1984 $$ = new ItemPRFXV4($1);
1985 }
1986 | TKN_PRFXV4RNG {
1987 $$ = new ItemPRFXV4Range($1);
1988 }
1989 ;
1990
1991 rs_members_attribute: ATTR_RS_MEMBERS opt_rs_members_list TKN_EOA {
1992 $$ = changeCurrentAttr(new AttrGeneric($1->type, $2));
1993 }
1994 | ATTR_RS_MEMBERS error TKN_EOA {
1995 $$ = $1;
1996 handle_error("Error: invalid member\n");
1997 yyerrok;
1998 }
1999 ;
2000
2001 //**** dictionary *********************************************************
2002
2003 rpattr_attribute: ATTR_RP_ATTR TKN_WORD methods TKN_EOA {
2004 $$ = changeCurrentAttr(new AttrRPAttr($2, $3));
2005 }
2006 | ATTR_RP_ATTR TKN_RP_ATTR methods TKN_EOA {
2007 $$ = changeCurrentAttr(new AttrRPAttr($2->name, $3));
2008 }
2009 | ATTR_RP_ATTR error TKN_EOA {
2010 $$ = $1;
2011 handle_error("Error: invalid rp-attribute specification\n");
2012 yyerrok;
2013 }
2014 ;
2015
2016 methods: method {
2017 $$ = new List<AttrMethod>;
2018 if ($1)
2019 $$->append($1);
2020 }
2021 | methods method {
2022 $$ = $1;
2023 if ($2)
2024 $$->append($2);
2025 }
2026 ;
2027
2028 method: TKN_WORD '(' ')' {
2029 $$ = new AttrMethod($1, new List<RPTypeNode>, false);
2030 }
2031 | TKN_WORD '(' typedef_type_list ')' {
2032 $$ = new AttrMethod($1, $3, false);
2033 }
2034 | TKN_WORD '(' typedef_type_list ',' TKN_3DOTS ')' {
2035 $$ = new AttrMethod($1, $3, true);
2036 }
2037 | KEYW_OPERATOR TKN_OPERATOR '(' typedef_type_list ')' {
2038 char buffer[16];
2039 strcpy(buffer, "operator");
2040 strcat(buffer, $2);
2041 $$ = new AttrMethod(strdup(buffer), $4, false, true);
2042 free($2);
2043 }
2044 | KEYW_OPERATOR TKN_OPERATOR '(' typedef_type_list ',' TKN_3DOTS ')' {
2045 char buffer[16];
2046 strcpy(buffer, "operator");
2047 strcat(buffer, $2);
2048 $$ = new AttrMethod(strdup(buffer), $4, true, true);
2049 free($2);
2050 }
2051 | TKN_WORD error ')' {
2052 free($1);
2053 $$ = NULL;
2054 handle_error("Error: invalid method specification for %s\n", $1);
2055 }
2056 | KEYW_OPERATOR TKN_OPERATOR error ')' {
2057 $$ = NULL;
2058 handle_error("Error: invalid operator specification for %s\n", $2);
2059 free($2);
2060 }
2061 | KEYW_OPERATOR error ')' {
2062 $$ = NULL;
2063 handle_error("Error: invalid operator\n");
2064 }
2065 | error ')' {
2066 $$ = NULL;
2067 handle_error("Error: method specification expected\n");
2068 }
2069 ;
2070
2071 //// typedef attribute /////////////////////////////////////////////////
2072
2073 typedef_attribute: ATTR_TYPEDEF TKN_WORD typedef_type TKN_EOA {
2074 $$ = changeCurrentAttr(new AttrTypedef($2, $3));
2075 }
2076 | ATTR_TYPEDEF error TKN_EOA {
2077 $$ = $1;
2078 handle_error("Error: invalid typedef specification\n");
2079 yyerrok;
2080 }
2081 ;
2082
2083 typedef_type_list: typedef_type {
2084 $$ = new List<RPTypeNode>;
2085 if ($1)
2086 $$->append(new RPTypeNode($1));
2087 }
2088 | typedef_type_list ',' typedef_type {
2089 $$ = $1;
2090 if ($3)
2091 $$->append(new RPTypeNode($3));
2092 }
2093 ;
2094
2095 typedef_type: KEYW_UNION typedef_type_list {
2096 $$ = RPType::newRPType("union", $2);
2097 if (!$$) {
2098 handle_error("Error: empty union specification\n");
2099 delete $2;
2100 }
2101 }
2102 | KEYW_RANGE KEYW_OF typedef_type {
2103 if ($3)
2104 $$ = new RPTypeRange($3);
2105 else {
2106 $$ = NULL;
2107 }
2108 }
2109 | TKN_WORD {
2110 $$ = RPType::newRPType($1);
2111 if (!$$) {
2112 handle_error("Error: invalid type %s\n", $1);
2113 }
2114 free($1);
2115 }
2116 | TKN_WORD '[' TKN_INT ',' TKN_INT ']' {
2117 $$ = RPType::newRPType($1, $3, $5);
2118 if (!$$) {
2119 handle_error("Error: invalid type %s[%d,%d]\n", $1, $3, $5);
2120 }
2121 free($1);
2122 }
2123 | TKN_WORD '[' TKN_REAL ',' TKN_REAL ']' {
2124 $$ = RPType::newRPType($1, $3, $5);
2125 if (!$$) {
2126 handle_error("Error: invalid type %s[%f,%f]\n", $1, $3, $5);
2127 }
2128 free($1);
2129 }
2130 | TKN_WORD '[' enum_list ']' {
2131 $$ = RPType::newRPType($1, $3);
2132 if (!$$) {
2133 handle_error("Error: invalid type %s, enum expected\n", $1);
2134 delete $3;
2135 }
2136 free($1);
2137 }
2138 | KEYW_LIST '[' TKN_INT ':' TKN_INT ']' KEYW_OF typedef_type {
2139 if ($8)
2140 if ($3 < $5)
2141 $$ = new RPTypeList($8, $3, $5);
2142 else
2143 $$ = new RPTypeList($8, $5, $3);
2144 else {
2145 $$ = NULL;
2146 delete $8;
2147 }
2148 }
2149 | KEYW_LIST KEYW_OF typedef_type {
2150 if ($3)
2151 $$ = new RPTypeList($3);
2152 else {
2153 $$ = NULL;
2154 }
2155 }
2156 | KEYW_LIST error KEYW_OF typedef_type {
2157 $$ = NULL;
2158 delete $4;
2159 handle_error("Error: invalid list size\n");
2160 }
2161 ;
2162
2163 enum_list: tkn_word {
2164 $$ = new List<WordNode>;
2165 $$->append(new WordNode($1));
2166 }
2167 | enum_list ',' tkn_word {
2168 $$ = $1;
2169 $$->append(new WordNode($3));
2170 }
2171 ;
2172
2173 //// protocol attribute /////////////////////////////////////////////////
2174
2175 protocol_attribute: ATTR_PROTOCOL tkn_word protocol_options TKN_EOA {
2176 $$ = changeCurrentAttr(new AttrProtocol($2, $3));
2177 }
2178 | ATTR_PROTOCOL tkn_word error TKN_EOA {
2179 $$ = $1;
2180 handle_error("Error: invalid protocol option\n");
2181 yyerrok;
2182 }
2183 | ATTR_PROTOCOL error TKN_EOA {
2184 $$ = $1;
2185 handle_error("Error: invalid protocol name\n");
2186 yyerrok;
2187 }
2188 ;
2189
2190 protocol_options: {
2191 $$ = new List<AttrProtocolOption>;
2192 }
2193 | protocol_options protocol_option {
2194 $$ = $1;
2195 $$->append($2);
2196 }
2197 ;
2198
2199 protocol_option: KEYW_MANDATORY method {
2200 $$ = new AttrProtocolOption(false, $2);
2201 }
2202 | KEYW_OPTIONAL method {
2203 $$ = new AttrProtocolOption(true, $2);
2204 }
2205 ;
2206
2207 //**** schema class *******************************************************
2208
2209 opt_attr_options: {
2210 $$ = new AttrAttr(ATTR_GENERIC, RPType::newRPType("free_text"));
2211 }
2212 | attr_options {
2213 $$ = new AttrAttr(ATTR_GENERIC, RPType::newRPType("free_text"));
2214 *$$ |= *$1;
2215 delete $1;
2216 }
2217 ;
2218
2219 attr_options: attr_option {
2220 $$ = $1;
2221 }
2222 | attr_options ',' attr_option {
2223 $$ = $1;
2224 *$$ |= *$3;
2225 delete $3;
2226 }
2227 | error ',' attr_option {
2228 $$ = $3;
2229 handle_error("Error: in attr option specification.\n");
2230 }
2231 ;
2232
2233 attr_option: KEYW_SYNTAX '(' typedef_type ')' {
2234 $$ = new AttrAttr(ATTR_GENERIC, $3);
2235 }
2236 | KEYW_SYNTAX '(' KEYW_SPECIAL ',' tkn_word ')' {
2237 int syntax = schema.searchAttrSyntax($5);
2238 if (syntax < 0) {
2239 handle_error("Error: no known syntax rule for %s.\n", $5);
2240 $$ = new AttrAttr;
2241 } else
2242 $$ = new AttrAttr(syntax, NULL);
2243 free($5);
2244 }
2245 | KEYW_OPTIONAL {
2246 $$ = new AttrAttr(AttrAttr::OPTIONAL);
2247 }
2248 | KEYW_MANDATORY {
2249 $$ = new AttrAttr;
2250 }
2251 | KEYW_DELETED {
2252 $$ = new AttrAttr(AttrAttr::DELETED)
2253 }
2254 | KEYW_SINGLEVALUED {
2255 $$ = new AttrAttr;
2256 }
2257 | KEYW_MULTIVALUED {
2258 $$ = new AttrAttr(AttrAttr::MULTIVALUED);
2259 }
2260 | KEYW_LOOKUP {
2261 $$ = new AttrAttr(AttrAttr::LOOKUP);
2262 }
2263 | KEYW_KEY {
2264 $$ = new AttrAttr(AttrAttr::KEY);
2265 }
2266 | KEYW_OBSOLETE {
2267 $$ = new AttrAttr(AttrAttr::OBSOLETE);
2268 }
2269 | KEYW_INTERNAL {
2270 $$ = new AttrAttr(AttrAttr::INTERNAL);
2271 }
2272 | KEYW_GENERATED {
2273 $$ = new AttrAttr(AttrAttr::GENERATED);
2274 }
2275 ;
2276
2277 attr_attribute: ATTR_ATTR tkn_word opt_attr_options TKN_EOA {
2278 $3->setName($2);
2279 $$ = changeCurrentAttr($3);
2280 }
2281 | ATTR_ATTR tkn_word error TKN_EOA {
2282 $$ = $1;
2283 free($2);
2284 handle_error("Error: in attr option specification.\n");
2285 yyerrok;
2286 }
2287 | ATTR_ATTR error TKN_EOA {
2288 $$ = $1;
2289 handle_error("Error: attr name expected.\n");
2290 yyerrok;
2291 }
2292 ;
2293
2294 //**** rps-auth stuff *****************************************************
2295
2296 mnt_routes_attribute: ATTR_MNT_ROUTES mnt_routes_list TKN_EOA {
2297 $$ = changeCurrentAttr(new AttrMntRoutes($2));
2298 }
2299 ;
2300
2301 mnt_routes_list: mnt_routes_list_item {
2302 $$ = new List<AttrMntRoutes::MntPrfxPair>;
2303 $$->append($1);
2304 }
2305 | mnt_routes_list ',' mnt_routes_list_item {
2306 $$ = $1;
2307 $$->append($3);
2308 }
2309 ;
2310
2311 mnt_routes_list_item: tkn_word {
2312 $$ = new AttrMntRoutes::MntPrfxPair($1, NULL);
2313 }
2314 | tkn_word KEYW_ANY {
2315 $$ = new AttrMntRoutes::MntPrfxPair($1, NULL);
2316 }
2317 | tkn_word '{' opt_filter_prefix_list '}' {
2318 $$ = new AttrMntRoutes::MntPrfxPair($1, (FilterPRFXList *) $3);
2319 }
2320 ;
2321
2322 %%
2323
2324 void enable_yy_parser_debugging() {
/* [<][>][^][v][top][bottom][index][help] */
2325 #if YYDEBUG != 0
2326 yydebug = 1;
2327 #endif
2328 }
2329
2330 void handleArgumentTypeError(char *attr, char *method, int position,
/* [<][>][^][v][top][bottom][index][help] */
2331 const RPType *correctType,
2332 bool isOperator = false) {
2333 if (isOperator)
2334 if (position)
2335 handle_error("Error: argument %d to %s.operator%s should be %s.\n",
2336 position, attr, method, ((RPType *) correctType)->name());
2337 else
2338 handle_error("Error: wrong number of arguments to %s.operator%s.\n",
2339 attr, method);
2340 else
2341 if (position)
2342 handle_error("Error: argument %d to %s.%s should be %s.\n",
2343 position, attr, method, ((RPType *) correctType)->name());
2344 else
2345 handle_error("Error: wrong number of arguments to %s.%s.\n",
2346 attr, method);
2347 }
2348
2349 const AttrMethod *searchMethod(const AttrRPAttr *rp_attr, char *method, ItemList *args) {
/* [<][>][^][v][top][bottom][index][help] */
2350 const AttrMethod *mtd = rp_attr->searchMethod(method);
2351 int position;
2352 const RPType *correctType;
2353
2354 if (!mtd) {
2355 handle_error("Error: rp-attribute %s does not have %s defined.\n",
2356 rp_attr->name, method);
2357 return NULL;
2358 }
2359
2360 for (; mtd; mtd = rp_attr->searchNextMethod(mtd))
2361 if (mtd->validateArgs(args, position, correctType))
2362 return mtd;
2363
2364 handleArgumentTypeError(rp_attr->name, method, position, correctType);
2365
2366 return NULL;
2367 }