From b3b1d9397541e27ba473657472e25f9299f1e594 Mon Sep 17 00:00:00 2001 From: claudio Date: Wed, 24 Jan 2024 14:51:11 +0000 Subject: [PATCH] Convert the community parsers to the new ibuf api. 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 | 24 ++++++---------- usr.sbin/bgpd/rde.h | 9 +++--- usr.sbin/bgpd/rde_community.c | 53 +++++++++++++++-------------------- 3 files changed, 36 insertions(+), 50 deletions(-) diff --git a/usr.sbin/bgpd/rde.c b/usr.sbin/bgpd/rde.c index f1b6c26515f..5517ca99bcf 100644 --- a/usr.sbin/bgpd/rde.c +++ b/usr.sbin/bgpd/rde.c @@ -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 @@ -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), diff --git a/usr.sbin/bgpd/rde.h b/usr.sbin/bgpd/rde.h index 7d1fb40954f..895e7302854 100644 --- a/usr.sbin/bgpd/rde.h +++ b/usr.sbin/bgpd/rde.h @@ -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 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); diff --git a/usr.sbin/bgpd/rde_community.c b/usr.sbin/bgpd/rde_community.c index 803a374e8b6..0b89858ed73 100644 --- a/usr.sbin/bgpd/rde_community.c +++ b/usr.sbin/bgpd/rde_community.c @@ -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 @@ -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)) -- 2.20.1