]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Int sets moved to core. It is now possible to have variable of type clist.
authorPavel Machek <pavel@ucw.cz>
Mon, 17 Apr 2000 11:34:38 +0000 (11:34 +0000)
committerPavel Machek <pavel@ucw.cz>
Mon, 17 Apr 2000 11:34:38 +0000 (11:34 +0000)
filter/config.Y
filter/filter.c
filter/test.conf
nest/a-set.c
nest/attrs.h

index 6ce89e7acab8d22c186b9abc1c05cee70ec7daa7..9cdc8159aacf323bf62114fa84294ec8e432aab8 100644 (file)
@@ -390,6 +390,7 @@ term:
        case SYM_VARIABLE | T_IP:
        case SYM_VARIABLE | T_PATH_MASK:
        case SYM_VARIABLE | T_PATH:
+       case SYM_VARIABLE | T_CLIST:
         $$->code = 'C';
         $$->a1.p = $1->aux2;
         break;
@@ -423,7 +424,11 @@ term:
  | term '.' RESET { }
 
  | '+' EMPTY '+' { $$ = f_new_inst(); $$->code = 'E'; $$->aux = T_PATH; }
+ | '-' EMPTY '-' { $$ = f_new_inst(); $$->code = 'E'; $$->aux = T_CLIST; }
  | PREPEND '(' term ',' term ')' { $$ = f_new_inst(); $$->code = P('A','p'); $$->a1.p = $3; $$->a2.p = $5; } 
+/* | ADD '(' term, ',' term ')' { $$ = f_new_inst(); $$->code = P('C','a'); $$->a1.p = $3; $$->a2.p = $5; $$->aux = 'a'; } 
+ | DELETE '(' term, ',' term ')' { $$ = f_new_inst(); $$->code = P('C','a'); $$->a1.p = $3; $$->a2.p = $5; $$->aux = 'd'; } */
 
 /* | term '.' LEN { $$->code = P('P','l'); } */
 
index 267fa166f90c0292b9ba4874717b653feec76381..d9ef65a4ca8c500daad5cc07ac6909bfde00ebf5 100644 (file)
@@ -483,6 +483,21 @@ interpret(struct f_inst *what)
     res.val.ad = as_path_prepend(f_pool, v1.val.ad, v2.val.i);
     break;
 
+  case P('C','a'):     /* Community list add or delete */
+    TWOARGS;
+    if (v1.type != T_CLIST)
+      runtime("Can't add/delete to non-clist");
+    if (v2.type != T_PAIR)
+      runtime("Can't add/delete non-pair");
+
+    res.type = T_CLIST;
+    switch (what->aux) {
+    case 'a': res.val.ad = int_set_add(f_pool, v1.val.ad, v2.val.i); break;
+    case 'd': res.val.ad = int_set_del(f_pool, v1.val.ad, v2.val.i); break;
+    default: bug("unknown Ca operation");
+    }
+    break;
+
   default:
     bug( "Unknown instruction %d (%c)", what->code, what->code & 0xff);
   }
@@ -566,6 +581,7 @@ i_same(struct f_inst *f1, struct f_inst *f2)
   case P('S','W'): ONEARG; if (!same_tree(f1->a2.p, f2->a2.p)) return 0; break;
   case P('i','M'): TWOARGS; break;
   case P('A','p'): TWOARGS; break;
+  case P('C','a'): TWOARGS; break;
   default:
     bug( "Unknown instruction %d in same (%c)", f1->code, f1->code & 0xff);
   }
index a39e6a3d65aae69ba3c9f1f4b08366f8bd1f6d6b..abe9d3fd30201b32feeb4b7942b3d09c00450563 100644 (file)
@@ -32,6 +32,7 @@ function fifteen()
 function paths()
 bgpmask p;
 bgppath p2;
+clist l;
 {
        p = / 4 3 2 1 /;
        print "Testing path masks: ", p;
@@ -46,6 +47,10 @@ bgppath p2;
        print "Should be false: ", p2 ~ p;
        print "Should be true: ", p2 ~ / * 4 3 2 1 /, p2, / * 4 3 2 1 /;
        print "5 = ", p2.len;
+
+       l = - empty -;
+       l = add( l, (1,2) );
+       print "Community list ", l;
 }
 
 function startup() 
index deef5df8ec790d981268d9d9d952143b94535383..1d2cebff6405757b8f85b48842cec0bebc4111d9 100644 (file)
@@ -38,3 +38,46 @@ int_set_format(struct adata *set, byte *buf, unsigned int size)
     }
   *buf = 0;
 }
+
+struct adata *
+int_set_add(struct linpool *pool, struct adata *list, u32 val)
+{
+  struct adata *res = lp_alloc(pool, list->length + sizeof(struct adata) + 4);
+  res->length = list->length+4;
+  * (u32 *) res->data = val;
+  memcpy((char *) res->data + 4, list->data, list->length);
+  return res;
+}
+
+int
+int_set_contains(struct adata *list, u32 val)
+{
+  u32 *l = &(list->data);
+  int i;
+  for (i=0; i<list->length/4; i++)
+    if (*l++ == val)
+      return 1;
+  return 0;
+}
+
+struct adata *
+int_set_del(struct linpool *pool, struct adata *list, u32 val)
+{
+  struct adata *res;
+  u32 *l, *k;
+  int i;
+
+  if (!int_set_contains(list, val))
+    return list;
+
+  res = lp_alloc(pool, list->length + sizeof(struct adata) - 4);
+  res->length = list->length-4;
+
+  l = &(list->data);
+  k = &(res->data);
+  for (i=0; i<list->length/4; i++)
+    if (l[i] != val)
+      *k++ = l[i];
+
+  return res;
+}
index ede152ce84734c98514ad24b2507b505ab7f5859..630550f30482d057182288cdf95126ad7fe5a794 100644 (file)
@@ -29,5 +29,9 @@ int as_path_match(struct adata *path, struct f_path_mask *mask);
 /* a-set.c */
 
 void int_set_format(struct adata *set, byte *buf, unsigned int size);
+struct adata *int_set_add(struct linpool *pool, struct adata *list, u32 val);
+int int_set_contains(struct adata *list, u32 val);
+struct adata *int_set_del(struct linpool *pool, struct adata *list, u32 val);
+
 
 #endif