On Sun, Jun 25, 2017 at 11:47:09PM +0200, Remi Locherer wrote:
> 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
>
ping.
Any comments, opinions or improvements about this patch?
>
> 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;
> }
> }
> }