Commit 931c6ff5 authored by Alexander Zubkov's avatar Alexander Zubkov Committed by Ondrej Zajicek (work)
Browse files

Filter: Add literal for empty set

Add literal for empty set [], which works both for tree-based sets
and prefix sets by using existing constant promotion mechanism.

Minor changes by committer.
parent bfad73ee
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -674,6 +674,7 @@ bgp_path:
bgp_path_tail:
   NUM bgp_path_tail		{ $$ = f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_PATH_MASK_ITEM, .val.pmi = { .asn = $1, .kind = PM_ASN, }, }); $$->next = $2;  }
 | NUM DDOT NUM bgp_path_tail	{ $$ = f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_PATH_MASK_ITEM, .val.pmi = { .from = $1, .to = $3, .kind = PM_ASN_RANGE }, }); $$->next = $4; }
 | '[' ']' bgp_path_tail { $$ = f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_PATH_MASK_ITEM, .val.pmi = { .set = NULL, .kind = PM_ASN_SET }, }); $$->next = $3; }
 | '[' set_items ']' bgp_path_tail {
   if ($2->from.type != T_INT) cf_error("Only integer sets allowed in path mask");
   $$ = f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_PATH_MASK_ITEM, .val.pmi = { .set = build_tree($2), .kind = PM_ASN_SET }, }); $$->next = $4;
@@ -693,6 +694,7 @@ constant:
 | fipa	  { $$ = f_new_inst(FI_CONSTANT, $1); }
 | VPN_RD { $$ = f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_RD, .val.ec = $1, }); }
 | net_   { $$ = f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_NET, .val.net = $1, }); }
 | '[' ']' { $$ = f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_SET, .val.t = NULL, }); }
 | '[' set_items ']' {
     DBG( "We've got a set here..." );
     $$ = f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_SET, .val.t = build_tree($2), });
+14 −0
Original line number Diff line number Diff line
@@ -79,6 +79,8 @@ f_type_element_type(enum f_type t)
  };
}

const struct f_trie f_const_empty_trie = { .ipv4 = -1, };

const struct f_val f_const_empty_path = {
  .type = T_PATH,
  .val.ad = &null_adata,
@@ -91,6 +93,9 @@ const struct f_val f_const_empty_path = {
}, f_const_empty_lclist = {
  .type = T_LCLIST,
  .val.ad = &null_adata,
}, f_const_empty_prefix_set = {
  .type = T_PREFIX_SET,
  .val.ti = &f_const_empty_trie,
};

static struct adata *
@@ -301,6 +306,12 @@ val_same(const struct f_val *v1, const struct f_val *v2)
int
clist_set_type(const struct f_tree *set, struct f_val *v)
{
  if (!set)
  {
    v->type = T_VOID;
    return 1;
  }

  switch (set->from.type)
  {
  case T_PAIR:
@@ -537,6 +548,9 @@ val_in_range(const struct f_val *v1, const struct f_val *v2)
  if (v2->type != T_SET)
    return F_CMP_ERROR;

  if (!v2->val.t)
    return 0;

  /* With integrated Quad<->IP implicit conversion */
  if ((v1->type == v2->val.t->from.type) ||
      ((v1->type == T_QUAD) && val_is_ip4(&(v2->val.t->from)) && val_is_ip4(&(v2->val.t->to))))
+4 −4
Original line number Diff line number Diff line
@@ -279,11 +279,11 @@ int val_in_range(const struct f_val *v1, const struct f_val *v2);

int clist_set_type(const struct f_tree *set, struct f_val *v);
static inline int eclist_set_type(const struct f_tree *set)
{ return set->from.type == T_EC; }
{ return !set || set->from.type == T_EC; }
static inline int lclist_set_type(const struct f_tree *set)
{ return set->from.type == T_LC; }
{ return !set || set->from.type == T_LC; }
static inline int path_set_type(const struct f_tree *set)
{ return set->from.type == T_INT; }
{ return !set || set->from.type == T_INT; }

const struct adata *clist_filter(struct linpool *pool, const struct adata *list, const struct f_val *set, int pos);
const struct adata *eclist_filter(struct linpool *pool, const struct adata *list, const struct f_val *set, int pos);
@@ -299,7 +299,7 @@ undef_value(struct f_val v)
    (v.val.ad == &null_adata);
}

extern const struct f_val f_const_empty_path, f_const_empty_clist, f_const_empty_eclist, f_const_empty_lclist;
extern const struct f_val f_const_empty_path, f_const_empty_clist, f_const_empty_eclist, f_const_empty_lclist, f_const_empty_prefix_set;

enum filter_return f_eval(const struct f_line *expr, struct linpool *tmp_pool, struct f_val *pres);

+5 −0
Original line number Diff line number Diff line
@@ -501,6 +501,11 @@ f_const_promotion(struct f_inst *arg, enum f_type want)
    return 1;
  }

  else if ((c->type == T_SET) && (!c->val.t) && (want == T_PREFIX_SET)) {
    *c = f_const_empty_prefix_set;
    return 1;
  }

  return 0;
}

+1 −1
Original line number Diff line number Diff line
@@ -401,7 +401,7 @@
	  break;

	case T_SET:
	  if (vv(i).val.t->from.type != T_INT)
	  if (!path_set_type(vv(i).val.t))
	    runtime("Only integer sets allowed in path mask");

	  pm->item[i] = (struct f_path_mask_item) {
Loading