-/* $OpenBSD: rde.c,v 1.613 2023/12/14 13:52:37 claudio Exp $ */
+/* $OpenBSD: rde.c,v 1.614 2024/01/15 15:44:50 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
struct bgpd_addr *, uint8_t);
int rde_attr_parse(u_char *, uint16_t, struct rde_peer *,
struct filterstate *, struct mpattr *);
-int rde_attr_add(struct filterstate *, u_char *, uint16_t);
+int rde_attr_add(struct filterstate *, struct ibuf *);
uint8_t rde_attr_missing(struct rde_aspath *, int, uint16_t);
int rde_get_mp_nexthop(u_char *, uint16_t, uint8_t,
struct rde_peer *, struct filterstate *);
{
static struct flowspec *curflow;
struct imsg imsg;
+ struct ibuf ibuf;
struct rde_peer_stats stats;
struct ctl_show_set cset;
struct ctl_show_rib csr;
struct ctl_show_rib_request req;
struct session_up sup;
+ struct peer_config pconf;
struct rde_peer *peer;
struct rde_aspath *asp;
struct filter_set *s;
struct as_set *aset;
struct rde_prefixset *pset;
- uint8_t *asdata;
ssize_t n;
- size_t aslen;
+ uint32_t peerid;
+ pid_t pid;
int verbose;
- uint16_t len;
uint8_t aid;
while (imsgbuf) {
if (n == 0)
break;
- switch (imsg.hdr.type) {
+ peerid = imsg_get_id(&imsg);
+ pid = imsg_get_pid(&imsg);
+ switch (imsg_get_type(&imsg)) {
case IMSG_UPDATE:
case IMSG_REFRESH:
- if ((peer = peer_get(imsg.hdr.peerid)) == NULL) {
+ if ((peer = peer_get(peerid)) == NULL) {
log_warnx("rde_dispatch: unknown peer id %d",
- imsg.hdr.peerid);
+ peerid);
break;
}
peer_imsg_push(peer, &imsg);
break;
case IMSG_SESSION_ADD:
- if (imsg.hdr.len - IMSG_HEADER_SIZE !=
- sizeof(struct peer_config))
+ if (imsg_get_data(&imsg, &pconf, sizeof(pconf)) == -1)
fatalx("incorrect size of session request");
- peer = peer_add(imsg.hdr.peerid, imsg.data, out_rules);
+ peer = peer_add(peerid, &pconf, out_rules);
/* make sure rde_eval_all is on if needed. */
if (peer->conf.flags & PEERFLAG_EVALUATE_ALL)
rde_eval_all = 1;
break;
case IMSG_SESSION_UP:
- if ((peer = peer_get(imsg.hdr.peerid)) == NULL) {
+ if ((peer = peer_get(peerid)) == NULL) {
log_warnx("%s: unknown peer id %d",
- "IMSG_SESSION_UP", imsg.hdr.peerid);
+ "IMSG_SESSION_UP", peerid);
break;
}
- if (imsg.hdr.len - IMSG_HEADER_SIZE != sizeof(sup))
+ if (imsg_get_data(&imsg, &sup, sizeof(sup)) == -1)
fatalx("incorrect size of session request");
- memcpy(&sup, imsg.data, sizeof(sup));
peer_up(peer, &sup);
/* make sure rde_eval_all is on if needed. */
if (peer_has_add_path(peer, AID_UNSPEC, CAPA_AP_SEND))
rde_eval_all = 1;
break;
case IMSG_SESSION_DOWN:
- if ((peer = peer_get(imsg.hdr.peerid)) == NULL) {
+ if ((peer = peer_get(peerid)) == NULL) {
log_warnx("%s: unknown peer id %d",
- "IMSG_SESSION_DOWN", imsg.hdr.peerid);
+ "IMSG_SESSION_DOWN", peerid);
break;
}
peer_down(peer, NULL);
case IMSG_SESSION_NOGRACE:
case IMSG_SESSION_FLUSH:
case IMSG_SESSION_RESTARTED:
- if ((peer = peer_get(imsg.hdr.peerid)) == NULL) {
+ if ((peer = peer_get(peerid)) == NULL) {
log_warnx("%s: unknown peer id %d",
- "graceful restart", imsg.hdr.peerid);
+ "graceful restart", peerid);
break;
}
- if (imsg.hdr.len - IMSG_HEADER_SIZE != sizeof(aid)) {
+ if (imsg_get_data(&imsg, &aid, sizeof(aid)) == -1) {
log_warnx("%s: wrong imsg len", __func__);
break;
}
- memcpy(&aid, imsg.data, sizeof(aid));
if (aid >= AID_MAX) {
log_warnx("%s: bad AID", __func__);
break;
}
- switch (imsg.hdr.type) {
+ switch (imsg_get_type(&imsg)) {
case IMSG_SESSION_STALE:
case IMSG_SESSION_NOGRACE:
peer_stale(peer, aid,
- imsg.hdr.type == IMSG_SESSION_NOGRACE);
+ imsg_get_type(&imsg) == IMSG_SESSION_NOGRACE);
break;
case IMSG_SESSION_FLUSH:
peer_flush(peer, aid, peer->staletime[aid]);
}
break;
case IMSG_NETWORK_ADD:
- if (imsg.hdr.len - IMSG_HEADER_SIZE !=
- sizeof(struct network_config)) {
+ if (imsg_get_data(&imsg, &netconf_s,
+ sizeof(netconf_s)) == -1) {
log_warnx("rde_dispatch: wrong imsg len");
break;
}
- memcpy(&netconf_s, imsg.data, sizeof(netconf_s));
TAILQ_INIT(&netconf_s.attrset);
rde_filterstate_init(&netconf_state);
asp = &netconf_state.aspath;
F_ANN_DYNAMIC;
break;
case IMSG_NETWORK_ASPATH:
- if (imsg.hdr.len - IMSG_HEADER_SIZE <
- sizeof(csr)) {
+ if (imsg_get_ibuf(&imsg, &ibuf) == -1) {
+ log_warnx("rde_dispatch: bad imsg");
+ memset(&netconf_s, 0, sizeof(netconf_s));
+ break;
+ }
+ if (ibuf_get(&ibuf, &csr, sizeof(csr)) == -1) {
log_warnx("rde_dispatch: wrong imsg len");
memset(&netconf_s, 0, sizeof(netconf_s));
break;
}
- aslen = imsg.hdr.len - IMSG_HEADER_SIZE - sizeof(csr);
- asdata = imsg.data;
- asdata += sizeof(struct ctl_show_rib);
- memcpy(&csr, imsg.data, sizeof(csr));
asp = &netconf_state.aspath;
asp->lpref = csr.local_pref;
asp->med = csr.med;
asp->origin = csr.origin;
asp->flags |= F_PREFIX_ANNOUNCED | F_ANN_DYNAMIC;
aspath_put(asp->aspath);
- asp->aspath = aspath_get(asdata, aslen);
+ asp->aspath = aspath_get(ibuf_data(&ibuf),
+ ibuf_size(&ibuf));
break;
case IMSG_NETWORK_ATTR:
- if (imsg.hdr.len <= IMSG_HEADER_SIZE) {
- log_warnx("rde_dispatch: wrong imsg len");
- break;
- }
/* parse optional path attributes */
- len = imsg.hdr.len - IMSG_HEADER_SIZE;
- if (rde_attr_add(&netconf_state, imsg.data,
- len) == -1) {
+ if (imsg_get_ibuf(&imsg, &ibuf) == -1 ||
+ rde_attr_add(&netconf_state, &ibuf) == -1) {
log_warnx("rde_dispatch: bad network "
"attribute");
rde_filterstate_clean(&netconf_state);
}
break;
case IMSG_NETWORK_DONE:
- if (imsg.hdr.len != IMSG_HEADER_SIZE) {
- log_warnx("rde_dispatch: wrong imsg len");
- break;
- }
TAILQ_CONCAT(&netconf_s.attrset, &session_set, entry);
switch (netconf_s.prefix.aid) {
case AID_INET:
rde_filterstate_clean(&netconf_state);
break;
case IMSG_NETWORK_REMOVE:
- if (imsg.hdr.len - IMSG_HEADER_SIZE !=
- sizeof(struct network_config)) {
+ if (imsg_get_data(&imsg, &netconf_s,
+ sizeof(netconf_s)) == -1) {
log_warnx("rde_dispatch: wrong imsg len");
break;
}
- memcpy(&netconf_s, imsg.data, sizeof(netconf_s));
TAILQ_INIT(&netconf_s.attrset);
switch (netconf_s.prefix.aid) {
}
break;
case IMSG_NETWORK_FLUSH:
- if (imsg.hdr.len != IMSG_HEADER_SIZE) {
- log_warnx("rde_dispatch: wrong imsg len");
- break;
- }
if (rib_dump_new(RIB_ADJ_IN, AID_UNSPEC,
RDE_RUNNER_ROUNDS, NULL, network_flush_upcall,
NULL, NULL) == -1)
log_warn("rde_dispatch: IMSG_NETWORK_FLUSH");
break;
case IMSG_FLOWSPEC_ADD:
- if (imsg.hdr.len - IMSG_HEADER_SIZE <= FLOWSPEC_SIZE) {
- log_warnx("rde_dispatch: wrong imsg len");
- break;
- }
if (curflow != NULL) {
log_warnx("rde_dispatch: "
"unexpected flowspec add");
break;
}
- curflow = malloc(imsg.hdr.len - IMSG_HEADER_SIZE);
+ if (imsg_get_ibuf(&imsg, &ibuf) == -1 ||
+ ibuf_size(&ibuf) <= FLOWSPEC_SIZE) {
+ log_warnx("rde_dispatch: wrong imsg len");
+ break;
+ }
+ curflow = malloc(ibuf_size(&ibuf));
if (curflow == NULL)
fatal(NULL);
- memcpy(curflow, imsg.data,
- imsg.hdr.len - IMSG_HEADER_SIZE);
- if (curflow->len + FLOWSPEC_SIZE !=
- imsg.hdr.len - IMSG_HEADER_SIZE) {
+ memcpy(curflow, ibuf_data(&ibuf), ibuf_size(&ibuf));
+ if (curflow->len + FLOWSPEC_SIZE != ibuf_size(&ibuf)) {
free(curflow);
curflow = NULL;
log_warnx("rde_dispatch: wrong flowspec len");
curflow = NULL;
break;
case IMSG_FLOWSPEC_REMOVE:
- if (imsg.hdr.len - IMSG_HEADER_SIZE <= FLOWSPEC_SIZE) {
- log_warnx("rde_dispatch: wrong imsg len");
- break;
- }
if (curflow != NULL) {
log_warnx("rde_dispatch: "
"unexpected flowspec remove");
break;
}
- curflow = malloc(imsg.hdr.len - IMSG_HEADER_SIZE);
+ if (imsg_get_ibuf(&imsg, &ibuf) == -1 ||
+ ibuf_size(&ibuf) <= FLOWSPEC_SIZE) {
+ log_warnx("rde_dispatch: wrong imsg len");
+ break;
+ }
+ curflow = malloc(ibuf_size(&ibuf));
if (curflow == NULL)
fatal(NULL);
- memcpy(curflow, imsg.data,
- imsg.hdr.len - IMSG_HEADER_SIZE);
- if (curflow->len + FLOWSPEC_SIZE !=
- imsg.hdr.len - IMSG_HEADER_SIZE) {
+ memcpy(curflow, ibuf_data(&ibuf), ibuf_size(&ibuf));
+ if (curflow->len + FLOWSPEC_SIZE != ibuf_size(&ibuf)) {
free(curflow);
curflow = NULL;
log_warnx("rde_dispatch: wrong flowspec len");
curflow = NULL;
break;
case IMSG_FLOWSPEC_FLUSH:
- if (imsg.hdr.len != IMSG_HEADER_SIZE) {
- log_warnx("rde_dispatch: wrong imsg len");
- break;
- }
prefix_flowspec_dump(AID_UNSPEC, NULL,
flowspec_flush_upcall, NULL);
break;
case IMSG_FILTER_SET:
- if (imsg.hdr.len - IMSG_HEADER_SIZE !=
- sizeof(struct filter_set)) {
+ if ((s = malloc(sizeof(struct filter_set))) == NULL)
+ fatal(NULL);
+ if (imsg_get_data(&imsg, s, sizeof(struct filter_set))
+ == -1) {
log_warnx("rde_dispatch: wrong imsg len");
+ free(s);
break;
}
- if ((s = malloc(sizeof(struct filter_set))) == NULL)
- fatal(NULL);
- memcpy(s, imsg.data, sizeof(struct filter_set));
if (s->type == ACTION_SET_NEXTHOP) {
s->action.nh_ref =
nexthop_get(&s->action.nexthop);
case IMSG_CTL_SHOW_NETWORK:
case IMSG_CTL_SHOW_RIB:
case IMSG_CTL_SHOW_RIB_PREFIX:
- if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(req)) {
+ if (imsg_get_data(&imsg, &req, sizeof(req)) == -1) {
log_warnx("rde_dispatch: wrong imsg len");
break;
}
- memcpy(&req, imsg.data, sizeof(req));
- rde_dump_ctx_new(&req, imsg.hdr.pid, imsg.hdr.type);
+ rde_dump_ctx_new(&req, pid, imsg_get_type(&imsg));
break;
case IMSG_CTL_SHOW_FLOWSPEC:
- if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(req)) {
+ if (imsg_get_data(&imsg, &req, sizeof(req)) == -1) {
log_warnx("rde_dispatch: wrong imsg len");
break;
}
- memcpy(&req, imsg.data, sizeof(req));
- prefix_flowspec_dump(req.aid, &imsg.hdr.pid,
+ prefix_flowspec_dump(req.aid, &pid,
flowspec_dump_upcall, flowspec_dump_done);
break;
case IMSG_CTL_SHOW_NEIGHBOR:
- if (imsg.hdr.len - IMSG_HEADER_SIZE != 0) {
- log_warnx("rde_dispatch: wrong imsg len");
- break;
- }
- peer = peer_get(imsg.hdr.peerid);
+ peer = peer_get(peerid);
if (peer != NULL)
memcpy(&stats, &peer->stats, sizeof(stats));
else
memset(&stats, 0, sizeof(stats));
imsg_compose(ibuf_se_ctl, IMSG_CTL_SHOW_NEIGHBOR,
- imsg.hdr.peerid, imsg.hdr.pid, -1,
- &stats, sizeof(stats));
+ peerid, pid, -1, &stats, sizeof(stats));
break;
case IMSG_CTL_SHOW_RIB_MEM:
imsg_compose(ibuf_se_ctl, IMSG_CTL_SHOW_RIB_MEM, 0,
- imsg.hdr.pid, -1, &rdemem, sizeof(rdemem));
+ pid, -1, &rdemem, sizeof(rdemem));
break;
case IMSG_CTL_SHOW_SET:
/* first roa set */
cset.v4_cnt = pset->th.v4_cnt;
cset.v6_cnt = pset->th.v6_cnt;
imsg_compose(ibuf_se_ctl, IMSG_CTL_SHOW_SET, 0,
- imsg.hdr.pid, -1, &cset, sizeof(cset));
+ pid, -1, &cset, sizeof(cset));
/* then aspa set */
memset(&cset, 0, sizeof(cset));
strlcpy(cset.name, "RPKI ASPA", sizeof(cset.name));
aspa_table_stats(rde_aspa, &cset);
imsg_compose(ibuf_se_ctl, IMSG_CTL_SHOW_SET, 0,
- imsg.hdr.pid, -1, &cset, sizeof(cset));
+ pid, -1, &cset, sizeof(cset));
SIMPLEQ_FOREACH(aset, &conf->as_sets, entry) {
memset(&cset, 0, sizeof(cset));
cset.lastchange = aset->lastchange;
cset.as_cnt = set_nmemb(aset->set);
imsg_compose(ibuf_se_ctl, IMSG_CTL_SHOW_SET, 0,
- imsg.hdr.pid, -1, &cset, sizeof(cset));
+ pid, -1, &cset, sizeof(cset));
}
SIMPLEQ_FOREACH(pset, &conf->rde_prefixsets, entry) {
memset(&cset, 0, sizeof(cset));
cset.v4_cnt = pset->th.v4_cnt;
cset.v6_cnt = pset->th.v6_cnt;
imsg_compose(ibuf_se_ctl, IMSG_CTL_SHOW_SET, 0,
- imsg.hdr.pid, -1, &cset, sizeof(cset));
+ pid, -1, &cset, sizeof(cset));
}
SIMPLEQ_FOREACH(pset, &conf->rde_originsets, entry) {
memset(&cset, 0, sizeof(cset));
cset.v4_cnt = pset->th.v4_cnt;
cset.v6_cnt = pset->th.v6_cnt;
imsg_compose(ibuf_se_ctl, IMSG_CTL_SHOW_SET, 0,
- imsg.hdr.pid, -1, &cset, sizeof(cset));
+ pid, -1, &cset, sizeof(cset));
}
- imsg_compose(ibuf_se_ctl, IMSG_CTL_END, 0, imsg.hdr.pid,
+ imsg_compose(ibuf_se_ctl, IMSG_CTL_END, 0, pid,
-1, NULL, 0);
break;
case IMSG_CTL_LOG_VERBOSE:
/* already checked by SE */
- memcpy(&verbose, imsg.data, sizeof(verbose));
+ if (imsg_get_data(&imsg, &verbose, sizeof(verbose)) ==
+ -1) {
+ log_warnx("rde_dispatch: wrong imsg len");
+ break;
+ }
log_setverbose(verbose);
break;
case IMSG_CTL_END:
- imsg_compose(ibuf_se_ctl, IMSG_CTL_END, 0, imsg.hdr.pid,
+ imsg_compose(ibuf_se_ctl, IMSG_CTL_END, 0, pid,
-1, NULL, 0);
break;
case IMSG_CTL_TERMINATE:
- rde_dump_ctx_terminate(imsg.hdr.pid);
+ rde_dump_ctx_terminate(pid);
break;
case IMSG_XON:
- if (imsg.hdr.peerid) {
- peer = peer_get(imsg.hdr.peerid);
+ if (peerid) {
+ peer = peer_get(peerid);
if (peer)
peer->throttled = 0;
} else {
- rde_dump_ctx_throttle(imsg.hdr.pid, 0);
+ rde_dump_ctx_throttle(pid, 0);
}
break;
case IMSG_XOFF:
- if (imsg.hdr.peerid) {
- peer = peer_get(imsg.hdr.peerid);
+ if (peerid) {
+ peer = peer_get(peerid);
if (peer)
peer->throttled = 1;
} else {
- rde_dump_ctx_throttle(imsg.hdr.pid, 1);
+ rde_dump_ctx_throttle(pid, 1);
}
break;
case IMSG_RECONF_DRAIN:
static struct l3vpn *vpn;
static struct flowspec *curflow;
struct imsg imsg;
+ struct ibuf ibuf;
+ struct bgpd_config tconf;
+ struct filterstate state;
+ struct kroute_nexthop knext;
struct mrt xmrt;
- struct roa roa;
+ struct prefixset_item psi;
struct rde_rib rr;
- struct filterstate state;
+ struct roa roa;
+ char name[SET_NAME_LEN];
struct imsgbuf *i;
struct filter_head *nr;
struct filter_rule *r;
struct rib *rib;
struct rde_prefixset *ps;
struct rde_aspath *asp;
- struct prefixset_item psi;
- char *name;
size_t nmemb;
int n, fd, rv;
uint16_t rid;
if (n == 0)
break;
- switch (imsg.hdr.type) {
+ switch (imsg_get_type(&imsg)) {
case IMSG_SOCKET_CONN:
case IMSG_SOCKET_CONN_CTL:
case IMSG_SOCKET_CONN_RTR:
if ((i = malloc(sizeof(struct imsgbuf))) == NULL)
fatal(NULL);
imsg_init(i, fd);
- switch (imsg.hdr.type) {
+ switch (imsg_get_type(&imsg)) {
case IMSG_SOCKET_CONN:
if (ibuf_se) {
log_warnx("Unexpected imsg connection "
}
break;
case IMSG_NETWORK_ADD:
- if (imsg.hdr.len - IMSG_HEADER_SIZE !=
- sizeof(struct network_config)) {
+ if (imsg_get_data(&imsg, &netconf_p,
+ sizeof(netconf_p)) == -1) {
log_warnx("rde_dispatch: wrong imsg len");
break;
}
- memcpy(&netconf_p, imsg.data, sizeof(netconf_p));
TAILQ_INIT(&netconf_p.attrset);
break;
case IMSG_NETWORK_DONE:
rde_filterstate_clean(&state);
break;
case IMSG_NETWORK_REMOVE:
- if (imsg.hdr.len - IMSG_HEADER_SIZE !=
- sizeof(struct network_config)) {
+ if (imsg_get_data(&imsg, &netconf_p,
+ sizeof(netconf_p)) == -1) {
log_warnx("rde_dispatch: wrong imsg len");
break;
}
- memcpy(&netconf_p, imsg.data, sizeof(netconf_p));
TAILQ_INIT(&netconf_p.attrset);
network_delete(&netconf_p);
break;
case IMSG_FLOWSPEC_ADD:
- if (imsg.hdr.len - IMSG_HEADER_SIZE <= FLOWSPEC_SIZE) {
- log_warnx("rde_dispatch: wrong imsg len");
- break;
- }
if (curflow != NULL) {
log_warnx("rde_dispatch: "
"unexpected flowspec add");
break;
}
- curflow = malloc(imsg.hdr.len - IMSG_HEADER_SIZE);
+ if (imsg_get_ibuf(&imsg, &ibuf) == -1 ||
+ ibuf_size(&ibuf) <= FLOWSPEC_SIZE) {
+ log_warnx("rde_dispatch: wrong imsg len");
+ break;
+ }
+ curflow = malloc(ibuf_size(&ibuf));
if (curflow == NULL)
fatal(NULL);
- memcpy(curflow, imsg.data,
- imsg.hdr.len - IMSG_HEADER_SIZE);
- if (curflow->len + FLOWSPEC_SIZE !=
- imsg.hdr.len - IMSG_HEADER_SIZE) {
+ memcpy(curflow, ibuf_data(&ibuf), ibuf_size(&ibuf));
+ if (curflow->len + FLOWSPEC_SIZE != ibuf_size(&ibuf)) {
free(curflow);
curflow = NULL;
log_warnx("rde_dispatch: wrong flowspec len");
curflow = NULL;
break;
case IMSG_FLOWSPEC_REMOVE:
- if (imsg.hdr.len - IMSG_HEADER_SIZE <= FLOWSPEC_SIZE) {
- log_warnx("rde_dispatch: wrong imsg len");
- break;
- }
if (curflow != NULL) {
log_warnx("rde_dispatch: "
"unexpected flowspec remove");
break;
}
- curflow = malloc(imsg.hdr.len - IMSG_HEADER_SIZE);
+ if (imsg_get_ibuf(&imsg, &ibuf) == -1 ||
+ ibuf_size(&ibuf) <= FLOWSPEC_SIZE) {
+ log_warnx("rde_dispatch: wrong imsg len");
+ break;
+ }
+ curflow = malloc(ibuf_size(&ibuf));
if (curflow == NULL)
fatal(NULL);
- memcpy(curflow, imsg.data,
- imsg.hdr.len - IMSG_HEADER_SIZE);
- if (curflow->len + FLOWSPEC_SIZE !=
- imsg.hdr.len - IMSG_HEADER_SIZE) {
+ memcpy(curflow, ibuf_data(&ibuf), ibuf_size(&ibuf));
+ if (curflow->len + FLOWSPEC_SIZE != ibuf_size(&ibuf)) {
free(curflow);
curflow = NULL;
log_warnx("rde_dispatch: wrong flowspec len");
curflow = NULL;
break;
case IMSG_RECONF_CONF:
- if (imsg.hdr.len - IMSG_HEADER_SIZE !=
- sizeof(struct bgpd_config))
+ if (imsg_get_data(&imsg, &tconf, sizeof(tconf)) == -1)
fatalx("IMSG_RECONF_CONF bad len");
out_rules_tmp = calloc(1, sizeof(struct filter_head));
if (out_rules_tmp == NULL)
fatal(NULL);
TAILQ_INIT(out_rules_tmp);
nconf = new_config();
- copy_config(nconf, imsg.data);
+ copy_config(nconf, &tconf);
for (rid = 0; rid < rib_size; rid++) {
if ((rib = rib_byid(rid)) == NULL)
}
break;
case IMSG_RECONF_RIB:
- if (imsg.hdr.len - IMSG_HEADER_SIZE !=
- sizeof(struct rde_rib))
+ if (imsg_get_data(&imsg, &rr, sizeof(rr)) == -1)
fatalx("IMSG_RECONF_RIB bad len");
- memcpy(&rr, imsg.data, sizeof(rr));
rib = rib_byid(rib_find(rr.name));
if (rib == NULL) {
rib = rib_new(rr.name, rr.rtableid, rr.flags);
}
break;
case IMSG_RECONF_FILTER:
- if (imsg.hdr.len - IMSG_HEADER_SIZE !=
- sizeof(struct filter_rule))
- fatalx("IMSG_RECONF_FILTER bad len");
if ((r = malloc(sizeof(struct filter_rule))) == NULL)
fatal(NULL);
- memcpy(r, imsg.data, sizeof(struct filter_rule));
+ if (imsg_get_data(&imsg, r, sizeof(*r)) == -1)
+ fatalx("IMSG_RECONF_FILTER bad len");
if (r->match.prefixset.name[0] != '\0') {
r->match.prefixset.ps =
rde_find_prefixset(r->match.prefixset.name,
break;
case IMSG_RECONF_PREFIX_SET:
case IMSG_RECONF_ORIGIN_SET:
- if (imsg.hdr.len - IMSG_HEADER_SIZE !=
- sizeof(ps->name))
- fatalx("IMSG_RECONF_PREFIX_SET bad len");
ps = calloc(1, sizeof(struct rde_prefixset));
if (ps == NULL)
fatal(NULL);
- memcpy(ps->name, imsg.data, sizeof(ps->name));
- if (imsg.hdr.type == IMSG_RECONF_ORIGIN_SET) {
+ if (imsg_get_data(&imsg, ps->name, sizeof(ps->name)) ==
+ -1)
+ fatalx("IMSG_RECONF_PREFIX_SET bad len");
+ if (imsg_get_type(&imsg) == IMSG_RECONF_ORIGIN_SET) {
SIMPLEQ_INSERT_TAIL(&nconf->rde_originsets, ps,
entry);
} else {
last_prefixset = ps;
break;
case IMSG_RECONF_ROA_ITEM:
- if (imsg.hdr.len - IMSG_HEADER_SIZE != sizeof(roa))
+ if (imsg_get_data(&imsg, &roa, sizeof(roa)) == -1)
fatalx("IMSG_RECONF_ROA_ITEM bad len");
- memcpy(&roa, imsg.data, sizeof(roa));
rv = trie_roa_add(&last_prefixset->th, &roa);
break;
case IMSG_RECONF_PREFIX_SET_ITEM:
- if (imsg.hdr.len - IMSG_HEADER_SIZE != sizeof(psi))
+ if (imsg_get_data(&imsg, &psi, sizeof(psi)) == -1)
fatalx("IMSG_RECONF_PREFIX_SET_ITEM bad len");
- memcpy(&psi, imsg.data, sizeof(psi));
if (last_prefixset == NULL)
fatalx("King Bula has no prefixset");
rv = trie_add(&last_prefixset->th,
psi.p.len);
break;
case IMSG_RECONF_AS_SET:
- if (imsg.hdr.len - IMSG_HEADER_SIZE !=
- sizeof(nmemb) + SET_NAME_LEN)
+ if (imsg_get_ibuf(&imsg, &ibuf) == -1 ||
+ ibuf_get(&ibuf, &nmemb, sizeof(nmemb)) == -1 ||
+ ibuf_get(&ibuf, name, sizeof(name)) == -1)
fatalx("IMSG_RECONF_AS_SET bad len");
- memcpy(&nmemb, imsg.data, sizeof(nmemb));
- name = (char *)imsg.data + sizeof(nmemb);
if (as_sets_lookup(&nconf->as_sets, name) != NULL)
fatalx("duplicate as-set %s", name);
last_as_set = as_sets_new(&nconf->as_sets, name, nmemb,
sizeof(uint32_t));
break;
case IMSG_RECONF_AS_SET_ITEMS:
- nmemb = imsg.hdr.len - IMSG_HEADER_SIZE;
- nmemb /= sizeof(uint32_t);
- if (set_add(last_as_set->set, imsg.data, nmemb) != 0)
+ if (imsg_get_ibuf(&imsg, &ibuf) == -1)
+ fatalx("IMSG_RECONF_AS_SET_ITEMS bad len");
+ nmemb = ibuf_size(&ibuf) / sizeof(uint32_t);
+ if (set_add(last_as_set->set, ibuf_data(&ibuf),
+ nmemb) != 0)
fatal(NULL);
break;
case IMSG_RECONF_AS_SET_DONE:
last_as_set = NULL;
break;
case IMSG_RECONF_VPN:
- if (imsg.hdr.len - IMSG_HEADER_SIZE !=
- sizeof(struct l3vpn))
- fatalx("IMSG_RECONF_VPN bad len");
- if ((vpn = malloc(sizeof(struct l3vpn))) == NULL)
+ if ((vpn = malloc(sizeof(*vpn))) == NULL)
fatal(NULL);
- memcpy(vpn, imsg.data, sizeof(struct l3vpn));
+ if (imsg_get_data(&imsg, vpn, sizeof(*vpn)) == -1)
+ fatalx("IMSG_RECONF_VPN bad len");
TAILQ_INIT(&vpn->import);
TAILQ_INIT(&vpn->export);
TAILQ_INIT(&vpn->net_l);
rde_reload_done();
break;
case IMSG_NEXTHOP_UPDATE:
- nexthop_update(imsg.data);
+ if (imsg_get_data(&imsg, &knext, sizeof(knext)) == -1)
+ fatalx("IMSG_NEXTHOP_UPDATE bad len");
+ nexthop_update(&knext);
break;
case IMSG_FILTER_SET:
- if (imsg.hdr.len > IMSG_HEADER_SIZE +
- sizeof(struct filter_set))
- fatalx("IMSG_FILTER_SET bad len");
- if ((s = malloc(sizeof(struct filter_set))) == NULL)
+ if ((s = malloc(sizeof(*s))) == NULL)
fatal(NULL);
- memcpy(s, imsg.data, sizeof(struct filter_set));
+ if (imsg_get_data(&imsg, s, sizeof(*s)) == -1)
+ fatalx("IMSG_FILTER_SET bad len");
if (s->type == ACTION_SET_NEXTHOP) {
s->action.nh_ref =
nexthop_get(&s->action.nexthop);
break;
case IMSG_MRT_OPEN:
case IMSG_MRT_REOPEN:
- if (imsg.hdr.len > IMSG_HEADER_SIZE +
- sizeof(struct mrt)) {
+ if (imsg_get_data(&imsg, &xmrt, sizeof(xmrt)) == -1) {
log_warnx("wrong imsg len");
break;
}
- memcpy(&xmrt, imsg.data, sizeof(xmrt));
if ((fd = imsg_get_fd(&imsg)) == -1)
log_warnx("expected to receive fd for mrt dump "
"but didn't receive any");
else if (xmrt.type == MRT_TABLE_DUMP ||
xmrt.type == MRT_TABLE_DUMP_MP ||
xmrt.type == MRT_TABLE_DUMP_V2) {
- rde_dump_mrt_new(&xmrt, imsg.hdr.pid, fd);
+ rde_dump_mrt_new(&xmrt, imsg_get_pid(&imsg),
+ fd);
} else
close(fd);
break;
/* ignore end message because a dump is atomic */
break;
default:
- fatalx("unhandled IMSG %u", imsg.hdr.type);
+ fatalx("unhandled IMSG %u", imsg_get_type(&imsg));
}
imsg_free(&imsg);
}
if (n == 0)
break;
- switch (imsg.hdr.type) {
+ switch (imsg_get_type(&imsg)) {
case IMSG_RECONF_ROA_SET:
/* start of update */
trie_free(&roa_new.th); /* clear new roa */
break;
case IMSG_RECONF_ROA_ITEM:
- if (imsg.hdr.len - IMSG_HEADER_SIZE !=
- sizeof(roa))
+ if (imsg_get_data(&imsg, &roa, sizeof(roa)) == -1)
fatalx("IMSG_RECONF_ROA_ITEM bad len");
- memcpy(&roa, imsg.data, sizeof(roa));
if (trie_roa_add(&roa_new.th, &roa) != 0) {
struct bgpd_addr p = {
.aid = roa.aid,
}
break;
case IMSG_RECONF_ASPA_PREP:
- if (imsg.hdr.len - IMSG_HEADER_SIZE != sizeof(ap))
+ if (imsg_get_data(&imsg, &ap, sizeof(ap)) == -1)
fatalx("IMSG_RECONF_ASPA_PREP bad len");
if (aspa_new)
fatalx("unexpected IMSG_RECONF_ASPA_PREP");
- memcpy(&ap, imsg.data, sizeof(ap));
aspa_new = aspa_table_prep(ap.entries, ap.datasize);
break;
case IMSG_RECONF_ASPA:
fatalx("unexpected IMSG_RECONF_ASPA");
if (aspa != NULL)
fatalx("IMSG_RECONF_ASPA already sent");
- if (imsg.hdr.len - IMSG_HEADER_SIZE !=
- sizeof(uint32_t) * 2)
- fatalx("IMSG_RECONF_ASPA bad len");
-
if ((aspa = calloc(1, sizeof(*aspa))) == NULL)
fatal("IMSG_RECONF_ASPA");
- memcpy(&aspa->as, imsg.data, sizeof(aspa->as));
- memcpy(&aspa->num, (char *)imsg.data + sizeof(aspa->as),
- sizeof(aspa->num));
+ if (imsg_get_data(&imsg, aspa,
+ offsetof(struct aspa_set, tas)) == -1)
+ fatal("IMSG_RECONF_ASPA bad len");
break;
case IMSG_RECONF_ASPA_TAS:
if (aspa == NULL)
fatalx("unexpected IMSG_RECONF_ASPA_TAS");
- if (imsg.hdr.len - IMSG_HEADER_SIZE !=
- aspa->num * sizeof(uint32_t))
+ if (imsg_get_len(&imsg) != aspa->num * sizeof(uint32_t))
fatalx("IMSG_RECONF_ASPA_TAS bad len");
aspa->tas = reallocarray(NULL, aspa->num,
sizeof(uint32_t));
if (aspa->tas == NULL)
fatal("IMSG_RECONF_ASPA_TAS");
- memcpy(aspa->tas, imsg.data,
- aspa->num * sizeof(uint32_t));
+ if (imsg_get_data(&imsg, aspa->tas,
+ aspa->num * sizeof(uint32_t)) == -1)
+ fatal("IMSG_RECONF_ASPA_TAS bad len");
break;
case IMSG_RECONF_ASPA_DONE:
if (aspa_new == NULL)
if (!peer_imsg_pop(peer, &imsg))
return;
- switch (imsg.hdr.type) {
+ switch (imsg_get_type(&imsg)) {
case IMSG_UPDATE:
if (peer->state != PEER_UP)
break;
rde_update_dispatch(peer, &imsg);
break;
case IMSG_REFRESH:
- if (imsg.hdr.len - IMSG_HEADER_SIZE != sizeof(rr)) {
+ if (imsg_get_data(&imsg, &rr, sizeof(rr)) == -1) {
log_warnx("route refresh: wrong imsg len");
break;
}
- memcpy(&rr, imsg.data, sizeof(rr));
if (rr.aid >= AID_MAX) {
log_peer_warnx(&peer->conf,
"route refresh: bad AID %d", rr.aid);
break;
default:
log_warnx("%s: unhandled imsg type %d", __func__,
- imsg.hdr.type);
+ imsg_get_type(&imsg));
break;
}
return (plen);
}
+#undef UPD_READ
+#undef CHECK_FLAGS
+
int
-rde_attr_add(struct filterstate *state, u_char *p, uint16_t len)
+rde_attr_add(struct filterstate *state, struct ibuf *buf)
{
uint16_t attr_len;
- uint16_t plen = 0;
uint8_t flags;
uint8_t type;
uint8_t tmp8;
- if (len < 3)
+ if (ibuf_get_n8(buf, &flags) == -1 ||
+ ibuf_get_n8(buf, &type) == -1)
return (-1);
- UPD_READ(&flags, p, plen, 1);
- UPD_READ(&type, p, plen, 1);
-
if (flags & ATTR_EXTLEN) {
- if (len - plen < 2)
+ if (ibuf_get_n16(buf, &attr_len) == -1)
return (-1);
- UPD_READ(&attr_len, p, plen, 2);
- attr_len = ntohs(attr_len);
} else {
- UPD_READ(&tmp8, p, plen, 1);
+ if (ibuf_get_n8(buf, &tmp8) == -1)
+ return (-1);
attr_len = tmp8;
}
- if (len - plen < attr_len)
+ if (ibuf_size(buf) != attr_len)
return (-1);
switch (type) {
case ATTR_COMMUNITIES:
- return community_add(&state->communities, flags, p, attr_len);
+ return community_add(&state->communities, flags,
+ ibuf_data(buf), attr_len);
case ATTR_LARGE_COMMUNITIES:
- return community_large_add(&state->communities, flags, p,
- attr_len);
+ return community_large_add(&state->communities, flags,
+ ibuf_data(buf), attr_len);
case ATTR_EXT_COMMUNITIES:
return community_ext_add(&state->communities, flags, 0,
- p, attr_len);
+ ibuf_data(buf), attr_len);
}
- if (attr_optadd(&state->aspath, flags, type, p, attr_len) == -1)
+ if (attr_optadd(&state->aspath, flags, type, ibuf_data(buf),
+ attr_len) == -1)
return (-1);
return (0);
}
-#undef UPD_READ
-#undef CHECK_FLAGS
-
uint8_t
rde_attr_missing(struct rde_aspath *a, int ebgp, uint16_t nlrilen)
{