Statistics
| Branch: | Revision:

iof-bird-daemon / filter / filter.c @ 9b0a0ba9

History | View | Annotate | Download (44.1 KB)

1
/*
2
 *        Filters: utility functions
3
 *
4
 *        Copyright 1998 Pavel Machek <pavel@ucw.cz>
5
 *
6
 *        Can be freely distributed and used under the terms of the GNU GPL.
7
 *
8
 */
9

    
10
/**
11
 * DOC: Filters
12
 *
13
 * You can find sources of the filter language in |filter/|
14
 * directory. File |filter/config.Y| contains filter grammar and basically translates
15
 * the source from user into a tree of &f_inst structures. These trees are
16
 * later interpreted using code in |filter/filter.c|.
17
 *
18
 * A filter is represented by a tree of &f_inst structures, one structure per
19
 * "instruction". Each &f_inst contains @code, @aux value which is
20
 * usually the data type this instruction operates on and two generic
21
 * arguments (@a1, @a2). Some instructions contain pointer(s) to other
22
 * instructions in their (@a1, @a2) fields.
23
 *
24
 * Filters use a &f_val structure for their data. Each &f_val
25
 * contains type and value (types are constants prefixed with %T_). Few
26
 * of the types are special; %T_RETURN can be or-ed with a type to indicate
27
 * that return from a function or from the whole filter should be
28
 * forced. Important thing about &f_val's is that they may be copied
29
 * with a simple |=|. That's fine for all currently defined types: strings
30
 * are read-only (and therefore okay), paths are copied for each
31
 * operation (okay too).
32
 */
33

    
34
#undef LOCAL_DEBUG
35

    
36
#include "nest/bird.h"
37
#include "lib/lists.h"
38
#include "lib/resource.h"
39
#include "lib/socket.h"
40
#include "lib/string.h"
41
#include "lib/unaligned.h"
42
#include "lib/net.h"
43
#include "lib/ip.h"
44
#include "nest/route.h"
45
#include "nest/protocol.h"
46
#include "nest/iface.h"
47
#include "nest/attrs.h"
48
#include "conf/conf.h"
49
#include "filter/filter.h"
50

    
51
#define P(a,b) ((a<<8) | b)
52

    
53
#define CMP_ERROR 999
54

    
55
void (*bt_assert_hook)(int result, struct f_inst *assert);
56

    
57
static struct adata *
58
adata_empty(struct linpool *pool, int l)
59
{
60
  struct adata *res = lp_alloc(pool, sizeof(struct adata) + l);
61
  res->length = l;
62
  return res;
63
}
64

    
65
static void
66
pm_format(struct f_path_mask *p, buffer *buf)
67
{
68
  buffer_puts(buf, "[= ");
69

    
70
  while (p)
71
  {
72
    switch(p->kind)
73
    {
74
    case PM_ASN:
75
      buffer_print(buf, "%u ", p->val);
76
      break;
77

    
78
    case PM_QUESTION:
79
      buffer_puts(buf, "? ");
80
      break;
81

    
82
    case PM_ASTERISK:
83
      buffer_puts(buf, "* ");
84
      break;
85

    
86
    case PM_ASN_RANGE:
87
      buffer_print(buf, "%u..%u ", p->val, p->val2);
88
      break;
89

    
90
    case PM_ASN_EXPR:
91
      buffer_print(buf, "%u ", f_eval_asn((struct f_inst *) p->val));
92
      break;
93
    }
94

    
95
    p = p->next;
96
  }
97

    
98
  buffer_puts(buf, "=]");
99
}
100

    
101
static inline int val_is_ip4(const struct f_val v)
102
{ return (v.type == T_IP) && ipa_is_ip4(v.val.ip); }
103

    
104
static inline int
105
lcomm_cmp(lcomm v1, lcomm v2)
106
{
107
  if (v1.asn != v2.asn)
108
    return (v1.asn > v2.asn) ? 1 : -1;
109
  if (v1.ldp1 != v2.ldp1)
110
    return (v1.ldp1 > v2.ldp1) ? 1 : -1;
111
  if (v1.ldp2 != v2.ldp2)
112
    return (v1.ldp2 > v2.ldp2) ? 1 : -1;
113
  return 0;
114
}
115

    
116
/**
117
 * val_compare - compare two values
118
 * @v1: first value
119
 * @v2: second value
120
 *
121
 * Compares two values and returns -1, 0, 1 on <, =, > or CMP_ERROR on
122
 * error. Tree module relies on this giving consistent results so
123
 * that it can be used for building balanced trees.
124
 */
125
int
126
val_compare(struct f_val v1, struct f_val v2)
127
{
128
  if (v1.type != v2.type) {
129
    if (v1.type == T_VOID)        /* Hack for else */
130
      return -1;
131
    if (v2.type == T_VOID)
132
      return 1;
133

    
134
    /* IP->Quad implicit conversion */
135
    if ((v1.type == T_QUAD) && val_is_ip4(v2))
136
      return uint_cmp(v1.val.i, ipa_to_u32(v2.val.ip));
137
    if (val_is_ip4(v1) && (v2.type == T_QUAD))
138
      return uint_cmp(ipa_to_u32(v1.val.ip), v2.val.i);
139

    
140
    debug( "Types do not match in val_compare\n" );
141
    return CMP_ERROR;
142
  }
143

    
144
  switch (v1.type) {
145
  case T_VOID:
146
    return 0;
147
  case T_ENUM:
148
  case T_INT:
149
  case T_BOOL:
150
  case T_PAIR:
151
  case T_QUAD:
152
    return uint_cmp(v1.val.i, v2.val.i);
153
  case T_EC:
154
    return u64_cmp(v1.val.ec, v2.val.ec);
155
  case T_LC:
156
    return lcomm_cmp(v1.val.lc, v2.val.lc);
157
  case T_IP:
158
    return ipa_compare(v1.val.ip, v2.val.ip);
159
  case T_NET:
160
    return net_compare(v1.val.net, v2.val.net);
161
  case T_STRING:
162
    return strcmp(v1.val.s, v2.val.s);
163
  default:
164
    return CMP_ERROR;
165
  }
166
}
167

    
168
static int
169
pm_same(struct f_path_mask *m1, struct f_path_mask *m2)
170
{
171
  while (m1 && m2)
172
  {
173
    if (m1->kind != m2->kind)
174
      return 0;
175

    
176
    if (m1->kind == PM_ASN_EXPR)
177
    {
178
      if (!i_same((struct f_inst *) m1->val, (struct f_inst *) m2->val))
179
        return 0;
180
    }
181
    else
182
    {
183
      if ((m1->val != m2->val) || (m1->val2 != m2->val2))
184
        return 0;
185
    }
186

    
187
    m1 = m1->next;
188
    m2 = m2->next;
189
  }
190

    
191
  return !m1 && !m2;
192
}
193

    
194
/**
195
 * val_same - compare two values
196
 * @v1: first value
197
 * @v2: second value
198
 *
199
 * Compares two values and returns 1 if they are same and 0 if not.
200
 * Comparison of values of different types is valid and returns 0.
201
 */
