This diff provides a working 'ospf6ctl reload'.

Must be applied after https://marc.info/?l=openbsd-tech&m=159084971620177&w=2

Index: ospf6ctl/ospf6ctl.c
===================================================================
RCS file: /home/denis/dev/cvs/src/usr.sbin/ospf6ctl/ospf6ctl.c,v
retrieving revision 1.51
diff -u -p -r1.51 ospf6ctl.c
--- ospf6ctl/ospf6ctl.c 5 Apr 2020 18:19:04 -0000       1.51
+++ ospf6ctl/ospf6ctl.c 30 May 2020 18:02:41 -0000
@@ -235,14 +235,10 @@ main(int argc, char *argv[])
                done = 1;
                break;
        case RELOAD:
-#ifdef notyet
                imsg_compose(ibuf, IMSG_CTL_RELOAD, 0, 0, -1, NULL, 0);
                printf("reload request sent.\n");
                done = 1;
                break;
-#else
-               errx(1, "reload not supported");
-#endif
        }
 
        while (ibuf->w.queued)
Index: ospf6d/ospf6d.c
===================================================================
RCS file: /home/denis/dev/cvs/src/usr.sbin/ospf6d/ospf6d.c,v
retrieving revision 1.47
diff -u -p -r1.47 ospf6d.c
--- ospf6d/ospf6d.c     30 May 2020 18:02:13 -0000      1.47
+++ ospf6d/ospf6d.c     30 May 2020 18:02:41 -0000
@@ -277,6 +277,8 @@ main(int argc, char *argv[])
                fatalx("control socket setup failed");
        main_imsg_compose_ospfe_fd(IMSG_CONTROLFD, 0, control_fd);
 
+       if (unveil("/", "r") == -1)
+               fatal("unveil");
        if (unveil(ospfd_conf->csock, "c") == -1)
                fatal("unveil");
        if (unveil(NULL, NULL) == -1)
@@ -611,23 +613,37 @@ ospf_redistribute(struct kroute *kr, u_i
 int
 ospf_reload(void)
 {
-#ifdef notyet
        struct area             *area;
+       struct iface            *iface;
        struct ospfd_conf       *xconf;
 
        if ((xconf = parse_config(conffile, ospfd_conf->opts)) == NULL)
                return (-1);
 
-       /* XXX bail out if router-id changed */
+       /* No router-id was specified, keep existing value */
+       if (xconf->rtr_id.s_addr == 0)
+               xconf->rtr_id.s_addr = ospfd_conf->rtr_id.s_addr;
+
+       /* Abort the reload if rtr_id changed */
+       if (ospfd_conf->rtr_id.s_addr != xconf->rtr_id.s_addr) {
+               log_warnx("router-id changed: restart required");
+               return (-1);
+       }
 
        /* send config to childs */
        if (ospf_sendboth(IMSG_RECONF_CONF, xconf, sizeof(*xconf)) == -1)
                return (-1);
 
-       /* send areas, interfaces happen out of band */
+       /* send areas & interfaces */
        LIST_FOREACH(area, &xconf->area_list, entry) {
                if (ospf_sendboth(IMSG_RECONF_AREA, area, sizeof(*area)) == -1)
                        return (-1);
+
+               LIST_FOREACH(iface, &area->iface_list, entry) {
+                       if (ospf_sendboth(IMSG_RECONF_IFACE, iface,
+                           sizeof(*iface)) == -1)
+                               return (-1);
+               }
        }
 
        if (ospf_sendboth(IMSG_RECONF_END, NULL, 0) == -1)
@@ -639,9 +655,6 @@ ospf_reload(void)
        /* update redistribute lists */
        kr_reload(ospfd_conf->redist_label_or_prefix);
        return (0);
-#else
-       return (-1);
-#endif
 }
 
 int
@@ -725,6 +738,22 @@ merge_config(struct ospfd_conf *conf, st
                 * stub is not yet used but switching between stub and normal
                 * will be another painful job.
                 */
+               if (a->stub != xa->stub && ospfd_process == PROC_OSPF_ENGINE)
+                       a->dirty = 1; /* force rtr LSA update */
+#if 0
+               if (xa->stub && ospfd_process == PROC_RDE_ENGINE) {
+                       while ((r = SIMPLEQ_FIRST(&a->redist_list)) != NULL) {
+                               SIMPLEQ_REMOVE_HEAD(&a->redist_list, entry);
+                               free(r);
+                       }
+
+                       while ((r = SIMPLEQ_FIRST(&xa->redist_list)) != NULL) {
+                               SIMPLEQ_REMOVE_HEAD(&xa->redist_list, entry);
+                               SIMPLEQ_INSERT_TAIL(&a->redist_list, r, entry);
+                       }
+               }
+#endif
+
                a->stub = xa->stub;
                a->stub_default_cost = xa->stub_default_cost;
                if (ospfd_process == PROC_RDE_ENGINE)
@@ -746,7 +775,15 @@ merge_config(struct ospfd_conf *conf, st
                        }
                        if (a->dirty) {
                                a->dirty = 0;
-                               orig_rtr_lsa(LIST_FIRST(&a->iface_list)->area);
+                               orig_rtr_lsa(a);
+                       }
+               }
+       }
+       if (ospfd_process == PROC_RDE_ENGINE) {
+               LIST_FOREACH(a, &conf->area_list, entry) {
+                       if (a->dirty) {
+                               start_spf_timer();
+                               break;
                        }
                }
        }
