]> git.ipfire.org Git - thirdparty/FORT-validator.git/commitdiff
Fix SLURM issues, and compile warning.
authorpcarana <pc.moreno2099@gmail.com>
Wed, 21 Aug 2019 17:24:49 +0000 (12:24 -0500)
committerpcarana <pc.moreno2099@gmail.com>
Wed, 21 Aug 2019 17:24:49 +0000 (12:24 -0500)
-SLURM filters weren't correctly applied when the filter had a prefix and an asn, only the asn was taken into account.
-Another error at filters, if a prefix X covered ROA prefix Y, the ROA prefix wasn't filtered; so apply the filter as specified in RFC 8416.
-Remove compile warning '_BSD_SOURCE and _SVID_SOURCE are deprecated', and set '_DEFAULT_SOURCE' at generated code by asn1c 'GeneralizedTime.c'.

src/address.c
src/address.h
src/asn1/asn1c/GeneralizedTime.c
src/rtr/db/vrp.h
src/slurm/slurm_db.c
src/slurm/slurm_db.h

index 296584f93aee9fefd3600953166a0b8c331131f3..93e62e4d44769ce760dbe6721a913365a425ff82 100644 (file)
@@ -496,3 +496,32 @@ ipv6_prefix_validate(struct ipv6_prefix *prefix)
 
        return 0;
 }
+
+/*
+ * Check if @son_addr is covered by @f_addr prefix of @f_len length
+ */
+bool
+ipv4_covered(struct in_addr *f_addr, uint8_t f_len, struct in_addr *son_addr)
+{
+       return (son_addr->s_addr & ~be32_suffix_mask(f_len)) == f_addr->s_addr;
+}
+
+/*
+ * Check if @son_addr is covered by @f_addr prefix of @f_len length
+ */
+bool
+ipv6_covered(struct in6_addr *f_addr, uint8_t f_len, struct in6_addr *son_addr)
+{
+       struct in6_addr suffix;
+       unsigned int i;
+
+       memset(&suffix, 0, sizeof(suffix));
+       ipv6_suffix_mask(f_len, &suffix);
+
+       for (i = 0; i < 16; i++)
+               if ((son_addr->s6_addr[i] & ~suffix.s6_addr[i]) !=
+                   f_addr->s6_addr[i])
+                       return false;
+
+       return true;
+}
index 78f9fdb22286de4f64b137521d0c3015769f5fb4..fb6e1e7a2dc536713dac377eea39be65fbe2ae18 100644 (file)
@@ -47,4 +47,7 @@ int prefix_length_parse(const char *, uint8_t *, uint8_t);
 int ipv4_prefix_validate(struct ipv4_prefix *);
 int ipv6_prefix_validate(struct ipv6_prefix *);
 
+bool ipv4_covered(struct in_addr *, uint8_t, struct in_addr *);
+bool ipv6_covered(struct in6_addr *, uint8_t, struct in6_addr *);
+
 #endif /* SRC_ADDRESS_H_ */
index dd4c386a0fbb92f7e365915f3b5fe766c44931b1..11515c5c2e1beb3575d4edc70f5346556dd32d72 100644 (file)
@@ -5,6 +5,9 @@
 #define        _POSIX_PTHREAD_SEMANTICS        /* for Sun */
 #define        _REENTRANT                      /* for Sun */
 #define __EXTENSIONS__                  /* for Sun */
+#ifndef _DEFAULT_SOURCE
+#define _DEFAULT_SOURCE 1
+#endif
 #ifndef _BSD_SOURCE
 #define _BSD_SOURCE     /* for timegm(3) */
 #endif
index 70d5503c289dbcdc3bc9c2b774a71070f15bdaf3..d083f09786f39855b5275a72381cd6b01f08c8d4 100644 (file)
@@ -3,6 +3,7 @@
 
 #include <stdint.h>
 #include <netinet/in.h>
+#include "address.h"
 
 #define FLAG_WITHDRAWAL                0
 #define FLAG_ANNOUNCEMENT      1
 #define VRP_MAX_PREFIX_LEN_EQ(a, b)                                    \
        (a)->max_prefix_length == (b)->max_prefix_length
 
+#define SAME_ADDR_FAM(a, b, fam)                                       \
+       (a)->addr_fam == fam &&                                         \
+       (b)->addr_fam == fam
+
 #define VRP_PREFIX_V4_EQ(a, b)                                         \
