From 7f893e0cbaa30667b9cacb947cb5fc65fedd29ae Mon Sep 17 00:00:00 2001 From: claudio Date: Wed, 4 Sep 2024 13:30:10 +0000 Subject: [PATCH] Call pfkey_remove() only after the Session Engine finished reloading its configuration. Doing so before could result in some messages being sent out without proper TCP-MD5 signature. Fix for: https://github.com/openbgpd-portable/openbgpd-portable/issues/82 OK tb@ --- usr.sbin/bgpd/bgpd.c | 14 +++++++++----- usr.sbin/bgpd/config.c | 29 +++++++++++++++++++++-------- usr.sbin/bgpd/session.h | 3 ++- 3 files changed, 32 insertions(+), 14 deletions(-) diff --git a/usr.sbin/bgpd/bgpd.c b/usr.sbin/bgpd/bgpd.c index 8b6e1bc70ce..e997d680259 100644 --- a/usr.sbin/bgpd/bgpd.c +++ b/usr.sbin/bgpd/bgpd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bgpd.c,v 1.265 2024/08/12 09:04:23 claudio Exp $ */ +/* $OpenBSD: bgpd.c,v 1.266 2024/09/04 13:30:10 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer @@ -575,13 +575,11 @@ reconfigure(char *conffile, struct bgpd_config *conf) merge_config(conf, new_conf); - if (prepare_listeners(conf) == -1) { + if (prepare_listeners(conf) == -1) return (1); - } - if (control_setup(conf) == -1) { + if (control_setup(conf) == -1) return (1); - } return send_config(conf); } @@ -647,6 +645,9 @@ send_config(struct bgpd_config *conf) /* send peer list to the SE */ RB_FOREACH(p, peer_head, &conf->peers) { + if (p->reconf_action == RECONF_DELETE) + continue; + if (imsg_compose(ibuf_se, IMSG_RECONF_PEER, p->conf.id, 0, -1, &p->conf, sizeof(p->conf)) == -1) return (-1); @@ -1025,6 +1026,9 @@ dispatch_imsg(struct imsgbuf *imsgbuf, int idx, struct bgpd_config *conf) /* redistribute list needs to be reloaded too */ kr_reload(); + + /* also remove old peers */ + free_deleted_peers(conf); } reconfpending--; break; diff --git a/usr.sbin/bgpd/config.c b/usr.sbin/bgpd/config.c index bf93a521beb..94efad738b8 100644 --- a/usr.sbin/bgpd/config.c +++ b/usr.sbin/bgpd/config.c @@ -1,4 +1,4 @@ -/* $OpenBSD: config.c,v 1.110 2024/08/14 19:09:51 claudio Exp $ */ +/* $OpenBSD: config.c,v 1.111 2024/09/04 13:30:10 claudio Exp $ */ /* * Copyright (c) 2003, 2004, 2005 Henning Brauer @@ -434,8 +434,7 @@ merge_config(struct bgpd_config *xconf, struct bgpd_config *conf) * merge peers: * - need to know which peers are new, replaced and removed * - walk over old peers and check if there is a corresponding new - * peer if so mark it RECONF_KEEP. Remove all old peers. - * - swap lists (old peer list is actually empty). + * peer if so mark it RECONF_KEEP. Mark all old peers RECONF_DELETE. */ RB_FOREACH_SAFE(p, peer_head, &xconf->peers, nextp) { np = getpeerbyid(conf, p->conf.id); @@ -443,13 +442,12 @@ merge_config(struct bgpd_config *xconf, struct bgpd_config *conf) np->reconf_action = RECONF_KEEP; /* copy the auth state since parent uses it */ np->auth = p->auth; + + RB_REMOVE(peer_head, &xconf->peers, p); + free(p); } else { - /* peer no longer exists, clear pfkey state */ - pfkey_remove(p); + p->reconf_action = RECONF_DELETE; } - - RB_REMOVE(peer_head, &xconf->peers, p); - free(p); } RB_FOREACH_SAFE(np, peer_head, &conf->peers, nextp) { RB_REMOVE(peer_head, &conf->peers, np); @@ -461,6 +459,21 @@ merge_config(struct bgpd_config *xconf, struct bgpd_config *conf) free_config(conf); } +void +free_deleted_peers(struct bgpd_config *conf) +{ + struct peer *p, *nextp; + + RB_FOREACH_SAFE(p, peer_head, &conf->peers, nextp) { + if (p->reconf_action == RECONF_DELETE) { + /* peer no longer exists, clear pfkey state */ + pfkey_remove(p); + RB_REMOVE(peer_head, &conf->peers, p); + free(p); + } + } +} + uint32_t get_bgpid(void) { diff --git a/usr.sbin/bgpd/session.h b/usr.sbin/bgpd/session.h index cd008c0ae77..12e871eef4d 100644 --- a/usr.sbin/bgpd/session.h +++ b/usr.sbin/bgpd/session.h @@ -1,4 +1,4 @@ -/* $OpenBSD: session.h,v 1.172 2024/08/20 11:59:39 claudio Exp $ */ +/* $OpenBSD: session.h,v 1.173 2024/09/04 13:30:10 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer @@ -247,6 +247,7 @@ int carp_demote_set(char *, int); /* config.c */ void merge_config(struct bgpd_config *, struct bgpd_config *); +void free_deleted_peers(struct bgpd_config *); int prepare_listeners(struct bgpd_config *); /* control.c */ -- 2.20.1