]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Filter: Add operators to pick community components
authorAlexander Zubkov <green@qrator.net>
Tue, 28 Dec 2021 02:46:13 +0000 (03:46 +0100)
committerOndrej Zajicek (work) <santiago@crfreenet.org>
Tue, 28 Dec 2021 03:07:00 +0000 (04:07 +0100)
Add operators that can be used to pick components from
pair (standard community) or lc (large community) types.
For example:

(10, 20).asn --> 10
(10, 20).data --> 20

(10, 20, 30).asn --> 10
(10, 20, 30).data1 --> 20
(10, 20, 30).data2 --> 30

Signed-off-by: Alexander Zubkov <green@qrator.net>
filter/config.Y
filter/f-inst.c
filter/test.conf

index 7820e719d65298e2a16c07203a8e706ff9c50794..2fb55e4e7a1e8df10cc5f6ccd2650865e7113c3a 100644 (file)
@@ -283,6 +283,7 @@ CF_KEYWORDS(FUNCTION, PRINT, PRINTN, UNSET, RETURN,
        ROA_CHECK, ASN, SRC, DST,
        IS_V4, IS_V6,
        LEN, MAXLEN,
+       DATA, DATA1, DATA2,
        DEFINED,
        ADD, DELETE, CONTAINS, RESET,
        PREPEND, FIRST, LAST, LAST_NONAGGREGATED, MATCH,
@@ -789,13 +790,16 @@ term:
  | term '.' RD { $$ = f_new_inst(FI_ROUTE_DISTINGUISHER, $1); }
  | term '.' LEN { $$ = f_new_inst(FI_LENGTH, $1); }
  | term '.' MAXLEN { $$ = f_new_inst(FI_ROA_MAXLEN, $1); }
- | term '.' ASN { $$ = f_new_inst(FI_ROA_ASN, $1); }
+ | term '.' ASN { $$ = f_new_inst(FI_ASN, $1); }
  | term '.' SRC { $$ = f_new_inst(FI_NET_SRC, $1); }
  | term '.' DST { $$ = f_new_inst(FI_NET_DST, $1); }
  | term '.' MASK '(' term ')' { $$ = f_new_inst(FI_IP_MASK, $1, $5); }
  | term '.' FIRST { $$ = f_new_inst(FI_AS_PATH_FIRST, $1); }
  | term '.' LAST  { $$ = f_new_inst(FI_AS_PATH_LAST, $1); }
  | term '.' LAST_NONAGGREGATED  { $$ = f_new_inst(FI_AS_PATH_LAST_NAG, $1); }
+ | term '.' DATA { $$ = f_new_inst(FI_PAIR_DATA, $1); }
+ | term '.' DATA1 { $$ = f_new_inst(FI_LC_DATA1, $1); }
+ | term '.' DATA2 { $$ = f_new_inst(FI_LC_DATA2, $1); }
 
 /* Communities */
 /* This causes one shift/reduce conflict
index b876a937226583aa6ce58b436489399c3026c5c7..7e9e77d239cb1214b120618b9b2835f76dad61b0 100644 (file)
       ((net_addr_roa6 *) v1.val.net)->max_pxlen);
   }
 
-  INST(FI_ROA_ASN, 1, 1) {     /* Get ROA ASN */
-    ARG(1, T_NET);
-    if (!net_is_roa(v1.val.net))
-      runtime( "ROA expected" );
+  INST(FI_ASN, 1, 1) {         /* Get ROA ASN or community ASN part */
+    ARG_ANY(1);
+    RESULT_TYPE(T_INT);
+    switch(v1.type)
+    {
+      case T_NET:
+        if (!net_is_roa(v1.val.net))
+          runtime( "ROA expected" );
 
-    RESULT(T_INT, i, (v1.val.net->type == NET_ROA4) ?
-      ((net_addr_roa4 *) v1.val.net)->asn :
-      ((net_addr_roa6 *) v1.val.net)->asn);
+        RESULT_(T_INT, i, (v1.val.net->type == NET_ROA4) ?
+          ((net_addr_roa4 *) v1.val.net)->asn :
+          ((net_addr_roa6 *) v1.val.net)->asn);
+        break;
+
+      case T_PAIR:
+        RESULT_(T_INT, i, v1.val.i >> 16);
+        break;
+
+      case T_LC:
+        RESULT_(T_INT, i, v1.val.lc.asn);
+        break;
+
+      default:
+        runtime( "Net, pair or lc expected" );
+    }
   }
 
   INST(FI_IP, 1, 1) {  /* Convert prefix to ... */
     RESULT(T_INT, i, as_path_get_last_nonaggregated(v1.val.ad));
   }
 
+  INST(FI_PAIR_DATA, 1, 1) {   /* Get data part from the standard community */
+    ARG(1, T_PAIR);
+    RESULT(T_INT, i, v1.val.i & 0xFFFF);
+  }
+
+  INST(FI_LC_DATA1, 1, 1) {    /* Get data1 part from the large community */
+    ARG(1, T_LC);
+    RESULT(T_INT, i, v1.val.lc.ldp1);
+  }
+
+  INST(FI_LC_DATA2, 1, 1) {    /* Get data2 part from the large community */
+    ARG(1, T_LC);
+    RESULT(T_INT, i, v1.val.lc.ldp2);
+  }
+
   INST(FI_RETURN, 1, 1) {
     NEVER_CONSTANT;
     /* Acquire the return value */
index 3a8804a1554f20e5c027b86f4ad4813796bb9bea..6f2f6fb56ed748e6a75998e21a319cf132f36ef0 100644 (file)
@@ -684,6 +684,11 @@ clist l;
 clist l2;
 clist r;
 {
+       bt_assert((10, 20).asn = 10);
+       bt_assert((10, 20).data = 20);
+       bt_assert(p23.asn = 2);
+       bt_assert(p23.data = 3);
+
        l = - empty -;
        bt_assert(l !~ [(*,*)]);
        bt_assert((l ~ [(*,*)]) != (l !~ [(*,*)]));
@@ -940,6 +945,10 @@ lclist r;
        bt_assert(---empty--- = ---empty---);
        bt_assert((10, 20, 30) !~ ---empty---);
 
+       bt_assert((10, 20, 30).asn = 10);
+       bt_assert((10, 20, 30).data1 = 20);
+       bt_assert((10, 20, 30).data2 = 30);
+
        ll = --- empty ---;
        ll = add(ll, (ten, 20, 30));
        ll = add(ll, (1000, 2000, 3000));