~brightbox/bird/debian-packaging

« back to all changes in this revision

Viewing changes to filter/filter.c

  • Committer: Ondřej Surý
  • Date: 2013-11-25 14:59:24 UTC
  • Revision ID: git-v1:a3c058b8752bd98df2231ac88d94931fdb4e0c65
New upstream version 1.4.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
59
59
}
60
60
 
61
61
static void
62
 
pm_format(struct f_path_mask *p, byte *buf, unsigned int size)
 
62
pm_format(struct f_path_mask *p, buffer *buf)
63
63
{
64
 
  byte *end = buf + size - 16;
 
64
  buffer_puts(buf, "[= ");
65
65
 
66
66
  while (p)
 
67
  {
 
68
    switch(p->kind)
67
69
    {
68
 
      if (buf > end)
69
 
        {
70
 
          strcpy(buf, " ...");
71
 
          return;
72
 
        }
73
 
 
74
 
      switch(p->kind)
75
 
        {
76
 
        case PM_ASN:
77
 
          buf += bsprintf(buf, " %u", p->val);
78
 
          break;
79
 
 
80
 
        case PM_QUESTION:
81
 
          buf += bsprintf(buf, " ?");
82
 
          break;
83
 
 
84
 
        case PM_ASTERISK:
85
 
          buf += bsprintf(buf, " *");
86
 
          break;
87
 
 
88
 
        case PM_ASN_EXPR:
89
 
          buf += bsprintf(buf, " %u", f_eval_asn((struct f_inst *) p->val));
90
 
          break;
91
 
        }
92
 
 
93
 
      p = p->next;
 
70
    case PM_ASN:
 
71
      buffer_print(buf, "%u ", p->val);
 
72
      break;
 
73
 
 
74
    case PM_QUESTION:
 
75
      buffer_puts(buf, "? ");
 
76
      break;
 
77
 
 
78
    case PM_ASTERISK:
 
79
      buffer_puts(buf, "* ");
 
80
      break;
 
81
 
 
82
    case PM_ASN_EXPR:
 
83
      buffer_print(buf, "%u ", f_eval_asn((struct f_inst *) p->val));
 
84
      break;
94
85
    }
95
86
 
96
 
  *buf = 0;
97
 
}
98
 
 
99
 
static inline int
100
 
int_cmp(int i1, int i2)
101
 
{
102
 
  return (i1 > i2) - (i1 < i2); 
103
 
}
104
 
 
105
 
static inline int
106
 
uint_cmp(unsigned int i1, unsigned int i2)
 
87
    p = p->next;
 
88
  }
 
89
 
 
90
  buffer_puts(buf, "=]");
 
91
}
 
92
 
 
93
static inline int
 
94
uint_cmp(uint i1, uint i2)
107
95
{
108
96
  return (int)(i1 > i2) - (int)(i1 < i2);
109
97
}
152
140
  case T_ENUM:
153
141
  case T_INT:
154
142
  case T_BOOL:
155
 
    return int_cmp(v1.val.i, v2.val.i);
156
143
  case T_PAIR:
157
144
  case T_QUAD:
158
145
    return uint_cmp(v1.val.i, v2.val.i);
163
150
  case T_PREFIX:
164
151
    if (rc = ipa_compare(v1.val.px.ip, v2.val.px.ip))
165
152
      return rc;
166
 
    return int_cmp(v1.val.px.len, v2.val.px.len);
 
153
    return uint_cmp(v1.val.px.len, v2.val.px.len);
167
154
  case T_STRING:
168
155
    return strcmp(v1.val.s, v2.val.s);
169
156
  default:
392
379
    return as_path_match(v1.val.ad, v2.val.path_mask);
393
380
 
394
381
  if ((v1.type == T_INT) && (v2.type == T_PATH))
395
 
    return as_path_is_member(v2.val.ad, v1.val.i);
 
382
    return as_path_contains(v2.val.ad, v1.val.i, 1);
396
383
 
397
384
  if (((v1.type == T_PAIR) || (v1.type == T_QUAD)) && (v2.type == T_CLIST))
398
385
    return int_set_contains(v2.val.ad, v1.val.i);
437
424
  return CMP_ERROR;
438
425
}
439
426
 
