Extend rde_community_test to check various aspects of non-transitive
authorclaudio <claudio@openbsd.org>
Wed, 11 Oct 2023 07:05:11 +0000 (07:05 +0000)
committerclaudio <claudio@openbsd.org>
Wed, 11 Oct 2023 07:05:11 +0000 (07:05 +0000)
extended communities. Mainly that the non-transitive communities are
properly stripped.
Test fails without rev 1.14 of rde_community.c

regress/usr.sbin/bgpd/unittests/rde_community_test.c
regress/usr.sbin/bgpd/unittests/rde_community_test.h

index 31df805..099b7e0 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: rde_community_test.c,v 1.8 2023/07/12 15:27:11 claudio Exp $ */
+/*     $OpenBSD: rde_community_test.c,v 1.9 2023/10/11 07:05:11 claudio Exp $ */
 
 /*
  * Copyright (c) 2019 Claudio Jeker <claudio@openbsd.org>
@@ -43,64 +43,85 @@ dump(uint8_t *b, size_t len)
 }
 
 static int
-test_parsing(size_t num, uint8_t *in, size_t inlen)
+test_parsing(size_t num, uint8_t *in, size_t inlen, uint8_t *out, size_t outlen)
 {
-       const char *func = "community";
        struct ibuf *buf;
        uint8_t flags, type, attr[256];
-       size_t skip = 2;
+       size_t skip;
        uint16_t attr_len;
        int r;
 
        communities_clean(&comm);
 
-       flags = in[0];
-       type = in[1];
-       if (flags & ATTR_EXTLEN) {
-               memcpy(&attr_len, in + 2, sizeof(attr_len));
-               attr_len = ntohs(attr_len);
-               skip += 2;
-       } else {
-               attr_len = in[2];
-               skip += 1;
-       }
-
-       switch (type) {
-       case ATTR_COMMUNITIES:
-               r = community_add(&comm, flags, in + skip, attr_len);
-               break;
-       case ATTR_EXT_COMMUNITIES:
-               r = community_ext_add(&comm, flags, 0, in + skip, attr_len);
-               break;
-       case ATTR_LARGE_COMMUNITIES:
-               r = community_large_add(&comm, flags, in + skip, attr_len);
-               break;
-       }
-       if (r == -1) {
-               printf("Test %zu: %s_add failed\n", num, func);
-               return -1;
-       }
+       do {
+               flags = in[0];
+               type = in[1];
+               skip = 2;
+               if (flags & ATTR_EXTLEN) {
+                       memcpy(&attr_len, in + 2, sizeof(attr_len));
+                       attr_len = ntohs(attr_len);
+                       skip += 2;
+               } else {
+                       attr_len = in[2];
+                       skip += 1;
+               }
+               if (skip + attr_len > inlen) {
+                       printf("Test %zu: attribute parse failure\n", num);
+                       return -1;
+               }
+
+               switch (type) {
+               case ATTR_COMMUNITIES:
+                       r = community_add(&comm, flags, in + skip, attr_len);
+                       break;
+               case ATTR_EXT_COMMUNITIES:
+                       r = community_ext_add(&comm, flags, 0, in + skip,
+                           attr_len);
+                       break;
+               case ATTR_LARGE_COMMUNITIES:
+                       r = community_large_add(&comm, flags, in + skip,
+                           attr_len);
+                       break;
+               }
+               if (r == -1) {
+                       printf("Test %zu: community_add failed\n", num);
+                       return -1;
+               }
+               in += skip + attr_len;
+               inlen -= (skip + attr_len);
+       } while (inlen > 0);
 
        if ((buf = ibuf_dynamic(0, 4096)) == NULL) {
                printf("Test %zu: ibuf_dynamic failed\n", num);
                return -1;
        }
 
-       if (community_writebuf(&comm, type, 0, buf) == -1) {
+       if (community_writebuf(&comm, ATTR_COMMUNITIES, 1, buf) == -1) {
+               printf("Test %zu: community_writebuf failed\n", num);
+               return -1;
+       }
+       if (community_writebuf(&comm, ATTR_EXT_COMMUNITIES, 1, buf) == -1) {
+               printf("Test %zu: community_writebuf failed\n", num);
+               return -1;
+       }
+       if (community_writebuf(&comm, ATTR_LARGE_COMMUNITIES, 1, buf) == -1) {
                printf("Test %zu: community_writebuf failed\n", num);
                return -1;
        }
 
-       if (ibuf_size(buf) != inlen) {
-               printf("Test %zu: %s_write return value %zd != %zd\n",
-                   num, func, ibuf_size(buf), inlen);
+       if (ibuf_size(buf) != outlen) {
+               printf("Test %zu: ibuf size value %zd != %zd:",
+                   num, ibuf_size(buf), outlen);
+               dump(ibuf_data(buf), ibuf_size(buf));
+               printf("expected: ");
+               dump(out, outlen);
                return -1;
        }
-       if (memcmp(ibuf_data(buf), in, inlen) != 0) {
-               printf("Test %zu: %s_write unexpected encoding: ", num, func);
+       if (memcmp(ibuf_data(buf), out, outlen) != 0) {
+               printf("Test %zu: unexpected encoding: ", num);
                dump(ibuf_data(buf), ibuf_size(buf));
                printf("expected: ");
-               dump(in, inlen);
+               dump(out, outlen);
                return -1;
        }
 
@@ -185,7 +206,16 @@ main(int argc, char *argv[])
        int error = 0;
 
        for (t = 0; t < sizeof(vectors) / sizeof(*vectors); t++) {
-               if (test_parsing(t, vectors[t].data, vectors[t].size) == -1)
+               size_t outlen = vectors[t].expsize;
+               uint8_t *out = vectors[t].expected;
+
+               if (vectors[t].expected == NULL) {
+                       outlen = vectors[t].size;
+                       out = vectors[t].data;
+               }
+
+               if (test_parsing(t, vectors[t].data, vectors[t].size,
+                   out, outlen) == -1)
                        error = 1;
        }
 
index 0036891..284e810 100644 (file)
@@ -18,6 +18,8 @@ struct rde_peer peer_b4 = {
 struct vector {
        uint8_t *data;
        size_t  size;
+       uint8_t *expected;
+       size_t  expsize;
 } vectors[] = {
 
        {
@@ -117,6 +119,11 @@ struct vector {
                .data = "\xc0\x10\x08\x00\x02\xfd\xe8\x00\x00\x2a\xf8",
                .size = 11
        },
+       {
+               .data = "\xc0\x20\x0c\x00\x00\xd0\x5b\x00\x00\x00\x0b\x00\x00"
+                   "\x00\x03",
+               .size = 15
+       },
        {
                .data = "\xc0\x20\x18\x00\x00\xd0\x5b\x00\x00\x00\x0b\x00\x00"
                    "\x00\x01\x00\x00\xd0\x5b\x00\x00\x00\x0b\x00\x00"
@@ -272,7 +279,65 @@ struct vector {
                    "\x00\xd0\x00\x03\x22\xd3\x00\x00\x00\x79\x00\x00"
                    "\x00\x00",
                .size = 183
-       }
+       },
+       {
+               .data = "\xc0\x10\x08\x43\x00\x00\x00\x00\x00\x00\x02",
+               .size = 11,
+               .expected = "",
+               .expsize = 0,
+       },
+       {
+               .data = "\xc0\x10\x10\x00\x02\xfc\x00\x00\x00\x00\x40"
+                   "\x43\x00\x00\x00\x00\x00\x00\x02",
+               .size = 19,
+               .expected = "\xc0\x10\x08\x00\x02\xfc\x00\x00\x00\x00\x40",
+               .expsize = 11,
+       },
+       {
+               .data = "\xc0\x10\x18\x00\x02\xfc\x00\x00\x00\x00\x40"
+                   "\x43\x00\x00\x00\x00\x00\x00\x02"
+                   "\x06\x00\x00\x00\x00\x00\x00\x01",
+               .size = 27,
+               .expected = "\xc0\x10\x10\x06\x00\x00\x00\x00\x00\x00\x01"
+                   "\x00\x02\xfc\x00\x00\x00\x00\x40",
+               .expsize = 19,
+       },
+       {
+               .data = "\xe0\x08\x04\x4e\x97\x00\x03"
+                   "\xc0\x10\x08\x43\x00\x00\x00\x00\x00\x00\x02",
+               .size = 7 + 11,
+               .expected = "\xe0\x08\x04\x4e\x97\x00\x03",
+               .expsize = 7,
+       },
+       {
+               .data = "\xe0\x08\x04\x4e\x97\x00\x03"
+                   "\xc0\x10\x10\x00\x02\xfc\x00\x00\x00\x00\x40"
+                   "\x43\x00\x00\x00\x00\x00\x00\x02",
+               .size = 7 + 19,
+               .expected = "\xe0\x08\x04\x4e\x97\x00\x03"
+                   "\xc0\x10\x08\x00\x02\xfc\x00\x00\x00\x00\x40",
+               .expsize = 7 + 11,
+       },
+       {
+               .data = "\xc0\x10\x08\x43\x00\x00\x00\x00\x00\x00\x02"
+                   "\xc0\x20\x0c\x00\x00\xd0\x5b\x00\x00\x00\x0b"
+                   "\x00\x00\x00\x03",
+               .size = 11 + 15,
+               .expected = "\xc0\x20\x0c\x00\x00\xd0\x5b\x00\x00\x00\x0b"
+                   "\x00\x00\x00\x03",
+               .expsize = 15,
+       },
+       {
+               .data = "\xe0\x08\x04\x4e\x97\x00\x03"
+                   "\xc0\x10\x08\x43\x00\x00\x00\x00\x00\x00\x02"
+                   "\xc0\x20\x0c\x00\x00\xd0\x5b\x00\x00\x00\x0b"
+                   "\x00\x00\x00\x03",
+               .size = 7 + 11 + 15,
+               .expected = "\xe0\x08\x04\x4e\x97\x00\x03"
+                   "\xc0\x20\x0c\x00\x00\xd0\x5b\x00\x00\x00\x0b"
+                   "\x00\x00\x00\x03",
+               .expsize = 7 + 15,
+       },
 };
 
 struct community filters[] = {