202
int
203
val_same(struct f_val v1, struct f_val v2)
204
{
205
  int rc;
206

    
207
  rc = val_compare(v1, v2);
208
  if (rc != CMP_ERROR)
209
    return !rc;
210

    
211
  if (v1.type != v2.type)
212
    return 0;
213

    
214
  switch (v1.type) {
215
  case T_PATH_MASK:
216
    return pm_same(v1.val.path_mask, v2.val.path_mask);
217
  case T_PATH:
218
  case T_CLIST:
219
  case T_ECLIST:
220
  case T_LCLIST:
221
    return adata_same(v1.val.ad, v2.val.ad);
222
  case T_SET:
223
    return same_tree(v1.val.t, v2.val.t);
224
  case T_PREFIX_SET:
225
    return trie_same(v1.val.ti, v2.val.ti);
226
  default:
227
    bug("Invalid type in val_same(): %x", v1.type);
228
  }
229
}
230

    
231
static int
232
clist_set_type(struct f_tree *set, struct f_val *v)
233
{
234
  switch (set->from.type)
235
  {
236
  case T_PAIR:
237
    v->type = T_PAIR;
238
    return 1;
239

    
240
  case T_QUAD:
241
    v->type = T_QUAD;
242
    return 1;
243

    
244
  case T_IP:
245
    if (val_is_ip4(set->from) && val_is_ip4(set->to))
246
    {
247
      v->type = T_QUAD;
248
      return 1;
249
    }
250
    /* Fall through */
251
  default:
252
    v->type = T_VOID;
253
    return 0;
254
  }
255
}
256

    
257
static inline int
258
eclist_set_type(struct f_tree *set)
259
{ return set->from.type == T_EC; }
260

    
261
static inline int
262
lclist_set_type(struct f_tree *set)
263
{ return set->from.type == T_LC; }
264

    
265
static int
266
clist_match_set(struct adata *clist, struct f_tree *set)
267
{
268
  if (!clist)
269
    return 0;
270

    
271
  struct f_val v;
272
  if (!clist_set_type(set, &v))
273
    return CMP_ERROR;
274

    
275
  u32 *l = (u32 *) clist->data;
276
  u32 *end = l + clist->length/4;
277

    
278
  while (l < end) {
279
    v.val.i = *l++;
280
    if (find_tree(set, v))
281
      return 1;
282
  }
283
  return 0;
284
}
285

    
286
static int
287
eclist_match_set(struct adata *list, struct f_tree *set)
288
{
289
  if (!list)
290
    return 0;
291

    
292
  if (!eclist_set_type(set))
293
    return CMP_ERROR;
294

    
295
  struct f_val v;
296
  u32 *l = int_set_get_data(list);
297
  int len = int_set_get_size(list);
298
  int i;
299

    
300
  v.type = T_EC;
301
  for (i = 0; i < len; i += 2) {
302
    v.val.ec = ec_get(l, i);
303
    if (find_tree(set, v))
304
      return 1;
305
  }
306

    
307
  return 0;
308
}
309

    
310
static int
311
lclist_match_set(struct adata *list, struct f_tree *set)
312
{
313
  if (!list)
314
    return 0;
315

    
316
  if (!lclist_set_type(set))
317
    return CMP_ERROR;
318

    
319
  struct f_val v;
320
  u32 *l = int_set_get_data(list);
321
  int len = int_set_get_size(list);
322
  int i;
323

    
324
  v.type = T_LC;
325
  for (i = 0; i < len; i += 3) {
326
    v.val.lc = lc_get(l, i);
327
    if (find_tree(set, v))
328
      return 1;
329
  }
330

    
331
  return 0;
332
}
333

    
334
static struct adata *
335
clist_filter(struct linpool *pool, struct adata *list, struct f_val set, int pos)
336
{
337
  if (!list)
338
    return NULL;
339

    
340
  int tree = (set.type == T_SET);        /* 1 -> set is T_SET, 0 -> set is T_CLIST */
341
  struct f_val v;
342
  if (tree)
343
    clist_set_type(set.val.t, &v);
344
  else
345
    v.type = T_PAIR;
346

    
347
  int len = int_set_get_size(list);
348
  u32 *l = int_set_get_data(list);
349
  u32 tmp[len];
350
  u32 *k = tmp;
351
  u32 *end = l + len;
352

    
353
  while (l < end) {
354
    v.val.i = *l++;
355
    /* pos && member(val, set) || !pos && !member(val, set),  member() depends on tree */
356
    if ((tree ? !!find_tree(set.val.t, v) : int_set_contains(set.val.ad, v.val.i)) == pos)
357
      *k++ = v.val.i;
358
  }
359

    
360
  uint nl = (k - tmp) * sizeof(u32);
361
  if (nl == list->length)
362
    return list;
363

    
364
  struct adata *res = adata_empty(pool, nl);
365
  memcpy(res->data, tmp, nl);
366
  return res;
367
}
368

    
369
static struct adata *
370
eclist_filter(struct linpool *pool, struct adata *list, struct f_val set, int pos)
371
{
372
  if (!list)
373
    return NULL;
374

    
375
  int tree = (set.type == T_SET);        /* 1 -> set is T_SET, 0 -> set is T_CLIST */
376
  struct f_val v;
377

    
378
  int len = int_set_get_size(list);
379
  u32 *l = int_set_get_data(list);
380
  u32 tmp[len];
381
  u32 *k = tmp;
382
  int i;
383

    
384
  v.type = T_EC;
385
  for (i = 0; i < len; i += 2) {
386
    v.val.ec = ec_get(l, i);
387
    /* pos && member(val, set) || !pos && !member(val, set),  member() depends on tree */
388
    if ((tree ? !!find_tree(set.val.t, v) : ec_set_contains(set.val.ad, v.val.ec)) == pos) {
389
      *k++ = l[i];
390
      *k++ = l[i+1];
391
    }
392
  }
393

    
394
  uint nl = (k - tmp) * sizeof(u32);
395
  if (nl == list->length)
396
    return list;
397

    
398
  struct adata *res = adata_empty(pool, nl);
399
  memcpy(res->data, tmp, nl);
400
  return res;
401
}
402

    
403
static struct adata *
404
lclist_filter(struct linpool *pool, struct adata *list, struct f_val set, int pos)
405
{
406
  if (!list)
407
    return NULL;
408

    
409
  int tree = (set.type == T_SET);        /* 1 -> set is T_SET, 0 -> set is T_CLIST */
410
  struct f_val v;
411

    
412
  int len = int_set_get_size(list);
413
  u32 *l = int_set_get_data(list);
414
  u32 tmp[len];
415
  u32 *k = tmp;
416
  int i;
417

    
418
  v.type = T_LC;
419
  for (i = 0; i < len; i += 3) {
420
    v.val.lc = lc_get(l, i);
421
    /* pos && member(val, set) || !pos && !member(val, set),  member() depends on tree */
422
    if ((tree ? !!find_tree(set.val.t, v) : lc_set_contains(set.val.ad, v.val.lc)) == pos)
423
      k = lc_copy(k, l+i);
424
  }
425

    
426
  uint nl = (k - tmp) * sizeof(u32);
427
  if (nl == list->length)
428
    return list;
429

    
430
  struct adata *res = adata_empty(pool, nl);
431
  memcpy(res->data, tmp, nl);
432
  return res;
433
}
434

    
435
/**
436
 * val_in_range - implement |~| operator
437
 * @v1: element
438
 * @v2: set
439
 *
440
 * Checks if @v1 is element (|~| operator) of @v2.
441
 */
442
static int
443
val_in_range(struct f_val v1, struct f_val v2)
444
{
445
  if ((v1.type == T_PATH) && (v2.type == T_PATH_MASK))
446
    return as_path_match(v1.val.ad, v2.val.path_mask);
447

    
448
  if ((v1.type == T_INT) && (v2.type == T_PATH))
449
    return as_path_contains(v2.val.ad, v1.val.i, 1);
450

    
451
  if (((v1.type == T_PAIR) || (v1.type == T_QUAD)) && (v2.type == T_CLIST))
452
    return int_set_contains(v2.val.ad, v1.val.i);
453

    
454
  /* IP->Quad implicit conversion */
455
  if (val_is_ip4(v1) && (v2.type == T_CLIST))
456
    return int_set_contains(v2.val.ad, ipa_to_u32(v1.val.ip));
457

    
458
  if ((v1.type == T_EC) && (v2.type == T_ECLIST))
459
    return ec_set_contains(v2.val.ad, v1.val.ec);
460

    
461
  if ((v1.type == T_LC) && (v2.type == T_LCLIST))
462
    return lc_set_contains(v2.val.ad, v1.val.lc);
463

    
464
  if ((v1.type == T_STRING) && (v2.type == T_STRING))
465
    return patmatch(v2.val.s, v1.val.s);
466

    
467
  if ((v1.type == T_IP) && (v2.type == T_NET))
468
    return ipa_in_netX(v1.val.ip, v2.val.net);
469

    
470
  if ((v1.type == T_NET) && (v2.type == T_NET))
471
    return net_in_netX(v1.val.net, v2.val.net);
472

    
473
  if ((v1.type == T_NET) && (v2.type == T_PREFIX_SET))
474
    return trie_match_net(v2.val.ti, v1.val.net);
475

    
476
  if (v2.type != T_SET)
477
    return CMP_ERROR;
478

    
479
  /* With integrated Quad<->IP implicit conversion */
480
  if ((v1.type == v2.val.t->from.type) ||
481
      ((v1.type == T_QUAD) && val_is_ip4(v2.val.t->from) && val_is_ip4(v2.val.t->to)))
482
    return !!find_tree(v2.val.t, v1);
483

    
484
  if (v1.type == T_CLIST)
485
    return clist_match_set(v1.val.ad, v2.val.t);
486

    
487
  if (v1.type == T_ECLIST)
488
    return eclist_match_set(v1.val.ad, v2.val.t);
489

    
490
  if (v1.type == T_LCLIST)
491
    return lclist_match_set(v1.val.ad, v2.val.t);
492

    
493
  if (v1.type == T_PATH)
494
    return as_path_match_set(v1.val.ad, v2.val.t);
495

    
496
  return CMP_ERROR;
497
}
498

    
499
/*
500
 * val_format - format filter value
501
 */
