]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Add AS# ranges to bgpmask.
authorOndrej Filip <feela@network.cz>
Wed, 8 Jun 2016 14:22:44 +0000 (16:22 +0200)
committerOndrej Filip <feela@network.cz>
Wed, 8 Jun 2016 14:22:44 +0000 (16:22 +0200)
doc/bird.sgml
filter/config.Y
filter/filter.c
filter/test.conf
nest/a-path.c
nest/attrs.h

index f3c34a14adb35a09e57f3db1914bc8cb62ee451d..de7041a91b8b8a8db0ea8e488d22471311459824 100644 (file)
@@ -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
index b94f5dfff0be4fe7abb22df66fd3b57111bed64e..e53d8def04e57066a9311f9ebf12ebc6e2236572 100644 (file)
@@ -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; }
index eddf4228cb6d94243d9d863e51c76d20412d6892..dce98e4d32c0ef1e32fb8fe710353372f8c50b4f 100644 (file)
@@ -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;
index a99d0a516ce28045013648dc6bad234d98b7516d..ad8f9386cc7903f4bd28f9ad2bd4690d4e4cbb73 100644 (file)
@@ -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;
index 32e2d27eb184de7638e116bfcbe366513a830af9..e1031b7bde06a6d8cc43edf235c7ad8b598e8ca6 100644 (file)
@@ -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,12 +531,16 @@ 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:
          nh = nl = -1;
@@ -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);
              }
 
index 0171c6a8fe509e8633688079a6a97864954aa459..670b048f26843dbf7d524f8d9bce13dad8ccdf6f 100644 (file)
@@ -45,11 +45,13 @@ struct adata *as_path_filter(struct linpool *pool, struct adata *path, struct f_
 #define PM_QUESTION    1
 #define PM_ASTERISK    2
 #define PM_ASN_EXPR    3
+#define PM_ASN_RANGE   4
 
 struct f_path_mask {
   struct f_path_mask *next;
   int kind;
   uintptr_t val;
+  uintptr_t val2;
 };
 
 int as_path_match(struct adata *path, struct f_path_mask *mask);