]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Nest: Cleanups in as_path_filter()
authorOndrej Zajicek (work) <santiago@crfreenet.org>
Fri, 4 Mar 2022 01:01:34 +0000 (02:01 +0100)
committerOndrej Zajicek (work) <santiago@crfreenet.org>
Fri, 4 Mar 2022 01:24:28 +0000 (02:24 +0100)
Use struct f_val as a common argument for as_path_filter(), as suggested
by Alexander Zubkov. That allows to use NULL sets as valid arguments.

filter/data.h
filter/f-inst.c
nest/a-path.c
nest/a-path_test.c
nest/attrs.h

index 4cb6b7a8b2419825fed706bcac8eb2f9827ce7ce..8cba8c0efba3ab5fc3463d4f0675781f55f2dc32 100644 (file)
@@ -282,6 +282,8 @@ static inline int eclist_set_type(const struct f_tree *set)
 { return set->from.type == T_EC; }
 static inline int lclist_set_type(const struct f_tree *set)
 { return set->from.type == T_LC; }
+static inline int path_set_type(const struct f_tree *set)
+{ return 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);
index 2a02c8e5a5ead2c6995883e26b9afcb8394e07db..5d42c40aabe20e2266dc3f03618c811e2e3a5339 100644 (file)
     RESULT(T_INT, i, v1.val.lc.ldp2);
   }
 
-  INST(FI_MIN, 1, 1) { /* Get minimum element from set */
+  INST(FI_MIN, 1, 1) { /* Get minimum element from list */
     ARG_ANY(1);
     RESULT_TYPE(f_type_element_type(v1.type));
     switch(v1.type)
     }
   }
 
-  INST(FI_MAX, 1, 1) { /* Get maximum element from set */
+  INST(FI_MAX, 1, 1) { /* Get maximum element from list */
     ARG_ANY(1);
     RESULT_TYPE(f_type_element_type(v1.type));
     switch(v1.type)
 
     if (v1.type == T_PATH)
     {
-      const struct f_tree *set = NULL;
-      u32 key = 0;
-
-      if (v2.type == T_INT)
-       key = v2.val.i;
-      else if ((v2.type == T_SET) && (v2.val.t->from.type == T_INT))
-       set = v2.val.t;
+      if ((v2.type == T_SET) && path_set_type(v2.val.t) || (v2.type == T_INT))
+       RESULT_(T_PATH, ad, [[ as_path_filter(fpool, v1.val.ad, &v2, 0) ]]);
       else
        runtime("Can't delete non-integer (set)");
-
-      RESULT_(T_PATH, ad, [[ as_path_filter(fpool, v1.val.ad, set, key, 0) ]]);
     }
 
     else if (v1.type == T_CLIST)
 
     if (v1.type == T_PATH)
     {
-      u32 key = 0;
-
-      if ((v2.type == T_SET) && (v2.val.t->from.type == T_INT))
-       RESULT_(T_PATH, ad, [[ as_path_filter(fpool, v1.val.ad, v2.val.t, key, 1) ]]);
+      if ((v2.type == T_SET) && path_set_type(v2.val.t))
+       RESULT_(T_PATH, ad, [[ as_path_filter(fpool, v1.val.ad, &v2, 1) ]]);
       else
        runtime("Can't filter integer");
     }
index 2e34a3d1c2eaf16cf8df4641652b9ec35a34cb1c..d5b01635e9d22b1b177dab0dff4862bd75331f54 100644 (file)
@@ -602,8 +602,10 @@ as_path_match_set(const struct adata *path, const struct f_tree *set)
 }
 
 const struct adata *
-as_path_filter(struct linpool *pool, const struct adata *path, const struct f_tree *set, u32 key, int pos)
+as_path_filter(struct linpool *pool, const struct adata *path, const struct f_val *set, int pos)
 {
+  ASSERT((set->type == T_SET) || (set->type == T_INT));
+
   if (!path)
     return NULL;
 
@@ -629,13 +631,13 @@ as_path_filter(struct linpool *pool, const struct adata *path, const struct f_tr
          u32 as = get_as(p);
          int match;
 
-         if (set)
+         if (set->type == T_SET)
            {
              struct f_val v = {T_INT, .val.i = as};
-             match = !!find_tree(set, &v);
+             match = !!find_tree(set->val.t, &v);
            }
-         else
-           match = (as == key);
+         else /* T_INT */
+           match = (as == set->val.i);
 
          if (match == pos)
            {
index 9ed0a786d56dbcb495b3f00bb41290d08b18cb94..97924c006eb6b33b3b3598101b1d4c545e7263e0 100644 (file)
@@ -12,6 +12,7 @@
 #include "nest/route.h"
 #include "nest/attrs.h"
 #include "lib/resource.h"
+#include "filter/data.h"
 
 #define TESTS_NUM 30
 #define AS_PATH_LENGTH 1000
@@ -136,8 +137,9 @@ t_path_include(void)
     int counts_of_contains = count_asn_in_array(as_nums, as_nums[i]);
     bt_assert_msg(as_path_contains(as_path, as_nums[i], counts_of_contains), "AS Path should contains %d-times number %d", counts_of_contains, as_nums[i]);
 
-    bt_assert(as_path_filter(lp, as_path, NULL, as_nums[i], 0) != NULL);
-    bt_assert(as_path_filter(lp, as_path, NULL, as_nums[i], 1) != NULL);
+    struct f_val v = { .type = T_INT, .val.i = as_nums[i] };
+    bt_assert(as_path_filter(lp, as_path, &v, 0) != NULL);
+    bt_assert(as_path_filter(lp, as_path, &v, 1) != NULL);
   }
 
   for (i = 0; i < 10000; i++)
index ef2b95e68e99caff31d313a72599dce2bf9fbad6..22e2ff4aa2f5a6551b6c5a94dd0be80017b3ab6f 100644 (file)
@@ -28,6 +28,7 @@
  * to 16bit slot (like in 16bit AS_PATH). See RFC 4893 for details
  */
 
+struct f_val;
 struct f_tree;
 
 int as_path_valid(byte *data, uint len, int bs, int sets, int confed, char *err, uint elen);
@@ -49,7 +50,7 @@ int as_path_get_last(const struct adata *path, u32 *last_as);
 u32 as_path_get_last_nonaggregated(const struct adata *path);
 int as_path_contains(const struct adata *path, u32 as, int min);
 int as_path_match_set(const struct adata *path, const struct f_tree *set);
-const struct adata *as_path_filter(struct linpool *pool, const struct adata *path, const struct f_tree *set, u32 key, int pos);
+const struct adata *as_path_filter(struct linpool *pool, const struct adata *path, const struct f_val *set, int pos);
 
 static inline struct adata *as_path_prepend(struct linpool *pool, const struct adata *path, u32 as)
 { return as_path_prepend2(pool, path, AS_PATH_SEQUENCE, as); }