502
void
503
val_format(struct f_val v, buffer *buf)
504
{
505
  char buf2[1024];
506
  switch (v.type)
507
  {
508
  case T_VOID:        buffer_puts(buf, "(void)"); return;
509
  case T_BOOL:        buffer_puts(buf, v.val.i ? "TRUE" : "FALSE"); return;
510
  case T_INT:        buffer_print(buf, "%u", v.val.i); return;
511
  case T_STRING: buffer_print(buf, "%s", v.val.s); return;
512
  case T_IP:        buffer_print(buf, "%I", v.val.ip); return;
513
  case T_NET:   buffer_print(buf, "%N", v.val.net); return;
514
  case T_PAIR:        buffer_print(buf, "(%u,%u)", v.val.i >> 16, v.val.i & 0xffff); return;
515
  case T_QUAD:        buffer_print(buf, "%R", v.val.i); return;
516
  case T_EC:        ec_format(buf2, v.val.ec); buffer_print(buf, "%s", buf2); return;
517
  case T_LC:        lc_format(buf2, v.val.lc); buffer_print(buf, "%s", buf2); return;
518
  case T_PREFIX_SET: trie_format(v.val.ti, buf); return;
519
  case T_SET:        tree_format(v.val.t, buf); return;
520
  case T_ENUM:        buffer_print(buf, "(enum %x)%u", v.type, v.val.i); return;
521
  case T_PATH:        as_path_format(v.val.ad, buf2, 1000); buffer_print(buf, "(path %s)", buf2); return;
522
  case T_CLIST:        int_set_format(v.val.ad, 1, -1, buf2, 1000); buffer_print(buf, "(clist %s)", buf2); return;
523
  case T_ECLIST: ec_set_format(v.val.ad, -1, buf2, 1000); buffer_print(buf, "(eclist %s)", buf2); return;
524
  case T_LCLIST: lc_set_format(v.val.ad, -1, buf2, 1000); buffer_print(buf, "(lclist %s)", buf2); return;
525
  case T_PATH_MASK: pm_format(v.val.path_mask, buf); return;
526
  default:        buffer_print(buf, "[unknown type %x]", v.type); return;
527
  }
528
}
529

    
530
static struct rte **f_rte;
531
static struct rta *f_old_rta;
532
static struct ea_list **f_tmp_attrs;
533
static struct linpool *f_pool;
534
static struct buffer f_buf;
535
static int f_flags;
536

    
537
static inline void f_rte_cow(void)
538
{
539
  *f_rte = rte_cow(*f_rte);
540
}
541

    
542
/*
543
 * rta_cow - prepare rta for modification by filter
544
 */
545
static void
546
f_rta_cow(void)
547
{
548
  if (!rta_is_cached((*f_rte)->attrs))
549
    return;
550

    
551
  /* Prepare to modify rte */
552
  f_rte_cow();
553

    
554
  /* Store old rta to free it later, it stores reference from rte_cow() */
555
  f_old_rta = (*f_rte)->attrs;
556

    
557
  /*
558
   * Get shallow copy of rta. Fields eattrs and nexthops of rta are shared
559
   * with f_old_rta (they will be copied when the cached rta will be obtained
560
   * at the end of f_run()), also the lock of hostentry is inherited (we
561
   * suppose hostentry is not changed by filters).
562
   */
563
  (*f_rte)->attrs = rta_do_cow((*f_rte)->attrs, f_pool);
564
}
565

    
566
static struct tbf rl_runtime_err = TBF_DEFAULT_LOG_LIMITS;
567

    
568
#define runtime(fmt, ...) do { \
569
    log_rl(&rl_runtime_err, L_ERR "filters, line %d: " fmt, what->lineno, ##__VA_ARGS__); \
570
    res.type = T_RETURN; \
571
    res.val.i = F_ERROR; \
572
    return res; \
573
  } while(0)
574

    
575
#define ARG(x,y) \
576
        x = interpret(what->y); \
577
        if (x.type & T_RETURN) \
578
                return x;
579

    
580
#define ONEARG ARG(v1, a1.p)
581
#define TWOARGS ARG(v1, a1.p) \
582
                ARG(v2, a2.p)
583
#define TWOARGS_C TWOARGS \
584
                  if (v1.type != v2.type) \
585
                    runtime( "Can't operate with values of incompatible types" );
586
#define ACCESS_RTE \
587
  do { if (!f_rte) runtime("No route to access"); } while (0)
588

    
589
#define BITFIELD_MASK(what) \
590
  (1u << (what->a2.i >> 24))
591

    
592
/**
593
 * interpret
594
 * @what: filter to interpret
595
 *
596
 * Interpret given tree of filter instructions. This is core function
597
 * of filter system and does all the hard work.
598
 *
599
 * Each instruction has 4 fields: code (which is instruction code),
600
 * aux (which is extension to instruction code, typically type),
601
 * arg1 and arg2 - arguments. Depending on instruction, arguments
602
 * are either integers, or pointers to instruction trees. Common
603
 * instructions like +, that have two expressions as arguments use
604
 * TWOARGS macro to get both of them evaluated.
605
 *
606
 * &f_val structures are copied around, so there are no problems with
607
 * memory managment.
608
 */
