From: pcarana Date: Wed, 21 Aug 2019 17:24:49 +0000 (-0500) Subject: Fix SLURM issues, and compile warning. X-Git-Tag: v1.0.0^2~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0d317eb82236ca6abed50f0f3b3ff4e4145cedb7;p=thirdparty%2FFORT-validator.git Fix SLURM issues, and compile warning. -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'. --- diff --git a/src/address.c b/src/address.c index 296584f9..93e62e4d 100644 --- a/src/address.c +++ b/src/address.c @@ -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; +} diff --git a/src/address.h b/src/address.h index 78f9fdb2..fb6e1e7a 100644 --- a/src/address.h +++ b/src/address.h @@ -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_ */ diff --git a/src/asn1/asn1c/GeneralizedTime.c b/src/asn1/asn1c/GeneralizedTime.c index dd4c386a..11515c5c 100644 --- a/src/asn1/asn1c/GeneralizedTime.c +++ b/src/asn1/asn1c/GeneralizedTime.c @@ -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 diff --git a/src/rtr/db/vrp.h b/src/rtr/db/vrp.h index 70d5503c..d083f097 100644 --- a/src/rtr/db/vrp.h +++ b/src/rtr/db/vrp.h @@ -3,6 +3,7 @@ #include #include +#include "address.h" #define FLAG_WITHDRAWAL 0 #define FLAG_ANNOUNCEMENT 1 @@ -13,21 +14,39 @@ #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)) diff --git a/src/slurm/slurm_db.c b/src/slurm/slurm_db.c index fa0dfd95..57dc8331 100644 --- a/src/slurm/slurm_db.c +++ b/src/slurm/slurm_db.c @@ -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 diff --git a/src/slurm/slurm_db.h b/src/slurm/slurm_db.h index f664f2f7..6f4d41a5 100644 --- a/src/slurm/slurm_db.h +++ b/src/slurm/slurm_db.h @@ -3,6 +3,7 @@ #include #include "slurm/slurm_parser.h" +#include "rtr/db/vrp.h" typedef int (*assertion_pfx_foreach_cb)(struct slurm_prefix *, void *);