summaryrefslogtreecommitdiff
path: root/usr.sbin/bgpd
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/bgpd')
-rw-r--r--usr.sbin/bgpd/rde.c63
-rw-r--r--usr.sbin/bgpd/rde.h4
-rw-r--r--usr.sbin/bgpd/rde_peer.c8
-rw-r--r--usr.sbin/bgpd/rde_update.c12
-rw-r--r--usr.sbin/bgpd/session.c33
5 files changed, 83 insertions, 37 deletions
diff --git a/usr.sbin/bgpd/rde.c b/usr.sbin/bgpd/rde.c
index bb3be1adb36..0c36005cff7 100644
--- a/usr.sbin/bgpd/rde.c
+++ b/usr.sbin/bgpd/rde.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde.c,v 1.519 2021/04/27 09:07:10 claudio Exp $ */
+/* $OpenBSD: rde.c,v 1.520 2021/05/06 09:18:54 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -666,6 +666,10 @@ badnetdel:
rde_dump_ctx_throttle(imsg.hdr.pid, 1);
}
break;
+ case IMSG_RECONF_DRAIN:
+ imsg_compose(ibuf_se, IMSG_RECONF_DRAIN, 0, 0,
+ -1, NULL, 0);
+ break;
default:
break;
}
@@ -2136,7 +2140,7 @@ rde_update_log(const char *message, u_int16_t rid,
char *p = NULL;
if (!((conf->log & BGPD_LOG_UPDATES) ||
- (peer->conf.flags & PEERFLAG_LOG_UPDATES)))
+ (peer->flags & PEERFLAG_LOG_UPDATES)))
return;
if (next != NULL)
@@ -2919,7 +2923,7 @@ rde_generate_updates(struct rib *rib, struct prefix *new, struct prefix *old,
if (peer->state != PEER_UP)
continue;
/* handle evaluate all, keep track if it is needed */
- if (peer->conf.flags & PEERFLAG_EVALUATE_ALL)
+ if (peer->flags & PEERFLAG_EVALUATE_ALL)
rde_eval_all = 1;
else if (eval_all)
/* skip default peers if the best path didn't change */
@@ -2931,8 +2935,8 @@ rde_generate_updates(struct rib *rib, struct prefix *new, struct prefix *old,
if (peer->capa.mp[aid] == 0)
continue;
/* skip peers with special export types */
- if (peer->conf.export_type == EXPORT_NONE ||
- peer->conf.export_type == EXPORT_DEFAULT_ROUTE)
+ if (peer->export_type == EXPORT_NONE ||
+ peer->export_type == EXPORT_DEFAULT_ROUTE)
continue;
up_generate_updates(out_rules, peer, new, old);
@@ -3289,13 +3293,34 @@ rde_reload_done(void)
continue;
peer->reconf_out = 0;
peer->reconf_rib = 0;
+ if (peer->export_type != peer->conf.export_type) {
+ log_peer_info(&peer->conf, "export type change, "
+ "reloading");
+ peer->reconf_rib = 1;
+ }
+ if ((peer->flags & PEERFLAG_EVALUATE_ALL) !=
+ (peer->conf.flags & PEERFLAG_EVALUATE_ALL)) {
+ log_peer_info(&peer->conf, "rde evaluate change, "
+ "reloading");
+ peer->reconf_rib = 1;
+ }
+ if ((peer->flags & PEERFLAG_TRANS_AS) !=
+ (peer->conf.flags & PEERFLAG_TRANS_AS)) {
+ log_peer_info(&peer->conf, "transparent-as change, "
+ "reloading");
+ peer->reconf_rib = 1;
+ }
if (peer->loc_rib_id != rib_find(peer->conf.rib)) {
log_peer_info(&peer->conf, "rib change, reloading");
peer->loc_rib_id = rib_find(peer->conf.rib);
if (peer->loc_rib_id == RIB_NOTFOUND)
fatalx("King Bula's peer met an unknown RIB");
peer->reconf_rib = 1;
- softreconfig++;
+ }
+ peer->export_type = peer->conf.export_type;
+ peer->flags = peer->conf.flags;
+
+ if (peer->reconf_rib) {
if (prefix_dump_new(peer, AID_UNSPEC,
RDE_RUNNER_ROUNDS, NULL, rde_up_flush_upcall,
rde_softreconfig_in_done, NULL) == -1)
@@ -3362,15 +3387,15 @@ rde_reload_done(void)
log_info("RDE reconfigured");
+ softreconfig++;
if (reload > 0) {
- softreconfig++;
if (rib_dump_new(RIB_ADJ_IN, AID_UNSPEC, RDE_RUNNER_ROUNDS,
- rib_byid(RIB_ADJ_IN), rde_softreconfig_in,
- rde_softreconfig_in_done, NULL) == -1)
+ NULL, rde_softreconfig_in, rde_softreconfig_in_done,
+ NULL) == -1)
fatal("%s: rib_dump_new", __func__);
log_info("running softreconfig in");
} else {
- rde_softreconfig_in_done(NULL, AID_UNSPEC);
+ rde_softreconfig_in_done((void *)1, AID_UNSPEC);
}
}
@@ -3380,14 +3405,13 @@ rde_softreconfig_in_done(void *arg, u_int8_t dummy)
struct rde_peer *peer;
u_int16_t i;
- if (arg != NULL) {
- softreconfig--;
- /* one guy done but other dumps are still running */
- if (softreconfig > 0)
- return;
+ softreconfig--;
+ /* one guy done but other dumps are still running */
+ if (softreconfig > 0)
+ return;
+ if (arg == NULL)
log_info("softreconfig in done");
- }
/* now do the Adj-RIB-Out sync and a possible FIB sync */
softreconfig = 0;
@@ -3419,11 +3443,10 @@ rde_softreconfig_in_done(void *arg, u_int8_t dummy)
u_int8_t aid;
if (peer->reconf_out) {
- if (peer->conf.export_type == EXPORT_NONE) {
+ if (peer->export_type == EXPORT_NONE) {
/* nothing to do here */
peer->reconf_out = 0;
- } else if (peer->conf.export_type ==
- EXPORT_DEFAULT_ROUTE) {
+ } else if (peer->export_type == EXPORT_DEFAULT_ROUTE) {
/* just resend the default route */
for (aid = 0; aid < AID_MAX; aid++) {
if (peer->capa.mp[aid])
@@ -3739,7 +3762,7 @@ rde_as4byte(struct rde_peer *peer)
static int
rde_no_as_set(struct rde_peer *peer)
{
- return (peer->conf.flags & PEERFLAG_NO_AS_SET);
+ return (peer->flags & PEERFLAG_NO_AS_SET);
}
/* End-of-RIB marker, RFC 4724 */
diff --git a/usr.sbin/bgpd/rde.h b/usr.sbin/bgpd/rde.h
index df20239c164..1fad1c41fdc 100644
--- a/usr.sbin/bgpd/rde.h
+++ b/usr.sbin/bgpd/rde.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde.h,v 1.237 2021/03/02 09:45:07 claudio Exp $ */
+/* $OpenBSD: rde.h,v 1.238 2021/05/06 09:18:54 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org> and
@@ -103,12 +103,14 @@ struct rde_peer {
u_int32_t up_nlricnt;
u_int32_t up_wcnt;
enum peer_state state;
+ enum export_type export_type;
u_int16_t loc_rib_id;
u_int16_t short_as;
u_int16_t mrt_idx;
u_int8_t reconf_out; /* out filter changed */
u_int8_t reconf_rib; /* rib changed */
u_int8_t throttled;
+ u_int8_t flags;
};
#define AS_SET 1
diff --git a/usr.sbin/bgpd/rde_peer.c b/usr.sbin/bgpd/rde_peer.c
index 8f9dd053836..1bbebf93c48 100644
--- a/usr.sbin/bgpd/rde_peer.c
+++ b/usr.sbin/bgpd/rde_peer.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde_peer.c,v 1.6 2020/12/04 11:57:13 claudio Exp $ */
+/* $OpenBSD: rde_peer.c,v 1.7 2021/05/06 09:18:54 claudio Exp $ */
/*
* Copyright (c) 2019 Claudio Jeker <claudio@openbsd.org>
@@ -170,6 +170,8 @@ peer_add(u_int32_t id, struct peer_config *p_conf)
if (peer->loc_rib_id == RIB_NOTFOUND)
fatalx("King Bula's new peer met an unknown RIB");
peer->state = PEER_NONE;
+ peer->export_type = peer->conf.export_type;
+ peer->flags = peer->conf.flags;
SIMPLEQ_INIT(&peer->imsg_queue);
head = PEER_HASH(id);
@@ -429,11 +431,11 @@ peer_stale(struct rde_peer *peer, u_int8_t aid)
void
peer_dump(struct rde_peer *peer, u_int8_t aid)
{
- if (peer->conf.export_type == EXPORT_NONE) {
+ if (peer->export_type == EXPORT_NONE) {
/* nothing to send apart from the marker */
if (peer->capa.grestart.restart)
prefix_add_eor(peer, aid);
- } else if (peer->conf.export_type == EXPORT_DEFAULT_ROUTE) {
+ } else if (peer->export_type == EXPORT_DEFAULT_ROUTE) {
up_generate_default(out_rules, peer, aid);
rde_up_dump_done(peer, aid);
} else {
diff --git a/usr.sbin/bgpd/rde_update.c b/usr.sbin/bgpd/rde_update.c
index 0d7193af0d1..8910ca0db63 100644
--- a/usr.sbin/bgpd/rde_update.c
+++ b/usr.sbin/bgpd/rde_update.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde_update.c,v 1.126 2021/04/20 11:19:56 claudio Exp $ */
+/* $OpenBSD: rde_update.c,v 1.127 2021/05/06 09:18:54 claudio Exp $ */
/*
* Copyright (c) 2004 Claudio Jeker <claudio@openbsd.org>
@@ -135,7 +135,7 @@ again:
* skip the filters.
*/
if (need_withdraw &&
- !(peer->conf.flags & PEERFLAG_EVALUATE_ALL)) {
+ !(peer->flags & PEERFLAG_EVALUATE_ALL)) {
new = NULL;
goto again;
}
@@ -148,7 +148,7 @@ again:
new->pt->prefixlen, prefix_vstate(new), &state) ==
ACTION_DENY) {
rde_filterstate_clean(&state);
- if (peer->conf.flags & PEERFLAG_EVALUATE_ALL)
+ if (peer->flags & PEERFLAG_EVALUATE_ALL)
new = LIST_NEXT(new, entry.list.rib);
else
new = NULL;
@@ -360,7 +360,7 @@ up_generate_attr(u_char *buf, int len, struct rde_peer *peer,
break;
case ATTR_ASPATH:
if (!peer->conf.ebgp ||
- peer->conf.flags & PEERFLAG_TRANS_AS)
+ peer->flags & PEERFLAG_TRANS_AS)
pdata = aspath_prepend(asp->aspath,
peer->conf.local_as, 0, &plen);
else
@@ -399,7 +399,7 @@ up_generate_attr(u_char *buf, int len, struct rde_peer *peer,
*/
if (asp->flags & F_ATTR_MED && (!peer->conf.ebgp ||
asp->flags & F_ATTR_MED_ANNOUNCE ||
- peer->conf.flags & PEERFLAG_TRANS_AS)) {
+ peer->flags & PEERFLAG_TRANS_AS)) {
tmp32 = htonl(asp->med);
if ((r = attr_write(buf + wlen, len,
ATTR_OPTIONAL, ATTR_MED, &tmp32, 4)) == -1)
@@ -439,7 +439,7 @@ up_generate_attr(u_char *buf, int len, struct rde_peer *peer,
case ATTR_AS4_PATH:
if (neednewpath) {
if (!peer->conf.ebgp ||
- peer->conf.flags & PEERFLAG_TRANS_AS)
+ peer->flags & PEERFLAG_TRANS_AS)
pdata = aspath_prepend(asp->aspath,
peer->conf.local_as, 0, &plen);
else
diff --git a/usr.sbin/bgpd/session.c b/usr.sbin/bgpd/session.c
index e2649432b9b..b8b6b6dc11b 100644
--- a/usr.sbin/bgpd/session.c
+++ b/usr.sbin/bgpd/session.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: session.c,v 1.413 2021/05/03 14:08:09 claudio Exp $ */
+/* $OpenBSD: session.c,v 1.414 2021/05/06 09:18:54 claudio Exp $ */
/*
* Copyright (c) 2003, 2004, 2005 Henning Brauer <henning@openbsd.org>
@@ -2734,10 +2734,24 @@ session_dispatch_imsg(struct imsgbuf *ibuf, int idx, u_int *listener_cnt)
}
break;
case IMSG_RECONF_DRAIN:
- if (idx != PFD_PIPE_MAIN)
- fatalx("reconf request not from parent");
- imsg_compose(ibuf_main, IMSG_RECONF_DRAIN, 0, 0,
- -1, NULL, 0);
+ switch (idx) {
+ case PFD_PIPE_ROUTE:
+ if (nconf != NULL)
+ fatalx("got unexpected %s from RDE",
+ "IMSG_RECONF_DONE");
+ imsg_compose(ibuf_main, IMSG_RECONF_DONE, 0, 0,
+ -1, NULL, 0);
+ break;
+ case PFD_PIPE_MAIN:
+ if (nconf == NULL)
+ fatalx("got unexpected %s from parent",
+ "IMSG_RECONF_DONE");
+ imsg_compose(ibuf_main, IMSG_RECONF_DRAIN, 0, 0,
+ -1, NULL, 0);
+ break;
+ default:
+ fatalx("reconf request not from parent or RDE");
+ }
break;
case IMSG_RECONF_DONE:
if (idx != PFD_PIPE_MAIN)
@@ -2771,8 +2785,10 @@ session_dispatch_imsg(struct imsgbuf *ibuf, int idx, u_int *listener_cnt)
nconf = NULL;
pending_reconf = 0;
log_info("SE reconfigured");
- imsg_compose(ibuf_main, IMSG_RECONF_DONE, 0, 0,
- -1, NULL, 0);
+ /*
+ * IMSG_RECONF_DONE is sent when the RDE drained
+ * the peer config sent in merge_peers().
+ */
break;
case IMSG_IFINFO:
if (idx != PFD_PIPE_MAIN)
@@ -3343,6 +3359,9 @@ merge_peers(struct bgpd_config *c, struct bgpd_config *nc)
}
}
+ if (imsg_rde(IMSG_RECONF_DRAIN, 0, NULL, 0) == -1)
+ fatalx("imsg_compose error");
+
/* pfkeys of new peers already loaded by the parent process */
RB_FOREACH_SAFE(np, peer_head, &nc->peers, next) {
RB_REMOVE(peer_head, &nc->peers, np);