609
static struct f_val
610
interpret(struct f_inst *what)
611
{
612
  struct symbol *sym;
613
  struct f_val v1, v2, res, *vp;
614
  unsigned u1, u2;
615
  int i;
616
  u32 as;
617

    
618
  res.type = T_VOID;
619
  if (!what)
620
    return res;
621

    
622
  switch(what->code) {
623
  case ',':
624
    TWOARGS;
625
    break;
626

    
627
/* Binary operators */
628
  case '+':
629
    TWOARGS_C;
630
    switch (res.type = v1.type) {
631
    case T_VOID: runtime( "Can't operate with values of type void" );
632
    case T_INT: res.val.i = v1.val.i + v2.val.i; break;
633
    default: runtime( "Usage of unknown type" );
634
    }
635
    break;
636
  case '-':
637
    TWOARGS_C;
638
    switch (res.type = v1.type) {
639
    case T_VOID: runtime( "Can't operate with values of type void" );
640
    case T_INT: res.val.i = v1.val.i - v2.val.i; break;
641
    default: runtime( "Usage of unknown type" );
642
    }
643
    break;
644
  case '*':
645
    TWOARGS_C;
646
    switch (res.type = v1.type) {
647
    case T_VOID: runtime( "Can't operate with values of type void" );
648
    case T_INT: res.val.i = v1.val.i * v2.val.i; break;
649
    default: runtime( "Usage of unknown type" );
650
    }
651
    break;
652
  case '/':
653
    TWOARGS_C;
654
    switch (res.type = v1.type) {
655
    case T_VOID: runtime( "Can't operate with values of type void" );
656
    case T_INT: if (v2.val.i == 0) runtime( "Mother told me not to divide by 0" );
657
                      res.val.i = v1.val.i / v2.val.i; break;
658
    default: runtime( "Usage of unknown type" );
659
    }
660
    break;
661

    
662
  case '&':
663
  case '|':
664
    ARG(v1, a1.p);
665
    if (v1.type != T_BOOL)
666
      runtime( "Can't do boolean operation on non-booleans" );
667
    if (v1.val.i == (what->code == '|')) {
668
      res.type = T_BOOL;
669
      res.val.i = v1.val.i;
670
      break;
671
    }
672

    
673
    ARG(v2, a2.p);
674
    if (v2.type != T_BOOL)
675
      runtime( "Can't do boolean operation on non-booleans" );
676
    res.type = T_BOOL;
677
    res.val.i = v2.val.i;
678
    break;
679

    
680
  case P('m','p'):
681
    TWOARGS;
682
    if ((v1.type != T_INT) || (v2.type != T_INT))
683
      runtime( "Can't operate with value of non-integer type in pair constructor" );
684
    u1 = v1.val.i;
685
    u2 = v2.val.i;
686
    if ((u1 > 0xFFFF) || (u2 > 0xFFFF))
687
      runtime( "Can't operate with value out of bounds in pair constructor" );
688
    res.val.i = (u1 << 16) | u2;
689
    res.type = T_PAIR;
690
    break;
691

    
692
  case P('m','c'):
693
    {
694
      TWOARGS;
695

    
696
      int check, ipv4_used;
697
      u32 key, val;
698

    
699
      if (v1.type == T_INT) {
700
        ipv4_used = 0; key = v1.val.i;
701
      }
702
      else if (v1.type == T_QUAD) {
703
        ipv4_used = 1; key = v1.val.i;
704
      }
705
      /* IP->Quad implicit conversion */
706
      else if (val_is_ip4(v1)) {
707
        ipv4_used = 1; key = ipa_to_u32(v1.val.ip);
708
      }
709
      else
710
        runtime("Can't operate with key of non-integer/IPv4 type in EC constructor");
711

    
712
      if (v2.type != T_INT)
713
        runtime("Can't operate with value of non-integer type in EC constructor");
714
      val = v2.val.i;
715

    
716
      /* XXXX */
717
      res.type = T_EC;
718

    
719
      if (what->aux == EC_GENERIC) {
720
        check = 0; res.val.ec = ec_generic(key, val);
721
      }
722
      else if (ipv4_used) {
723
        check = 1; res.val.ec = ec_ip4(what->aux, key, val);
724
      }
725
      else if (key < 0x10000) {
726
        check = 0; res.val.ec = ec_as2(what->aux, key, val);
727
      }
728
      else {
729
        check = 1; res.val.ec = ec_as4(what->aux, key, val);
730
      }
731

    
732
      if (check && (val > 0xFFFF))
733
        runtime("Can't operate with value out of bounds in EC constructor");
734

    
735
      break;
736
    }
737

    
738
  case P('m','l'):
739
    {
740
      TWOARGS;
741

    
742
      /* Third argument hack */
743
      struct f_val v3 = interpret(INST3(what).p);
744
      if (v3.type & T_RETURN)
745
        return v3;
746

    
747
      if ((v1.type != T_INT) || (v2.type != T_INT) || (v3.type != T_INT))
748
        runtime( "Can't operate with value of non-integer type in LC constructor" );
749

    
750
      res.type = T_LC;
751
      res.val.lc = (lcomm) { v1.val.i, v2.val.i, v3.val.i };
752

    
753
      break;
754
    }
755

    
756
/* Relational operators */
757

    
758
#define COMPARE(x) \
759
    TWOARGS; \
760
    i = val_compare(v1, v2); \
761
    if (i==CMP_ERROR) \
762
      runtime( "Can't compare values of incompatible types" ); \
763
    res.type = T_BOOL; \
764
    res.val.i = (x); \
765
    break;
766

    
767
#define SAME(x) \
768
    TWOARGS; \
769
    i = val_same(v1, v2); \
770
    res.type = T_BOOL; \
771
    res.val.i = (x); \
772
    break;
773

    
774
  case P('!','='): SAME(!i);
775
  case P('=','='): SAME(i);
776
  case '<': COMPARE(i==-1);
777
  case P('<','='): COMPARE(i!=1);
778

    
779
  case '!':
780
    ONEARG;
781
    if (v1.type != T_BOOL)
782
      runtime( "Not applied to non-boolean" );
783
    res = v1;
784
    res.val.i = !res.val.i;
785
    break;
786

    
787
  case '~':
788
    TWOARGS;
789
    res.type = T_BOOL;
790
    res.val.i = val_in_range(v1, v2);
791
    if (res.val.i == CMP_ERROR)
792
      runtime( "~ applied on unknown type pair" );
793
    res.val.i = !!res.val.i;
794
    break;
795

    
796
  case P('!','~'):
797
    TWOARGS;
798
    res.type = T_BOOL;
799
    res.val.i = val_in_range(v1, v2);
800
    if (res.val.i == CMP_ERROR)
801
      runtime( "!~ applied on unknown type pair" );
802
    res.val.i = !res.val.i;
803
    break;
804

    
805
  case P('d','e'):
806
    ONEARG;
807
    res.type = T_BOOL;
808
    res.val.i = (v1.type != T_VOID);
809
    break;
810

    
811
  /* Set to indirect value, a1 = variable, a2 = value */
812
  case 's':
813
    ARG(v2, a2.p);
814
    sym = what->a1.p;
815
    vp = sym->def;
816
    if ((sym->class != (SYM_VARIABLE | v2.type)) && (v2.type != T_VOID))
817
    {
818
      /* IP->Quad implicit conversion */
819
      if ((sym->class == (SYM_VARIABLE | T_QUAD)) && val_is_ip4(v2))
820
      {
821
        vp->type = T_QUAD;
822
        vp->val.i = ipa_to_u32(v2.val.ip);
823
        break;
824
      }
825
      runtime( "Assigning to variable of incompatible type" );
826
    }
827
    *vp = v2;
828
    break;
829

    
830
    /* some constants have value in a2, some in *a1.p, strange. */
831
  case 'c':        /* integer (or simple type) constant, string, set, or prefix_set */
832
    res.type = what->aux;
833

    
834
    if (res.type == T_PREFIX_SET)
835
      res.val.ti = what->a2.p;
836
    else if (res.type == T_SET)
837
      res.val.t = what->a2.p;
838
    else if (res.type == T_STRING)
839
      res.val.s = what->a2.p;
840
    else
841
      res.val.i = what->a2.i;
842
    break;
843
  case 'V':
844
  case 'C':
845
    res = * ((struct f_val *) what->a1.p);
846
    break;
847
  case 'p':
848
    ONEARG;
849
    val_format(v1, &f_buf);
850
    break;
851
  case '?':        /* ? has really strange error value, so we can implement if ... else nicely :-) */
852
    ONEARG;
853
    if (v1.type != T_BOOL)
854
      runtime( "If requires boolean expression" );
855
    if (v1.val.i) {
856
      ARG(res,a2.p);
857
      res.val.i = 0;
858
    } else res.val.i = 1;
859
    res.type = T_BOOL;
860
    break;
861
  case '0':
862
    debug( "No operation\n" );
863
    break;
864
  case P('p',','):
865
    ONEARG;
866
    if (what->a2.i == F_NOP || (what->a2.i != F_NONL && what->a1.p))
867
      log_commit(*L_INFO, &f_buf);
868

    
869
    switch (what->a2.i) {
870
    case F_QUITBIRD:
871
      die( "Filter asked me to die" );
872
    case F_ACCEPT:
873
      /* Should take care about turning ACCEPT into MODIFY */
874
    case F_ERROR:
875
    case F_REJECT:        /* FIXME (noncritical) Should print complete route along with reason to reject route */
876
      res.type = T_RETURN;
877
      res.val.i = what->a2.i;
878
      return res;        /* We have to return now, no more processing. */
879
    case F_NONL:
880
    case F_NOP:
881
      break;
882
    default:
883
      bug( "unknown return type: Can't happen");
884
    }
885
    break;
886
  case 'a':        /* rta access */
887
    {
888
      ACCESS_RTE;
889
      struct rta *rta = (*f_rte)->attrs;
890
      res.type = what->aux;
891

    
892
      switch (what->a2.i)
893
      {
894
      case SA_FROM:        res.val.ip = rta->from; break;
895
      case SA_GW:        res.val.ip = rta->gw; break;
896
      case SA_NET:        res.val.net = (*f_rte)->net->n.addr; break;
897
      case SA_PROTO:        res.val.s = rta->src->proto->name; break;
898
      case SA_SOURCE:        res.val.i = rta->source; break;
899
      case SA_SCOPE:        res.val.i = rta->scope; break;
900
      case SA_CAST:        res.val.i = rta->cast; break;
901
      case SA_DEST:        res.val.i = rta->dest; break;
902
      case SA_IFNAME:        res.val.s = rta->iface ? rta->iface->name : ""; break;
903
      case SA_IFINDEX:        res.val.i = rta->iface ? rta->iface->index : 0; break;
904

    
905
      default:
906
        bug("Invalid static attribute access (%x)", res.type);
907
      }
908
    }
909
    break;
910
  case P('a','S'):
911
    ACCESS_RTE;
912
    ONEARG;
913
    if (what->aux != v1.type)
914
      runtime( "Attempt to set static attribute to incompatible type" );
915

    
916
    f_rta_cow();
917
    {
918
      struct rta *rta = (*f_rte)->attrs;
919

    
920
      switch (what->a2.i)
921
      {
922
      case SA_FROM:
923
        rta->from = v1.val.ip;
924
        break;
925

    
926
      case SA_GW:
927
        {
928
          ip_addr ip = v1.val.ip;
929
          neighbor *n = neigh_find(rta->src->proto, &ip, 0);
930
          if (!n || (n->scope == SCOPE_HOST))
931
            runtime( "Invalid gw address" );
932

    
933
          rta->dest = RTD_ROUTER;
934
          rta->gw = ip;
935
          rta->iface = n->iface;
936
          rta->nexthops = NULL;
937
          rta->hostentry = NULL;
938
        }
939
        break;
940

    
941
      case SA_SCOPE:
942
        rta->scope = v1.val.i;
943
        break;
944

    
945
      case SA_DEST:
946
        i = v1.val.i;
947
        if ((i != RTD_BLACKHOLE) && (i != RTD_UNREACHABLE) && (i != RTD_PROHIBIT))
948
          runtime( "Destination can be changed only to blackhole, unreachable or prohibit" );
949

    
950
        rta->dest = i;
951
        rta->gw = IPA_NONE;
952
        rta->iface = NULL;
953
        rta->nexthops = NULL;
954
        rta->hostentry = NULL;
955
        break;
956

    
957
      default:
958
        bug("Invalid static attribute access (%x)", res.type);
959
      }
960
    }
961
    break;
962
  case P('e','a'):        /* Access to extended attributes */
963
    ACCESS_RTE;
964
    {
965
      eattr *e = NULL;
966
      u16 code = what->a2.i;
967

    
968
      if (!(f_flags & FF_FORCE_TMPATTR))
969
        e = ea_find((*f_rte)->attrs->eattrs, code);
970
      if (!e)
971
        e = ea_find((*f_tmp_attrs), code);
972
      if ((!e) && (f_flags & FF_FORCE_TMPATTR))
973
        e = ea_find((*f_rte)->attrs->eattrs, code);
974

    
975
      if (!e) {
976
        /* A special case: undefined int_set looks like empty int_set */
977
        if ((what->aux & EAF_TYPE_MASK) == EAF_TYPE_INT_SET) {
978
          res.type = T_CLIST;
979
          res.val.ad = adata_empty(f_pool, 0);
980
          break;
981
        }
982

    
983
        /* The same special case for ec_set */
984
        if ((what->aux & EAF_TYPE_MASK) == EAF_TYPE_EC_SET) {
985
          res.type = T_ECLIST;
986
          res.val.ad = adata_empty(f_pool, 0);
987
          break;
988
        }
989

    
990
        /* The same special case for lc_set */
991
        if ((what->aux & EAF_TYPE_MASK) == EAF_TYPE_LC_SET) {
992
          res.type = T_LCLIST;
993
          res.val.ad = adata_empty(f_pool, 0);
994
          break;
995
        }
996

    
997
        /* Undefined value */
998
        res.type = T_VOID;
999
        break;
1000
      }
1001

    
1002
      switch (what->aux & EAF_TYPE_MASK) {
1003
      case EAF_TYPE_INT:
1004
        res.type = T_INT;
1005
        res.val.i = e->u.data;
1006
        break;
1007
      case EAF_TYPE_ROUTER_ID:
1008
        res.type = T_QUAD;
1009
        res.val.i = e->u.data;
1010
        break;
1011
      case EAF_TYPE_OPAQUE:
1012
        res.type = T_ENUM_EMPTY;
1013
        res.val.i = 0;
1014
        break;
1015
      case EAF_TYPE_IP_ADDRESS:
1016
        res.type = T_IP;
1017
        struct adata * ad = e->u.ptr;
1018
        res.val.ip = * (ip_addr *) ad->data;
1019
        break;
1020
      case EAF_TYPE_AS_PATH:
1021
        res.type = T_PATH;
1022
        res.val.ad = e->u.ptr;
1023
        break;
1024
      case EAF_TYPE_BITFIELD:
1025
        res.type = T_BOOL;
1026
        res.val.i = !!(e->u.data & BITFIELD_MASK(what));
1027
        break;
1028
      case EAF_TYPE_INT_SET:
1029
        res.type = T_CLIST;
1030
        res.val.ad = e->u.ptr;
1031
        break;
1032
      case EAF_TYPE_EC_SET:
1033
        res.type = T_ECLIST;
1034
        res.val.ad = e->u.ptr;
1035
        break;
1036
      case EAF_TYPE_LC_SET:
1037
        res.type = T_LCLIST;
1038
        res.val.ad = e->u.ptr;
1039
        break;
1040
      case EAF_TYPE_UNDEF:
1041
        res.type = T_VOID;
1042
        break;
1043
      default:
1044
        bug("Unknown type in e,a");
1045
      }
1046
    }
1047
    break;
1048
  case P('e','S'):
1049
    ACCESS_RTE;
1050
    ONEARG;
1051
    {
1052
      struct ea_list *l = lp_alloc(f_pool, sizeof(struct ea_list) + sizeof(eattr));
1053
      u16 code = what->a2.i;
1054

    
1055
      l->next = NULL;
1056
      l->flags = EALF_SORTED;
1057
      l->count = 1;
1058
      l->attrs[0].id = code;
1059
      l->attrs[0].flags = 0;
1060
      l->attrs[0].type = what->aux | EAF_ORIGINATED;
1061

    
1062
      switch (what->aux & EAF_TYPE_MASK) {
1063
      case EAF_TYPE_INT:
1064
        if (v1.type != T_INT)
1065
          runtime( "Setting int attribute to non-int value" );
1066
        l->attrs[0].u.data = v1.val.i;
1067
        break;
1068

    
1069
      case EAF_TYPE_ROUTER_ID:
1070
        /* IP->Quad implicit conversion */
1071
        if (val_is_ip4(v1)) {
1072
          l->attrs[0].u.data = ipa_to_u32(v1.val.ip);
1073
          break;
1074
        }
1075
        /* T_INT for backward compatibility */
1076
        if ((v1.type != T_QUAD) && (v1.type != T_INT))
1077
          runtime( "Setting quad attribute to non-quad value" );
1078
        l->attrs[0].u.data = v1.val.i;
1079
        break;
1080

    
1081
      case EAF_TYPE_OPAQUE:
1082
        runtime( "Setting opaque attribute is not allowed" );
1083
        break;
1084
      case EAF_TYPE_IP_ADDRESS:
1085
        if (v1.type != T_IP)
1086
          runtime( "Setting ip attribute to non-ip value" );
1087
        int len = sizeof(ip_addr);
1088
        struct adata *ad = lp_alloc(f_pool, sizeof(struct adata) + len);
1089
        ad->length = len;
1090
        (* (ip_addr *) ad->data) = v1.val.ip;
1091
        l->attrs[0].u.ptr = ad;
1092
        break;
1093
      case EAF_TYPE_AS_PATH:
1094
        if (v1.type != T_PATH)
1095
          runtime( "Setting path attribute to non-path value" );
1096
        l->attrs[0].u.ptr = v1.val.ad;
1097
        break;
1098
      case EAF_TYPE_BITFIELD:
1099
        if (v1.type != T_BOOL)
1100
          runtime( "Setting bit in bitfield attribute to non-bool value" );
1101
        {
1102
          /* First, we have to find the old value */
1103
          eattr *e = NULL;
1104
          if (!(f_flags & FF_FORCE_TMPATTR))
1105
            e = ea_find((*f_rte)->attrs->eattrs, code);
1106
          if (!e)
1107
            e = ea_find((*f_tmp_attrs), code);
1108
          if ((!e) && (f_flags & FF_FORCE_TMPATTR))
1109
            e = ea_find((*f_rte)->attrs->eattrs, code);
1110
          u32 data = e ? e->u.data : 0;
1111

    
1112
          if (v1.val.i)
1113
            l->attrs[0].u.data = data | BITFIELD_MASK(what);
1114
          else
1115
            l->attrs[0].u.data = data & ~BITFIELD_MASK(what);;
1116
        }
1117
        break;
1118
      case EAF_TYPE_INT_SET:
1119
        if (v1.type != T_CLIST)
1120
          runtime( "Setting clist attribute to non-clist value" );
1121
        l->attrs[0].u.ptr = v1.val.ad;
1122
        break;
1123
      case EAF_TYPE_EC_SET:
1124
        if (v1.type != T_ECLIST)
1125
          runtime( "Setting eclist attribute to non-eclist value" );
1126
        l->attrs[0].u.ptr = v1.val.ad;
1127
        break;
1128
      case EAF_TYPE_LC_SET:
1129
        if (v1.type != T_LCLIST)
1130
          runtime( "Setting lclist attribute to non-lclist value" );
1131
        l->attrs[0].u.ptr = v1.val.ad;
1132
        break;
1133
      case EAF_TYPE_UNDEF:
1134
        if (v1.type != T_VOID)
1135
          runtime( "Setting void attribute to non-void value" );
1136
        l->attrs[0].u.data = 0;
1137
        break;
1138
      default: bug("Unknown type in e,S");
1139
      }
1140

    
1141
      if (!(what->aux & EAF_TEMP) && (!(f_flags & FF_FORCE_TMPATTR))) {
1142
        f_rta_cow();
1143
        l->next = (*f_rte)->attrs->eattrs;
1144
        (*f_rte)->attrs->eattrs = l;
1145
      } else {
1146
        l->next = (*f_tmp_attrs);
1147
        (*f_tmp_attrs) = l;
1148
      }
1149
    }
1150
    break;
1151
  case 'P':
1152
    ACCESS_RTE;
1153
    res.type = T_INT;
1154
    res.val.i = (*f_rte)->pref;
1155
    break;
1156
  case P('P','S'):
1157
    ACCESS_RTE;
1158
    ONEARG;
1159
    if (v1.type != T_INT)
1160
      runtime( "Can't set preference to non-integer" );
1161
    if (v1.val.i > 0xFFFF)
1162
      runtime( "Setting preference value out of bounds" );
1163
    f_rte_cow();
1164
    (*f_rte)->pref = v1.val.i;
1165
    break;
1166
  case 'L':        /* Get length of */
1167
    ONEARG;
1168
    res.type = T_INT;
1169
    switch(v1.type) {
1170
    case T_NET:    res.val.i = net_pxlen(v1.val.net); break;
1171
    case T_PATH:   res.val.i = as_path_getlen(v1.val.ad); break;
1172
    case T_CLIST:  res.val.i = int_set_get_size(v1.val.ad); break;
1173
    case T_ECLIST: res.val.i = ec_set_get_size(v1.val.ad); break;
1174
    case T_LCLIST: res.val.i = lc_set_get_size(v1.val.ad); break;
1175
    default: runtime( "Prefix, path, clist or eclist expected" );
1176
    }
1177
    break;
1178
  case P('c','p'):        /* Convert prefix to ... */
1179
    ONEARG;
1180
    if (v1.type != T_NET)
1181
      runtime( "Prefix expected" );
1182
    res.type = T_IP;
1183
    res.val.ip = net_prefix(v1.val.net);
1184
    break;
1185
  case P('a','f'):        /* Get first ASN from AS PATH */
1186
    ONEARG;
1187
    if (v1.type != T_PATH)
1188
      runtime( "AS path expected" );
1189

    
1190
    as = 0;
1191
    as_path_get_first(v1.val.ad, &as);
1192
    res.type = T_INT;
1193
    res.val.i = as;
1194
    break;
1195
  case P('a','l'):        /* Get last ASN from AS PATH */
1196
    ONEARG;
1197
    if (v1.type != T_PATH)
1198
      runtime( "AS path expected" );
1199

    
1200
    as = 0;
1201
    as_path_get_last(v1.val.ad, &as);
1202
    res.type = T_INT;
1203
    res.val.i = as;
1204
    break;
1205
  case P('a','L'):        /* Get last ASN from non-aggregated part of AS PATH */
1206
    ONEARG;
1207
    if (v1.type != T_PATH)
1208
      runtime( "AS path expected" );
1209

    
1210
    res.type = T_INT;
1211
    res.val.i = as_path_get_last_nonaggregated(v1.val.ad);
1212
    break;
1213
  case 'r':
1214
    ONEARG;
1215
    res = v1;
1216
    res.type |= T_RETURN;
1217
    return res;
1218
  case P('c','a'): /* CALL: this is special: if T_RETURN and returning some value, mask it out  */
1219
    ONEARG;
1220
    res = interpret(what->a2.p);
1221
    if (res.type == T_RETURN)
1222
      return res;
1223
    res.type &= ~T_RETURN;
1224
    break;
1225
  case P('c','v'):        /* Clear local variables */
1226
    for (sym = what->a1.p; sym != NULL; sym = sym->aux2)
1227
      ((struct f_val *) sym->def)->type = T_VOID;
1228
    break;
1229
  case P('S','W'):
1230
    ONEARG;
1231
    {
1232
      struct f_tree *t = find_tree(what->a2.p, v1);
1233
      if (!t) {
1234
        v1.type = T_VOID;
1235
        t = find_tree(what->a2.p, v1);
1236
        if (!t) {
1237
          debug( "No else statement?\n");
1238
          break;
1239
        }
1240
      }
1241
      /* It is actually possible to have t->data NULL */
1242

    
1243
      res = interpret(t->data);
1244
      if (res.type & T_RETURN)
1245
        return res;
1246
    }
1247
    break;
1248
  case P('i','M'): /* IP.MASK(val) */
1249
    TWOARGS;
1250
    if (v2.type != T_INT)
1251
      runtime( "Integer expected");
1252
    if (v1.type != T_IP)
1253
      runtime( "You can mask only IP addresses" );
1254

    
1255
    res.type = T_IP;
1256
    res.val.ip = ipa_is_ip4(v1.val.ip) ?
1257
      ipa_from_ip4(ip4_and(ipa_to_ip4(v1.val.ip), ip4_mkmask(v2.val.i))) :
1258
      ipa_from_ip6(ip6_and(ipa_to_ip6(v1.val.ip), ip6_mkmask(v2.val.i)));
1259
    break;
1260

    
1261
  case 'E':        /* Create empty attribute */
1262
    res.type = what->aux;
1263
    res.val.ad = adata_empty(f_pool, 0);
1264
    break;
1265
  case P('A','p'):        /* Path prepend */
1266
    TWOARGS;
1267
    if (v1.type != T_PATH)
1268
      runtime("Can't prepend to non-path");
1269
    if (v2.type != T_INT)
1270
      runtime("Can't prepend non-integer");
1271

    
1272
    res.type = T_PATH;
1273
    res.val.ad = as_path_prepend(f_pool, v1.val.ad, v2.val.i);
1274
    break;
1275

    
1276
  case P('C','a'):        /* (Extended) Community list add or delete */
1277
    TWOARGS;
1278
    if (v1.type == T_PATH)
1279
    {
1280
      struct f_tree *set = NULL;
1281
      u32 key = 0;
1282
      int pos;
1283

    
1284
      if (v2.type == T_INT)
1285
        key = v2.val.i;
1286
      else if ((v2.type == T_SET) && (v2.val.t->from.type == T_INT))
1287
        set = v2.val.t;
1288
      else
1289
        runtime("Can't delete non-integer (set)");
1290

    
1291
      switch (what->aux)
1292
      {
1293
      case 'a':        runtime("Can't add to path");
1294
      case 'd':        pos = 0; break;
1295
      case 'f':        pos = 1; break;
1296
      default:        bug("unknown Ca operation");
1297
      }
1298

    
1299
      if (pos && !set)
1300
        runtime("Can't filter integer");
1301

    
1302
      res.type = T_PATH;
1303
      res.val.ad = as_path_filter(f_pool, v1.val.ad, set, key, pos);
1304
    }
1305
    else if (v1.type == T_CLIST)
1306
    {
1307
      /* Community (or cluster) list */
1308
      struct f_val dummy;
1309
      int arg_set = 0;
1310
      uint n = 0;
1311

    
1312
      if ((v2.type == T_PAIR) || (v2.type == T_QUAD))
1313
        n = v2.val.i;
1314
      /* IP->Quad implicit conversion */
1315
      else if (val_is_ip4(v2))
1316
        n = ipa_to_u32(v2.val.ip);
1317
      else if ((v2.type == T_SET) && clist_set_type(v2.val.t, &dummy))
1318
        arg_set = 1;
1319
      else if (v2.type == T_CLIST)
1320
        arg_set = 2;
1321
      else
1322
        runtime("Can't add/delete non-pair");
1323

    
1324
      res.type = T_CLIST;
1325
      switch (what->aux)
1326
      {
1327
      case 'a':
1328
        if (arg_set == 1)
1329
          runtime("Can't add set");
1330
        else if (!arg_set)
1331
          res.val.ad = int_set_add(f_pool, v1.val.ad, n);
1332
        else
1333
          res.val.ad = int_set_union(f_pool, v1.val.ad, v2.val.ad);
1334
        break;
1335

    
1336
      case 'd':
1337
        if (!arg_set)
1338
          res.val.ad = int_set_del(f_pool, v1.val.ad, n);
1339
        else
1340
          res.val.ad = clist_filter(f_pool, v1.val.ad, v2, 0);
1341
        break;
1342

    
1343
      case 'f':
1344
        if (!arg_set)
1345
          runtime("Can't filter pair");
1346
        res.val.ad = clist_filter(f_pool, v1.val.ad, v2, 1);
1347
        break;
1348

    
1349
      default:
1350
        bug("unknown Ca operation");
1351
      }
1352
    }
1353
    else if (v1.type == T_ECLIST)
1354
    {
1355
      /* Extended community list */
1356
      int arg_set = 0;
1357

    
1358
      /* v2.val is either EC or EC-set */
1359
      if ((v2.type == T_SET) && eclist_set_type(v2.val.t))
1360
        arg_set = 1;
1361
      else if (v2.type == T_ECLIST)
1362
        arg_set = 2;
1363
      else if (v2.type != T_EC)
1364
        runtime("Can't add/delete non-ec");
1365

    
1366
      res.type = T_ECLIST;
1367
      switch (what->aux)
1368
      {
1369
      case 'a':
1370
        if (arg_set == 1)
1371
          runtime("Can't add set");
1372
        else if (!arg_set)
1373
          res.val.ad = ec_set_add(f_pool, v1.val.ad, v2.val.ec);
1374
        else
1375
          res.val.ad = ec_set_union(f_pool, v1.val.ad, v2.val.ad);
1376
        break;
1377

    
1378
      case 'd':
1379
        if (!arg_set)
1380
          res.val.ad = ec_set_del(f_pool, v1.val.ad, v2.val.ec);
1381
        else
1382
          res.val.ad = eclist_filter(f_pool, v1.val.ad, v2, 0);
1383
        break;
1384

    
1385
      case 'f':
1386
        if (!arg_set)
1387
          runtime("Can't filter ec");
1388
        res.val.ad = eclist_filter(f_pool, v1.val.ad, v2, 1);
1389
        break;
1390

    
1391
      default:
1392
        bug("unknown Ca operation");
1393
      }
1394
    }
1395
    else if (v1.type == T_LCLIST)
1396
    {
1397
      /* Large community list */
1398
      int arg_set = 0;
1399

    
1400
      /* v2.val is either LC or LC-set */
1401
      if ((v2.type == T_SET) && lclist_set_type(v2.val.t))
1402
        arg_set = 1;
1403
      else if (v2.type == T_LCLIST)
1404
        arg_set = 2;
1405
      else if (v2.type != T_LC)
1406
        runtime("Can't add/delete non-lc");
1407

    
1408
      res.type = T_LCLIST;
1409
      switch (what->aux)
1410
      {
1411
      case 'a':
1412
        if (arg_set == 1)
1413
          runtime("Can't add set");
1414
        else if (!arg_set)
1415
          res.val.ad = lc_set_add(f_pool, v1.val.ad, v2.val.lc);
1416
        else
1417
          res.val.ad = lc_set_union(f_pool, v1.val.ad, v2.val.ad);
1418
        break;
1419

    
1420
      case 'd':
1421
        if (!arg_set)
1422
          res.val.ad = lc_set_del(f_pool, v1.val.ad, v2.val.lc);
1423
        else
1424
          res.val.ad = lclist_filter(f_pool, v1.val.ad, v2, 0);
1425
        break;
1426

    
1427
      case 'f':
1428
        if (!arg_set)
1429
          runtime("Can't filter lc");
1430
        res.val.ad = lclist_filter(f_pool, v1.val.ad, v2, 1);
1431
        break;
1432

    
1433
      default:
1434
        bug("unknown Ca operation");
1435
      }
1436
    }
1437
    else
1438
      runtime("Can't add/delete to non-[e|l]clist");
1439

    
1440
    break;
1441

    
1442

    
1443
  case P('R','C'):        /* ROA Check */
1444
    if (what->arg1)
1445
    {
1446
      TWOARGS;
1447
      if ((v1.type != T_NET) || (v2.type != T_INT))
1448
        runtime("Invalid argument to roa_check()");
1449

    
1450
      as = v2.val.i;
1451
    }
1452
    else
1453
    {
1454
      ACCESS_RTE;
1455
      v1.val.net = (*f_rte)->net->n.addr;
1456

    
1457
      /* We ignore temporary attributes, probably not a problem here */
1458
      /* 0x02 is a value of BA_AS_PATH, we don't want to include BGP headers */
1459
      eattr *e = ea_find((*f_rte)->attrs->eattrs, EA_CODE(EAP_BGP, 0x02));
1460

    
1461
      if (!e || e->type != EAF_TYPE_AS_PATH)
1462
        runtime("Missing AS_PATH attribute");
1463

    
1464
      as_path_get_last(e->u.ptr, &as);
1465
    }
1466

    
1467
    struct rtable *table = ((struct f_inst_roa_check *) what)->rtc->table;
1468
    if (!table)
1469
      runtime("Missing ROA table");
1470

    
1471
    /* Table type is either NET_ROA4 or NET_ROA6, checked in parser */
1472
    if (v1.val.net->type != ((table->addr_type == NET_ROA4) ? NET_IP4 : NET_IP6))
1473
      runtime("Incompatible net type");
1474

    
1475
    res.type = T_ENUM_ROA;
1476
    res.val.i = net_roa_check(table, v1.val.net, as);
1477

    
1478
    break;
1479

    
1480
  case P('a', 's'):        /* Birdtest Assert */
1481
    ONEARG;
1482

    
1483
    if (v1.type != T_BOOL)
1484
      runtime("Should be boolean value");
1485

    
1486
    res.type = v1.type;
1487
    res.val = v1.val;
1488

    
1489
    CALL(bt_assert_hook, res.val.i, what);
1490
    break;
1491

    
1492
  default:
1493
    bug( "Unknown instruction %d (%c)", what->code, what->code & 0xff);
1494
  }
1495
  if (what->next)
1496
    return interpret(what->next);
1497
  return res;
1498
}
1499

    
1500
#undef ARG
1501
#define ARG(x,y) \
1502
        if (!i_same(f1->y, f2->y)) \
