Convert the community parsers to the new ibuf api.
authorclaudio <claudio@openbsd.org>
Wed, 24 Jan 2024 14:51:11 +0000 (14:51 +0000)
committerclaudio <claudio@openbsd.org>
Wed, 24 Jan 2024 14:51:11 +0000 (14:51 +0000)
This converts community_add(), community_large_add() and community_ext_add()
and as a result removes some hacks from rde_attr_add() and rde_attr_parse().
OK tb@

usr.sbin/bgpd/rde.c
usr.sbin/bgpd/rde.h
usr.sbin/bgpd/rde_community.c

index f1b6c26..5517ca9 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: rde.c,v 1.616 2024/01/23 16:13:35 claudio Exp $ */
+/*     $OpenBSD: rde.c,v 1.617 2024/01/24 14:51:11 claudio Exp $ */
 
 /*
  * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -2139,8 +2139,8 @@ rde_attr_parse(struct ibuf *buf, struct rde_peer *peer,
                if (!CHECK_FLAGS(flags, ATTR_OPTIONAL|ATTR_TRANSITIVE,
                    ATTR_PARTIAL))
                        goto bad_flags;
-               if (community_add(&state->communities, flags, p,
-                   attr_len) == -1) {
+               if (community_add(&state->communities, flags,
+                   &attrbuf) == -1) {
                        /*
                         * mark update as bad and withdraw all routes as per
                         * RFC 7606
@@ -2149,14 +2149,13 @@ rde_attr_parse(struct ibuf *buf, struct rde_peer *peer,
                        log_peer_warnx(&peer->conf, "bad COMMUNITIES, "
                            "path invalidated and prefix withdrawn");
                }
-               plen += attr_len;
                break;
        case ATTR_LARGE_COMMUNITIES:
                if (!CHECK_FLAGS(flags, ATTR_OPTIONAL|ATTR_TRANSITIVE,
                    ATTR_PARTIAL))
                        goto bad_flags;
-               if (community_large_add(&state->communities, flags, p,
-                   attr_len) == -1) {
+               if (community_large_add(&state->communities, flags,
+                   &attrbuf) == -1) {
                        /*
                         * mark update as bad and withdraw all routes as per
                         * RFC 7606
@@ -2165,14 +2164,13 @@ rde_attr_parse(struct ibuf *buf, struct rde_peer *peer,
                        log_peer_warnx(&peer->conf, "bad LARGE COMMUNITIES, "
                            "path invalidated and prefix withdrawn");
                }
-               plen += attr_len;
                break;
        case ATTR_EXT_COMMUNITIES:
                if (!CHECK_FLAGS(flags, ATTR_OPTIONAL|ATTR_TRANSITIVE,
                    ATTR_PARTIAL))
                        goto bad_flags;
                if (community_ext_add(&state->communities, flags,
-                   peer->conf.ebgp, p, attr_len) == -1) {
+                   peer->conf.ebgp, &attrbuf) == -1) {
                        /*
                         * mark update as bad and withdraw all routes as per
                         * RFC 7606
@@ -2181,7 +2179,6 @@ rde_attr_parse(struct ibuf *buf, struct rde_peer *peer,
                        log_peer_warnx(&peer->conf, "bad EXT_COMMUNITIES, "
                            "path invalidated and prefix withdrawn");
                }
-               plen += attr_len;
                break;
        case ATTR_ORIGINATOR_ID:
                if (attr_len != 4)
@@ -2338,14 +2335,11 @@ rde_attr_add(struct filterstate *state, struct ibuf *buf)
 
        switch (type) {
        case ATTR_COMMUNITIES:
-               return community_add(&state->communities, flags,
-                   ibuf_data(buf), attr_len);
+               return community_add(&state->communities, flags, buf);
        case ATTR_LARGE_COMMUNITIES:
-               return community_large_add(&state->communities, flags,
-                   ibuf_data(buf), attr_len);
+               return community_large_add(&state->communities, flags, buf);
        case ATTR_EXT_COMMUNITIES:
-               return community_ext_add(&state->communities, flags, 0,
-                   ibuf_data(buf), attr_len);
+               return community_ext_add(&state->communities, flags, 0, buf);
        }
 
        if (attr_optadd(&state->aspath, flags, type, ibuf_data(buf),
index 7d1fb40..895e730 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: rde.h,v 1.298 2024/01/23 16:13:35 claudio Exp $ */
+/*     $OpenBSD: rde.h,v 1.299 2024/01/24 14:51:12 claudio Exp $ */
 
 /*
  * Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org> and
@@ -435,10 +435,9 @@ int        community_set(struct rde_community *, struct community *,
 void   community_delete(struct rde_community *, struct community *,
            struct rde_peer *);
 
-int    community_add(struct rde_community *, int, void *, size_t);
-int    community_large_add(struct rde_community *, int, void *, size_t);
-int    community_ext_add(struct rde_community *, int, int, void *, size_t);
-
+int    community_add(struct rde_community *, int, struct ibuf *);
+int    community_large_add(struct rde_community *, int, struct ibuf *);
+int    community_ext_add(struct rde_community *, int, int, struct ibuf *);
 int    community_writebuf(struct rde_community *, uint8_t, int, struct ibuf *);
 
 void                    communities_shutdown(void);
index 803a374..0b89858 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: rde_community.c,v 1.14 2023/10/10 14:36:28 claudio Exp $ */
+/*     $OpenBSD: rde_community.c,v 1.15 2024/01/24 14:51:12 claudio Exp $ */
 
 /*
  * Copyright (c) 2019 Claudio Jeker <claudio@openbsd.org>
@@ -418,24 +418,23 @@ struct rde_peer *peer)
  * - community_ext_add for ATTR_EXT_COMMUNITIES
  */
 int