440
 
static void
441
 
tree_node_print(struct f_tree *t, char **sep)
442
 
{
443
 
  if (t == NULL)
444
 
    return;
445
 
 
446
 
  tree_node_print(t->left, sep);
447
 
 
448
 
  logn(*sep);
449
 
  val_print(t->from);
450
 
  if (val_compare(t->from, t->to) != 0)
451
 
    {
452
 
      logn( ".." );
453
 
      val_print(t->to);
454
 
    }
455
 
  *sep = ", ";
456
 
 
457
 
  tree_node_print(t->right, sep);
458
 
}
459
 
 
460
 
static void
461
 
tree_print(struct f_tree *t)
462
 
{
463
 
  char *sep = "";
464
 
  logn( "[" );
465
 
  tree_node_print(t, &sep);
466
 
  logn( "] " );
467
 
}
468
 
 
469
427
/*
470
 
 * val_print - format filter value
 
428
 * val_format - format filter value
471
429
 */
472
430
void
473
 
val_print(struct f_val v)
 
431
val_format(struct f_val v, buffer *buf)
474
432
{
475
433
  char buf2[1024];
476
 
  switch (v.type) {
477
 
  case T_VOID: logn("(void)"); return;
478
 
  case T_BOOL: logn(v.val.i ? "TRUE" : "FALSE"); return;
479
 
  case T_INT: logn("%d", v.val.i); return;
480
 
  case T_STRING: logn("%s", v.val.s); return;
481
 
  case T_IP: logn("%I", v.val.px.ip); return;
482
 
  case T_PREFIX: logn("%I/%d", v.val.px.ip, v.val.px.len); return;
483
 
  case T_PAIR: logn("(%d,%d)", v.val.i >> 16, v.val.i & 0xffff); return;
484
 
  case T_QUAD: logn("%R", v.val.i); return;
485
 
  case T_EC: ec_format(buf2, v.val.ec); logn("%s", buf2); return;
486
 
  case T_PREFIX_SET: trie_print(v.val.ti); return;
487
 
  case T_SET: tree_print(v.val.t); return;
488
 
  case T_ENUM: logn("(enum %x)%d", v.type, v.val.i); return;
489
 
  case T_PATH: as_path_format(v.val.ad, buf2, 1000); logn("(path %s)", buf2); return;
490
 
  case T_CLIST: int_set_format(v.val.ad, 1, -1, buf2, 1000); logn("(clist %s)", buf2); return;
491
 
  case T_ECLIST: ec_set_format(v.val.ad, -1, buf2, 1000); logn("(eclist %s)", buf2); return;
492
 
  case T_PATH_MASK: pm_format(v.val.path_mask, buf2, 1000); logn("(pathmask%s)", buf2); return;
493
 
  default: logn( "[unknown type %x]", v.type ); return;
 
434
  switch (v.type)
 
435
  {
 
436
  case T_VOID:  buffer_puts(buf, "(void)"); return;
 
437
  case T_BOOL:  buffer_puts(buf, v.val.i ? "TRUE" : "FALSE"); return;
 
438
  case T_INT:   buffer_print(buf, "%u", v.val.i); return;
 
439
  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;
 
442
  case T_PAIR:  buffer_print(buf, "(%u,%u)", v.val.i >> 16, v.val.i & 0xffff); return;
 
443
  case T_QUAD:  buffer_print(buf, "%R", v.val.i); return;
 
444
  case T_EC:    ec_format(buf2, v.val.ec); buffer_print(buf, "%s", buf2); return;
 
445
  case T_PREFIX_SET: trie_format(v.val.ti, buf); return;
 
446
  case T_SET:   tree_format(v.val.t, buf); return;
 
447
  case T_ENUM:  buffer_print(buf, "(enum %x)%u", v.type, v.val.i); return;
 
448
  case T_PATH:  as_path_format(v.val.ad, buf2, 1000); buffer_print(buf, "(path %s)", buf2); return;
 
449
  case T_CLIST: int_set_format(v.val.ad, 1, -1, buf2, 1000); buffer_print(buf, "(clist %s)", buf2); return;
 
450
  case T_ECLIST: ec_set_format(v.val.ad, -1, buf2, 1000); buffer_print(buf, "(eclist %s)", buf2); return;
 
451
  case T_PATH_MASK: pm_format(v.val.path_mask, buf); return;
 
452
  default:      buffer_print(buf, "[unknown type %x]", v.type); return;
494
453
  }
495
454
}
496
455
 
498
457
static struct rta *f_old_rta;
499
458
static struct ea_list **f_tmp_attrs;
500
459
static struct linpool *f_pool;
 
460
static struct buffer f_buf;
501
461
static int f_flags;
502
462
 
503
463
static inline void f_rte_cow(void)
786
746
    break;
787
747
  case 'p':
788
748
    ONEARG;
789
 
    val_print(v1);
 
749
    val_format(v1, &f_buf);
790
750
    break;
791
751
  case '?':     /* ? has really strange error value, so we can implement if ... else nicely :-) */
792
752
    ONEARG;
804
764
  case P('p',','):
805
765
    ONEARG;
806
766
    if (what->a2.i == F_NOP || (what->a2.i != F_NONL && what->a1.p))
807
 
      log_commit(*L_INFO);
 
767
      log_commit(*L_INFO, &f_buf);
808
768
 
809
769
    switch (what->a2.i) {
810
770
    case F_QUITBIRD:
1200
1160
      /* Community (or cluster) list */
1201
1161
      struct f_val dummy;
1202
1162
      int arg_set = 0;
1203
 
      i = 0;
 
1163
      uint n = 0;
1204
1164
 
1205
1165
      if ((v2.type == T_PAIR) || (v2.type == T_QUAD))
1206
 
        i = v2.val.i;
 
1166
        n = v2.val.i;
1207
1167
#ifndef IPV6
1208
1168
      /* IP->Quad implicit conversion */
1209
1169
      else if (v2.type == T_IP)
1210
 
        i = ipa_to_u32(v2.val.px.ip);
 
1170
        n = ipa_to_u32(v2.val.px.ip);
1211
1171
#endif
1212
1172
      else if ((v2.type == T_SET) && clist_set_type(v2.val.t, &dummy))
1213
1173
        arg_set = 1;
1223
1183
        if (arg_set == 1)
1224
1184
          runtime("Can't add set");
1225
1185
        else if (!arg_set)
1226
 
          res.val.ad = int_set_add(f_pool, v1.val.ad, i);
 
1186
          res.val.ad = int_set_add(f_pool, v1.val.ad, n);
1227
1187
        else 
1228
1188
          res.val.ad = int_set_union(f_pool, v1.val.ad, v2.val.ad);
1229
1189
        break;
1230
1190
      
1231
1191
      case 'd':
1232
1192
        if (!arg_set)
1233
 
          res.val.ad = int_set_del(f_pool, v1.val.ad, i);
 
1193
          res.val.ad = int_set_del(f_pool, v1.val.ad, n);
1234
1194
        else
1235
1195
          res.val.ad = clist_filter(f_pool, v1.val.ad, v2, 0);
1236
1196
        break;
1507
1467
  f_pool = tmp_pool;
1508
1468
  f_flags = flags;
1509
1469
 
1510
 
  log_reset();
 
1470
  LOG_BUFFER_INIT(f_buf);
 
1471
 
1511
1472
  struct f_val res = interpret(filter->root);
1512
1473
 
1513
1474
  if (f_old_rta) {
1534
1495
    log( L_ERR "Filter %s did not return accept nor reject. Make up your mind", filter->name); 
1535
1496
    return F_ERROR;
1536
1497
  }
1537
 
  DBG( "done (%d)\n", res.val.i );
 
1498
  DBG( "done (%u)\n", res.val.i );
1538
1499
  return res.val.i;
1539
1500
}
1540
1501
 
1546
1507
  f_rte = NULL;
1547
1508
  f_pool = tmp_pool;
1548
1509
 
1549
 
  log_reset();
 
1510
  LOG_BUFFER_INIT(f_buf);
 
1511
 
1550
1512
  return interpret(expr);
1551
1513
}
1552
1514
 
1553
 
int
 
1515
uint
1554
1516
f_eval_int(struct f_inst *expr)
1555
1517
{
1556
1518
  /* Called independently in parse-time to eval expressions */