-/* $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>
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
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
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
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)
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),
-/* $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
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);
-/* $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>
* - 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);
}
}
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);
}
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))