-community_add(struct rde_community *comm, int flags, void *buf, size_t len)
+community_add(struct rde_community *comm, int flags, struct ibuf *buf)
 {
        struct community set = { .flags = COMMUNITY_TYPE_BASIC };
-       uint8_t *b = buf;
-       uint16_t c;
-       size_t l;
+       uint16_t data1, data2;
 
-       if (len == 0 || len % 4 != 0)
+       if (ibuf_size(buf) == 0 || ibuf_size(buf) % 4 != 0)
                return -1;
 
        if (flags & ATTR_PARTIAL)
                comm->flags |= PARTIAL_COMMUNITIES;
 
-       for (l = 0; l < len; l += 4, b += 4) {
-               memcpy(&c, b, sizeof(c));
-               set.data1 = ntohs(c);
-               memcpy(&c, b + 2, sizeof(c));
-               set.data2 = ntohs(c);
+       while (ibuf_size(buf) > 0) {
+               if (ibuf_get_n16(buf, &data1) == -1 ||
+                   ibuf_get_n16(buf, &data2) == -1)
+                       return -1;
+               set.data1 = data1;
+               set.data2 = data2;
                insert_community(comm, &set);
        }
 
@@ -443,26 +442,21 @@ community_add(struct rde_community *comm, int flags, void *buf, size_t len)
 }
 
 int
-community_large_add(struct rde_community *comm, int flags, void *buf,
-    size_t len)
+community_large_add(struct rde_community *comm, int flags, struct ibuf *buf)
 {
        struct community set = { .flags = COMMUNITY_TYPE_LARGE };
-       uint8_t *b = buf;
-       size_t l;
 
-       if (len == 0 || len % 12 != 0)
+       if (ibuf_size(buf) == 0 || ibuf_size(buf) % 12 != 0)
                return -1;
 
        if (flags & ATTR_PARTIAL)
                comm->flags |= PARTIAL_LARGE_COMMUNITIES;
 
-       for (l = 0; l < len; l += 12, b += 12) {
-               memcpy(&set.data1, b, sizeof(set.data1));
-               memcpy(&set.data2, b + 4, sizeof(set.data2));
-               memcpy(&set.data3, b + 8, sizeof(set.data3));
-               set.data1 = ntohl(set.data1);
-               set.data2 = ntohl(set.data2);
-               set.data3 = ntohl(set.data3);
+       while (ibuf_size(buf) > 0) {
+               if (ibuf_get_n32(buf, &set.data1) == -1 ||
+                   ibuf_get_n32(buf, &set.data2) == -1 ||
+                   ibuf_get_n32(buf, &set.data3) == -1)
+                       return -1;
                insert_community(comm, &set);
        }
 
@@ -471,23 +465,22 @@ community_large_add(struct rde_community *comm, int flags, void *buf,
 
 int
 community_ext_add(struct rde_community *comm, int flags, int ebgp,
-    void *buf, size_t len)
+    struct ibuf *buf)
 {
        struct community set = { .flags = COMMUNITY_TYPE_EXT };
-       uint8_t *b = buf, type;
        uint64_t c;
-       size_t l;
+       uint8_t type;
 
-       if (len == 0 || len % 8 != 0)
+       if (ibuf_size(buf) == 0 || ibuf_size(buf) % 8 != 0)
                return -1;
 
        if (flags & ATTR_PARTIAL)
                comm->flags |= PARTIAL_EXT_COMMUNITIES;
 
-       for (l = 0; l < len; l += 8, b += 8) {
-               memcpy(&c, b, 8);
+       while (ibuf_size(buf) > 0) {
+               if (ibuf_get_n64(buf, &c) == -1)
+                       return (-1);
 
-               c = be64toh(c);
                type = c >> 56;
                /* filter out non-transitive ext communuties from ebgp peers */
                if (ebgp && (type & EXT_COMMUNITY_NON_TRANSITIVE))