From: Jan Maria Matejka Date: Thu, 7 Jun 2018 13:02:05 +0000 (+0200) Subject: WIP Nest: Making the clist/eclist/lclist even more generic X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9ca88473059f01db6d0a19821fd0ecea6db798ac;p=thirdparty%2Fbird.git WIP Nest: Making the clist/eclist/lclist even more generic --- diff --git a/filter/filter.c b/filter/filter.c index 4ca86de73..18ff15554 100644 --- a/filter/filter.c +++ b/filter/filter.c @@ -301,14 +301,10 @@ eclist_match_set(struct adata *list, struct f_tree *set) if (!eclist_set_type(set)) return CMP_ERROR; - struct f_val v; - u32 *l = int_set_get_data(list); - int len = int_set_get_size(list); - int i; - + struct f_val v = { .type = T_EC }; v.type = T_EC; - for (i = 0; i < len; i += 2) { - v.val.ec = ec_get(l, i); + for (void *p = list->data, *end = p + list->length; p < end; p += sizeof(u64)) { + memcpy(&v.val.ec, p, sizeof(u64)); if (find_tree(set, v)) return 1; } @@ -325,14 +321,10 @@ lclist_match_set(struct adata *list, struct f_tree *set) if (!lclist_set_type(set)) return CMP_ERROR; - struct f_val v; - u32 *l = int_set_get_data(list); - int len = int_set_get_size(list); - int i; - + struct f_val v = { .type = T_LC }; v.type = T_LC; - for (i = 0; i < len; i += 3) { - v.val.lc = lc_get(l, i); + for (void *p = list->data, *end = p + list->length; p < end; p += sizeof(lcomm)) { + memcpy(&v.val.ec, p, sizeof(lcomm)); if (find_tree(set, v)) return 1; } @@ -353,8 +345,8 @@ clist_filter(struct linpool *pool, struct adata *list, struct f_val set, int pos else v.type = T_PAIR; - int len = int_set_get_size(list); - u32 *l = int_set_get_data(list); + int len = list->length / 4; + u32 *l = (u32 *) list->data; u32 tmp[len]; u32 *k = tmp; u32 *end = l + len; @@ -384,15 +376,15 @@ eclist_filter(struct linpool *pool, struct adata *list, struct f_val set, int po int tree = (set.type == T_SET); /* 1 -> set is T_SET, 0 -> set is T_CLIST */ struct f_val v; - int len = int_set_get_size(list); - u32 *l = int_set_get_data(list); + int len = list->length / 4; + u32 *l = (u32 *) list->data; u32 tmp[len]; u32 *k = tmp; int i; v.type = T_EC; for (i = 0; i < len; i += 2) { - v.val.ec = ec_get(l, i); + memcpy(&(v.val.ec), &(l[i]), sizeof(u64)); /* pos && member(val, set) || !pos && !member(val, set), member() depends on tree */ if ((tree ? !!find_tree(set.val.t, v) : ec_set_contains(set.val.ad, v.val.ec)) == pos) { *k++ = l[i]; @@ -418,18 +410,21 @@ lclist_filter(struct linpool *pool, struct adata *list, struct f_val set, int po int tree = (set.type == T_SET); /* 1 -> set is T_SET, 0 -> set is T_CLIST */ struct f_val v; - int len = int_set_get_size(list); - u32 *l = int_set_get_data(list); + int len = list->length / 4; + u32 *l = (u32 *) list->data; u32 tmp[len]; u32 *k = tmp; int i; v.type = T_LC; for (i = 0; i < len; i += 3) { - v.val.lc = lc_get(l, i); + memcpy(&(v.val.lc), &(l[i]), sizeof(lcomm)); /* pos && member(val, set) || !pos && !member(val, set), member() depends on tree */ - if ((tree ? !!find_tree(set.val.t, v) : lc_set_contains(set.val.ad, v.val.lc)) == pos) - k = lc_copy(k, l+i); + if ((tree ? !!find_tree(set.val.t, v) : lc_set_contains(set.val.ad, v.val.lc)) != pos) + continue; + + memcpy(k, &(l[i]), sizeof(lcomm)); + k += sizeof(lcomm)/sizeof(u32); } uint nl = (k - tmp) * sizeof(u32); @@ -871,9 +866,9 @@ interpret(struct f_inst *what) switch(v1.type) { case T_NET: res.val.i = net_pxlen(v1.val.net); break; case T_PATH: res.val.i = as_path_getlen(v1.val.ad); break; - case T_CLIST: res.val.i = int_set_get_size(v1.val.ad); break; - case T_ECLIST: res.val.i = ec_set_get_size(v1.val.ad); break; - case T_LCLIST: res.val.i = lc_set_get_size(v1.val.ad); break; + case T_CLIST: res.val.i = v1.val.ad->length / 4; break; + case T_ECLIST: res.val.i = v1.val.ad->length / 8; break; + case T_LCLIST: res.val.i = v1.val.ad->length / 12; break; default: runtime( "Prefix, path, clist, eclist or lclist expected" ); } break; diff --git a/nest/a-set.c b/nest/a-set.c index 69d337354..c102a8e5f 100644 --- a/nest/a-set.c +++ b/nest/a-set.c @@ -117,10 +117,10 @@ ec_format(byte *buf, u64 ec) int ec_set_format(struct adata *set, int from, byte *buf, uint size) { - u32 *z = int_set_get_data(set); + u32 *z = (u32 *) set->data; byte *end = buf + size - 64; int from2 = MAX(from, 0); - int to = int_set_get_size(set); + int to = set->length / 4; int i; for (i = from2; i < to; i += 2) @@ -137,7 +137,9 @@ ec_set_format(struct adata *set, int from, byte *buf, uint size) if (i > from2) *buf++ = ' '; - buf += ec_format(buf, ec_get(z, i)); + u64 ec; + memcpy(&ec, &(z[i]), sizeof(u64)); + buf += ec_format(buf, ec); } *buf = 0; return 0; @@ -181,16 +183,16 @@ lc_set_format(struct adata *set, int from, byte *buf, uint bufsize) } int -set_position(struct adata *list, u32 *val, int skip) +set_position(struct adata *list, void *val, int size) { if (!list) return -1; - u32 *l = int_set_get_data(list); - int len = list->length / (skip * 4); + int len = list->length / size; + void *l = list->data; for (int i = 0; i < len; i++) - if (!memcmp(&(l[i*skip]), val, skip * 4)) + if (!memcmp(l + i * size, val, size)) return i; return -1; @@ -218,7 +220,7 @@ int_set_prepend(struct linpool *pool, struct adata *list, u32 val) } struct adata * -set_add(struct linpool *pool, struct adata *list, u32 *val, int size) +set_add(struct linpool *pool, struct adata *list, void *val, int size) { struct adata *res; int len; @@ -227,30 +229,30 @@ set_add(struct linpool *pool, struct adata *list, u32 *val, int size) return list; len = list ? list->length : 0; - res = lp_alloc(pool, sizeof(struct adata) + len + size * 4); - res->length = len + size * 4; + res = lp_alloc(pool, sizeof(struct adata) + len + size); + res->length = len + size; if (list) memcpy(res->data, list->data, len); - memcpy(res->data + len, val, size * 4); + memcpy(res->data + len, val, size); return res; } struct adata * -set_del(struct linpool *pool, struct adata *list, u32 *val, int size) +set_del(struct linpool *pool, struct adata *list, void *val, int size) { int pos = set_position(list, val, size); if (pos == -1) return list; - int len = list->length - 4*size; + int len = list->length - size; struct adata *res = lp_alloc(pool, sizeof(struct adata) + len); res->length = len; - u32 *dest = int_set_get_data(res); - u32 *src = int_set_get_data(list); + void *dest = res->data; + void *src = list->data; memcpy(dest, src, size * pos); memcpy(dest + size * pos, src + size * (pos + 1), size * (len - pos)); @@ -267,15 +269,15 @@ set_union(struct linpool *pool, struct adata *l1, struct adata *l2, int size) /* Filter out duplicit data from l2 */ struct adata *res; - int len = l2->length / (size * 4); - u32 *l = int_set_get_data(l2); - u32 tmp[len*size]; - u32 *k = tmp; + int len = l2->length / size; + void *l = l2->data; + u32 tmp[len*size/sizeof(u32)]; + void *k = tmp; for (int i = 0; i < len; i++) if (!set_contains(l1, l + i*size, size)) { - memcpy(k, l + i*size, size * 4); + memcpy(k, l + i*size, size); k += size; } @@ -283,7 +285,7 @@ set_union(struct linpool *pool, struct adata *l1, struct adata *l2, int size) if (k == tmp) return l1; - len = (k - tmp) * 4; + len = (k - (void*)tmp); res = lp_alloc(pool, sizeof(struct adata) + l1->length + len); res->length = l1->length + len; memcpy(res->data, l1->data, l1->length); @@ -296,9 +298,9 @@ struct adata * ec_set_del_nontrans(struct linpool *pool, struct adata *set) { adata *res = lp_alloc_adata(pool, set->length); - u32 *src = int_set_get_data(set); - u32 *dst = int_set_get_data(res); - int len = int_set_get_size(set); + u32 *src = (u32 *) set->data; + u32 *dst = (u32 *) res->data; + int len = set->length / 4; int i; /* Remove non-transitive communities (EC_TBIT set) */ @@ -336,8 +338,8 @@ int_set_sort(struct linpool *pool, struct adata *src) static int ec_set_cmp(const void *X, const void *Y) { - u64 x = ec_get(X, 0); - u64 y = ec_get(Y, 0); + u64 x = *((u64 *) X); + u64 y = *((u64 *) Y); return (x < y) ? -1 : (x > y) ? 1 : 0; } @@ -376,6 +378,6 @@ lc_set_sort(struct linpool *pool, struct adata *src) { struct adata *dst = lp_alloc_adata(pool, src->length); memcpy(dst->data, src->data, src->length); - qsort(dst->data, dst->length / LCOMM_LENGTH, LCOMM_LENGTH, lc_set_cmp); + qsort(dst->data, dst->length / sizeof(lcomm), sizeof(lcomm), lc_set_cmp); return dst; } diff --git a/nest/a-set_test.c b/nest/a-set_test.c index a5081f9f4..5deeb4f3a 100644 --- a/nest/a-set_test.c +++ b/nest/a-set_test.c @@ -69,21 +69,21 @@ generate_set_sequence(enum set_type type) static int t_set_int_contains(void) { - int i; + u32 i; resource_init(); generate_set_sequence(SET_TYPE_INT); - bt_assert(int_set_get_size(set_sequence) == SET_SIZE); + bt_assert(set_sequence->length / 4 == SET_SIZE); for (i = 0; i < SET_SIZE; i++) bt_assert(int_set_contains(set_sequence, i)); bt_assert(int_set_contains(set_sequence, -1) == 0); bt_assert(int_set_contains(set_sequence, SET_SIZE) == 0); - int *data = int_set_get_data(set_sequence); + u32 *data = (u32 *) set_sequence->data; for (i = 0; i < SET_SIZE; i++) - bt_assert_msg(data[i] == i, "(data[i] = %d) == i = %d)", data[i], i); + bt_assert_msg(data[i] == i, "(data[i] = %u) == i = %u)", data[i], i); rfree(lp); return 1; @@ -97,11 +97,11 @@ t_set_int_union(void) struct adata *set_union; set_union = int_set_union(lp, set_sequence, set_sequence_same); - bt_assert(int_set_get_size(set_union) == SET_SIZE); + bt_assert(set_union->length / 4 == SET_SIZE); bt_assert(int_set_format(set_union, 0, 2, buf, BUFFER_SIZE) == 0); set_union = int_set_union(lp, set_sequence, set_sequence_higher); - bt_assert_msg(int_set_get_size(set_union) == SET_SIZE*2, "int_set_get_size(set_union) %d, SET_SIZE*2 %d", int_set_get_size(set_union), SET_SIZE*2); + bt_assert_msg(set_union->length / 4 == SET_SIZE*2, "set_union->length/4 %d, SET_SIZE*2 %d", set_union->length / 4, SET_SIZE*2); bt_assert(int_set_format(set_union, 0, 2, buf, BUFFER_SIZE) == 0); rfree(lp); @@ -141,13 +141,13 @@ t_set_int_delete(void) for (i = 0; i < SET_SIZE; i++) { deleting_sequence = int_set_del(lp, deleting_sequence, i); - bt_assert_msg(int_set_get_size(deleting_sequence) == (int) (SET_SIZE-1-i), - "int_set_get_size(deleting_sequence) %d == SET_SIZE-1-i %d", - int_set_get_size(deleting_sequence), + bt_assert_msg(deleting_sequence->length / 4 == (uint) (SET_SIZE-1-i), + "deleting_sequence->length/4 %d == SET_SIZE-1-i %d", + deleting_sequence->length / 4, SET_SIZE-1-i); } - bt_assert(int_set_get_size(set_sequence) == SET_SIZE); + bt_assert(set_sequence->length/4 == SET_SIZE); return 1; } @@ -164,7 +164,7 @@ t_set_ec_contains(void) resource_init(); generate_set_sequence(SET_TYPE_EC); - bt_assert(ec_set_get_size(set_sequence) == SET_SIZE); + bt_assert(set_sequence->length/8 == SET_SIZE); for (i = 0; i < SET_SIZE; i++) bt_assert(ec_set_contains(set_sequence, i)); @@ -187,11 +187,11 @@ t_set_ec_union(void) struct adata *set_union; set_union = ec_set_union(lp, set_sequence, set_sequence_same); - bt_assert(ec_set_get_size(set_union) == SET_SIZE); + bt_assert(set_union->length/8 == SET_SIZE); bt_assert(ec_set_format(set_union, 0, buf, BUFFER_SIZE) == 0); set_union = ec_set_union(lp, set_sequence, set_sequence_higher); - bt_assert_msg(ec_set_get_size(set_union) == SET_SIZE*2, "ec_set_get_size(set_union) %d, SET_SIZE*2 %d", ec_set_get_size(set_union), SET_SIZE*2); + bt_assert_msg(set_union->length/8 == SET_SIZE*2, "set_union->length/8 %d, SET_SIZE*2 %d", set_union->length/8, SET_SIZE*2); bt_assert(ec_set_format(set_union, 0, buf, BUFFER_SIZE) == 0); rfree(lp); @@ -231,12 +231,12 @@ t_set_ec_delete(void) for (i = 0; i < SET_SIZE; i++) { deleting_sequence = ec_set_del(lp, deleting_sequence, i); - bt_assert_msg(ec_set_get_size(deleting_sequence) == (int) (SET_SIZE-1-i), + bt_assert_msg(deleting_sequence->length/8 == (uint) (SET_SIZE-1-i), "ec_set_get_size(deleting_sequence) %d == SET_SIZE-1-i %d", - ec_set_get_size(deleting_sequence), SET_SIZE-1-i); + deleting_sequence->length/8, SET_SIZE-1-i); } - bt_assert(ec_set_get_size(set_sequence) == SET_SIZE); + bt_assert(set_sequence->length/8 == SET_SIZE); return 1; } diff --git a/nest/attrs.h b/nest/attrs.h index 7058924d8..515bebc94 100644 --- a/nest/attrs.h +++ b/nest/attrs.h @@ -119,23 +119,6 @@ aggregator_to_old(struct linpool *pool, struct adata *a) #define ECOMM_LENGTH 8 -static inline int int_set_get_size(struct adata *list) -{ return list->length / 4; } - -static inline int ec_set_get_size(struct adata *list) -{ return list->length / 8; } - -static inline int lc_set_get_size(struct adata *list) -{ return list->length / 12; } - -static inline u32 *int_set_get_data(struct adata *list) -{ return (u32 *) list->data; } - -static inline u32 ec_hi(u64 ec) { return ec >> 32; } -static inline u32 ec_lo(u64 ec) { return ec; } -static inline u64 ec_get(const u32 *l, int i) -{ return (((u64) l[i]) << 32) | l[i+1]; } - /* RFC 4360 3.1. Two-Octet AS Specific Extended Community */ static inline u64 ec_as2(u64 kind, u64 key, u64 val) { return ((kind | 0x0000) << 48) | (key << 32) | val; } @@ -158,19 +141,8 @@ typedef struct lcomm { u32 ldp2; } lcomm; -#define LCOMM_LENGTH 12 - -static inline lcomm lc_get(const u32 *l, int i) -{ return (lcomm) { l[i], l[i+1], l[i+2] }; } - -static inline void lc_put(u32 *l, lcomm v) -{ l[0] = v.asn; l[1] = v.ldp1; l[2] = v.ldp2; } - -static inline int lc_match(const u32 *l, int i, lcomm v) -{ return (l[i] == v.asn && l[i+1] == v.ldp1 && l[i+2] == v.ldp2); } - -static inline u32 *lc_copy(u32 *dst, const u32 *src) -{ memcpy(dst, src, LCOMM_LENGTH); return dst + 3; } +static inline int int_set_get_size(struct adata *set) +{ return set->length / 4; } int int_set_format(struct adata *set, int way, int from, byte *buf, uint size); int ec_format(byte *buf, u64 ec); @@ -178,59 +150,42 @@ int ec_set_format(struct adata *set, int from, byte *buf, uint size); int lc_format(byte *buf, lcomm lc); int lc_set_format(struct adata *set, int from, byte *buf, uint size); -int set_position(struct adata *list, u32 *val, int skip); -static inline int set_contains(struct adata *list, u32 *val, int skip) -{ return set_position(list, val, skip) != -1; } +int set_position(struct adata *list, void *val, int size); +static inline int set_contains(struct adata *list, void *val, int size) +{ return set_position(list, val, size) != -1; } static inline int int_set_contains(struct adata *list, u32 val) -{ return set_contains(list, &val, 1); } +{ return set_contains(list, &val, sizeof(val)); } static inline int ec_set_contains(struct adata *list, u64 val) -{ - u32 ec[2] = { ec_hi(val), ec_lo(val) }; - return set_contains(list, ec, 2); -} +{ return set_contains(list, &val, sizeof(val)); } static inline int lc_set_contains(struct adata *list, lcomm val) -{ - u32 lc[3] = { val.asn, val.ldp1, val.ldp2 }; - return set_contains(list, lc, 3); -} +{ return set_contains(list, &val, sizeof(val)); } struct adata *int_set_prepend(struct linpool *pool, struct adata *list, u32 val); -struct adata *set_add(struct linpool *pool, struct adata *list, u32 *val, int size); +struct adata *set_add(struct linpool *pool, struct adata *list, void *val, int size); static inline struct adata *int_set_add(struct linpool *pool, struct adata *list, u32 val) -{ return set_add(pool, list, &val, 1); }; +{ return set_add(pool, list, &val, sizeof(val)); }; static inline struct adata *ec_set_add(struct linpool *pool, struct adata *list, u64 val) -{ - u32 ec[2] = { ec_hi(val), ec_lo(val) }; - return set_add(pool, list, ec, 2); -} +{ return set_add(pool, list, &val, sizeof(val)); }; static inline struct adata *lc_set_add(struct linpool *pool, struct adata *list, lcomm val) -{ - u32 lc[3] = { val.asn, val.ldp1, val.ldp2 }; - return set_add(pool, list, lc, 3); -} +{ return set_add(pool, list, &val, sizeof(val)); }; -struct adata *set_del(struct linpool *pool, struct adata *list, u32 *val, int size); +struct adata *set_del(struct linpool *pool, struct adata *list, void *val, int size); static inline struct adata *int_set_del(struct linpool *pool, struct adata *list, u32 val) -{ return set_del(pool, list, &val, 1); } +{ return set_del(pool, list, &val, sizeof(val)); } static inline struct adata *ec_set_del(struct linpool *pool, struct adata *list, u64 val) -{ - u32 ec[2] = { ec_hi(val), ec_lo(val) }; - return set_del(pool, list, ec, 2); -} +{ return set_del(pool, list, &val, sizeof(val)); } static inline struct adata *lc_set_del(struct linpool *pool, struct adata *list, lcomm val) -{ - u32 lc[3] = { val.asn, val.ldp1, val.ldp2 }; - return set_del(pool, list, lc, 3); -} +{ return set_del(pool, list, &val, sizeof(val)); } struct adata *set_union(struct linpool *pool, struct adata *l1, struct adata *l2, int size); static inline struct adata *int_set_union(struct linpool *pool, struct adata *l1, struct adata *l2) -{ return set_union(pool, l1, l2, 1); } +{ return set_union(pool, l1, l2, sizeof(u32)); } static inline struct adata *ec_set_union(struct linpool *pool, struct adata *l1, struct adata *l2) -{ return set_union(pool, l1, l2, 2); } +{ return set_union(pool, l1, l2, sizeof(u64)); } static inline struct adata *lc_set_union(struct linpool *pool, struct adata *l1, struct adata *l2) -{ return set_union(pool, l1, l2, 3); } +{ return set_union(pool, l1, l2, sizeof(lcomm)); } + struct adata *ec_set_del_nontrans(struct linpool *pool, struct adata *set); struct adata *int_set_sort(struct linpool *pool, struct adata *src);