@@ -767,7 +804,7 @@ merge_interfaces(struct area *a, struct 
 
        /* problems:
         * - new interfaces (easy)
-        * - deleted interfaces (needs to be done via fsm?)
+        * - deleted interfaces
         * - changing passive (painful?)
         */
        for (i = LIST_FIRST(&a->iface_list); i != NULL; i = ni) {
@@ -778,8 +815,11 @@ merge_interfaces(struct area *a, struct 
                            i->name);
                        if (ospfd_process == PROC_OSPF_ENGINE)
                                if_fsm(i, IF_EVT_DOWN);
+                       else if (ospfd_process == PROC_RDE_ENGINE)
+                               rde_nbr_iface_del(i);
                        LIST_REMOVE(i, entry);
                        if_del(i);
+                       dirty = 1; /* force rtr LSA update */
                }
        }
 
@@ -792,13 +832,13 @@ merge_interfaces(struct area *a, struct 
                            xi->name);
                        LIST_REMOVE(xi, entry);
                        LIST_INSERT_HEAD(&a->iface_list, xi, entry);
+                       xi->area = a;
                        if (ospfd_process == PROC_OSPF_ENGINE)
                                xi->state = IF_STA_NEW;
                        continue;
                }
                log_debug("merge_interfaces: proc %d area %s merging "
                    "interface %s", ospfd_process, inet_ntoa(a->id), i->name);
-               i->addr = xi->addr;
                i->dst = xi->dst;
                i->abr_id = xi->abr_id;
                i->baudrate = xi->baudrate;
@@ -814,11 +854,9 @@ merge_interfaces(struct area *a, struct 
                if (i->self)
                        i->self->priority = i->priority;
                i->flags = xi->flags; /* needed? */
-               i->type = xi->type; /* needed? */
                i->if_type = xi->if_type; /* needed? */
                i->linkstate = xi->linkstate; /* needed? */
 
-#if 0 /* XXX needs some kind of love */
                if (i->passive != xi->passive) {
                        /* need to restart interface to cope with this change */
                        if (ospfd_process == PROC_OSPF_ENGINE)
@@ -827,7 +865,15 @@ merge_interfaces(struct area *a, struct 
                        if (ospfd_process == PROC_OSPF_ENGINE)
                                if_fsm(i, IF_EVT_UP);
                }
-#endif
+
+               if (i->type != xi->type) {
+                       /* restart interface to enable or disable DR election */
+                       if (ospfd_process == PROC_OSPF_ENGINE)
+                               if_fsm(i, IF_EVT_DOWN);
+                       i->type = xi->type;
+                       if (ospfd_process == PROC_OSPF_ENGINE)
+                               if_fsm(i, IF_EVT_UP);
+               }
        }
        return (dirty);
 }
Index: ospf6d/ospf6d.h
===================================================================
RCS file: /home/denis/dev/cvs/src/usr.sbin/ospf6d/ospf6d.h,v
retrieving revision 1.50
diff -u -p -r1.50 ospf6d.h
--- ospf6d/ospf6d.h     30 May 2020 18:02:13 -0000      1.50
+++ ospf6d/ospf6d.h     30 May 2020 18:02:41 -0000
@@ -127,6 +127,7 @@ enum imsg_type {
        IMSG_ABR_DOWN,
        IMSG_RECONF_CONF,
        IMSG_RECONF_AREA,
+       IMSG_RECONF_IFACE,
        IMSG_RECONF_END,
        IMSG_DEMOTE
 };