1503
                return 0;
1504

    
1505
#define ONEARG ARG(v1, a1.p)
1506
#define TWOARGS ARG(v1, a1.p) \
1507
                ARG(v2, a2.p)
1508

    
1509
#define A2_SAME if (f1->a2.i != f2->a2.i) return 0;
1510

    
1511
/*
1512
 * i_same - function that does real comparing of instruction trees, you should call filter_same from outside
1513
 */
1514
int
1515
i_same(struct f_inst *f1, struct f_inst *f2)
1516
{
1517
  if ((!!f1) != (!!f2))
1518
    return 0;
1519
  if (!f1)
1520
    return 1;
1521
  if (f1->aux != f2->aux)
1522
    return 0;
1523
  if (f1->code != f2->code)
1524
    return 0;
1525
  if (f1 == f2)                /* It looks strange, but it is possible with call rewriting trickery */
1526
    return 1;
1527

    
1528
  switch(f1->code) {
1529
  case ',': /* fall through */
1530
  case '+':
1531
  case '-':
1532
  case '*':
1533
  case '/':
1534
  case '|':
1535
  case '&':
1536
  case P('m','p'):
1537
  case P('m','c'):
1538
  case P('!','='):
1539
  case P('=','='):
1540
  case '<':
1541
  case P('<','='): TWOARGS; break;
1542

    
1543
  case '!': ONEARG; break;
1544
  case '~': TWOARGS; break;
1545
  case P('d','e'): ONEARG; break;
1546

    
1547
  case P('m','l'):
1548
    TWOARGS;
1549
    if (!i_same(INST3(f1).p, INST3(f2).p))
1550
      return 0;
1551
    break;
1552

    
1553
  case 's':
1554
    ARG(v2, a2.p);
1555
    {
1556
      struct symbol *s1, *s2;
1557
      s1 = f1->a1.p;
1558
      s2 = f2->a1.p;
1559
      if (strcmp(s1->name, s2->name))
1560
        return 0;
1561
      if (s1->class != s2->class)
1562
        return 0;
1563
    }
1564
    break;
1565

    
1566
  case 'c':
1567
    switch (f1->aux) {
1568

    
1569
    case T_PREFIX_SET:
1570
      if (!trie_same(f1->a2.p, f2->a2.p))
1571
        return 0;
1572
      break;
1573

    
1574
    case T_SET:
1575
      if (!same_tree(f1->a2.p, f2->a2.p))
1576
        return 0;
1577
      break;
1578

    
1579
    case T_STRING:
1580
      if (strcmp(f1->a2.p, f2->a2.p))
1581
        return 0;
1582
      break;
1583

    
1584
    default:
1585
      A2_SAME;
1586
    }
1587
    break;
1588

    
1589
  case 'C':
1590
    if (!val_same(* (struct f_val *) f1->a1.p, * (struct f_val *) f2->a1.p))
1591
      return 0;
1592
    break;
1593

    
1594
  case 'V':
1595
    if (strcmp((char *) f1->a2.p, (char *) f2->a2.p))
1596
      return 0;
1597
    break;
1598
  case 'p': case 'L': ONEARG; break;
1599
  case '?': TWOARGS; break;
1600
  case '0': case 'E': break;
1601
  case P('p',','): ONEARG; A2_SAME; break;
1602
  case 'P':
1603
  case 'a': A2_SAME; break;
1604
  case P('e','a'): A2_SAME; break;
1605
  case P('P','S'):
1606
  case P('a','S'):
1607
  case P('e','S'): ONEARG; A2_SAME; break;
1608

    
1609
  case 'r': ONEARG; break;
1610
  case P('c','p'): ONEARG; break;
1611
  case P('c','a'): /* Call rewriting trickery to avoid exponential behaviour */
1612
             ONEARG;
1613
             if (!i_same(f1->a2.p, f2->a2.p))
1614
               return 0;
1615
             f2->a2.p = f1->a2.p;
1616
             break;
1617
  case P('c','v'): break; /* internal instruction */
1618
  case P('S','W'): ONEARG; if (!same_tree(f1->a2.p, f2->a2.p)) return 0; break;
1619
  case P('i','M'): TWOARGS; break;
1620
  case P('A','p'): TWOARGS; break;
1621
  case P('C','a'): TWOARGS; break;
1622
  case P('a','f'):
1623
  case P('a','l'):
1624
  case P('a','L'): ONEARG; break;
1625
#if 0
1626
  case P('R','C'):
1627
    TWOARGS;
1628
    /* Does not really make sense - ROA check resuls may change anyway */
1629
    if (strcmp(((struct f_inst_roa_check *) f1)->rtc->name,
1630
               ((struct f_inst_roa_check *) f2)->rtc->name))
1631
      return 0;
1632
    break;
1633
#endif
1634
  default:
1635
    bug( "Unknown instruction %d in same (%c)", f1->code, f1->code & 0xff);
1636
  }
1637
  return i_same(f1->next, f2->next);
1638
}
1639

    
1640
/**
1641
 * f_run - run a filter for a route
1642
 * @filter: filter to run
1643
 * @rte: route being filtered, may be modified
1644
 * @tmp_attrs: temporary attributes, prepared by caller or generated by f_run()
1645
 * @tmp_pool: all filter allocations go from this pool
1646
 * @flags: flags
1647
 *
1648
 * If filter needs to modify the route, there are several
1649
 * posibilities. @rte might be read-only (with REF_COW flag), in that
1650
 * case rw copy is obtained by rte_cow() and @rte is replaced. If
1651
 * @rte is originally rw, it may be directly modified (and it is never
1652
 * copied).
1653
 *
1654
 * The returned rte may reuse the (possibly cached, cloned) rta, or
1655
 * (if rta was modificied) contains a modified uncached rta, which
1656
 * uses parts allocated from @tmp_pool and parts shared from original
1657
 * rta. There is one exception - if @rte is rw but contains a cached
1658
 * rta and that is modified, rta in returned rte is also cached.
1659
 *
1660
 * Ownership of cached rtas is consistent with rte, i.e.
1661
 * if a new rte is returned, it has its own clone of cached rta
1662
 * (and cached rta of read-only source rte is intact), if rte is
1663
 * modified in place, old cached rta is possibly freed.
1664
 */
