Hi,

ospfd does not react nicely when running "sh /etc/netstart if".

This is because adding the same address again do an interface results
in RTM_DELADDR and RTM_NEWADDR. ospfd handles the former but the later.
If this happens ospfd says "interface vether0:192.168.250.1 gone".
Adjacencies on that interface are down and ospfd can not recover.

The below patch adds IMSG_IFADDRADD to deal with that. With it ospfd
logs the following after "ifconfig vether0 192.168.250.1/24" (same address
as active before):

orig_rtr_lsa: area 0.0.0.0
orig_rtr_lsa: stub net, interface iwm0
orig_rtr_lsa: stub net, interface vether0
orig_rtr_lsa: transit net, interface pair0
if_fsm: event DOWN resulted in action RESET and changing state for interface 
vether0 from DR to DOWN
interface vether0:192.168.250.1 gone
orig_rtr_lsa: area 0.0.0.0
orig_rtr_lsa: stub net, interface iwm0
orig_rtr_lsa: stub net, interface vether0
orig_rtr_lsa: transit net, interface pair0
if_fsm: event UP resulted in action START and changing state for interface 
vether0 from DOWN to WAIT
interface vether0:192.168.250.1 returned


In addition the patch also deals with a changed netmask if the address
stays the same.

A complete new address still needs a change in ospfd.conf and a reload.

Remi


Index: kroute.c
===================================================================
RCS file: /cvs/src/usr.sbin/ospfd/kroute.c,v
retrieving revision 1.107
diff -u -p -r1.107 kroute.c
--- kroute.c    27 Dec 2016 09:15:16 -0000      1.107
+++ kroute.c    25 Jun 2017 20:58:33 -0000
@@ -1046,6 +1046,7 @@ if_newaddr(u_short ifindex, struct socka
 {
        struct kif_node *kif;
        struct kif_addr *ka;
+       struct ifaddrnew ifn;
 
        if (ifa == NULL || ifa->sin_family != AF_INET)
                return;
@@ -1066,6 +1067,12 @@ if_newaddr(u_short ifindex, struct socka
                ka->dstbrd.s_addr = INADDR_NONE;
 
        TAILQ_INSERT_TAIL(&kif->addrs, ka, entry);
+
+       ifn.addr = ka->addr;
+       ifn.mask = ka->mask;
+       ifn.dst = ka->dstbrd;
+       ifn.ifindex = ifindex;
+       main_imsg_compose_ospfe(IMSG_IFADDRADD, 0, &ifn, sizeof(ifn));
 }
 
 void
Index: ospfd.h
===================================================================
RCS file: /cvs/src/usr.sbin/ospfd/ospfd.h,v
retrieving revision 1.97
diff -u -p -r1.97 ospfd.h
--- ospfd.h     24 Jan 2017 04:24:25 -0000      1.97
+++ ospfd.h     25 Jun 2017 20:58:33 -0000
@@ -132,6 +132,7 @@ enum imsg_type {
        IMSG_RECONF_REDIST,
        IMSG_RECONF_END,
        IMSG_DEMOTE,
+       IMSG_IFADDRADD,
        IMSG_IFADDRDEL
 };
 
@@ -358,6 +359,13 @@ struct iface {
        u_int8_t                 linkstate;
        u_int8_t                 priority;
        u_int8_t                 passive;
+};
+
+struct ifaddrnew {
+       struct in_addr          addr;
+       struct in_addr          mask;
+       struct in_addr          dst;
+       unsigned int            ifindex;
 };
 
 struct ifaddrdel {
Index: ospfe.c
===================================================================
RCS file: /cvs/src/usr.sbin/ospfd/ospfe.c,v
retrieving revision 1.99
diff -u -p -r1.99 ospfe.c
--- ospfe.c     24 Jan 2017 04:24:25 -0000      1.99
+++ ospfe.c     25 Jun 2017 20:58:33 -0000
@@ -278,6 +278,7 @@ ospfe_dispatch_main(int fd, short event,
 {
        static struct area      *narea;
        static struct iface     *niface;
+       struct ifaddrnew        *ifn;
        struct ifaddrdel        *ifc;
        struct imsg      imsg;
        struct imsgev   *iev = bula;
@@ -345,6 +346,28 @@ ospfe_dispatch_main(int fd, short event,
                                                            " down",
                                                            iface->name);
                                                }
+                                       }
+                               }
+                       }
+                       break;
+               case IMSG_IFADDRADD:
+                       if (imsg.hdr.len != IMSG_HEADER_SIZE +
+                           sizeof(struct ifaddrnew))
+                               fatalx("IFADDRADD imsg with wrong len");
+                       ifn = imsg.data;
+
+                       LIST_FOREACH(area, &oeconf->area_list, entry) {
+                               LIST_FOREACH(iface, &area->iface_list, entry) {
+                                       if (ifn->ifindex == iface->ifindex &&
+                                           ifn->addr.s_addr ==
+                                           iface->addr.s_addr) {
+                                               iface->mask = ifn->mask;
+                                               iface->dst = ifn->dst;
+                                               if_fsm(iface, IF_EVT_UP);
+                                               log_warnx("interface %s:%s "
+                                                   "returned", iface->name,
+                                                   inet_ntoa(iface->addr));
+                                               break;
                                        }
                                }
                        }

Reply via email to