Commit a0fe1944 authored by Ondrej Filip's avatar Ondrej Filip
Browse files

Add AS# ranges to bgpmask.

parent 90dc0f08
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -1165,8 +1165,10 @@ foot).
 	is 4 3 2 1, then: <tt>bgp_path &tilde; [= * 4 3 * =]</tt> is true,
	but <tt>bgp_path &tilde; [= * 4 5 * =]</tt> is false. BGP mask
	expressions can also contain integer expressions enclosed in parenthesis
	and integer variables, for example <tt>[= * 4 (1+2) a =]</tt>. There is
	also old syntax that uses / .. / instead of [= .. =] and ? instead of *.
	and integer variables, for example <tt>[= * 4 (1+2) a =]</tt>. You can
        also use ranges, for example <tt>[= * 3..5 2 100..200 * =]</tt>.
        There is also old (deprecated) syntax that uses / .. / instead of [= .. =]
        and ? instead of *.

	<tag/clist/
	Clist is similar to a set, except that unlike other sets, it can be
+1 −0
Original line number Diff line number Diff line
@@ -627,6 +627,7 @@ bgp_path:

bgp_path_tail1:
   NUM bgp_path_tail1 { $$ = cfg_alloc(sizeof(struct f_path_mask)); $$->next = $2; $$->kind = PM_ASN;      $$->val = $1; }
 | NUM DDOT NUM bgp_path_tail1 { $$ = cfg_alloc(sizeof(struct f_path_mask)); $$->next = $4; $$->kind = PM_ASN_RANGE;      $$->val = $1; $$->val2 = $3; }
 | '*' bgp_path_tail1 { $$ = cfg_alloc(sizeof(struct f_path_mask)); $$->next = $2; $$->kind = PM_ASTERISK; $$->val  = 0; }
 | '?' bgp_path_tail1 { $$ = cfg_alloc(sizeof(struct f_path_mask)); $$->next = $2; $$->kind = PM_QUESTION; $$->val  = 0; }
 | bgp_path_expr bgp_path_tail1 { $$ = cfg_alloc(sizeof(struct f_path_mask)); $$->next = $2; $$->kind = PM_ASN_EXPR; $$->val = (uintptr_t) $1; }
+4 −0
Original line number Diff line number Diff line
@@ -79,6 +79,10 @@ pm_format(struct f_path_mask *p, buffer *buf)
      buffer_puts(buf, "* ");
      break;

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

    case PM_ASN_EXPR:
      buffer_print(buf, "%u ", f_eval_asn((struct f_inst *) p->val));
      break;
+6 −3
Original line number Diff line number Diff line
@@ -90,20 +90,23 @@ clist l2;
eclist el;
eclist el2;
{
	print "Entering path test...";
	pm1 =  / 4 3 2 1 /;
	pm2 = [= 4 3 2 1 =];
	pm2 = [= 3..6 3 2 1..2 =];
	print "Testing path masks: ", pm1, " ", pm2;
	p2 = prepend( + empty +, 1 );
	p2 = prepend( p2, 2 );
	p2 = prepend( p2, 3 );
	p2 = prepend( p2, 4 );
	print "Testing paths: ", p2;
	print "Testing path: (4 3 2 1) = ", p2;
	print "Should be true: ", p2 ~ pm1, " ", p2 ~ pm2, " ", 3 ~ p2, " ", p2 ~ [2, 10..20], " ", p2 ~ [4, 10..20];
	print "4 = ", p2.len;
	p2 = prepend( p2, 5 );
	print "Should be false: ", p2 ~ pm1, " ", p2 ~ pm2, " ", 10 ~ p2, " ", p2 ~ [8, ten..(2*ten)];
	print "Testing path: (5 4 3 2 1) = ", p2;
	print "Should be false: ", p2 ~ pm1, " ", p2 ~ pm2, " ", 10 ~ p2, " ", p2 ~ [8, ten..(2*ten)], " ", p2 ~ [= 1..4 4 3 2 1 =], " ",  p2 ~ [= 5 4 4..100 2 1 =];
	print "Should be true: ", p2 ~  / ? 4 3 2 1 /,  " ", p2, " ",  / ? 4 3 2 1 /;
	print "Should be true: ", p2 ~ [= * 4 3 * 1 =], " ", p2, " ", [= * 4 3 * 1 =];
	print "Should be true: ", p2 ~ [= 5..6 4..10 1..3 1..3 1..65536 =];
	print "Should be true: ", p2 ~ [= (3+2) (2*2) 3 2 1 =], " ", p2 ~ mkpath(5, 4);
	print "Should be true: ", p2.len = 5, " ", p2.first = 5, " ", p2.last = 1;
	print "5 = ", p2.len;
+18 −8
Original line number Diff line number Diff line
@@ -435,18 +435,23 @@ parse_path(struct adata *path, struct pm_pos *pos)


static int
pm_match(struct pm_pos *pos, u32 asn)
pm_match(struct pm_pos *pos, u32 asn, u32 asn2)
{
  u32 gas;
  if (! pos->set)
    return pos->val.asn == asn;
    return ((pos->val.asn >= asn) && (pos->val.asn <= asn2));

  u8 *p = pos->val.sp;
  int len = *p++;
  int i;

  for (i = 0; i < len; i++)
    if (get_as(p + i * BS) == asn)
  {
    gas = get_as(p + i * BS);

    if ((gas >= asn) && (gas <= asn2))
      return 1;
  }

  return 0;
}
@@ -490,7 +495,7 @@ pm_mark(struct pm_pos *pos, int i, int plen, int *nl, int *nh)
 * next part of mask, we advance each marked state.
 * We start with marked first position, when we
 * run out of marked positions, we reject. When
 * we process the whole mask, we accept iff final position
 * we process the whole mask, we accept if final position
 * (auxiliary position after last real position in AS path)
 * is marked.
 */
@@ -502,6 +507,7 @@ as_path_match(struct adata *path, struct f_path_mask *mask)
  int plen = parse_path(path, pos);
  int l, h, i, nh, nl;
  u32 val = 0;
  u32 val2 = 0;

  /* l and h are bound of interval of positions where
     are marked states */
@@ -525,11 +531,15 @@ as_path_match(struct adata *path, struct f_path_mask *mask)
	  h = plen;
	  break;

	case PM_ASN:
	  val = mask->val;
	case PM_ASN:	/* Define single ASN as ASN..ASN - very narrow interval */
	  val2 = val = mask->val;
	  goto step;
	case PM_ASN_EXPR:
	  val = f_eval_asn((struct f_inst *) mask->val);
	  val2 = val = f_eval_asn((struct f_inst *) mask->val);
	  goto step;
	case PM_ASN_RANGE:
	  val = mask->val;
	  val2 = mask->val2;
          goto step;
	case PM_QUESTION:
	step:
@@ -538,7 +548,7 @@ as_path_match(struct adata *path, struct f_path_mask *mask)
	    if (pos[i].mark)
	      {
		pos[i].mark = 0;
		if ((mask->kind == PM_QUESTION) || pm_match(pos + i, val))
		if ((mask->kind == PM_QUESTION) || pm_match(pos + i, val, val2))
		  pm_mark(pos, i, plen, &nl, &nh);
	      }

Loading