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;
 }

Reply via email to