modules/rpsl/filter.y

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following functions.
  1. yyparse
  2. filtererror
  3. yyerror
  4. syntax_error
  5. yywrap
  6. yy_input
  7. main

   1 %{
   2 /*
   3   filename: filter.y
   4 
   5   description:
   6     Defines the grammar for an RPSL filter attribute.  It was mostly
   7     stolen from the IRRToolSet, simplified by removing ability to parse
   8     things defined by a dictionary (we use XML for extensibility rather
   9     than a dictionary).
  10 
  11   notes:
  12     Defines tokens for the associated lexer, filter.l.
  13 */
  14 %}
  15 
  16 %union {
  17     char *sval;
  18 }
  19 
  20 %token OP_OR OP_AND OP_NOT OP_MS OP_EQUAL OP_APPEND OP_COMPARE
  21 %token KEYW_ANY KEYW_PEERAS
  22 %token KEYW_IGP_COST KEYW_PREPEND KEYW_APPEND KEYW_DELETE KEYW_CONTAINS
  23 %token KEYW_INTERNET KEYW_NO_EXPORT KEYW_NO_ADVERTISE KEYW_SELF
  24 %token ASPATH_POSTFIX
  25 %token TKN_FLTRNAME TKN_ASNO TKN_RSNAME TKN_ASNAME TKN_PRFXV4 TKN_PRFXV4RNG
  26 %token TKN_PREF TKN_MED TKN_DPA TKN_ASPATH TKN_COMMUNITY
  27 %token TKN_COMM_NO TKN_NEXT_HOP TKN_IPV4 TKN_COST
  28 %token <sval> TKN_INT
  29 
  30 %{
  31 #include <stdio.h>
  32 #include <stdarg.h>
  33 #include <stdlib.h>
  34 
  35 int yyerror(const char *s);
  36 
  37 /* defines for unit testing */
  38 #ifdef UNIT_TEST
  39 int main();
  40 #endif /* UNIT_TEST */
  41 %}
  42 
  43 %%
     /* [<][>][^][v][top][bottom][index][help] */
  44 
  45 filter: filter OP_OR filter_term
  46 | filter filter_term %prec OP_OR
  47 | filter_term
  48 ;
  49 
  50 filter_term : filter_term OP_AND filter_factor
  51 | filter_factor
  52 ;
  53 
  54 filter_factor :  OP_NOT filter_factor
  55 | '(' filter ')'
  56 | filter_operand 
  57 ;
  58 
  59 filter_operand: KEYW_ANY
  60 | '<' filter_aspath '>'
  61 | rp_attribute
  62 | TKN_FLTRNAME
  63 | filter_prefix
  64 ;
  65 
  66 filter_prefix: filter_prefix_operand OP_MS
  67 |  filter_prefix_operand
  68 ;
  69 
  70 filter_prefix_operand: TKN_ASNO
  71 | KEYW_PEERAS
  72 | TKN_ASNAME
  73 | TKN_RSNAME
  74 | '{' opt_filter_prefix_list '}'
  75 ;
  76 
  77 opt_filter_prefix_list:
  78 | filter_prefix_list
  79 ;
  80 
  81 filter_prefix_list: filter_prefix_list_prefix 
  82 | filter_prefix_list ',' filter_prefix_list_prefix
  83 ;
  84 
  85 filter_prefix_list_prefix: TKN_PRFXV4
  86 | TKN_PRFXV4RNG
  87 ;
  88 
  89 filter_aspath: filter_aspath '|' filter_aspath_term
  90 | filter_aspath_term
  91 ;
  92 
  93 filter_aspath_term: filter_aspath_term filter_aspath_closure
  94 | filter_aspath_closure
  95 ;
  96 
  97 filter_aspath_closure: filter_aspath_closure '*'
  98 | filter_aspath_closure '?'
  99 | filter_aspath_closure '+'
 100 | filter_aspath_closure ASPATH_POSTFIX
 101 | filter_aspath_factor
 102 ;
 103 
 104 filter_aspath_factor: '^'
 105 | '$'
 106 | '(' filter_aspath ')'
 107 | filter_aspath_no
 108 ;
 109 
 110 filter_aspath_no: TKN_ASNO
 111 | KEYW_PEERAS
 112 | TKN_ASNAME
 113 | '.'
 114 | '[' filter_aspath_range ']'
 115 | '[' '^' filter_aspath_range ']'
 116 ;
 117 
 118 filter_aspath_range:
 119 | filter_aspath_range TKN_ASNO
 120 | filter_aspath_range KEYW_PEERAS
 121 | filter_aspath_range '.'
 122 | filter_aspath_range TKN_ASNO '-' TKN_ASNO
 123 | filter_aspath_range TKN_ASNAME 
 124 ;
 125 
 126 action: rp_attribute ';'
 127 | action rp_attribute ';'
 128 ;
 129 
 130 rp_attribute: pref
 131 | med
 132 | dpa
 133 | aspath
 134 | community
 135 | next_hop
 136 | cost
 137 ;
 138 
 139 pref: TKN_PREF OP_EQUAL TKN_INT {
 140       long int val;
 141       char *s, *p;
 142       p = $3;
 143       val = strtol(p, &s, 10);
 144       if ((val < 0) || (val > 65535)) {
 145           syntax_error("pref value \"%s\" is not between 0 and 65535", p);
 146       }
 147 }
 148 ;
 149 
 150 med: TKN_MED OP_EQUAL TKN_INT {
 151       long int val;
 152       char *s, *p;
 153       p = $3;
 154       val = strtol(p, &s, 10);
 155       if ((val < 0) || (val > 65535)) {
 156           syntax_error("med value \"%s\" is not between 0 and 65535", p);
 157       }
 158 }
 159 | TKN_MED OP_EQUAL KEYW_IGP_COST
 160 ;
 161 
 162 dpa: TKN_DPA OP_EQUAL TKN_INT {
 163       long int val;
 164       char *s, *p;
 165       p = $3;
 166       val = strtol(p, &s, 10);
 167       if ((val < 0) || (val > 65535)) {
 168           syntax_error("dpa value \"%s\" is not between 0 and 65535", p);
 169       }
 170 }
 171 ;
 172 
 173 aspath: TKN_ASPATH '.' KEYW_PREPEND '(' asno_list ')'
 174 ;
 175 
 176 asno_list: TKN_ASNO
 177 | asno_list ',' TKN_ASNO
 178 ;
 179 
 180 community: TKN_COMMUNITY OP_EQUAL community_list
 181 | TKN_COMMUNITY OP_APPEND community_list
 182 | TKN_COMMUNITY '.' KEYW_APPEND '(' community_elm_list ')'
 183 | TKN_COMMUNITY '.' KEYW_DELETE '(' community_elm_list ')'
 184 | TKN_COMMUNITY '.' KEYW_CONTAINS '(' community_elm_list ')'
 185 | TKN_COMMUNITY '(' community_elm_list ')'
 186 | TKN_COMMUNITY OP_COMPARE community_list
 187 ;
 188 
 189 community_list: '{' community_elm_list '}'
 190 ;
 191 
 192 community_elm_list: community_elm
 193 | community_elm_list ',' community_elm
 194 ;
 195 
 196 community_elm: KEYW_INTERNET
 197 | KEYW_NO_EXPORT
 198 | KEYW_NO_ADVERTISE
 199 | TKN_INT {
 200       unsigned long int val;
 201       char *s, *p;
 202       p = $1;
 203       val = strtoul(p, &s, 10);
 204       if ((val < 1) || (val > 4294967295UL) || (*s != '\0')) {
 205           syntax_error("community element \"%s\" is not between 1 and 4294967295",
 206                        p);
 207       }
 208 }
 209 | TKN_COMM_NO
 210 ;
 211 
 212 next_hop: TKN_NEXT_HOP OP_EQUAL TKN_IPV4
 213 | TKN_NEXT_HOP OP_EQUAL KEYW_SELF
 214 ;
 215 
 216 cost: TKN_COST OP_EQUAL TKN_INT {
 217       long int val;
 218       char *s, *p;
 219       p = $3;
 220       val = strtol(p, &s, 10);
 221       if ((val < 0) || (val > 65535)) {
 222           syntax_error("cost value \"%s\" is not between 0 and 65535", p);
 223       }
 224 }
 225 ;
 226 
 227 
 228 %%
 229 
 230 /* define a unit test that simply returns "yes" or "no" for filter input */
 231 #ifndef UNIT_TEST
 232 
 233 #undef filtererror
 234 #undef yyerror
 235 
 236 int
 237 filtererror (const char *s)
     /* [<][>][^][v][top][bottom][index][help] */
 238 {
 239     yyerror(s);
 240     return 0;
 241 }
 242 #else /* UNIT_TEST */
 243 
 244 int parse_error_count;
 245 
 246 /* parse error */
 247 void 
 248 yyerror(const char *s)
     /* [<][>][^][v][top][bottom][index][help] */
 249 {
 250     fputs(s, stderr);
 251     putc('\n', stderr);
 252     parse_error_count++;
 253 }
 254 
 255 /* syntax error */
 256 void 
 257 syntax_error(const char *fmt, ...)
     /* [<][>][^][v][top][bottom][index][help] */
 258 {
 259     va_list args;
 260     char buf[1024];
 261 
 262     va_start(args, fmt);
 263     vsnprintf(buf, sizeof(buf), fmt, args);
 264     va_end(args);
 265     yyerror(buf);
 266 }
 267 
 268 int
 269 yywrap()
     /* [<][>][^][v][top][bottom][index][help] */
 270 {
 271     return 1;
 272 }
 273 
 274 /* taken from _lex & yacc_ p.157, by Levine, Mason, & Brown (corrected) */
 275 char *myinputptr;
 276 char *myinputlim;
 277 
 278 #undef min
 279 #define min(a, b)  (((a) < (b)) ? (a) : (b))
 280 
 281 void
 282 yy_input(char *buf, int *result, int max_size)
     /* [<][>][^][v][top][bottom][index][help] */
 283 {
 284     int n = min(max_size, myinputlim - myinputptr);
 285 
 286     if (n > 0) {
 287         memcpy(buf, myinputptr, n);
 288         myinputptr += n;
 289     }
 290     *result = n;
 291 }
 292 
 293 /* program entry point */
 294 int 
 295 main()
     /* [<][>][^][v][top][bottom][index][help] */
 296 {
 297     char buf[4096];
 298 
 299     setbuf(stdout, NULL);
 300     for (;;) {
 301         printf("filter> ");
 302         if (gets(buf) == NULL) {
 303             printf("\n");
 304             return(0);
 305         }
 306         parse_error_count = 0;
 307         myinputptr = buf;
 308         myinputlim = buf + strlen(buf);
 309         filterparse();
 310         printf("%d parse errors\n", parse_error_count);
 311     }
 312 }
 313 #endif /* UNIT_TEST */

/* [<][>][^][v][top][bottom][index][help] */