Call pfkey_remove() only after the Session Engine finished reloading its
authorclaudio <claudio@openbsd.org>
Wed, 4 Sep 2024 13:30:10 +0000 (13:30 +0000)
committerclaudio <claudio@openbsd.org>
Wed, 4 Sep 2024 13:30:10 +0000 (13:30 +0000)
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
usr.sbin/bgpd/config.c
usr.sbin/bgpd/session.h

index 8b6e1bc..e997d68 100644 (file)
@@ -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 <henning@openbsd.org>
@@ -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;
index bf93a52..94efad7 100644 (file)
@@ -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 <henning@openbsd.org>
@@ -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)
 {
index cd008c0..12e871e 100644 (file)
@@ -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 <henning@openbsd.org>
@@ -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 */