Revision 5e173e9f

View differences:

conf/confbase.Y
61 61
  struct roa_table *rot;
62 62
  void *g;
63 63
  bird_clock_t time;
64
  struct prefix px;
64
  struct f_prefix px;
65 65
  struct proto_spec ps;
66 66
  struct timeformat *tf;
67 67
}
......
162 162
   ipa_raw
163 163
 | SYM {
164 164
     if ($1->class != (SYM_CONSTANT | T_IP)) cf_error("IP address expected");
165
     $$ = SYM_VAL($1).px.ip;
165
     $$ = SYM_VAL($1).ip;
166 166
   }
167 167
 ;
168 168

  
filter/config.Y
134 134

  
135 135
static inline struct f_inst *
136 136
f_generate_empty(struct f_inst *dyn)
137
{ 
137
{
138 138
  struct f_inst *e = f_new_inst();
139 139
  e->code = 'E';
140 140

  
......
217 217
    else if (val->type == T_QUAD) {
218 218
      ipv4_used = 1; key = val->val.i;
219 219
    }
220
    else if (val->type == T_IP) {
221
      ipv4_used = 1; key = ipa_to_u32(val->val.px.ip);
220
    else if ((val->type == T_IP) && ipa_is_ip4(val->val.ip)) {
221
      ipv4_used = 1; key = ipa_to_u32(val->val.ip);
222 222
    }
223 223
    else
224 224
      cf_error("Can't operate with key of non-integer/IPv4 type in EC constructor");
......
234 234

  
235 235
  if (c1 && c2) {
236 236
    u64 ec;
237
  
237

  
238 238
    if (kind == EC_GENERIC) {
239 239
      ec = ec_generic(key, val2);
240 240
    }
......
253 253
    NEW_F_VAL;
254 254
    rv = f_new_inst();
255 255
    rv->code = 'C';
256
    rv->a1.p = val;    
256
    rv->a1.p = val;
257 257
    val->type = T_EC;
258 258
    val->val.ec = ec;
259 259
  }
......
297 297
%type <i32> pair_atom ec_expr
298 298
%type <e> pair_item ec_item set_item switch_item set_items switch_items switch_body
299 299
%type <trie> fprefix_set
300
%type <v> set_atom switch_atom fprefix fprefix_s fipa
301
%type <s> decls declsn one_decl function_params 
300
%type <v> set_atom switch_atom fipa
301
%type <px> fprefix
302
%type <s> decls declsn one_decl function_params
302 303
%type <h> bgp_path bgp_path_tail1 bgp_path_tail2
303 304

  
304 305
CF_GRAMMAR
......
323 324
   INT { $$ = T_INT; }
324 325
 | BOOL { $$ = T_BOOL; }
325 326
 | IP { $$ = T_IP; }
326
 | PREFIX { $$ = T_PREFIX; }
327
 | PREFIX { $$ = T_NET; }
327 328
 | PAIR { $$ = T_PAIR; }
328 329
 | QUAD { $$ = T_QUAD; }
329 330
 | EC { $$ = T_EC; }
......
342 343
	       $$ = T_SET;
343 344
	       break;
344 345

  
345
	  case T_PREFIX:
346
	  case T_NET:
346 347
	       $$ = T_PREFIX_SET;
347 348
	    break;
348 349

  
......
477 478
 * Complex types, their bison value is struct f_val
478 479
 */
479 480
fipa:
480
   ipa_raw %prec PREFIX_DUMMY { $$.type = T_IP; $$.val.px.ip = $1; }
481
   ipa_raw %prec PREFIX_DUMMY { $$.type = T_IP; $$.val.ip = $1; }
481 482
 ;
482 483

  
483 484

  
......
572 573
 | switch_items ',' switch_item { $$ = f_merge_items($1, $3); }
573 574
 ;
574 575

  
575
fprefix_s:
576
   ipa_raw '/' NUM %prec '/' {
577
     if (($3 < 0) || ($3 > (ipa_is_ip4($1) ? IP4_MAX_PREFIX_LENGTH : IP6_MAX_PREFIX_LENGTH)) || !ip_is_prefix($1, $3)) cf_error("Invalid network prefix: %I/%d.", $1, $3);
578
     $$.type = T_PREFIX; $$.val.px.ip = $1; $$.val.px.len = $3;
579
   }
580
 ;
581

  
582 576
fprefix:
583
   fprefix_s { $$ = $1; }
584
 | fprefix_s '+' { $$ = $1; $$.val.px.len |= LEN_PLUS; }
585
 | fprefix_s '-' { $$ = $1; $$.val.px.len |= LEN_MINUS; }
586
 | fprefix_s '{' NUM ',' NUM '}' { 
587
     if (! ((0 <= $3) && ($3 <= $5) && ($5 <= (ipa_is_ip4($1.val.px.ip) ? IP4_MAX_PREFIX_LENGTH : IP6_MAX_PREFIX_LENGTH)))) cf_error("Invalid prefix pattern range: {%d, %d}.", $3, $5);
588
     $$ = $1; $$.val.px.len |= LEN_RANGE | ($3 << 16) | ($5 << 8);
577
   net_ip	{ $$.net = $1; $$.lo = $1.n.pxlen; $$.hi = $1.n.pxlen; }
578
 | net_ip '+'	{ $$.net = $1; $$.lo = $1.n.pxlen; $$.hi = net_max_prefix_length[$1.n.type]; }
579
 | net_ip '-'	{ $$.net = $1; $$.lo = 0; $$.hi = $1.n.pxlen; }
580
 | net_ip '{' NUM ',' NUM '}' {
581
     $$.net = $1; $$.lo = $3; $$.hi = $5;
582
     if ((0 > $3) || ($3 > $5) || ($5 > net_max_prefix_length[$1.n.type]))
583
       cf_error("Invalid prefix pattern range: {%d, %d}", $3, $5);
589 584
   }
590 585
 ;
591 586

  
592 587
fprefix_set:
593
   fprefix { $$ = f_new_trie(cfg_mem, sizeof(struct f_trie_node)); trie_add_fprefix($$, &($1.val.px)); }
594
 | fprefix_set ',' fprefix { $$ = $1; trie_add_fprefix($$, &($3.val.px)); }
588
   fprefix { $$ = f_new_trie(cfg_mem, sizeof(struct f_trie_node)); trie_add_prefix($$, &($1.net.n), $1.lo, $1.hi); }
589
 | fprefix_set ',' fprefix { $$ = $1; trie_add_prefix($$, &($3.net.n), $3.lo, $3.hi); }
595 590
 ;
596 591

  
597 592
switch_body: /* EMPTY */ { $$ = NULL; }
......
602 597
       t->data = $4;
603 598
     $$ = f_merge_items($1, $2);
604 599
   }
605
 | switch_body ELSECOL cmds { 
600
 | switch_body ELSECOL cmds {
606 601
     struct f_tree *t = f_new_tree();
607 602
     t->from.type = t->to.type = T_VOID;
608 603
     t->right = t;
......
642 637
 | TRUE   { $$ = f_new_inst(); $$->code = 'c'; $$->aux = T_BOOL; $$->a2.i = 1;  }
643 638
 | FALSE  { $$ = f_new_inst(); $$->code = 'c'; $$->aux = T_BOOL; $$->a2.i = 0;  }
644 639
 | TEXT   { $$ = f_new_inst(); $$->code = 'c'; $$->aux = T_STRING; $$->a2.p = $1; }
645
 | fipa	   { NEW_F_VAL; $$ = f_new_inst(); $$->code = 'C'; $$->a1.p = val; *val = $1; }
646
 | fprefix_s {NEW_F_VAL; $$ = f_new_inst(); $$->code = 'C'; $$->a1.p = val; *val = $1; }
640
 | fipa	  { NEW_F_VAL; $$ = f_new_inst(); $$->code = 'C'; $$->a1.p = val; *val = $1; }
641
 | net_any { NEW_F_VAL; $$ = f_new_inst(); $$->code = 'C'; val->type = T_NET; val->val.net = $1; $$->a1.p = val; }
647 642
 | '[' 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" ); }
648 643
 | '[' fprefix_set ']' { $$ = f_new_inst(); $$->code = 'c'; $$->aux = T_PREFIX_SET;  $$->a2.p = $2; }
649 644
 | ENUM	  { $$ = f_new_inst(); $$->code = 'c'; $$->aux = $1 >> 16; $$->a2.i = $1 & 0xffff; }
......
706 701
static_attr:
707 702
   FROM    { $$ = f_new_inst(); $$->aux = T_IP;         $$->a2.i = SA_FROM;	$$->a1.i = 1; }
708 703
 | GW      { $$ = f_new_inst(); $$->aux = T_IP;         $$->a2.i = SA_GW;	$$->a1.i = 1; }
709
 | NET     { $$ = f_new_inst(); $$->aux = T_PREFIX;     $$->a2.i = SA_NET; }
704
 | NET     { $$ = f_new_inst(); $$->aux = T_NET;        $$->a2.i = SA_NET; }
710 705
 | PROTO   { $$ = f_new_inst(); $$->aux = T_STRING;     $$->a2.i = SA_PROTO; }
711 706
 | SOURCE  { $$ = f_new_inst(); $$->aux = T_ENUM_RTS;   $$->a2.i = SA_SOURCE; }
712 707
 | SCOPE   { $$ = f_new_inst(); $$->aux = T_ENUM_SCOPE; $$->a2.i = SA_SCOPE;	$$->a1.i = 1; }
filter/filter.c
90 90
  buffer_puts(buf, "=]");
91 91
}
92 92

  
93
static inline int
94
uint_cmp(uint i1, uint i2)
95
{
96
  return (int)(i1 > i2) - (int)(i1 < i2);
97
}
98

  
99
static inline int
100
u64_cmp(u64 i1, u64 i2)
101
{
102
  return (int)(i1 > i2) - (int)(i1 < i2);
103
}
93
static inline int val_is_ip4(const struct f_val v)
94
{ return (v.type == T_IP) && ipa_is_ip4(v.val.ip); }
104 95

  
105 96
/**
106 97
 * val_compare - compare two values
......
114 105
int
115 106
val_compare(struct f_val v1, struct f_val v2)
116 107
{
117
  int rc;
118

  
119 108
  if (v1.type != v2.type) {
120 109
    if (v1.type == T_VOID)	/* Hack for else */
121 110
      return -1;
......
124 113

  
125 114
#ifndef IPV6
126 115
    /* IP->Quad implicit conversion */
127
    if ((v1.type == T_QUAD) && (v2.type == T_IP))
128
      return uint_cmp(v1.val.i, ipa_to_u32(v2.val.px.ip));
129
    if ((v1.type == T_IP) && (v2.type == T_QUAD))
130
      return uint_cmp(ipa_to_u32(v1.val.px.ip), v2.val.i);
116
    if ((v1.type == T_QUAD) && val_is_ip4(v2))
117
      return uint_cmp(v1.val.i, ipa_to_u32(v2.val.ip));
118
    if (val_is_ip4(v1) && (v2.type == T_QUAD))
119
      return uint_cmp(ipa_to_u32(v1.val.ip), v2.val.i);
131 120
#endif
132 121

  
133 122
    debug( "Types do not match in val_compare\n" );
......
146 135
  case T_EC:
147 136
    return u64_cmp(v1.val.ec, v2.val.ec);
148 137
  case T_IP:
149
    return ipa_compare(v1.val.px.ip, v2.val.px.ip);
150
  case T_PREFIX:
151
    if (rc = ipa_compare(v1.val.px.ip, v2.val.px.ip))
152
      return rc;
153
    return uint_cmp(v1.val.px.len, v2.val.px.len);
138
    return ipa_compare(v1.val.ip, v2.val.ip);
139
  case T_NET:
140
    return net_compare(v1.val.net, v2.val.net);
154 141
  case T_STRING:
155 142
    return strcmp(v1.val.s, v2.val.s);
156 143
  default:
......
209 196
  }
210 197
}
211 198

  
212
void
213
fprefix_get_bounds(struct f_prefix *px, int *l, int *h)
214
{
215
  *l = *h = px->len & LEN_MASK;
216

  
217
  if (px->len & LEN_MINUS)
218
    *l = 0;
219

  
220
  else if (px->len & LEN_PLUS)
221
    *h = ipa_is_ip4(px->ip) ? IP4_MAX_PREFIX_LENGTH : IP6_MAX_PREFIX_LENGTH;
222

  
223
  else if (px->len & LEN_RANGE)
224
    {
225
      *l = 0xff & (px->len >> 16);
226
      *h = 0xff & (px->len >> 8);
227
    }
228
}
229

  
230 199
static int
231 200
clist_set_type(struct f_tree *set, struct f_val *v)
232 201
{
......
385 354
    return int_set_contains(v2.val.ad, v1.val.i);
386 355
#ifndef IPV6
387 356
  /* IP->Quad implicit conversion */
388
  if ((v1.type == T_IP) && (v2.type == T_CLIST))
389
    return int_set_contains(v2.val.ad, ipa_to_u32(v1.val.px.ip));
357
  if (val_is_ip4(v1) && (v2.type == T_CLIST))
358
    return int_set_contains(v2.val.ad, ipa_to_u32(v1.val.ip));
390 359
#endif
391 360

  
392 361
  if ((v1.type == T_EC) && (v2.type == T_ECLIST))
......
395 364
  if ((v1.type == T_STRING) && (v2.type == T_STRING))
396 365
    return patmatch(v2.val.s, v1.val.s);
397 366

  
398
  if ((v1.type == T_IP) && (v2.type == T_PREFIX))
399
    return ipa_in_net(v1.val.px.ip, v2.val.px.ip, v2.val.px.len);
367
  if ((v1.type == T_IP) && (v2.type == T_NET))
368
    return ipa_in_netX(v1.val.ip, v2.val.net);
400 369

  
401
  if ((v1.type == T_PREFIX) && (v2.type == T_PREFIX))
402
    return net_in_net(v1.val.px.ip, v1.val.px.len, v2.val.px.ip, v2.val.px.len);
370
  if ((v1.type == T_NET) && (v2.type == T_NET))
371
    return net_in_netX(v1.val.net, v2.val.net);
403 372

  
404
  if ((v1.type == T_PREFIX) && (v2.type == T_PREFIX_SET))
405
    return trie_match_fprefix(v2.val.ti, &v1.val.px);
373
  if ((v1.type == T_NET) && (v2.type == T_PREFIX_SET))
374
    return trie_match_net(v2.val.ti, v1.val.net);
406 375

  
407 376
  if (v2.type != T_SET)
408 377
    return CMP_ERROR;
......
437 406
  case T_BOOL:	buffer_puts(buf, v.val.i ? "TRUE" : "FALSE"); return;
438 407
  case T_INT:	buffer_print(buf, "%u", v.val.i); return;
439 408
  case T_STRING: buffer_print(buf, "%s", v.val.s); return;
440
  case T_IP:	buffer_print(buf, "%I", v.val.px.ip); return;
441
  case T_PREFIX: buffer_print(buf, "%I/%d", v.val.px.ip, v.val.px.len); return;
409
  case T_IP:	buffer_print(buf, "%I", v.val.ip); return;
410
  case T_NET:   buffer_print(buf, "%N", v.val.net); return;
442 411
  case T_PAIR:	buffer_print(buf, "(%u,%u)", v.val.i >> 16, v.val.i & 0xffff); return;
443 412
  case T_QUAD:	buffer_print(buf, "%R", v.val.i); return;
444 413
  case T_EC:	ec_format(buf2, v.val.ec); buffer_print(buf, "%s", buf2); return;
......
630 599
      }
631 600
#ifndef IPV6
632 601
      /* IP->Quad implicit conversion */
633
      else if (v1.type == T_IP) {
634
	ipv4_used = 1; key = ipa_to_u32(v1.val.px.ip);
602
      else if (val_is_ip4(v1)) {
603
	ipv4_used = 1; key = ipa_to_u32(v1.val.ip);
635 604
      }
636 605
#endif
637 606
      else
......
715 684
    if ((sym->class != (SYM_VARIABLE | v2.type)) && (v2.type != T_VOID)) {
716 685
#ifndef IPV6
717 686
      /* IP->Quad implicit conversion */
718
      if ((sym->class == (SYM_VARIABLE | T_QUAD)) && (v2.type == T_IP)) {
687
      if ((sym->class == (SYM_VARIABLE | T_QUAD)) && val_is_ip4(v2))
688
      {
719 689
	vp->type = T_QUAD;
720
	vp->val.i = ipa_to_u32(v2.val.px.ip);
690
	vp->val.i = ipa_to_u32(v2.val.ip);
721 691
	break;
722 692
      }
723 693
#endif
......
790 760

  
791 761
      switch (what->a2.i)
792 762
      {
793
      case SA_FROM:	res.val.px.ip = rta->from; break;
794
      case SA_GW:	res.val.px.ip = rta->gw; break;
795
      case SA_NET:	res.val.px.ip = net_prefix((*f_rte)->net->n.addr);
796
			res.val.px.len = net_pxlen((*f_rte)->net->n.addr); break;
763
      case SA_FROM:	res.val.ip = rta->from; break;
764
      case SA_GW:	res.val.ip = rta->gw; break;
765
      case SA_NET:	res.val.net = (*f_rte)->net->n.addr; break;
797 766
      case SA_PROTO:	res.val.s = rta->src->proto->name; break;
798 767
      case SA_SOURCE:	res.val.i = rta->source; break;
799 768
      case SA_SCOPE:	res.val.i = rta->scope; break;
......
820 789
      switch (what->a2.i)
821 790
      {
822 791
      case SA_FROM:
823
	rta->from = v1.val.px.ip;
792
	rta->from = v1.val.ip;
824 793
	break;
825 794

  
826 795
      case SA_GW:
827 796
	{
828
	  ip_addr ip = v1.val.px.ip;
797
	  ip_addr ip = v1.val.ip;
829 798
	  neighbor *n = neigh_find(rta->src->proto, &ip, 0);
830 799
	  if (!n || (n->scope == SCOPE_HOST))
831 800
	    runtime( "Invalid gw address" );
......
908 877
      case EAF_TYPE_IP_ADDRESS:
909 878
	res.type = T_IP;
910 879
	struct adata * ad = e->u.ptr;
911
	res.val.px.ip = * (ip_addr *) ad->data;
880
	res.val.ip = * (ip_addr *) ad->data;
912 881
	break;
913 882
      case EAF_TYPE_AS_PATH:
914 883
        res.type = T_PATH;
......
958 927
      case EAF_TYPE_ROUTER_ID:
959 928
#ifndef IPV6
960 929
	/* IP->Quad implicit conversion */
961
	if (v1.type == T_IP) {
962
	  l->attrs[0].u.data = ipa_to_u32(v1.val.px.ip);
930
	if (val_is_ip4(v1)) {
931
	  l->attrs[0].u.data = ipa_to_u32(v1.val.ip);
963 932
	  break;
964 933
	}
965 934
#endif
......
978 947
	int len = sizeof(ip_addr);
979 948
	struct adata *ad = lp_alloc(f_pool, sizeof(struct adata) + len);
980 949
	ad->length = len;
981
	(* (ip_addr *) ad->data) = v1.val.px.ip;
950
	(* (ip_addr *) ad->data) = v1.val.ip;
982 951
	l->attrs[0].u.ptr = ad;
983 952
	break;
984 953
      case EAF_TYPE_AS_PATH:
......
1053 1022
    ONEARG;
1054 1023
    res.type = T_INT;
1055 1024
    switch(v1.type) {
1056
    case T_PREFIX: res.val.i = v1.val.px.len; break;
1025
    case T_NET:    res.val.i = net_pxlen(v1.val.net); break;
1057 1026
    case T_PATH:   res.val.i = as_path_getlen(v1.val.ad); break;
1058 1027
    case T_CLIST:  res.val.i = int_set_get_size(v1.val.ad); break;
1059 1028
    case T_ECLIST: res.val.i = ec_set_get_size(v1.val.ad); break;
......
1062 1031
    break;
1063 1032
  case P('c','p'):	/* Convert prefix to ... */
1064 1033
    ONEARG;
1065
    if (v1.type != T_PREFIX)
1034
    if (v1.type != T_NET)
1066 1035
      runtime( "Prefix expected" );
1067
    res.type = what->aux;
1068
    switch(res.type) {
1069
      /*    case T_INT:	res.val.i = v1.val.px.len; break; Not needed any more */
1070
    case T_IP: res.val.px.ip = v1.val.px.ip; break;
1071
    default: bug( "Unknown prefix to conversion" );
1072
    }
1036
    res.type = T_IP;
1037
    res.val.ip = net_prefix(v1.val.net);
1073 1038
    break;
1074 1039
  case P('a','f'):	/* Get first ASN from AS PATH */
1075 1040
    ONEARG;
......
1135 1100
    {
1136 1101
      ip_addr mask = ipa_mkmask(v2.val.i);
1137 1102
      res.type = T_IP;
1138
      res.val.px.ip = ipa_and(mask, v1.val.px.ip);
1103
      res.val.ip = ipa_and(mask, v1.val.ip);
1139 1104
    }
1140 1105
    break;
1141 1106

  
......
1195 1160
#ifndef IPV6
1196 1161
      /* IP->Quad implicit conversion */
1197 1162
      else if (v2.type == T_IP)
1198
	n = ipa_to_u32(v2.val.px.ip);
1163
	n = ipa_to_u32(v2.val.ip);
1199 1164
#endif
1200 1165
      else if ((v2.type == T_SET) && clist_set_type(v2.val.t, &dummy))
1201 1166
	arg_set = 1;
......
1284 1249
    if (what->arg1)
1285 1250
    {
1286 1251
      TWOARGS;
1287
      if ((v1.type != T_PREFIX) || (v2.type != T_INT))
1252
      if ((v1.type != T_NET) || (v2.type != T_INT))
1288 1253
	runtime("Invalid argument to roa_check()");
1289 1254

  
1290 1255
      as = v2.val.i;
......
1292 1257
    else
1293 1258
    {
1294 1259
      ACCESS_RTE;
1295
      v1.val.px.ip = net_prefix((*f_rte)->net->n.addr);
1296
      v1.val.px.len = net_pxlen((*f_rte)->net->n.addr);
1260
      v1.val.net = (*f_rte)->net->n.addr;
1297 1261

  
1298 1262
      /* We ignore temporary attributes, probably not a problem here */
1299 1263
      /* 0x02 is a value of BA_AS_PATH, we don't want to include BGP headers */
......
1310 1274
      runtime("Missing ROA table");
1311 1275

  
1312 1276
    res.type = T_ENUM_ROA;
1313
    res.val.i = roa_check(rtc->table, v1.val.px.ip, v1.val.px.len, as);
1277
    res.val.i = ROA_UNKNOWN;
1278
    // XXXX res.val.i = roa_check_net(rtc->table, &v1.val.net, as);
1314 1279
    break;
1315 1280

  
1316 1281
  default:
filter/filter.h
39 39
};
40 40

  
41 41
struct f_prefix {
42
  ip_addr ip;
43
  int len;
44
#define LEN_MASK 0xff
45
#define LEN_PLUS  0x1000000
46
#define LEN_MINUS 0x2000000
47
#define LEN_RANGE 0x4000000
48
  /* If range then prefix must be in range (len >> 16 & 0xff, len >> 8 & 0xff) */
42
  net_addr_union net;
43
  u8 lo, hi;
49 44
};
50 45

  
51 46
struct f_val {
......
53 48
  union {
54 49
    uint i;
55 50
    u64 ec;
56
    /*    ip_addr ip; Folded into prefix */	
57
    struct f_prefix px;
51
    ip_addr ip;
52
    const net_addr *net;
58 53
    char *s;
59 54
    struct f_tree *t;
60 55
    struct f_trie *ti;
......
81 76
void tree_format(struct f_tree *t, buffer *buf);
82 77

  
83 78
struct f_trie *f_new_trie(linpool *lp, uint node_size);
84
void *trie_add_prefix(struct f_trie *t, ip_addr px, int plen, int l, int h);
85
int trie_match_prefix(struct f_trie *t, ip_addr px, int plen);
79
void *trie_add_prefix(struct f_trie *t, net_addr *n, uint l, uint h);
80
int trie_match_net(struct f_trie *t, const net_addr *n);
86 81
int trie_same(struct f_trie *t1, struct f_trie *t2);
87 82
void trie_format(struct f_trie *t, buffer *buf);
88 83

  
89
void fprefix_get_bounds(struct f_prefix *px, int *l, int *h);
90

  
91
static inline void
92
trie_add_fprefix(struct f_trie *t, struct f_prefix *px)
93
{
94
  int l, h;
95
  fprefix_get_bounds(px, &l, &h);
96
  trie_add_prefix(t, px->ip, px->len & LEN_MASK, l, h);
97
}
98

  
99
static inline int
100
trie_match_fprefix(struct f_trie *t, struct f_prefix *px)
101
{
102
  return trie_match_prefix(t, px->ip, px->len & LEN_MASK);
103
}
104

  
105

  
106 84
struct ea_list;
107 85
struct rte;
108 86

  
......
163 141

  
164 142
/* Bigger ones */
165 143
#define T_IP 0x20
166
#define T_PREFIX 0x21
144
#define T_NET 0x21
167 145
#define T_STRING 0x22
168 146
#define T_PATH_MASK 0x23	/* mask for BGP path */
169 147
#define T_PATH 0x24		/* BGP path */
......
176 154
#define T_PREFIX_SET 0x81
177 155

  
178 156

  
179
#define SA_FROM		 1    
180
#define SA_GW		 2      
181
#define SA_NET		 3     
182
#define SA_PROTO	 4   
183
#define SA_SOURCE	 5  
184
#define SA_SCOPE	 6   
157
#define SA_FROM		 1
158
#define SA_GW		 2
159
#define SA_NET		 3
160
#define SA_PROTO	 4
161
#define SA_SOURCE	 5
162
#define SA_SCOPE	 6
185 163
#define SA_CAST    	 7
186 164
#define SA_DEST    	 8
187 165
#define SA_IFNAME  	 9
filter/trie.c
109 109
/**
110 110
 * trie_add_prefix
111 111
 * @t: trie to add to
112
 * @px: prefix address
113
 * @plen: prefix length
112
 * @net: IP network prefix
114 113
 * @l: prefix lower bound
115 114
 * @h: prefix upper bound
116 115
 *
117
 * Adds prefix (prefix pattern) @px/@plen to trie @t.  @l and @h are lower
116
 * Adds prefix (prefix pattern) @n to trie @t.  @l and @h are lower
118 117
 * and upper bounds on accepted prefix lengths, both inclusive.
119 118
 * 0 <= l, h <= 32 (128 for IPv6).
120 119
 *
......
124 123
 */
125 124

  
126 125
void *
127
trie_add_prefix(struct f_trie *t, ip_addr px, int plen, int l, int h)
126
trie_add_prefix(struct f_trie *t, net_addr *net, uint l, uint h)
128 127
{
128
  ip_addr px = net_prefix(net);
129
  uint plen = net_pxlen(net);
130

  
131
  if (net->type == NET_IP4)
132
  {
133
    const uint delta = IP6_MAX_PREFIX_LENGTH - IP4_MAX_PREFIX_LENGTH;
134
    plen += delta;
135
    l += delta;
136
    h += delta;
137
  }
138

  
129 139
  if (l == 0)
130 140
    t->zero = 1;
131 141
  else
......
140 150
  struct f_trie_node *o = NULL;
141 151
  struct f_trie_node *n = t->root;
142 152

  
143
  while(n)
153
  while (n)
144 154
    {
145 155
      ip_addr cmask = ipa_and(n->mask, pmask);
146 156

  
......
196 206
  return a;
197 207
}
198 208

  
199
/**
200
 * trie_match_prefix
201
 * @t: trie
202
 * @px: prefix address
203
 * @plen: prefix length
204
 *
205
 * Tries to find a matching prefix pattern in the trie such that
206
 * prefix @px/@plen matches that prefix pattern. Returns 1 if there
207
 * is such prefix pattern in the trie.
208
 */
209
int
209
static int
210 210
trie_match_prefix(struct f_trie *t, ip_addr px, int plen)
211 211
{
212 212
  ip_addr pmask = ipa_mkmask(plen);
......
241 241
  return 0;
242 242
}
243 243

  
244
/**
245
 * trie_match_net
246
 * @t: trie
247
 * @n: net address
248
 *
249
 * Tries to find a matching net in the trie such that
250
 * prefix @n matches that prefix pattern. Returns 1 if there
251
 * is such prefix pattern in the trie.
252
 */
253
int
254
trie_match_net(struct f_trie *t, const net_addr *n)
255
{
256
  int add = 0;
257
  switch (n->type) {
258
    case NET_IP4:
259
    case NET_VPN4: add = IP6_MAX_PREFIX_LENGTH - IP4_MAX_PREFIX_LENGTH;
260
  }
261

  
262
  return trie_match_prefix(t, net_prefix(n), net_pxlen(n) + add);
263
}
264

  
244 265
static int
245 266
trie_node_same(struct f_trie_node *t1, struct f_trie_node *t2)
246 267
{
lib/birdlib.h
35 35
#define DELTA(a,b) (((a)>=(b))?(a)-(b):(b)-(a))
36 36
#define ARRAY_SIZE(a) (sizeof(a)/sizeof(*(a)))
37 37

  
38
static inline int uint_cmp(uint i1, uint i2)
39
{ return (int)(i1 > i2) - (int)(i1 < i2); }
40

  
41
static inline int u64_cmp(u64 i1, u64 i2)
42
{ return (int)(i1 > i2) - (int)(i1 < i2); }
43

  
38 44

  
39 45
/* Bitfield macros */
40 46

  
lib/ip.h
492 492

  
493 493
char *ip_scope_text(uint);
494 494

  
495
struct prefix {
496
  ip_addr addr;
497
  uint len;
498
};
499

  
500

  
501 495
#endif
lib/net.c
58 58
  }
59 59
}
60 60

  
61

  
62
static inline int net_validate_ip4(const net_addr_ip4 *n)
61
int
62
net_compare(const net_addr *a, const net_addr *b)
63 63
{
64
  return (n->pxlen <= IP4_MAX_PREFIX_LENGTH) &&
65
    ip4_zero(ip4_and(n->prefix, ip4_not(ip4_mkmask(n->pxlen))));
66
}
64
  if (a->type != b->type)
65
    return uint_cmp(a->type, b->type);
67 66

  
68
static inline int net_validate_ip6(const net_addr_ip6 *n)
69
{
70
  return (n->pxlen <= IP6_MAX_PREFIX_LENGTH) &&
71
    ip6_zero(ip6_and(n->prefix, ip6_not(ip6_mkmask(n->pxlen))));
67
  switch (a->type)
68
  {
69
  case NET_IP4:
70
    return net_compare_ip4((const net_addr_ip4 *) a, (const net_addr_ip4 *) b);
71
  case NET_IP6:
72
    return net_compare_ip6((const net_addr_ip6 *) a, (const net_addr_ip6 *) b);
73
  case NET_VPN4:
74
    return net_compare_vpn4((const net_addr_vpn4 *) a, (const net_addr_vpn4 *) b);
75
  case NET_VPN6:
76
    return net_compare_vpn6((const net_addr_vpn6 *) a, (const net_addr_vpn6 *) b);
77
  }
78
  return 0;
72 79
}
73 80

  
74 81
int
75 82
net_validate(const net_addr *N)
76 83
{
77
  switch (a->type)
84
  switch (N->type)
78 85
  {
79 86
  case NET_IP4:
80 87
  case NET_VPN4:
lib/net.h
162 162
{ return !a->pxlen && ip6_zero(a->prefix) && !a->rd; }
163 163

  
164 164

  
165
static inline int net_compare_ip4(const net_addr_ip4 *a, const net_addr_ip4 *b)
166
{ return ip4_compare(a->prefix, b->prefix) ?: uint_cmp(a->pxlen, b->pxlen); }
167

  
168
static inline int net_compare_ip6(const net_addr_ip6 *a, const net_addr_ip6 *b)
169
{ return ip6_compare(a->prefix, b->prefix) ?: uint_cmp(a->pxlen, b->pxlen); }
170

  
171
static inline int net_compare_vpn4(const net_addr_vpn4 *a, const net_addr_vpn4 *b)
172
{ return u64_cmp(a->rd, b->rd) ?: ip4_compare(a->prefix, b->prefix) ?: uint_cmp(a->pxlen, b->pxlen); }
173

  
174
static inline int net_compare_vpn6(const net_addr_vpn6 *a, const net_addr_vpn6 *b)
175
{ return u64_cmp(a->rd, b->rd) ?: ip6_compare(a->prefix, b->prefix) ?: uint_cmp(a->pxlen, b->pxlen); }
176

  
177
int net_compare(const net_addr *a, const net_addr *b);
178

  
179

  
165 180
static inline void net_copy(net_addr *dst, const net_addr *src)
166 181
{ memcpy(dst, src, src->length); }
167 182

  
......
195 210
{ return ip6_hash(n->prefix) ^ ((u32) n->pxlen << 26) ^ u64_hash(n->rd); }
196 211

  
197 212

  
213
static inline int net_validate_ip4(const net_addr_ip4 *n)
214
{
215
  return (n->pxlen <= IP4_MAX_PREFIX_LENGTH) &&
216
    ip4_zero(ip4_and(n->prefix, ip4_not(ip4_mkmask(n->pxlen))));
217
}
218

  
219
static inline int net_validate_ip6(const net_addr_ip6 *n)
220
{
221
  return (n->pxlen <= IP6_MAX_PREFIX_LENGTH) &&
222
    ip6_zero(ip6_and(n->prefix, ip6_not(ip6_mkmask(n->pxlen))));
223
}
224

  
225
int net_validate(const net_addr *N);
226

  
227

  
198 228
static inline void net_normalize_ip4(net_addr_ip4 *n)
199 229
{ n->prefix = ip4_and(n->prefix, ip4_mkmask(n->pxlen)); }
200 230

  
......
203 233

  
204 234
void net_normalize(net_addr *N);
205 235

  
206
int net_validate(const net_addr *N);
207 236

  
208 237
int net_classify(const net_addr *N);
209 238
int net_format(const net_addr *N, char *buf, int buflen);
nest/config.Y
98 98
 | SYM {
99 99
     if ($1->class == (SYM_CONSTANT | T_INT) || $1->class == (SYM_CONSTANT | T_QUAD))
100 100
       $$ = SYM_VAL($1).i;
101
#ifndef IPV6
102
     else if ($1->class == (SYM_CONSTANT | T_IP))
103
       $$ = ipa_to_u32(SYM_VAL($1).px.ip);
104
#endif
101
     else if (($1->class == (SYM_CONSTANT | T_IP)) && ipa_is_ip4(SYM_VAL($1).ip))
102
       $$ = ipa_to_u32(SYM_VAL($1).ip);
105 103
     else
106 104
       cf_error("Number of IPv4 address constant expected");
107 105
   }
nest/rt-table.c
2293 2293
      he->igp_metric = rt_get_igp_metric(e);
2294 2294
    }
2295 2295

  
2296
  /* XXXX */
2297 2296
 done:
2298 2297
  /* Add a prefix range to the trie */
2298
  /* XXXX
2299 2299
  if (ipa_is_ip4(he->addr))
2300 2300
    trie_add_prefix(tab->hostcache->trie, he->addr, IP4_MAX_PREFIX_LENGTH, pxlen, IP4_MAX_PREFIX_LENGTH);
2301 2301
  else
2302 2302
    trie_add_prefix(tab->hostcache->trie, he->addr, IP6_MAX_PREFIX_LENGTH, pxlen, IP6_MAX_PREFIX_LENGTH);
2303
  */
2303 2304

  
2304 2305
  rta_free(old_src);
2305 2306
  return old_src != he->src;

Also available in: Unified diff