mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-12-22 09:41:54 +00:00
WIP Nest: Making the clist/eclist/lclist even more generic
This commit is contained in:
parent
7365219609
commit
9ca8847305
@ -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;
|
||||
|
56
nest/a-set.c
56
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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
85
nest/attrs.h
85
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);
|
||||
|
Loading…
Reference in New Issue
Block a user