-       ((a)->addr_fam == AF_INET &&                                    \
-       (b)->addr_fam == AF_INET &&                                     \
+       (SAME_ADDR_FAM(a, b, AF_INET) &&                                \
        (a)->prefix.v4.s_addr == (b)->prefix.v4.s_addr &&               \
        (a)->prefix_length == (b)->prefix_length)
 
+#define VRP_PREFIX_V4_COV(a, b)                                                \
+       (SAME_ADDR_FAM(a, b, AF_INET) &&                                \
+       ipv4_covered(&(a)->prefix.v4, (a)->prefix_length,               \
+           &(b)->prefix.v4) &&                                         \
+       (a)->prefix_length <= (b)->prefix_length)
+
 #define VRP_PREFIX_V6_EQ(a, b)                                         \
-       ((a)->addr_fam == AF_INET6 &&                                   \
-       (b)->addr_fam == AF_INET6 &&                                    \
+       (SAME_ADDR_FAM(a, b, AF_INET6) &&                               \
        IN6_ARE_ADDR_EQUAL(&(a)->prefix.v6, &(b)->prefix.v6) &&         \
        (a)->prefix_length == (b)->prefix_length)
 
+#define VRP_PREFIX_V6_COV(a, b)                                                \
+       (SAME_ADDR_FAM(a, b, AF_INET6) &&                               \
+       ipv6_covered(&(a)->prefix.v6, (a)->prefix_length,               \
+           &(b)->prefix.v6) &&                                         \
+       (a)->prefix_length <= (b)->prefix_length)
+
 #define VRP_PREFIX_EQ(a, b)                                            \
        (VRP_PREFIX_V4_EQ(a, b) || VRP_PREFIX_V6_EQ(a, b))
 
+/* Checks if 'a' equals or covers 'b' */
+#define VRP_PREFIX_COV(a, b)                                           \
+       (VRP_PREFIX_V4_COV(a, b) || VRP_PREFIX_V6_COV(a, b))
+
 #define VRP_EQ(a, b)                                                   \
        (VRP_ASN_EQ(a, b) && VRP_PREFIX_EQ(a, b) && VRP_MAX_PREFIX_LEN_EQ(a, b))
 
index fa0dfd9583b1e197f864d843ad8f0772b8cd54d1..57dc8331dca115d426c039f925dacbb040724295 100644 (file)
@@ -38,13 +38,20 @@ slurm_db_init(void)
 }
 
 static bool
-prefix_filtered_by(struct slurm_prefix *filter, struct slurm_prefix *prefix)
+prefix_filtered_by(struct slurm_prefix *filter, struct slurm_prefix *prefix,
+    bool exact_match)
 {
        struct vrp *filter_vrp, *prefix_vrp;
 
        filter_vrp = &filter->vrp;
        prefix_vrp = &prefix->vrp;
 
+       /* The filter has ASN and prefix */
+       if (exact_match && (filter->data_flag & ~SLURM_COM_FLAG_COMMENT) ==
+           (SLURM_COM_FLAG_ASN | SLURM_PFX_FLAG_PREFIX))
+               return VRP_ASN_EQ(filter_vrp, prefix_vrp) &&
+                   VRP_PREFIX_COV(filter_vrp, prefix_vrp);
+
        /* Both have ASN */
        if ((filter->data_flag & SLURM_COM_FLAG_ASN) > 0 &&
            (prefix->data_flag & SLURM_COM_FLAG_ASN) > 0)
@@ -53,7 +60,7 @@ prefix_filtered_by(struct slurm_prefix *filter, struct slurm_prefix *prefix)
        /* Both have a prefix of the same type */
        if ((filter->data_flag & SLURM_PFX_FLAG_PREFIX) > 0 &&
            (prefix->data_flag & SLURM_PFX_FLAG_PREFIX) > 0)
-               return VRP_PREFIX_EQ(filter_vrp, prefix_vrp);
+               return VRP_PREFIX_COV(filter_vrp, prefix_vrp);
 
        return false;
 }
@@ -84,12 +91,16 @@ prefix_contained(struct slurm_prefix_ctx *left_ctx, struct slurm_prefix *right,
 
        return (left->data_flag & SLURM_PFX_FLAG_PREFIX) > 0 &&
            (right->data_flag & SLURM_PFX_FLAG_PREFIX) > 0 &&
-           VRP_PREFIX_EQ(left_vrp, right_vrp);
+           VRP_PREFIX_COV(left_vrp, right_vrp);
 }
 
+/*
+ * @left_ctx is the prefix loaded from SLURM, @right is the VRP "masked" as a
+ * slurm prefix
+ */
 static bool
 prefix_equal(struct slurm_prefix_ctx *left_ctx, struct slurm_prefix *right,
-    int ctx, bool filter)
+    int ctx, bool filter, bool exact_match)
 {
        struct slurm_prefix *left;
        struct vrp *left_vrp, *right_vrp;
@@ -102,30 +113,40 @@ prefix_equal(struct slurm_prefix_ctx *left_ctx, struct slurm_prefix *right,
        if (prefix_contained(left_ctx, right, ctx))
                return true;
 
-       /* Ignore the comments */
+       /*
+        * Ignore the comments, remember: FILTERS don't have the same data (no
+        * max_length is declared), while ASSERTIONS do.
+        */
        if ((left->data_flag & ~SLURM_COM_FLAG_COMMENT) !=
            (right->data_flag & ~SLURM_COM_FLAG_COMMENT))
-               return filter && prefix_filtered_by(left, right);
+               return filter && prefix_filtered_by(left, right, exact_match);
 
        /* It has the same data, compare it */
        equal = true;
-       if ((left->data_flag & SLURM_COM_FLAG_ASN) > 0)
-               equal = equal && VRP_ASN_EQ(left_vrp, right_vrp);
+       if (equal && (left->data_flag & SLURM_COM_FLAG_ASN) > 0)
+               equal = VRP_ASN_EQ(left_vrp, right_vrp);
 
-       if ((left->data_flag & SLURM_PFX_FLAG_PREFIX) > 0)
-               equal = equal && VRP_PREFIX_EQ(left_vrp, right_vrp);
+       if (equal && (left->data_flag & SLURM_PFX_FLAG_PREFIX) > 0)
+               equal = (filter ?
+                   VRP_PREFIX_COV(left_vrp, right_vrp) :
+                   VRP_PREFIX_EQ(left_vrp, right_vrp));
 
-       if ((left->data_flag & SLURM_PFX_FLAG_MAX_LENGTH) > 0)
-               equal = equal &&
-                   ((left->data_flag & SLURM_PFX_FLAG_MAX_LENGTH) > 0) &&
-                   VRP_MAX_PREFIX_LEN_EQ(left_vrp, right_vrp);
+       if (equal && (left->data_flag & SLURM_PFX_FLAG_MAX_LENGTH) > 0)
+               equal = VRP_MAX_PREFIX_LEN_EQ(left_vrp, right_vrp);
 
        return equal;
 }
 
 static bool
-bgpsec_filtered_by(struct slurm_bgpsec *bgpsec, struct slurm_bgpsec *filter)
+bgpsec_filtered_by(struct slurm_bgpsec *bgpsec, struct slurm_bgpsec *filter,
+    bool exact_match)
 {
+       /* The filter has ASN and SKI */
+       if (exact_match && (filter->data_flag & ~SLURM_COM_FLAG_COMMENT) ==
+           (SLURM_COM_FLAG_ASN | SLURM_BGPS_FLAG_SKI))
+               return bgpsec->asn == filter->asn &&
+                   memcmp(bgpsec->ski, filter->ski, bgpsec->ski_len) == 0;
+
        /* Both have ASN */
        if ((bgpsec->data_flag & SLURM_COM_FLAG_ASN) > 0 &&
            (filter->data_flag & SLURM_COM_FLAG_ASN) > 0)
@@ -167,7 +188,7 @@ bgpsec_contained(struct slurm_bgpsec_ctx *left_ctx, struct slurm_bgpsec *right,
 
 static bool
 bgpsec_equal(struct slurm_bgpsec_ctx *left_ctx, struct slurm_bgpsec *right,
-    int ctx, bool filter)
+    int ctx, bool filter, bool exact_filter)
 {
        struct slurm_bgpsec *left;
        bool equal;
@@ -180,20 +201,19 @@ bgpsec_equal(struct slurm_bgpsec_ctx *left_ctx, struct slurm_bgpsec *right,
        /* Ignore the comments */
        if ((left->data_flag & ~SLURM_COM_FLAG_COMMENT) !=
            (right->data_flag & ~SLURM_COM_FLAG_COMMENT))
-               return filter && bgpsec_filtered_by(left, right);
+               return filter && bgpsec_filtered_by(left, right, exact_filter);
 
        /* It has the same data, compare it */
        equal = true;
-       if ((left->data_flag & SLURM_COM_FLAG_ASN) > 0)
-               equal = equal && left->asn == right->asn;
+       if (equal && (left->data_flag & SLURM_COM_FLAG_ASN) > 0)
+               equal = left->asn == right->asn;
 
-       if ((left->data_flag & SLURM_BGPS_FLAG_SKI) > 0)
-               equal = equal && left->ski_len == right->ski_len &&
+       if (equal && (left->data_flag & SLURM_BGPS_FLAG_SKI) > 0)
+               equal = left->ski_len == right->ski_len &&
                    memcmp(left->ski, right->ski, left->ski_len) == 0;
 
-       if ((left->data_flag & SLURM_BGPS_FLAG_ROUTER_KEY) > 0)
-               equal = equal &&
-                   left->router_public_key_len ==
+       if (equal && (left->data_flag & SLURM_BGPS_FLAG_ROUTER_KEY) > 0)
+               equal = left->router_public_key_len ==
                    right->router_public_key_len &&
                    memcmp(left->router_public_key, right->router_public_key,
                    left->router_public_key_len) == 0;
@@ -204,15 +224,18 @@ bgpsec_equal(struct slurm_bgpsec_ctx *left_ctx, struct slurm_bgpsec *right,
 #define ADD_FUNCS(name, type, list_name, db_list, db_alt_list, equal_cb,\
     cont_cb, filter)                                                   \
        static type *                                                   \
-       name##_locate(type *obj, int ctx)                               \
+       name##_locate(type *obj, bool flt, int ctx)                     \
        {                                                               \
                type##_ctx *cursor;                                     \
                array_index i;                                          \
                                                                        \
                ARRAYLIST_FOREACH(db_list, cursor, i)                   \
-                       if (equal_cb(cursor, obj, ctx, filter))         \
+                       if (equal_cb(cursor, obj, ctx, filter, flt))    \
                                return &cursor->element;                \
                                                                        \
+               if (ctx < 0)                                            \
+                       return NULL; /* Avoid the next loop */          \
+                                                                       \
                ARRAYLIST_FOREACH(db_alt_list, cursor, i)               \
                        if (cont_cb(cursor, obj, ctx))                  \
                                return &cursor->element;                \
@@ -221,15 +244,16 @@ bgpsec_equal(struct slurm_bgpsec_ctx *left_ctx, struct slurm_bgpsec *right,
        }                                                               \
                                                                        \
        static bool                                                     \
-       name##_exists(type *obj, int ctx)                               \
+       name##_exists(type *obj, bool flt, int ctx)                     \
        {                                                               \
-               return name##_locate(obj, ctx) != NULL;                 \
+               return name##_locate(obj, flt, ctx) != NULL;            \
        }                                                               \
                                                                        \
        int                                                             \
-       slurm_db_add_##name(type *elem, int ctx) {                      \
+       slurm_db_add_##name(type *elem, int ctx)                        \
+       {                                                               \
                type##_ctx new_elem;                                    \
-               if (name##_exists(elem, ctx))                           \
+               if (name##_exists(elem, !filter, ctx))                  \
                        return -EEXIST;                                 \
                new_elem.element = *elem;                               \
                new_elem.ctx = ctx;                                     \
@@ -259,7 +283,7 @@ slurm_db_vrp_is_filtered(struct vrp const *vrp)
        slurm_prefix.vrp = *vrp;
        slurm_prefix.comment = NULL;
 
-       return prefix_filter_exists(&slurm_prefix, -1);
+       return prefix_filter_exists(&slurm_prefix, true, -1);
 }
 
 int
index f664f2f7ea5acebe900c582f17bf097f52f9a3b6..6f4d41a51e778eb5c1872c550bce8b5bbdb6d994 100644 (file)
@@ -3,6 +3,7 @@
 
 #include <stdbool.h>
 #include "slurm/slurm_parser.h"
+#include "rtr/db/vrp.h"
 
 typedef int (*assertion_pfx_foreach_cb)(struct slurm_prefix *, void *);