Index: ospf6d/ospfe.c
===================================================================
RCS file: /home/denis/dev/cvs/src/usr.sbin/ospf6d/ospfe.c,v
retrieving revision 1.64
diff -u -p -r1.64 ospfe.c
--- ospf6d/ospfe.c      30 May 2020 18:02:13 -0000      1.64
+++ ospf6d/ospfe.c      30 May 2020 18:04:16 -0000
@@ -396,6 +396,18 @@ ospfe_dispatch_main(int fd, short event,
 
                        LIST_INSERT_HEAD(&nconf->area_list, narea, entry);
                        break;
+               case IMSG_RECONF_IFACE:
+                       if ((i = malloc(sizeof(struct iface))) == NULL)
+                               fatal(NULL);
+                       memcpy(i, imsg.data, sizeof(struct iface));
+
+                       LIST_INIT(&i->nbr_list);
+                       TAILQ_INIT(&i->ls_ack_list);
+                       RB_INIT(&i->lsa_tree);
+
+                       i->area = narea;
+                       LIST_INSERT_HEAD(&narea->iface_list, i, entry);
+                       break;
                case IMSG_RECONF_END:
                        if ((oeconf->flags & OSPFD_FLAG_STUB_ROUTER) !=
                            (nconf->flags & OSPFD_FLAG_STUB_ROUTER))
Index: ospf6d/rde.c
===================================================================
RCS file: /home/denis/dev/cvs/src/usr.sbin/ospf6d/rde.c,v
retrieving revision 1.89
diff -u -p -r1.89 rde.c
--- ospf6d/rde.c        30 May 2020 18:02:13 -0000      1.89
+++ ospf6d/rde.c        30 May 2020 18:04:49 -0000
@@ -635,6 +635,7 @@ void
 rde_dispatch_parent(int fd, short event, void *bula)
 {
        static struct area      *narea;
+       struct iface            *niface;
        struct imsg              imsg;
        struct kroute            kr;
        struct imsgev           *iev = bula;
@@ -700,6 +701,18 @@ rde_dispatch_parent(int fd, short event,
 
                        LIST_INSERT_HEAD(&nconf->area_list, narea, entry);
                        break;
+               case IMSG_RECONF_IFACE:
+                       if ((niface = malloc(sizeof(struct iface))) == NULL)
+                               fatal(NULL);
+                       memcpy(niface, imsg.data, sizeof(struct iface));
+
+                       LIST_INIT(&niface->nbr_list);
+                       TAILQ_INIT(&niface->ls_ack_list);
+                       RB_INIT(&niface->lsa_tree);
+
+                       niface->area = narea;
+                       LIST_INSERT_HEAD(&narea->iface_list, niface, entry);
+                       break;
                case IMSG_RECONF_END:
                        merge_config(rdeconf, nconf);
                        nconf = NULL;
@@ -956,6 +969,22 @@ rde_nbr_new(u_int32_t peerid, struct rde
        LIST_INSERT_HEAD(&area->nbr_list, nbr, entry);
 
        return (nbr);
+}
+
+void
+rde_nbr_iface_del(struct iface *iface)
+{
+       struct rde_nbr_head     *head;
+       struct rde_nbr          *nbr, *xnbr;
+       u_int32_t                i;
+
+       for (i = 0; i <= rdenbrtable.hashmask; i++) {
+               head = &rdenbrtable.hashtbl[i];
+               LIST_FOREACH_SAFE(nbr, head, hash, xnbr) {
+                       if (nbr->iface == iface)
+                               rde_nbr_del(nbr);
+               }
+       }
 }
 
 void
Index: ospf6d/rde.h
===================================================================
RCS file: /home/denis/dev/cvs/src/usr.sbin/ospf6d/rde.h,v
retrieving revision 1.25
diff -u -p -r1.25 rde.h
--- ospf6d/rde.h        17 Feb 2020 08:12:22 -0000      1.25
+++ ospf6d/rde.h        30 May 2020 18:02:41 -0000
@@ -129,6 +129,7 @@ int          rde_imsg_compose_ospfe(int, u_int3
 u_int32_t       rde_router_id(void);
 void            rde_send_change_kroute(struct rt_node *);
 void            rde_send_delete_kroute(struct rt_node *);
+void            rde_nbr_iface_del(struct iface *);
 void            rde_nbr_del(struct rde_nbr *);
 int             rde_nbr_loading(struct area *);
 struct rde_nbr *rde_nbr_self(struct area *);

Reply via email to