After prefix-set and as-set I'm looking at adding roa-set.
roa-sets are kind of a mix of a prefix-set and a as-set and therefor
this diff extends as-set code to allow for this.
Extend as_set to allow for different sized objects to be added. The only
requirement is that the first value of the struct is a 32bit ID which is
used in the bsearch. This allows to add more than just as numbers to a
set. as_set_match now returns a pointer to this data or NULL if not found.
--
:wq Claudio
PS: the diff is against /usr/src since it includes diff for bgpctl and
regress as well
Index: usr.sbin/bgpd/bgpd.h
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/bgpd.h,v
retrieving revision 1.339
diff -u -p -r1.339 bgpd.h
--- usr.sbin/bgpd/bgpd.h 10 Sep 2018 11:01:15 -0000 1.339
+++ usr.sbin/bgpd/bgpd.h 13 Sep 2018 09:29:25 -0000
@@ -1171,10 +1171,11 @@ void as_sets_print(struct as_set_head
int as_sets_send(struct imsgbuf *, struct as_set_head *);
void as_sets_mark_dirty(struct as_set_head *, struct as_set_head *);
-struct as_set *as_set_new(const char *, size_t);
-int as_set_add(struct as_set *, u_int32_t *, size_t);
+struct as_set *as_set_new(const char *, size_t, size_t);
+void as_set_free(struct as_set *);
+int as_set_add(struct as_set *, void *, size_t);
void as_set_prep(struct as_set *);
-int as_set_match(const struct as_set *, u_int32_t);
+void *as_set_match(const struct as_set *, u_int32_t);
int as_set_equal(const struct as_set *, const struct as_set *);
int as_set_dirty(const struct as_set *);
Index: usr.sbin/bgpd/parse.y
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/parse.y,v
retrieving revision 1.350
diff -u -p -r1.350 parse.y
--- usr.sbin/bgpd/parse.y 10 Sep 2018 11:09:25 -0000 1.350
+++ usr.sbin/bgpd/parse.y 13 Sep 2018 09:30:54 -0000
@@ -402,15 +403,19 @@ include : INCLUDE STRING {
;
as_set : ASSET STRING '{' optnl {
- if (new_as_set($2) != 0)
+ if (new_as_set($2) != 0) {
+ free($2);
YYERROR;
+ }
free($2);
} as_set_l optnl '}' {
done_as_set();
}
| ASSET STRING '{' optnl '}' {
- if (new_as_set($2) != 0)
+ if (new_as_set($2) != 0) {
+ free($2);
YYERROR;
+ }
free($2);
}
@@ -4186,7 +4183,7 @@ new_as_set(char *name)
return -1;
}
- aset = as_set_new(name, 0);
+ aset = as_set_new(name, 0, sizeof(u_int32_t));
if (aset == NULL)
fatal(NULL);
as_sets_insert(conf->as_sets, aset);
Index: usr.sbin/bgpd/rde.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/rde.c,v
retrieving revision 1.422
diff -u -p -r1.422 rde.c
--- usr.sbin/bgpd/rde.c 9 Sep 2018 15:02:26 -0000 1.422
+++ usr.sbin/bgpd/rde.c 13 Sep 2018 09:29:25 -0000
@@ -908,7 +908,8 @@ rde_dispatch_imsg_parent(struct imsgbuf
name = (char *)imsg.data + sizeof(nmemb);
if (as_sets_lookup(as_sets_tmp, name) != NULL)
fatalx("duplicate as-set %s", name);
- last_as_set = as_set_new(name, nmemb);
+ last_as_set = as_set_new(name, nmemb,
+ sizeof(u_int32_t));
break;
case IMSG_RECONF_AS_SET_ITEMS:
nmemb = imsg.hdr.len - IMSG_HEADER_SIZE;
Index: usr.sbin/bgpd/rde_sets.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/rde_sets.c,v
retrieving revision 1.3
diff -u -p -r1.3 rde_sets.c
--- usr.sbin/bgpd/rde_sets.c 10 Sep 2018 11:01:15 -0000 1.3
+++ usr.sbin/bgpd/rde_sets.c 13 Sep 2018 09:29:25 -0000
@@ -29,9 +29,10 @@
struct as_set {
char name[SET_NAME_LEN];
- u_int32_t *set;
+ void *set;
SIMPLEQ_ENTRY(as_set) entry;
size_t nmemb;
+ size_t size;
size_t max;
int dirty;
};
@@ -54,12 +55,6 @@ as_sets_lookup(struct as_set_head *as_se
return NULL;
}
-static void
-as_set_free(struct as_set *aset)
-{
- free(aset->set);
- free(aset);
-}
void
as_sets_free(struct as_set_head *as_sets)
@@ -92,7 +87,8 @@ as_sets_print(struct as_set_head *as_set
printf("\n\t");
len = 8;
}
- len += printf("%u ", aset->set[i]);
+ len += printf("%u ", *(u_int32_t *)
+ ((u_int8_t *)aset->set + i * aset->size));
}
printf("\n}\n\n");
}
@@ -120,7 +116,8 @@ as_sets_send(struct imsgbuf *ibuf, struc
l = (aset->nmemb - i > 1024 ? 1024 : aset->nmemb - i);
if (imsg_compose(ibuf, IMSG_RECONF_AS_SET_ITEMS, 0, 0,
- -1, aset->set + i, l * sizeof(*aset->set)) == -1)
+ -1, (u_int8_t *)aset->set + i * aset->size,
+ l * aset->size) == -1)
return -1;
}
@@ -144,7 +141,7 @@ as_sets_mark_dirty(struct as_set_head *o
}
struct as_set *
-as_set_new(const char *name, size_t nmemb)
+as_set_new(const char *name, size_t nmemb, size_t size)
{
struct as_set *aset;
size_t len;
@@ -157,10 +154,11 @@ as_set_new(const char *name, size_t nmem
assert(len < sizeof(aset->name));
if (nmemb == 0)
- nmemb = 16;
+ nmemb = 4;
+ aset->size = size;
aset->max = nmemb;
- aset->set = calloc(nmemb, sizeof(*aset->set));
+ aset->set = calloc(nmemb, aset->size);
if (aset->set == NULL) {
free(aset);
return NULL;
@@ -169,8 +167,17 @@ as_set_new(const char *name, size_t nmem
return aset;
}
+void
+as_set_free(struct as_set *aset)
+{
+ if (aset == NULL)
+ return;
+ free(aset->set);
+ free(aset);
+}
+
int
-as_set_add(struct as_set *aset, u_int32_t *elms, size_t nelms)
+as_set_add(struct as_set *aset, void *elms, size_t nelms)
{
if (aset->max < nelms || aset->max - nelms < aset->nmemb) {
u_int32_t *s;
@@ -183,14 +190,15 @@ as_set_add(struct as_set *aset, u_int32_
for (new_size = aset->max; new_size < aset->nmemb + nelms; )
new_size += (new_size < 4096 ? new_size : 4096);
- s = reallocarray(aset->set, new_size, sizeof(*aset->set));
+ s = reallocarray(aset->set, new_size, aset->size);
if (s == NULL)
return -1;
aset->set = s;
aset->max = new_size;
}
- memcpy(aset->set + aset->nmemb, elms, nelms * sizeof(*elms));
+ memcpy((u_int8_t *)aset->set + aset->nmemb * aset->size, elms,
+ nelms * aset->size);
aset->nmemb += nelms;
return 0;
@@ -212,16 +220,17 @@ as_set_cmp(const void *ap, const void *b
void
as_set_prep(struct as_set *aset)
{
- qsort(aset->set, aset->nmemb, sizeof(*aset->set), as_set_cmp);
+ if (aset == NULL)
+ return;
+ qsort(aset->set, aset->nmemb, aset->size, as_set_cmp);
}
-int
+void *
as_set_match(const struct as_set *a, u_int32_t asnum)
{
- if (bsearch(&asnum, a->set, a->nmemb, sizeof(asnum), as_set_cmp))
- return 1;
- else
- return 0;
+ if (a == NULL)
+ return NULL;
+ return bsearch(&asnum, a->set, a->nmemb, a->size, as_set_cmp);
}
int
@@ -229,7 +238,7 @@ as_set_equal(const struct as_set *a, con
{
if (a->nmemb != b->nmemb)
return 0;
- if (memcmp(a->set, b->set, a->nmemb * sizeof(*a->set)) != 0)
+ if (memcmp(a->set, b->set, a->nmemb * a->size) != 0)
return 0;
return 1;
}
Index: usr.sbin/bgpd/util.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/util.c,v
retrieving revision 1.34
diff -u -p -r1.34 util.c
--- usr.sbin/bgpd/util.c 7 Sep 2018 05:43:33 -0000 1.34
+++ usr.sbin/bgpd/util.c 13 Sep 2018 09:29:25 -0000
@@ -320,7 +320,7 @@ as_compare(struct filter_as *f, u_int32_
if (f->flags & AS_FLAG_AS_SET_NAME) /* should not happen */
return (0);
if (f->flags & AS_FLAG_AS_SET)
- return (as_set_match(f->aset, as));
+ return (as_set_match(f->aset, as) != NULL);
if (f->flags & AS_FLAG_NEIGHBORAS)
match = neighas;
Index: usr.sbin/bgpctl/bgpctl.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpctl/bgpctl.c,v
retrieving revision 1.215
diff -u -p -r1.215 bgpctl.c
--- usr.sbin/bgpctl/bgpctl.c 9 Sep 2018 12:53:41 -0000 1.215
+++ usr.sbin/bgpctl/bgpctl.c 13 Sep 2018 09:33:17 -0000
@@ -2656,8 +2656,8 @@ msg_type(u_int8_t type)
return (msgtypenames[type]);
}
-int
+void *
as_set_match(const struct as_set *a, u_int32_t asnum)
{
- return (0);
+ return (NULL);
}
Index: regress/usr.sbin/bgpd/unittests/rde_sets_test.c
===================================================================
RCS file: /cvs/src/regress/usr.sbin/bgpd/unittests/rde_sets_test.c,v
retrieving revision 1.2
diff -u -p -r1.2 rde_sets_test.c
--- regress/usr.sbin/bgpd/unittests/rde_sets_test.c 7 Sep 2018 09:31:14
-0000 1.2
+++ regress/usr.sbin/bgpd/unittests/rde_sets_test.c 13 Sep 2018 09:32:41
-0000
@@ -33,7 +33,7 @@ build_set(const char *name, u_int32_t *m
{
struct as_set *a;
- a = as_set_new(name, initial);
+ a = as_set_new(name, initial, sizeof(*mem));
if (a == NULL)
err(1, "as_set_new %s", name);
if (as_set_add(a, mem, nmemb) != 0)
@@ -46,18 +46,18 @@ build_set(const char *name, u_int32_t *m
int
main(int argc, char **argv)
{
- struct as_set *a, *aa, *b, *c;
+ struct as_set *a, *aa, *b, *c, *empty;
size_t i;
a = build_set("a", va, sizeof(va) / sizeof(va[0]),
sizeof(va) / sizeof(va[0]));
-
aa = build_set("aa", vaa, sizeof(vaa) / sizeof(vaa[0]), 0);
-
b = build_set("b", vb, sizeof(vb) / sizeof(vb[0]), 1);
-
c = build_set("c", vc, sizeof(vc) / sizeof(vc[0]), 1);
+ empty = build_set("empty", NULL, 0, 0);
+ if (!as_set_equal(a, a))
+ errx(1, "as_set_equal(a, a) non equal");
if (!as_set_equal(a, aa))
errx(1, "as_set_equal(a, aa) non equal");
if (as_set_equal(a, b))
@@ -75,6 +75,17 @@ main(int argc, char **argv)
if (as_set_match(c, 7))
errx(1, "as_set_match(c, %u) matched but should not", 7);
+ if (!as_set_equal(empty, empty))
+ errx(1, "as_set_equal(empty, empty) non equal");
+ if (as_set_match(empty, 42))
+ errx(1, "as_set_match(empty, %u) matched but should not", 42);
+
+ as_set_free(a);
+ as_set_free(aa);
+ as_set_free(b);
+ as_set_free(c);
+ as_set_free(empty);
+
printf("OK\n");
return 0;
}