1665
int
1666
f_run(struct filter *filter, struct rte **rte, struct ea_list **tmp_attrs, struct linpool *tmp_pool, int flags)
1667
{
1668
  if (filter == FILTER_ACCEPT)
1669
    return F_ACCEPT;
1670

    
1671
  if (filter == FILTER_REJECT)
1672
    return F_REJECT;
1673

    
1674
  int rte_cow = ((*rte)->flags & REF_COW);
1675
  DBG( "Running filter `%s'...", filter->name );
1676

    
1677
  f_rte = rte;
1678
  f_old_rta = NULL;
1679
  f_tmp_attrs = tmp_attrs;
1680
  f_pool = tmp_pool;
1681
  f_flags = flags;
1682

    
1683
  LOG_BUFFER_INIT(f_buf);
1684

    
1685
  struct f_val res = interpret(filter->root);
1686

    
1687
  if (f_old_rta) {
1688
    /*
1689
     * Cached rta was modified and f_rte contains now an uncached one,
1690
     * sharing some part with the cached one. The cached rta should
1691
     * be freed (if rte was originally COW, f_old_rta is a clone
1692
     * obtained during rte_cow()).
1693
     *
1694
     * This also implements the exception mentioned in f_run()
1695
     * description. The reason for this is that rta reuses parts of
1696
     * f_old_rta, and these may be freed during rta_free(f_old_rta).
1697
     * This is not the problem if rte was COW, because original rte
1698
     * also holds the same rta.
1699
     */
1700
    if (!rte_cow)
1701
      (*f_rte)->attrs = rta_lookup((*f_rte)->attrs);
1702

    
1703
    rta_free(f_old_rta);
1704
  }
1705

    
1706

    
1707
  if (res.type != T_RETURN) {
1708
    log_rl(&rl_runtime_err, L_ERR "Filter %s did not return accept nor reject. Make up your mind", filter->name);
1709
    return F_ERROR;
1710
  }
1711
  DBG( "done (%u)\n", res.val.i );
1712
  return res.val.i;
1713
}
1714

    
1715
/* TODO: perhaps we could integrate f_eval(), f_eval_rte() and f_run() */
1716

    
1717
struct f_val
1718
f_eval_rte(struct f_inst *expr, struct rte **rte, struct linpool *tmp_pool)
1719
{
1720
  struct ea_list *tmp_attrs = NULL;
1721

    
1722
  f_rte = rte;
1723
  f_old_rta = NULL;
1724
  f_tmp_attrs = &tmp_attrs;
1725
  f_pool = tmp_pool;
1726
  f_flags = 0;
1727

    
1728
  LOG_BUFFER_INIT(f_buf);
1729

    
1730
  /* Note that in this function we assume that rte->attrs is private / uncached */
1731
  struct f_val res = interpret(expr);
1732

    
1733
  /* Hack to include EAF_TEMP attributes to the main list */
1734
  (*rte)->attrs->eattrs = ea_append(tmp_attrs, (*rte)->attrs->eattrs);
1735

    
1736
  return res;
1737
}
1738

    
1739
struct f_val
1740
f_eval(struct f_inst *expr, struct linpool *tmp_pool)
1741
{
1742
  f_flags = 0;
1743
  f_tmp_attrs = NULL;
1744
  f_rte = NULL;
1745
  f_pool = tmp_pool;
1746

    
1747
  LOG_BUFFER_INIT(f_buf);
1748

    
1749
  return interpret(expr);
1750
}
1751

    
1752
uint
1753
f_eval_int(struct f_inst *expr)
1754
{
1755
  /* Called independently in parse-time to eval expressions */
1756
  struct f_val res = f_eval(expr, cfg_mem);
1757

    
1758
  if (res.type != T_INT)
1759
    cf_error("Integer expression expected");
1760

    
1761
  return res.val.i;
1762
}
1763

    
1764
u32
1765
f_eval_asn(struct f_inst *expr)
1766
{
1767
  /* Called as a part of another interpret call, therefore no log_reset() */
1768
  struct f_val res = interpret(expr);
1769
  return (res.type == T_INT) ? res.val.i : 0;
1770
}
1771

    
1772
/**
1773
 * filter_same - compare two filters
1774
 * @new: first filter to be compared
1775
 * @old: second filter to be compared, notice that this filter is
1776
 * damaged while comparing.
1777
 *
1778
 * Returns 1 in case filters are same, otherwise 0. If there are
1779
 * underlying bugs, it will rather say 0 on same filters than say
1780
 * 1 on different.
1781
 */
1782
int
1783
filter_same(struct filter *new, struct filter *old)
1784
{
1785
  if (old == new)        /* Handle FILTER_ACCEPT and FILTER_REJECT */
1786
    return 1;
1787
  if (old == FILTER_ACCEPT || old == FILTER_REJECT ||
1788
      new == FILTER_ACCEPT || new == FILTER_REJECT)
1789
    return 0;
1790
  return i_same(new->root, old->root);
1791
}