Revision 42a0c054 filter/config.Y

View differences:

filter/config.Y
75 75
  return lst;
76 76
}
77 77

  
78
#define EC_ALL 0xFFFFFFFF
79

  
80
static struct f_tree *
81
f_new_ec_item(u32 kind, u32 ipv4_used, u32 key, u32 vf, u32 vt)
82
{
83
  u64 fm, to;
84

  
85
  if (ipv4_used || (key >= 0x10000)) {
86
    check_u16(vf);
87
    if (vt == EC_ALL)
88
      vt = 0xFFFF;
89
    else
90
      check_u16(vt);
91
  }
92

  
93
  if (kind == EC_GENERIC) {
94
    fm = ec_generic(key, vf);
95
    to = ec_generic(key, vt);
96
  }
97
  else if (ipv4_used) {
98
    fm = ec_ip4(kind, key, vf);
99
    to = ec_ip4(kind, key, vt);
100
  }
101
  else if (key < 0x10000) {
102
    fm = ec_as2(kind, key, vf);
103
    to = ec_as2(kind, key, vt);
104
  }
105
  else {
106
    fm = ec_as4(kind, key, vf);
107
    to = ec_as4(kind, key, vt);
108
  }
109

  
110
  struct f_tree *t = f_new_tree();
111
  t->right = t;
112
  t->from.type = t->to.type = T_EC;
113
  t->from.val.ec = fm;
114
  t->to.val.ec = to;
115
  return t;
116
}
117

  
118
static inline struct f_inst *
119
f_generate_empty(struct f_inst *dyn)
120
{ 
121
  struct f_inst *e = f_new_inst();
122
  e->code = 'E';
123

  
124
  switch (dyn->aux & EAF_TYPE_MASK) {
125
    case EAF_TYPE_AS_PATH:
126
      e->aux = T_PATH;
127
      break;
128
    case EAF_TYPE_INT_SET:
129
      e->aux = T_CLIST;
130
      break;
131
    case EAF_TYPE_EC_SET:
132
      e->aux = T_ECLIST;
133
      break;
134
    default:
135
      cf_error("Can't empty that attribute");
136
  }
137

  
138
  dyn->code = P('e','S');
139
  dyn->a1.p = e;
140
  return dyn;
141
}
142

  
143

  
144
static inline struct f_inst *
145
f_generate_dpair(struct f_inst *t1, struct f_inst *t2)
146
{
147
  struct f_inst *rv;
148

  
149
  if ((t1->code == 'c') && (t2->code == 'c')) {
150
    if ((t1->aux != T_INT) || (t2->aux != T_INT))
151
      cf_error( "Can't operate with value of non-integer type in pair constructor");
152

  
153
    check_u16(t1->a2.i);
154
    check_u16(t2->a2.i);
155

  
156
    rv = f_new_inst();
157
    rv->code = 'c';
158
    rv->aux = T_PAIR;
159
    rv->a2.i = pair(t1->a2.i, t2->a2.i);
160
  }
161
  else {
162
    rv = f_new_inst();
163
    rv->code = P('m', 'p');
164
    rv->a1.p = t1;
165
    rv->a2.p = t2;
166
  }
167

  
168
  return rv;
169
}
170

  
171
static inline struct f_inst *
172
f_generate_ec(u16 kind, struct f_inst *tk, struct f_inst *tv)
173
{
174
  struct f_inst *rv;
175
  int c1 = 0, c2 = 0, ipv4_used = 0;
176
  u32 key = 0, val2 = 0;
177

  
178
  if (tk->code == 'c') {
179
    c1 = 1;
180

  
181
    if (tk->aux == T_INT) {
182
      ipv4_used = 0; key = tk->a2.i;
183
    }
184
    else if (tk->aux == T_QUAD) {
185
      ipv4_used = 1; key = tk->a2.i;
186
    }
187
    else
188
      cf_error("Can't operate with key of non-integer/IPv4 type in EC constructor");
189
  }
190

  
191
#ifndef IPV6
192
  /* IP->Quad implicit conversion */
193
  else if (tk->code == 'C') {
194
    c1 = 1;
195
    struct f_val *val = tk->a1.p;
196
    if (val->type == T_IP) {
197
      ipv4_used = 1; key = ipa_to_u32(val->val.px.ip);
198
    }
199
    else
200
      cf_error("Can't operate with key of non-integer/IPv4 type in EC constructor");
201
  }
202
#endif
203

  
204
  if (tv->code == 'c') {
205
    if (tv->aux != T_INT)
206
      cf_error("Can't operate with value of non-integer type in EC constructor");
207
    c2 = 1;
208
    val2 = tv->a2.i;
209
  }
210

  
211
  if (c1 && c2) {
212
    u64 ec;
213
  
214
    if (kind == EC_GENERIC) {
215
      ec = ec_generic(key, val2);
216
    }
217
    else if (ipv4_used) {
218
      check_u16(val2);
219
      ec = ec_ip4(kind, key, val2);
220
    }
221
    else if (key < 0x10000) {
222
      ec = ec_as2(kind, key, val2);
223
    }
224
    else {
225
      check_u16(val2);
226
      ec = ec_as4(kind, key, val2);
227
    }
228

  
229
    NEW_F_VAL;
230
    rv = f_new_inst();
231
    rv->code = 'C';
232
    rv->a1.p = val;    
233
    val->type = T_EC;
234
    val->val.ec = ec;
235
  }
236
  else {
237
    rv = f_new_inst();
238
    rv->code = P('m','c');
239
    rv->aux = kind;
240
    rv->a1.p = tk;
241
    rv->a2.p = tv;
242
  }
243

  
244
  return rv;
245
};
246

  
247

  
248

  
78 249
CF_DECLS
79 250

  
80 251
CF_KEYWORDS(FUNCTION, PRINT, PRINTN, UNSET, RETURN,
81 252
	ACCEPT, REJECT, ERROR, QUITBIRD,
82
	INT, BOOL, IP, PREFIX, PAIR, QUAD, SET, STRING, BGPMASK, BGPPATH, CLIST,
253
	INT, BOOL, IP, PREFIX, PAIR, QUAD, EC,
254
	SET, STRING, BGPMASK, BGPPATH, CLIST, ECLIST,
83 255
	IF, THEN, ELSE, CASE,
84
	TRUE, FALSE,
256
	TRUE, FALSE, RT, RO, UNKNOWN, GENERIC,
85 257
	FROM, GW, NET, MASK, PROTO, SOURCE, SCOPE, CAST, DEST, PREFERENCE,
86 258
	LEN,
87 259
	DEFINED,
......
93 265
%nonassoc THEN
94 266
%nonassoc ELSE
95 267

  
96
%type <x> term block cmds cmds_int cmd function_body constant print_one print_list var_list var_listn dynamic_attr static_attr function_call symbol dpair bgp_path_expr
268
%type <x> term block cmds cmds_int cmd function_body constant constructor print_one print_list var_list var_listn dynamic_attr static_attr function_call symbol bgp_path_expr
97 269
%type <f> filter filter_body where_filter
98
%type <i> type break_command pair_expr
99
%type <i32> pair_atom
100
%type <e> pair_item set_item switch_item set_items switch_items switch_body
270
%type <i> type break_command pair_expr ec_kind
271
%type <i32> pair_atom ec_expr
272
%type <e> pair_item ec_item set_item switch_item set_items switch_items switch_body
101 273
%type <trie> fprefix_set
102 274
%type <v> set_atom switch_atom fprefix fprefix_s fipa
103 275
%type <s> decls declsn one_decl function_params 
......
128 300
 | PREFIX { $$ = T_PREFIX; }
129 301
 | PAIR { $$ = T_PAIR; }
130 302
 | QUAD { $$ = T_QUAD; }
303
 | EC { $$ = T_EC; }
131 304
 | STRING { $$ = T_STRING; }
132 305
 | BGPMASK { $$ = T_PATH_MASK; }
133 306
 | BGPPATH { $$ = T_PATH; }
134 307
 | CLIST { $$ = T_CLIST; }
308
 | ECLIST { $$ = T_ECLIST; }
135 309
 | type SET { 
136 310
	switch ($1) {
137 311
	  case T_INT:
138 312
	  case T_PAIR:
139 313
	  case T_QUAD:
314
	  case T_EC:
140 315
	  case T_IP:
141 316
	       $$ = T_SET;
142 317
	       break;
......
324 499
   }
325 500
 ;
326 501

  
502
ec_expr:
503
   term { $$ = f_eval_int($1); }
504

  
505
ec_kind:
506
   RT { $$ = EC_RT; }
507
 | RO { $$ = EC_RO; }
508
 | UNKNOWN NUM { $$ = $2; }
509
 | GENERIC { $$ = EC_GENERIC; }
510
 ;
511

  
512
ec_item:
513
   '(' ec_kind ',' ec_expr ',' ec_expr ')' { $$ = f_new_ec_item($2, 0, $4, $6, $6); }
514
 | '(' ec_kind ',' ec_expr ',' ec_expr DDOT ec_expr ')' { $$ = f_new_ec_item($2, 0, $4, $6, $8); }
515
 | '(' ec_kind ',' ec_expr ',' '*' ')' {  $$ = f_new_ec_item($2, 0, $4, 0, EC_ALL); }
516
 ;
517

  
327 518
set_item:
328 519
   pair_item
520
 | ec_item
329 521
 | set_atom { $$ = f_new_item($1, $1); }
330 522
 | set_atom DDOT set_atom { $$ = f_new_item($1, $3); }
331 523
 ;
332 524

  
333 525
switch_item:
334 526
   pair_item
527
 | ec_item
335 528
 | switch_atom { $$ = f_new_item($1, $1); }
336 529
 | switch_atom DDOT switch_atom { $$ = f_new_item($1, $3); }
337 530
 ;
......
411 604
 | 		      { $$ = NULL; }
412 605
 ;
413 606

  
414
dpair:
415
   '(' term ',' term ')' {
416
        if (($2->code == 'c') && ($4->code == 'c'))
417
          { 
418
            if (($2->aux != T_INT) || ($4->aux != T_INT))
419
              cf_error( "Can't operate with value of non-integer type in pair constructor" );
420
	    check_u16($2->a2.i); check_u16($4->a2.i);
421
            $$ = f_new_inst(); $$->code = 'c'; $$->aux = T_PAIR;  $$->a2.i = pair($2->a2.i, $4->a2.i);
422
          }
423
	else
424
	  { $$ = f_new_inst(); $$->code = P('m', 'p'); $$->a1.p = $2; $$->a2.p = $4; }
425
    }
426
 ;
427

  
428 607
constant:
429 608
   NUM    { $$ = f_new_inst(); $$->code = 'c'; $$->aux = T_INT;  $$->a2.i = $1; }
430 609
 | TRUE   { $$ = f_new_inst(); $$->code = 'c'; $$->aux = T_BOOL; $$->a2.i = 1;  }
......
439 618
 | bgp_path { NEW_F_VAL; $$ = f_new_inst(); $$->code = 'C'; val->type = T_PATH_MASK; val->val.path_mask = $1; $$->a1.p = val; }
440 619
 ;
441 620

  
621
constructor:
622
   '(' term ',' term ')' { $$ = f_generate_dpair($2, $4); };
623
 | '(' ec_kind ',' term ',' term ')' { $$ = f_generate_ec($2, $4, $6); };
624
 ;
625

  
442 626

  
443 627
/*
444 628
 *  Maybe there are no dynamic attributes defined by protocols.
......
490 674
       case SYM_VARIABLE | T_INT:
491 675
       case SYM_VARIABLE | T_PAIR:
492 676
       case SYM_VARIABLE | T_QUAD:
677
       case SYM_VARIABLE | T_EC:
493 678
       case SYM_VARIABLE | T_STRING:
494 679
       case SYM_VARIABLE | T_IP:
495 680
       case SYM_VARIABLE | T_PREFIX:
......
498 683
       case SYM_VARIABLE | T_PATH:
499 684
       case SYM_VARIABLE | T_PATH_MASK:
500 685
       case SYM_VARIABLE | T_CLIST:
686
       case SYM_VARIABLE | T_ECLIST:
501 687
	 $$->code = 'V';
502 688
	 $$->a1.p = $1->def;
503 689
	 $$->a2.p = $1->name;
......
539 725

  
540 726
 | symbol   { $$ = $1; }
541 727
 | constant { $$ = $1; }
542
 | dpair    { $$ = $1; }
728
 | constructor { $$ = $1; }
543 729

  
544 730
 | PREFERENCE { $$ = f_new_inst(); $$->code = 'P'; }
545 731

  
......
563 749

  
564 750
 | '+' EMPTY '+' { $$ = f_new_inst(); $$->code = 'E'; $$->aux = T_PATH; }
565 751
 | '-' EMPTY '-' { $$ = f_new_inst(); $$->code = 'E'; $$->aux = T_CLIST; }
752
 | '-' '-' EMPTY '-' '-' { $$ = f_new_inst(); $$->code = 'E'; $$->aux = T_ECLIST; }
566 753
 | PREPEND '(' term ',' term ')' { $$ = f_new_inst(); $$->code = P('A','p'); $$->a1.p = $3; $$->a2.p = $5; } 
567 754
 | ADD '(' term ',' term ')' { $$ = f_new_inst(); $$->code = P('C','a'); $$->a1.p = $3; $$->a2.p = $5; $$->aux = 'a'; } 
568 755
 | DELETE '(' term ',' term ')' { $$ = f_new_inst(); $$->code = P('C','a'); $$->a1.p = $3; $$->a2.p = $5; $$->aux = 'd'; }
......
702 889
   }
703 890

  
704 891

  
705
 | rtadot dynamic_attr '.' EMPTY ';' 
706
  { struct f_inst *i = f_new_inst(); i->code = 'E'; i->aux = T_CLIST; $$ = $2; $$->code = P('e','S'); $$->a1.p = i; }
892
 | rtadot dynamic_attr '.' EMPTY ';' { $$ = f_generate_empty($2); }
707 893
 | rtadot dynamic_attr '.' PREPEND '(' term ')' ';'   { $$ = f_generate_complex( P('A','p'), 'x', $2, $6 ); }
708
 | rtadot dynamic_attr '.' ADD '(' term ')' ';'       { $$ = f_generate_complex( P('C','a'), 'a', $2, $6 ); } 
709
 | rtadot dynamic_attr '.' DELETE '(' term ')' ';'    { $$ = f_generate_complex( P('C','a'), 'd', $2, $6 ); } 
710
 | rtadot dynamic_attr '.' FILTER '(' term ')' ';'    { $$ = f_generate_complex( P('C','a'), 'f', $2, $6 ); } 
894
 | rtadot dynamic_attr '.' ADD '(' term ')' ';'       { $$ = f_generate_complex( P('C','a'), 'a', $2, $6 ); }
895
 | rtadot dynamic_attr '.' DELETE '(' term ')' ';'    { $$ = f_generate_complex( P('C','a'), 'd', $2, $6 ); }
896
 | rtadot dynamic_attr '.' FILTER '(' term ')' ';'    { $$ = f_generate_complex( P('C','a'), 'f', $2, $6 ); }
711 897
 ;
712 898

  
713 899
CF_END

Also available in: Unified diff