Revision 758458be

View differences:

TODO
1 1
Core
2 2
~~~~
3
- config: when parsing prefix, check zero bits
4 3
- config: try to unify expressions
5 4

  
6 5
- static: check validity of route destination?
conf/confbase.Y
40 40
  struct rt_show_data *ra;
41 41
  void *g;
42 42
  bird_clock_t time;
43
  struct prefix px;
43 44
}
44 45

  
45 46
%token END CLI_MARKER INVALID_TOKEN
......
52 53

  
53 54
%type <i> expr bool pxlen
54 55
%type <time> datetime
56
%type <px> prefix
55 57

  
56 58
%nonassoc '=' '<' '>' '~' '.' GEQ LEQ NEQ
57 59
%left '+' '-'
......
109 111

  
110 112
/* Prefixes and netmasks */
111 113

  
114
prefix:
115
   IPA pxlen {
116
     if (!ip_is_prefix($1, $2)) cf_error("Invalid prefix");
117
     $$.addr = $1; $$.len = $2;
118
   }
119
 ;
120

  
112 121
pxlen:
113 122
   '/' NUM {
114 123
     if ($2 < 0 || $2 > BITS_PER_IP_ADDRESS) cf_error("Invalid prefix length %d", $2);
filter/config.Y
42 42
%type <f> filter filter_body where_filter
43 43
%type <i> type break_command pair
44 44
%type <e> set_item set_items switch_body
45
%type <v> set_atom prefix prefix_s ipa
45
%type <v> set_atom fprefix fprefix_s ipa
46 46
%type <s> decls declsn one_decl function_params 
47 47
%type <h> bgp_path
48 48
%type <i> bgp_one
......
212 212
/*
213 213
 * Complex types, their bison value is struct f_val
214 214
 */
215
prefix_s:
216
   IPA '/' NUM { $$.type = T_PREFIX; $$.val.px.ip = $1; $$.val.px.len = $3; if (ipa_nonzero(ipa_and($$.val.px.ip, ipa_not(ipa_mkmask($$.val.px.len))))) cf_error( "%I/%d is not really prefix\n", $$.val.px.ip, $$.val.px.len ); }
215
fprefix_s:
216
   IPA '/' NUM {
217
     if (!ip_is_prefix($1, $3)) cf_error("Invalid network prefix: %I/%d", $1, $3);
218
     $$.type = T_PREFIX; $$.val.px.ip = $1; $$.val.px.len = $3;
219
   }
217 220
 ;
218 221

  
219
prefix:
220
   prefix_s { $$ = $1; }
221
 | prefix_s '+' { $$ = $1; $$.val.px.len |= LEN_PLUS; }
222
 | prefix_s '-' { $$ = $1; $$.val.px.len |= LEN_MINUS; }
223
 | prefix_s '{' NUM ',' NUM '}' { $$ = $1; $$.val.px.len |= LEN_RANGE | ($3 << 16) | ($5 << 8); }
222
fprefix:
223
   fprefix_s { $$ = $1; }
224
 | fprefix_s '+' { $$ = $1; $$.val.px.len |= LEN_PLUS; }
225
 | fprefix_s '-' { $$ = $1; $$.val.px.len |= LEN_MINUS; }
226
 | fprefix_s '{' NUM ',' NUM '}' { $$ = $1; $$.val.px.len |= LEN_RANGE | ($3 << 16) | ($5 << 8); }
224 227
 ;
225 228

  
226 229
ipa:
......
231 234
   NUM  { $$.type = T_INT; $$.val.i = $1; }
232 235
 | pair { $$.type = T_PAIR; $$.val.i = $1; }
233 236
 | ipa  { $$ = $1; }
234
 | prefix { $$ = $1; }
237
 | fprefix { $$ = $1; }
235 238
 ; 
236 239

  
237 240
set_item:
......
291 294
 | TEXT   { $$ = f_new_inst(); $$->code = 'c'; $$->aux = T_STRING; $$->a2.p = $1; }
292 295
 | pair   { $$ = f_new_inst(); $$->code = 'c'; $$->aux = T_PAIR;  $$->a2.i = $1; }
293 296
 | ipa	   { NEW_F_VAL; $$ = f_new_inst(); $$->code = 'C'; $$->a1.p = val; *val = $1; }
294
 | prefix_s {NEW_F_VAL; $$ = f_new_inst(); $$->code = 'C'; $$->a1.p = val; *val = $1; }
297
 | fprefix_s {NEW_F_VAL; $$ = f_new_inst(); $$->code = 'C'; $$->a1.p = val; *val = $1; }
295 298
 | '[' set_items ']' { DBG( "We've got a set here..." ); $$ = f_new_inst(); $$->code = 'c'; $$->aux = T_SET; $$->a2.p = build_tree($2); DBG( "ook\n" ); }
296 299
 | ENUM	  { $$ = f_new_inst(); $$->code = 'c'; $$->aux = $1 >> 16; $$->a2.i = $1 & 0xffff; }
297 300
 | '/' bgp_path '/' { NEW_F_VAL; $$ = f_new_inst(); $$->code = 'C'; val->type = T_PATH_MASK; val->val.path_mask = $2; $$->a1.p = val; }
filter/filter.h
30 30
#define arg1 a1.p
31 31
#define arg2 a2.p
32 32

  
33
struct prefix {
33
struct f_prefix {
34 34
  ip_addr ip;
35 35
  int len;
36 36
#define LEN_MASK 0xff
......
45 45
  union {
46 46
    int i;
47 47
    /*    ip_addr ip; Folded into prefix */	
48
    struct prefix px;
48
    struct f_prefix px;
49 49
    char *s;
50 50
    struct f_tree *t;
51 51
    struct adata *ad;
lib/ip.h
41 41
char *ip_scope_text(unsigned);
42 42

  
43 43
/*
44
 *	Is it a valid network prefix?
44
 *	Network prefixes
45 45
 */
46 46

  
47
struct prefix {
48
  ip_addr addr;
49
  int len;
50
};
51

  
47 52
#define ip_is_prefix(a,l) (!ipa_nonzero(ipa_and(a, ipa_not(ipa_mkmask(l)))))
48 53

  
49 54
/*
nest/config.Y
124 124

  
125 125
iface_patt:
126 126
   TEXT { this_ipatt->pattern = $1; this_ipatt->prefix = IPA_NONE; this_ipatt->pxlen = 0; }
127
 | IPA pxlen { this_ipatt->pattern = NULL; this_ipatt->prefix = $1; this_ipatt->pxlen = $2; }
128
 | TEXT IPA pxlen { this_ipatt->pattern = $1; this_ipatt->prefix = $2; this_ipatt->pxlen = $3; }
127
 | prefix { this_ipatt->pattern = NULL; this_ipatt->prefix = $1.addr; this_ipatt->pxlen = $1.len; }
128
 | TEXT prefix { this_ipatt->pattern = $1; this_ipatt->prefix = $2.addr; this_ipatt->pxlen = $2.len; }
129 129
 ;
130 130

  
131 131
/* Direct device route protocol */
......
250 250
     $$->filter = FILTER_ACCEPT;
251 251
     $$->table = config->master_rtc->table;
252 252
   }
253
 | r_args IPA pxlen {
253
 | r_args prefix {
254 254
     $$ = $1;
255 255
     if ($$->pxlen != 256) cf_error("Only one prefix expected");
256
     if (!ip_is_prefix($2, $3)) cf_error("Invalid prefix");
257
     $$->prefix = $2;
258
     $$->pxlen = $3;
256
     $$->prefix = $2.addr;
257
     $$->pxlen = $2.len;
259 258
   }
260 259
 | r_args TABLE SYM {
261 260
     $$ = $1;
proto/static/config.Y
34 34
 | static_proto stat_route ';'
35 35
 ;
36 36

  
37
stat_route0: ROUTE IPA pxlen {
37
stat_route0: ROUTE prefix {
38 38
     this_srt = cfg_allocz(sizeof(struct static_route));
39 39
     add_tail(&((struct static_config *) this_proto)->other_routes, &this_srt->n);
40
     if (!ip_is_prefix($2, $3)) cf_error("Invalid network prefix: %I/%d", $2, $3);
41
     this_srt->net = $2;
42
     this_srt->masklen = $3;
40
     this_srt->net = $2.addr;
41
     this_srt->masklen = $2.len;
43 42
  }
44 43
 ;
45 44

  

Also available in: Unified diff