Remi Locherer(remi.loche...@relo.ch) on 2020.06.03 15:36:17 +0200: > On Sat, May 30, 2020 at 04:37:43PM +0200, Denis Fondras wrote: > > This diff updates how ospf6d(8) handles interfaces. > > It is now in line with what ospfd(8) does. > > > > Last step before enabling reload. > > > > Tested against Mikrotik and Zebra implementations. > > > > Warning: it changes the default behaviour. No prefix is announced if no > > "redistribute" statement is present in config file. Is this a showstopper ? > > The diff reads good and works. I mostly agree with it. > > But we should not change the behaviour. That prefixes configured on an > interface need a redistribute statement is counter intuitive. The "passive" > statement would be useless.
There is also a behaviour difference: the "interface { passive }" way only announces the prefix on active/master interfaces. I think it needs to stay. Great work btw! /Benno > > > > > Index: hello.c > > =================================================================== > > RCS file: /cvs/src/usr.sbin/ospf6d/hello.c,v > > retrieving revision 1.22 > > diff -u -p -r1.22 hello.c > > --- hello.c 3 Jan 2020 17:25:48 -0000 1.22 > > +++ hello.c 30 May 2020 14:19:09 -0000 > > @@ -175,12 +175,16 @@ recv_hello(struct iface *iface, struct i > > nbr->priority = LSA_24_GETHI(ntohl(hello.opts)); > > /* XXX neighbor address shouldn't be stored on virtual links */ > > nbr->addr = *src; > > + ospfe_imsg_compose_rde(IMSG_NEIGHBOR_ADDR, nbr->peerid, 0, > > + src, sizeof(struct in6_addr)); > > } > > > > if (!IN6_ARE_ADDR_EQUAL(&nbr->addr, src)) { > > log_warnx("%s: neighbor ID %s changed its address to %s", > > __func__, inet_ntoa(nbr->id), log_in6addr(src)); > > nbr->addr = *src; > > + ospfe_imsg_compose_rde(IMSG_NEIGHBOR_ADDR, nbr->peerid, 0, > > + src, sizeof(struct in6_addr)); > > } > > > > nbr->options = opts; > > Index: interface.c > > =================================================================== > > RCS file: /cvs/src/usr.sbin/ospf6d/interface.c,v > > retrieving revision 1.29 > > diff -u -p -r1.29 interface.c > > --- interface.c 27 May 2020 09:03:56 -0000 1.29 > > +++ interface.c 30 May 2020 14:19:09 -0000 > > @@ -72,8 +72,6 @@ struct { > > static int vlink_cnt = 0; > > #endif > > > > -TAILQ_HEAD(, iface) iflist; > > - > > const char * const if_event_names[] = { > > "NOTHING", > > "UP", > > @@ -145,10 +143,6 @@ if_fsm(struct iface *iface, enum iface_e > > area_track(iface->area); > > orig_rtr_lsa(iface->area); > > orig_link_lsa(iface); > > - > > - /* state change inform RDE */ > > - ospfe_imsg_compose_rde(IMSG_IFINFO, iface->self->peerid, 0, > > - &iface->state, sizeof(iface->state)); > > } > > > > if (old_state & (IF_STA_MULTI | IF_STA_POINTTOPOINT) && > > @@ -166,41 +160,8 @@ if_fsm(struct iface *iface, enum iface_e > > return (ret); > > } > > > > -int > > -if_init(void) > > -{ > > - TAILQ_INIT(&iflist); > > - > > - return (fetchifs(0)); > > -} > > - > > -/* XXX using a linked list should be OK for now */ > > struct iface * > > -if_find(unsigned int ifindex) > > -{ > > - struct iface *iface; > > - > > - TAILQ_FOREACH(iface, &iflist, list) { > > - if (ifindex == iface->ifindex) > > - return (iface); > > - } > > - return (NULL); > > -} > > - > > -struct iface * > > -if_findname(char *name) > > -{ > > - struct iface *iface; > > - > > - TAILQ_FOREACH(iface, &iflist, list) { > > - if (!strcmp(name, iface->name)) > > - return (iface); > > - } > > - return (NULL); > > -} > > - > > -struct iface * > > -if_new(u_short ifindex, char *ifname) > > +if_new(struct kif *kif, struct kif_addr *ka) > > { > > struct iface *iface; > > > > @@ -210,7 +171,6 @@ if_new(u_short ifindex, char *ifname) > > iface->state = IF_STA_DOWN; > > > > LIST_INIT(&iface->nbr_list); > > - TAILQ_INIT(&iface->ifa_list); > > TAILQ_INIT(&iface->ls_ack_list); > > RB_INIT(&iface->lsa_tree); > > > > @@ -225,34 +185,36 @@ if_new(u_short ifindex, char *ifname) > > return (iface); > > } > > #endif > > - strlcpy(iface->name, ifname, sizeof(iface->name)); > > - iface->ifindex = ifindex; > > - > > - TAILQ_INSERT_TAIL(&iflist, iface, list); > > - > > - return (iface); > > -} > > > > -void > > -if_update(struct iface *iface, int mtu, int flags, u_int8_t type, > > - u_int8_t state, u_int64_t rate, u_int32_t rdomain) > > -{ > > - iface->mtu = mtu; > > - iface->flags = flags; > > - iface->if_type = type; > > - iface->linkstate = state; > > - iface->baudrate = rate; > > - iface->rdomain = rdomain; > > + strlcpy(iface->name, kif->ifname, sizeof(iface->name)); > > > > - /* set type */ > > - if (flags & IFF_POINTOPOINT) > > + /* get type */ > > + if (kif->flags & IFF_POINTOPOINT) > > iface->type = IF_TYPE_POINTOPOINT; > > - if (flags & IFF_BROADCAST && flags & IFF_MULTICAST) > > + if (kif->flags & IFF_BROADCAST && kif->flags & IFF_MULTICAST) > > iface->type = IF_TYPE_BROADCAST; > > - if (flags & IFF_LOOPBACK) { > > + if (kif->flags & IFF_LOOPBACK) { > > iface->type = IF_TYPE_POINTOPOINT; > > - iface->cflags |= F_IFACE_PASSIVE; > > + iface->passive = 1; > > } > > + > > + /* get mtu, index and flags */ > > + iface->mtu = kif->mtu; > > + iface->ifindex = kif->ifindex; > > + iface->rdomain = kif->rdomain; > > + iface->flags = kif->flags; > > + iface->linkstate = kif->link_state; > > + iface->if_type = kif->if_type; > > + iface->baudrate = kif->baudrate; > > + > > + /* set address, mask and p2p addr */ > > + iface->addr = ka->addr; > > + iface->prefixlen = ka->prefixlen; > > + if (kif->flags & IFF_POINTOPOINT) { > > + iface->dst = ka->dstbrd; > > + } > > + > > + return (iface); > > } > > > > void > > @@ -278,7 +240,6 @@ if_del(struct iface *iface) > > evtimer_del(&iface->lsack_tx_timer); > > > > ls_ack_list_clr(iface); > > - TAILQ_REMOVE(&iflist, iface, list); > > free(iface); > > } > > > > @@ -370,19 +331,20 @@ if_act_start(struct iface *iface) > > struct in6_addr addr; > > struct timeval now; > > > > - if (!((iface->flags & IFF_UP) && > > - LINK_STATE_IS_UP(iface->linkstate))) { > > + if (!(iface->flags & IFF_UP) || > > + (!LINK_STATE_IS_UP(iface->linkstate) && > > + !(iface->if_type == IFT_CARP && > > + iface->linkstate == LINK_STATE_DOWN))) { > > log_debug("if_act_start: interface %s link down", > > iface->name); > > return (0); > > } > > > > - if (iface->if_type == IFT_CARP && > > - !(iface->cflags & F_IFACE_PASSIVE)) { > > + if (iface->if_type == IFT_CARP && iface->passive == 0) { > > /* force passive mode on carp interfaces */ > > log_warnx("if_act_start: forcing interface %s to passive", > > iface->name); > > - iface->cflags |= F_IFACE_PASSIVE; > > + iface->passive = 1; > > } > > > > gettimeofday(&now, NULL); > > @@ -392,7 +354,7 @@ if_act_start(struct iface *iface) > > if (iface->flags & IFF_LOOPBACK) > > iface->state = IF_STA_LOOPBACK; > > > > - if (iface->cflags & F_IFACE_PASSIVE) { > > + if (iface->passive) { > > /* for an update of stub network entries */ > > orig_rtr_lsa(iface->area); > > return (0); > > @@ -583,7 +545,7 @@ if_act_reset(struct iface *iface) > > struct nbr *nbr = NULL; > > struct in6_addr addr; > > > > - if (iface->cflags & F_IFACE_PASSIVE) { > > + if (iface->passive) { > > /* for an update of stub network entries */ > > orig_rtr_lsa(iface->area); > > return (0); > > @@ -681,7 +643,7 @@ if_to_ctl(struct iface *iface) > > ictl.linkstate = iface->linkstate; > > ictl.if_type = iface->if_type; > > ictl.priority = iface->priority; > > - ictl.passive = (iface->cflags & F_IFACE_PASSIVE) == F_IFACE_PASSIVE; > > + ictl.passive = iface->passive; > > > > gettimeofday(&now, NULL); > > if (evtimer_pending(&iface->hello_timer, &tv)) { > > Index: kroute.c > > =================================================================== > > RCS file: /cvs/src/usr.sbin/ospf6d/kroute.c,v > > retrieving revision 1.64 > > diff -u -p -r1.64 kroute.c > > --- kroute.c 17 May 2020 18:29:25 -0000 1.64 > > +++ kroute.c 30 May 2020 14:19:09 -0000 > > @@ -57,10 +57,17 @@ struct kroute_node { > > struct kroute r; > > }; > > > > +struct kif_node { > > + RB_ENTRY(kif_node) entry; > > + TAILQ_HEAD(, kif_addr) addrs; > > + struct kif k; > > +}; > > + > > void kr_redist_remove(struct kroute_node *, struct kroute_node *); > > int kr_redist_eval(struct kroute *, struct kroute *); > > void kr_redistribute(struct kroute_node *); > > int kroute_compare(struct kroute_node *, struct kroute_node *); > > +int kif_compare(struct kif_node *, struct kif_node *); > > int kr_change_fib(struct kroute_node *, struct kroute *, int, int); > > int kr_delete_fib(struct kroute_node *); > > > > @@ -72,8 +79,11 @@ int kroute_insert(struct > > kroute_node > > int kroute_remove(struct kroute_node *); > > void kroute_clear(void); > > > > -struct iface *kif_update(u_short, int, struct if_data *, > > - struct sockaddr_dl *); > > +struct kif_node *kif_find(u_short); > > +struct kif_node *kif_insert(u_short); > > +int kif_remove(struct kif_node *); > > +struct kif *kif_update(u_short, int, struct if_data *, > > + struct sockaddr_dl *); > > int kif_validate(u_short); > > > > struct kroute_node *kroute_match(struct in6_addr *); > > @@ -90,12 +100,26 @@ void if_announce(void *); > > int send_rtmsg(int, int, struct kroute *); > > int dispatch_rtmsg(void); > > int fetchtable(void); > > +int fetchifs(u_short); > > int rtmsg_process(char *, size_t); > > > > RB_HEAD(kroute_tree, kroute_node) krt; > > RB_PROTOTYPE(kroute_tree, kroute_node, entry, kroute_compare) > > RB_GENERATE(kroute_tree, kroute_node, entry, kroute_compare) > > > > +RB_HEAD(kif_tree, kif_node) kit = RB_INITIALIZER(&kit); > > +RB_PROTOTYPE(kif_tree, kif_node, entry, kif_compare) > > +RB_GENERATE(kif_tree, kif_node, entry, kif_compare) > > + > > +int > > +kif_init(void) > > +{ > > + if (fetchifs(0) == -1) > > + return (-1); > > + > > + return (0); > > +} > > + > > int > > kr_init(int fs, u_int rdomain, int redis_label_or_prefix, u_int8_t > > fib_prio) > > { > > @@ -317,7 +341,6 @@ kr_delete(struct kroute *kroute) > > return (-1); > > kr = nkr; > > } > > - > > return (0); > > } > > > > @@ -326,6 +349,7 @@ kr_shutdown(void) > > { > > kr_fib_decouple(); > > kroute_clear(); > > + kif_clear(); > > } > > > > void > > @@ -375,8 +399,8 @@ kr_fib_update_prio(u_int8_t fib_prio) > > if ((kr->r.flags & F_OSPFD_INSERTED)) > > kr->r.priority = fib_prio; > > > > - log_info("fib priority changed from %hhu to %hhu", kr_state.fib_prio, > > - fib_prio); > > + log_info("fib priority changed from %hhu to %hhu", > > + kr_state.fib_prio, fib_prio); > > > > kr_state.fib_prio = fib_prio; > > } > > @@ -437,7 +461,7 @@ kr_show_route(struct imsg *imsg) > > void > > kr_redist_remove(struct kroute_node *kh, struct kroute_node *kn) > > { > > - struct kroute *kr; > > + struct kroute *kr; > > > > /* was the route redistributed? */ > > if ((kn->r.flags & F_REDISTRIBUTED) == 0) > > @@ -570,6 +594,7 @@ kr_reload(int redis_label_or_prefix) > > /* not fatal */ > > } > > > > + /* update redistribute lists */ > > RB_FOREACH(kr, kroute_tree, &krt) { > > for (kn = kr; kn; kn = kn->next) { > > r = ospf_redistribute(&kn->r, &dummy); > > @@ -615,6 +640,12 @@ kroute_compare(struct kroute_node *a, st > > return (0); > > } > > > > +int > > +kif_compare(struct kif_node *a, struct kif_node *b) > > +{ > > + return (b->k.ifindex - a->k.ifindex); > > +} > > + > > /* tree management */ > > struct kroute_node * > > kroute_find(const struct in6_addr *prefix, u_int8_t prefixlen, u_int8_t > > prio) > > @@ -740,46 +771,128 @@ kroute_clear(void) > > kroute_remove(kr); > > } > > > > -struct iface * > > +struct kif_node * > > +kif_find(u_short ifindex) > > +{ > > + struct kif_node s; > > + > > + memset(&s, 0, sizeof(s)); > > + s.k.ifindex = ifindex; > > + > > + return (RB_FIND(kif_tree, &kit, &s)); > > +} > > + > > +struct kif * > > +kif_findname(char *ifname, struct in6_addr *addr, struct kif_addr **kap) > > +{ > > + struct kif_node *kif; > > + struct kif_addr *ka; > > + > > + RB_FOREACH(kif, kif_tree, &kit) > > + if (!strcmp(ifname, kif->k.ifname)) { > > + ka = TAILQ_FIRST(&kif->addrs); > > + if (!IN6_IS_ADDR_UNSPECIFIED(addr)) { > > + TAILQ_FOREACH(ka, &kif->addrs, entry) { > > + log_debug("%s", log_in6addr(&ka->addr)); > > + if (IN6_ARE_ADDR_EQUAL(addr, &ka->addr)) > > + break; > > + } > > + } > > + if (kap != NULL) > > + *kap = ka; > > + return (&kif->k); > > + } > > + > > + return (NULL); > > +} > > + > > +struct kif_node * > > +kif_insert(u_short ifindex) > > +{ > > + struct kif_node *kif; > > + > > + if ((kif = calloc(1, sizeof(struct kif_node))) == NULL) > > + return (NULL); > > + > > + kif->k.ifindex = ifindex; > > + TAILQ_INIT(&kif->addrs); > > + > > + if (RB_INSERT(kif_tree, &kit, kif) != NULL) > > + fatalx("kif_insert: RB_INSERT"); > > + > > + return (kif); > > +} > > + > > +int > > +kif_remove(struct kif_node *kif) > > +{ > > + struct kif_addr *ka; > > + > > + if (RB_REMOVE(kif_tree, &kit, kif) == NULL) { > > + log_warnx("RB_REMOVE(kif_tree, &kit, kif)"); > > + return (-1); > > + } > > + > > + while ((ka = TAILQ_FIRST(&kif->addrs)) != NULL) { > > + TAILQ_REMOVE(&kif->addrs, ka, entry); > > + free(ka); > > + } > > + free(kif); > > + return (0); > > +} > > + > > +void > > +kif_clear(void) > > +{ > > + struct kif_node *kif; > > + > > + while ((kif = RB_MIN(kif_tree, &kit)) != NULL) > > + kif_remove(kif); > > +} > > + > > +struct kif * > > kif_update(u_short ifindex, int flags, struct if_data *ifd, > > struct sockaddr_dl *sdl) > > { > > - struct iface *iface; > > - char ifname[IF_NAMESIZE]; > > + struct kif_node *kif; > > > > - if ((iface = if_find(ifindex)) == NULL) { > > - bzero(ifname, sizeof(ifname)); > > - if (sdl && sdl->sdl_family == AF_LINK) { > > - if (sdl->sdl_nlen >= sizeof(ifname)) > > - memcpy(ifname, sdl->sdl_data, > > - sizeof(ifname) - 1); > > - else if (sdl->sdl_nlen > 0) > > - memcpy(ifname, sdl->sdl_data, sdl->sdl_nlen); > > - else > > - return (NULL); > > - } else > > - return (NULL); > > - if ((iface = if_new(ifindex, ifname)) == NULL) > > + if ((kif = kif_find(ifindex)) == NULL) { > > + if ((kif = kif_insert(ifindex)) == NULL) > > return (NULL); > > + kif->k.nh_reachable = (flags & IFF_UP) && > > + LINK_STATE_IS_UP(ifd->ifi_link_state); > > } > > > > - if_update(iface, ifd->ifi_mtu, flags, ifd->ifi_type, > > - ifd->ifi_link_state, ifd->ifi_baudrate, ifd->ifi_rdomain); > > + kif->k.flags = flags; > > + kif->k.link_state = ifd->ifi_link_state; > > + kif->k.if_type = ifd->ifi_type; > > + kif->k.baudrate = ifd->ifi_baudrate; > > + kif->k.mtu = ifd->ifi_mtu; > > + kif->k.rdomain = ifd->ifi_rdomain; > > + > > + if (sdl && sdl->sdl_family == AF_LINK) { > > + if (sdl->sdl_nlen >= sizeof(kif->k.ifname)) > > + memcpy(kif->k.ifname, sdl->sdl_data, > > + sizeof(kif->k.ifname) - 1); > > + else if (sdl->sdl_nlen > 0) > > + memcpy(kif->k.ifname, sdl->sdl_data, sdl->sdl_nlen); > > + /* string already terminated via calloc() */ > > + } > > > > - return (iface); > > + return (&kif->k); > > } > > > > int > > kif_validate(u_short ifindex) > > { > > - struct iface *iface; > > + struct kif_node *kif; > > > > - if ((iface = if_find(ifindex)) == NULL) { > > + if ((kif = kif_find(ifindex)) == NULL) { > > log_warnx("interface with index %u not found", ifindex); > > - return (-1); > > + return (1); > > } > > > > - return ((iface->flags & IFF_UP) && LINK_STATE_IS_UP(iface->linkstate)); > > + return (kif->k.nh_reachable); > > } > > > > struct kroute_node * > > @@ -847,35 +960,32 @@ if_change(u_short ifindex, int flags, st > > struct sockaddr_dl *sdl) > > { > > struct kroute_node *kr, *tkr; > > - struct iface *iface; > > - u_int8_t wasvalid, isvalid; > > + struct kif *kif; > > + u_int8_t reachable; > > > > - wasvalid = kif_validate(ifindex); > > - > > - if ((iface = kif_update(ifindex, flags, ifd, sdl)) == NULL) { > > - log_warn("if_change: kif_update(%u)", ifindex); > > + if ((kif = kif_update(ifindex, flags, ifd, sdl)) == NULL) { > > + log_warn("if_change: kif_update(%u)", ifindex); > > return; > > } > > > > - /* inform engine and rde about state change */ > > - main_imsg_compose_rde(IMSG_IFINFO, 0, iface, sizeof(struct iface)); > > - main_imsg_compose_ospfe(IMSG_IFINFO, 0, iface, sizeof(struct iface)); > > + /* notify ospfe about interface link state */ > > + main_imsg_compose_ospfe(IMSG_IFINFO, 0, kif, sizeof(struct kif)); > > + > > + reachable = (kif->flags & IFF_UP) && LINK_STATE_IS_UP(kif->link_state); > > > > - isvalid = (iface->flags & IFF_UP) && > > - LINK_STATE_IS_UP(iface->linkstate); > > + if (reachable == kif->nh_reachable) > > + return; /* nothing changed wrt nexthop validity */ > > > > - if (wasvalid == isvalid) > > - return; /* nothing changed wrt validity */ > > + kif->nh_reachable = reachable; > > > > /* update redistribute list */ > > RB_FOREACH(kr, kroute_tree, &krt) { > > for (tkr = kr; tkr != NULL; tkr = tkr->next) { > > if (tkr->r.ifindex == ifindex) { > > - if (isvalid) > > + if (reachable) > > tkr->r.flags &= ~F_DOWN; > > else > > tkr->r.flags |= F_DOWN; > > - > > } > > } > > kr_redistribute(kr); > > @@ -886,16 +996,18 @@ void > > if_newaddr(u_short ifindex, struct sockaddr_in6 *ifa, struct sockaddr_in6 > > *mask, > > struct sockaddr_in6 *brd) > > { > > - struct iface *iface; > > - struct iface_addr *ia; > > - struct ifaddrchange ifc; > > + struct kif_node *kif; > > + struct kif_addr *ka; > > + struct ifaddrchange ifn; > > > > if (ifa == NULL || ifa->sin6_family != AF_INET6) > > return; > > - if ((iface = if_find(ifindex)) == NULL) { > > + if ((kif = kif_find(ifindex)) == NULL) { > > log_warnx("if_newaddr: corresponding if %d not found", ifindex); > > return; > > } > > + if ((ka = calloc(1, sizeof(struct kif_addr))) == NULL) > > + fatal("if_newaddr"); > > > > /* We only care about link-local and global-scope. */ > > if (IN6_IS_ADDR_UNSPECIFIED(&ifa->sin6_addr) || > > @@ -908,65 +1020,41 @@ if_newaddr(u_short ifindex, struct socka > > > > clearscope(&ifa->sin6_addr); > > > > - if (IN6_IS_ADDR_LINKLOCAL(&ifa->sin6_addr) || > > - iface->flags & IFF_LOOPBACK) > > - iface->addr = ifa->sin6_addr; > > - > > - if ((ia = calloc(1, sizeof(struct iface_addr))) == NULL) > > - fatal("if_newaddr"); > > - > > - ia->addr = ifa->sin6_addr; > > + ka->addr = ifa->sin6_addr; > > > > if (mask) > > - ia->prefixlen = mask2prefixlen(mask); > > + ka->prefixlen = mask2prefixlen(mask); > > else > > - ia->prefixlen = 0; > > + ka->prefixlen = 0; > > if (brd && brd->sin6_family == AF_INET6) > > - ia->dstbrd = brd->sin6_addr; > > + ka->dstbrd = brd->sin6_addr; > > else > > - bzero(&ia->dstbrd, sizeof(ia->dstbrd)); > > + bzero(&ka->dstbrd, sizeof(ka->dstbrd)); > > > > - switch (iface->type) { > > - case IF_TYPE_BROADCAST: > > - case IF_TYPE_NBMA: > > - log_debug("if_newaddr: ifindex %u, addr %s/%d", > > - ifindex, log_in6addr(&ia->addr), ia->prefixlen); > > - break; > > - case IF_TYPE_VIRTUALLINK: /* FIXME */ > > - break; > > - case IF_TYPE_POINTOPOINT: > > - case IF_TYPE_POINTOMULTIPOINT: > > - log_debug("if_newaddr: ifindex %u, addr %s/%d, " > > - "dest %s", ifindex, log_in6addr(&ia->addr), > > - ia->prefixlen, log_in6addr(&ia->dstbrd)); > > - break; > > - default: > > - fatalx("if_newaddr: unknown interface type"); > > - } > > - > > - TAILQ_INSERT_TAIL(&iface->ifa_list, ia, entry); > > - /* inform engine and rde if interface is used */ > > - if (iface->cflags & F_IFACE_CONFIGURED) { > > - ifc.addr = ia->addr; > > - ifc.dstbrd = ia->dstbrd; > > - ifc.prefixlen = ia->prefixlen; > > - ifc.ifindex = ifindex; > > - main_imsg_compose_ospfe(IMSG_IFADDRNEW, 0, &ifc, sizeof(ifc)); > > - main_imsg_compose_rde(IMSG_IFADDRNEW, 0, &ifc, sizeof(ifc)); > > - } > > + log_debug("if_newaddr: ifindex %u, addr %s/%d, " > > + "dest %s", ifindex, log_in6addr(&ka->addr), > > + ka->prefixlen, log_in6addr(&ka->dstbrd)); > > + > > + TAILQ_INSERT_TAIL(&kif->addrs, ka, entry); > > + > > + ifn.addr = ka->addr; > > + ifn.prefixlen = ka->prefixlen; > > + ifn.dstbrd = ka->dstbrd; > > + ifn.ifindex = ifindex; > > + main_imsg_compose_ospfe(IMSG_IFADDRADD, 0, &ifn, sizeof(ifn)); > > } > > > > void > > if_deladdr(u_short ifindex, struct sockaddr_in6 *ifa, struct sockaddr_in6 > > *mask, > > struct sockaddr_in6 *brd) > > { > > - struct iface *iface; > > - struct iface_addr *ia, *nia; > > + struct kif_node *kif; > > + struct kif_addr *ka, *nka; > > struct ifaddrchange ifc; > > > > if (ifa == NULL || ifa->sin6_family != AF_INET6) > > return; > > - if ((iface = if_find(ifindex)) == NULL) { > > + if ((kif = kif_find(ifindex)) == NULL) { > > log_warnx("if_deladdr: corresponding if %d not found", ifindex); > > return; > > } > > @@ -982,25 +1070,20 @@ if_deladdr(u_short ifindex, struct socka > > > > clearscope(&ifa->sin6_addr); > > > > - for (ia = TAILQ_FIRST(&iface->ifa_list); ia != NULL; ia = nia) { > > - nia = TAILQ_NEXT(ia, entry); > > + for (ka = TAILQ_FIRST(&kif->addrs); ka != NULL; ka = nka) { > > + nka = TAILQ_NEXT(ka, entry); > > > > - if (IN6_ARE_ADDR_EQUAL(&ia->addr, &ifa->sin6_addr)) { > > + if (IN6_ARE_ADDR_EQUAL(&ka->addr, &ifa->sin6_addr)) { > > log_debug("if_deladdr: ifindex %u, addr %s/%d", > > - ifindex, log_in6addr(&ia->addr), ia->prefixlen); > > - TAILQ_REMOVE(&iface->ifa_list, ia, entry); > > - /* inform engine and rde if interface is used */ > > - if (iface->cflags & F_IFACE_CONFIGURED) { > > - ifc.addr = ia->addr; > > - ifc.dstbrd = ia->dstbrd; > > - ifc.prefixlen = ia->prefixlen; > > - ifc.ifindex = ifindex; > > - main_imsg_compose_ospfe(IMSG_IFADDRDEL, 0, &ifc, > > - sizeof(ifc)); > > - main_imsg_compose_rde(IMSG_IFADDRDEL, 0, &ifc, > > - sizeof(ifc)); > > - } > > - free(ia); > > + ifindex, log_in6addr(&ka->addr), ka->prefixlen); > > + TAILQ_REMOVE(&kif->addrs, ka, entry); > > + ifc.addr = ka->addr; > > + ifc.prefixlen = ka->prefixlen; > > + ifc.dstbrd = ka->dstbrd; > > + ifc.ifindex = ifindex; > > + main_imsg_compose_ospfe(IMSG_IFADDRDEL, 0, &ifc, > > + sizeof(ifc)); > > + free(ka); > > return; > > } > > } > > @@ -1010,18 +1093,18 @@ void > > if_announce(void *msg) > > { > > struct if_announcemsghdr *ifan; > > - struct iface *iface; > > + struct kif_node *kif; > > > > ifan = msg; > > > > switch (ifan->ifan_what) { > > case IFAN_ARRIVAL: > > - if ((iface = if_new(ifan->ifan_index, ifan->ifan_name)) == NULL) > > - fatal("if_announce failed"); > > + kif = kif_insert(ifan->ifan_index); > > + strlcpy(kif->k.ifname, ifan->ifan_name, sizeof(kif->k.ifname)); > > break; > > case IFAN_DEPARTURE: > > - iface = if_find(ifan->ifan_index); > > - if_del(iface); > > + kif = kif_find(ifan->ifan_index); > > + kif_remove(kif); > > break; > > } > > } > > Index: ospf6d.c > > =================================================================== > > RCS file: /cvs/src/usr.sbin/ospf6d/ospf6d.c,v > > retrieving revision 1.46 > > diff -u -p -r1.46 ospf6d.c > > --- ospf6d.c 2 Jan 2020 10:16:46 -0000 1.46 > > +++ ospf6d.c 30 May 2020 14:19:09 -0000 > > @@ -176,12 +176,14 @@ main(int argc, char *argv[]) > > opts |= OSPFD_OPT_STUB_ROUTER; > > } > > > > - /* prepare and fetch interfaces early */ > > - if_init(); > > + /* fetch interfaces early */ > > + kif_init(); > > > > /* parse config file */ > > - if ((ospfd_conf = parse_config(conffile, opts)) == NULL ) > > + if ((ospfd_conf = parse_config(conffile, opts)) == NULL) { > > + kif_clear(); > > exit(1); > > + } > > > > if (sockname == NULL) { > > if (asprintf(&sockname, "%s.%d", OSPF6D_SOCKET, > > @@ -196,6 +198,7 @@ main(int argc, char *argv[]) > > print_config(ospfd_conf); > > else > > fprintf(stderr, "configuration OK\n"); > > + kif_clear(); > > exit(0); > > } > > > > @@ -515,18 +518,20 @@ ospf_redistribute(struct kroute *kr, u_i > > { > > struct redistribute *r; > > struct in6_addr ina, inb; > > - struct iface *iface; > > + struct kif *kif; > > u_int8_t is_default = 0; > > int depend_ok; > > > > + memset(&ina, 0, sizeof(ina)); > > + > > /* only allow ::/0 via REDIST_DEFAULT */ > > if (IN6_IS_ADDR_UNSPECIFIED(&kr->prefix) && kr->prefixlen == 0) > > is_default = 1; > > > > SIMPLEQ_FOREACH(r, &ospfd_conf->redist_list, entry) { > > if (r->dependon[0] != '\0') { > > - if ((iface = if_findname(r->dependon))) > > - depend_ok = ifstate_is_up(iface); > > + if ((kif = kif_findname(r->dependon, &ina, NULL))) > > + depend_ok = ifstate_is_up(kif); > > else > > depend_ok = 0; > > } else > > @@ -833,18 +838,20 @@ iface_lookup(struct area *area, struct i > > struct iface *i; > > > > LIST_FOREACH(i, &area->iface_list, entry) > > - if (i->ifindex == iface->ifindex) > > + if (i->ifindex == iface->ifindex && > > + IN6_ARE_ADDR_EQUAL(&i->addr, &iface->addr) && > > + i->prefixlen == iface->prefixlen) > > return (i); > > return (NULL); > > } > > > > int > > -ifstate_is_up(struct iface *iface) > > +ifstate_is_up(struct kif *kif) > > { > > - if (!(iface->flags & IFF_UP)) > > + if (!(kif->flags & IFF_UP)) > > return (0); > > - if (iface->if_type == IFT_CARP && > > - iface->linkstate == LINK_STATE_UNKNOWN) > > + if (kif->if_type == IFT_CARP && > > + kif->link_state == LINK_STATE_UNKNOWN) > > return (0); > > - return LINK_STATE_IS_UP(iface->linkstate); > > + return LINK_STATE_IS_UP(kif->link_state); > > } > > Index: ospf6d.h > > =================================================================== > > RCS file: /cvs/src/usr.sbin/ospf6d/ospf6d.h,v > > retrieving revision 1.49 > > diff -u -p -r1.49 ospf6d.h > > --- ospf6d.h 17 May 2020 18:29:25 -0000 1.49 > > +++ ospf6d.h 30 May 2020 14:19:09 -0000 > > @@ -103,10 +103,11 @@ enum imsg_type { > > IMSG_KROUTE_CHANGE, > > IMSG_KROUTE_DELETE, > > IMSG_IFINFO, > > - IMSG_IFADDRNEW, > > + IMSG_IFADDRADD, > > IMSG_IFADDRDEL, > > IMSG_NEIGHBOR_UP, > > IMSG_NEIGHBOR_DOWN, > > + IMSG_NEIGHBOR_ADDR, > > IMSG_NEIGHBOR_CHANGE, > > IMSG_NETWORK_ADD, > > IMSG_NETWORK_DEL, > > @@ -273,28 +274,17 @@ enum rib_type { > > RIB_EXT > > }; > > > > -struct iface_addr { > > - TAILQ_ENTRY(iface_addr) entry; > > - struct in6_addr addr; > > - struct in6_addr dstbrd; > > - u_int8_t prefixlen; > > - u_int8_t redistribute; > > -}; > > - > > /* lsa list used in RDE and OE */ > > TAILQ_HEAD(lsa_head, lsa_entry); > > > > struct iface { > > LIST_ENTRY(iface) entry; > > - TAILQ_ENTRY(iface) list; > > struct event hello_timer; > > struct event wait_timer; > > struct event lsack_tx_timer; > > > > LIST_HEAD(, nbr) nbr_list; > > - TAILQ_HEAD(, iface_addr) ifa_list; > > struct lsa_head ls_ack_list; > > - > > struct lsa_tree lsa_tree; /* LSA with link local scope */ > > > > char name[IF_NAMESIZE]; > > @@ -327,9 +317,8 @@ struct iface { > > u_int8_t if_type; > > u_int8_t linkstate; > > u_int8_t priority; > > - u_int8_t cflags; > > -#define F_IFACE_PASSIVE 0x01 > > -#define F_IFACE_CONFIGURED 0x02 > > + u_int8_t passive; > > + u_int8_t prefixlen; > > }; > > > > struct ifaddrchange { > > @@ -405,6 +394,25 @@ struct kroute { > > u_int8_t priority; > > }; > > > > +struct kif_addr { > > + TAILQ_ENTRY(kif_addr) entry; > > + struct in6_addr addr; > > + struct in6_addr dstbrd; > > + u_int8_t prefixlen; > > +}; > > + > > +struct kif { > > + char ifname[IF_NAMESIZE]; > > + u_int64_t baudrate; > > + int flags; > > + int mtu; > > + unsigned int ifindex; > > + u_int rdomain; > > + u_int8_t if_type; > > + u_int8_t link_state; > > + u_int8_t nh_reachable; /* for nexthop verification */ > > +}; > > + > > /* name2id */ > > struct n2id_label { > > TAILQ_ENTRY(n2id_label) entry; > > @@ -524,14 +532,6 @@ struct ospfd_conf *parse_config(char *, > > int cmdline_symset(char *); > > void conf_clear_redist_list(struct redist_list *); > > > > -/* interface.c */ > > -int if_init(void); > > -struct iface *if_find(unsigned int); > > -struct iface *if_findname(char *); > > -struct iface *if_new(u_short, char *); > > -void if_update(struct iface *, int, int, u_int8_t, u_int8_t, > > - u_int64_t, u_int32_t); > > - > > /* in_cksum.c */ > > u_int16_t in_cksum(void *, size_t); > > > > @@ -539,6 +539,8 @@ u_int16_t in_cksum(void *, size_t); > > u_int16_t iso_cksum(void *, u_int16_t, u_int16_t); > > > > /* kroute.c */ > > +int kif_init(void); > > +void kif_clear(void); > > int kr_init(int, u_int, int, u_int8_t); > > int kr_change(struct kroute *, int); > > int kr_delete(struct kroute *); > > @@ -548,6 +550,7 @@ void kr_fib_decouple(void); > > void kr_fib_update_prio(u_int8_t); > > void kr_dispatch_msg(int, short, void *); > > void kr_show_route(struct imsg *); > > +struct kif *kif_findname(char *, struct in6_addr *, struct kif_addr **); > > void kr_reload(int); > > > > void embedscope(struct sockaddr_in6 *); > > @@ -558,8 +561,6 @@ u_int8_t mask2prefixlen(struct sockaddr > > struct in6_addr *prefixlen2mask(u_int8_t); > > void inet6applymask(struct in6_addr *, const struct in6_addr > > *, int); > > > > -int fetchifs(u_short); > > - > > /* logmsg.h */ > > const char *log_in6addr(const struct in6_addr *); > > const char *log_in6addr_scope(const struct in6_addr *, unsigned int); > > @@ -588,7 +589,7 @@ void merge_config(struct ospfd_conf *, s > > void imsg_event_add(struct imsgev *); > > int imsg_compose_event(struct imsgev *, u_int16_t, u_int32_t, > > pid_t, int, void *, u_int16_t); > > -int ifstate_is_up(struct iface *iface); > > +int ifstate_is_up(struct kif *); > > > > /* printconf.c */ > > void print_config(struct ospfd_conf *); > > Index: ospfe.c > > =================================================================== > > RCS file: /cvs/src/usr.sbin/ospf6d/ospfe.c,v > > retrieving revision 1.63 > > diff -u -p -r1.63 ospfe.c > > --- ospfe.c 16 May 2020 15:54:12 -0000 1.63 > > +++ ospfe.c 30 May 2020 14:19:09 -0000 > > @@ -86,6 +86,9 @@ ospfe(struct ospfd_conf *xconf, int pipe > > return (pid); > > } > > > > + /* cleanup a bit */ > > + kif_clear(); > > + > > /* create the raw ip socket */ > > if ((xconf->ospf_socket = socket(AF_INET6, > > SOCK_RAW | SOCK_CLOEXEC | SOCK_NONBLOCK, IPPROTO_OSPF)) == -1) > > @@ -250,13 +253,13 @@ ospfe_dispatch_main(int fd, short event, > > { > > static struct area *narea; > > struct area *area; > > - struct iface *iface, *ifp, *i; > > + struct kif *kif; > > + struct iface *i; > > struct ifaddrchange *ifc; > > - struct iface_addr *ia, *nia; > > struct imsg imsg; > > struct imsgev *iev = bula; > > struct imsgbuf *ibuf = &iev->ibuf; > > - int n, stub_changed, shut = 0, isvalid, wasvalid; > > + int n, stub_changed, link_ok, shut = 0; > > > > if (event & EV_READ) { > > if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN) > > @@ -280,71 +283,79 @@ ospfe_dispatch_main(int fd, short event, > > switch (imsg.hdr.type) { > > case IMSG_IFINFO: > > if (imsg.hdr.len != IMSG_HEADER_SIZE + > > - sizeof(struct iface)) > > + sizeof(struct kif)) > > fatalx("IFINFO imsg with wrong len"); > > - ifp = imsg.data; > > + kif = imsg.data; > > + link_ok = (kif->flags & IFF_UP) && > > + LINK_STATE_IS_UP(kif->link_state); > > > > LIST_FOREACH(area, &oeconf->area_list, entry) { > > LIST_FOREACH(i, &area->iface_list, entry) { > > - if (strcmp(i->dependon, > > - ifp->name) == 0) { > > + if (kif->ifindex == i->ifindex && > > + i->type != IF_TYPE_VIRTUALLINK) { > > + int prev_link_state = > > + (i->flags & IFF_UP) && > > + > > LINK_STATE_IS_UP(i->linkstate); > > + > > + i->flags = kif->flags; > > + i->linkstate = kif->link_state; > > + i->mtu = kif->mtu; > > + > > + if (link_ok == prev_link_state) > > + break; > > + if (link_ok) { > > + if_fsm(i, IF_EVT_UP); > > + log_warnx("interface %s" > > + " up", i->name); > > + } else { > > + if_fsm(i, IF_EVT_DOWN); > > + log_warnx("interface %s" > > + " down", i->name); > > + } > > + } > > + if (strcmp(kif->ifname, > > + i->dependon) == 0) { > > log_warnx("interface %s" > > " changed state, %s" > > " depends on it", > > - ifp->name, i->name); > > + kif->ifname, > > + i->name); > > i->depend_ok = > > - ifstate_is_up(ifp); > > - if (ifstate_is_up(i)) > > + ifstate_is_up(kif); > > + if ((i->flags & IFF_UP) && > > + > > LINK_STATE_IS_UP(i->linkstate)) > > orig_rtr_lsa(i->area); > > } > > } > > } > > - > > - if (!(ifp->cflags & F_IFACE_CONFIGURED)) > > - break; > > - iface = if_find(ifp->ifindex); > > - if (iface == NULL) > > - fatalx("interface lost in ospfe"); > > - > > - wasvalid = (iface->flags & IFF_UP) && > > - LINK_STATE_IS_UP(iface->linkstate); > > - > > - if_update(iface, ifp->mtu, ifp->flags, ifp->if_type, > > - ifp->linkstate, ifp->baudrate, ifp->rdomain); > > - > > - isvalid = (iface->flags & IFF_UP) && > > - LINK_STATE_IS_UP(iface->linkstate); > > - > > - if (wasvalid == isvalid) > > - break; > > - > > - if (isvalid) { > > - if_fsm(iface, IF_EVT_UP); > > - log_warnx("interface %s up", iface->name); > > - } else { > > - if_fsm(iface, IF_EVT_DOWN); > > - log_warnx("interface %s down", iface->name); > > - } > > break; > > - case IMSG_IFADDRNEW: > > + case IMSG_IFADDRADD: > > if (imsg.hdr.len != IMSG_HEADER_SIZE + > > sizeof(struct ifaddrchange)) > > fatalx("IFADDRNEW imsg with wrong len"); > > ifc = imsg.data; > > > > - iface = if_find(ifc->ifindex); > > - if (iface == NULL) > > - fatalx("IFADDRNEW interface lost in ospfe"); > > - > > - if ((ia = calloc(1, sizeof(struct iface_addr))) == > > - NULL) > > - fatal("ospfe_dispatch_main IFADDRNEW"); > > - ia->addr = ifc->addr; > > - ia->dstbrd = ifc->dstbrd; > > - ia->prefixlen = ifc->prefixlen; > > - > > - TAILQ_INSERT_TAIL(&iface->ifa_list, ia, entry); > > - orig_link_lsa(iface); > > + LIST_FOREACH(area, &oeconf->area_list, entry) { > > + LIST_FOREACH(i, &area->iface_list, entry) { > > + if (ifc->ifindex == i->ifindex && > > + IN6_ARE_ADDR_EQUAL(&ifc->addr, > > + &i->addr)) { > > + i->prefixlen = ifc->prefixlen; > > + i->dst = ifc->dstbrd; > > + /* > > + * Previous down event might > > + * have failed if the address > > + * was not present at that > > + * time. > > + */ > > + if_fsm(i, IF_EVT_DOWN); > > + if_fsm(i, IF_EVT_UP); > > + log_warnx("interface %s " > > + "returned", i->name); > > + break; > > + } > > + } > > + } > > break; > > case IMSG_IFADDRDEL: > > if (imsg.hdr.len != IMSG_HEADER_SIZE + > > @@ -352,23 +363,18 @@ ospfe_dispatch_main(int fd, short event, > > fatalx("IFADDRDEL imsg with wrong len"); > > ifc = imsg.data; > > > > - iface = if_find(ifc->ifindex); > > - if (iface == NULL) > > - fatalx("IFADDRDEL interface lost in ospfe"); > > - > > - for (ia = TAILQ_FIRST(&iface->ifa_list); ia != NULL; > > - ia = nia) { > > - nia = TAILQ_NEXT(ia, entry); > > - > > - if (IN6_ARE_ADDR_EQUAL(&ia->addr, > > - &ifc->addr)) { > > - TAILQ_REMOVE(&iface->ifa_list, ia, > > - entry); > > - free(ia); > > - break; > > + LIST_FOREACH(area, &oeconf->area_list, entry) { > > + LIST_FOREACH(i, &area->iface_list, entry) { > > + if (ifc->ifindex == i->ifindex && > > + IN6_ARE_ADDR_EQUAL(&ifc->addr, > > + &i->addr)) { > > + if_fsm(i, IF_EVT_DOWN); > > + log_warnx("interface %s gone", > > + i->name); > > + break; > > + } > > } > > } > > - orig_link_lsa(iface); > > break; > > case IMSG_RECONF_CONF: > > if ((nconf = malloc(sizeof(struct ospfd_conf))) == > > @@ -1047,11 +1053,12 @@ orig_net_lsa(struct iface *iface) > > void > > orig_link_lsa(struct iface *iface) > > { > > + struct area *area; > > + struct iface *ifa; > > struct lsa_hdr lsa_hdr; > > struct lsa_link lsa_link; > > struct lsa_prefix lsa_prefix; > > struct ibuf *buf; > > - struct iface_addr *ia; > > struct in6_addr prefix; > > unsigned int num_prefix = 0; > > u_int16_t chksum; > > @@ -1086,25 +1093,29 @@ orig_link_lsa(struct iface *iface) > > fatal("orig_link_lsa: ibuf_reserve failed"); > > > > /* link-local address, and all prefixes configured on interface */ > > - TAILQ_FOREACH(ia, &iface->ifa_list, entry) { > > - if (IN6_IS_ADDR_LINKLOCAL(&ia->addr)) { > > - log_debug("orig_link_lsa: link local address %s", > > - log_in6addr(&ia->addr)); > > - lsa_link.lladdr = ia->addr; > > - continue; > > - } > > + LIST_FOREACH(area, &oeconf->area_list, entry) { > > + LIST_FOREACH(ifa, &area->iface_list, entry) { > > + if (ifa->ifindex == iface->ifindex && > > + IN6_IS_ADDR_LINKLOCAL(&iface->addr)) { > > + log_debug("orig_link_lsa: link local address " > > + "%s", log_in6addr(&iface->addr)); > > + lsa_link.lladdr = iface->addr; > > + continue; > > + } > > > > - lsa_prefix.prefixlen = ia->prefixlen; > > - lsa_prefix.options = 0; > > - lsa_prefix.metric = 0; > > - inet6applymask(&prefix, &ia->addr, ia->prefixlen); > > - log_debug("orig_link_lsa: prefix %s", log_in6addr(&prefix)); > > - if (ibuf_add(buf, &lsa_prefix, sizeof(lsa_prefix))) > > - fatal("orig_link_lsa: ibuf_add failed"); > > - if (ibuf_add(buf, &prefix.s6_addr[0], > > - LSA_PREFIXSIZE(ia->prefixlen))) > > - fatal("orig_link_lsa: ibuf_add failed"); > > - num_prefix++; > > + lsa_prefix.prefixlen = iface->prefixlen; > > + lsa_prefix.options = 0; > > + lsa_prefix.metric = 0; > > + inet6applymask(&prefix, &iface->addr, iface->prefixlen); > > + log_debug("orig_link_lsa: prefix %s", > > + log_in6addr(&prefix)); > > + if (ibuf_add(buf, &lsa_prefix, sizeof(lsa_prefix))) > > + fatal("orig_link_lsa: ibuf_add failed"); > > + if (ibuf_add(buf, &prefix.s6_addr[0], > > + LSA_PREFIXSIZE(iface->prefixlen))) > > + fatal("orig_link_lsa: ibuf_add failed"); > > + num_prefix++; > > + } > > } > > > > /* LSA link header (lladdr has already been filled in above) */ > > Index: ospfe.h > > =================================================================== > > RCS file: /cvs/src/usr.sbin/ospf6d/ospfe.h,v > > retrieving revision 1.23 > > diff -u -p -r1.23 ospfe.h > > --- ospfe.h 2 Jan 2020 10:16:46 -0000 1.23 > > +++ ospfe.h 30 May 2020 14:19:09 -0000 > > @@ -130,6 +130,7 @@ void ospfe_demote_iface(struct iface * > > /* interface.c */ > > int if_fsm(struct iface *, enum iface_event); > > > > +struct iface *if_new(struct kif *, struct kif_addr *); > > void if_del(struct iface *); > > void if_start(struct ospfd_conf *, struct iface *); > > > > Index: packet.c > > =================================================================== > > RCS file: /cvs/src/usr.sbin/ospf6d/packet.c,v > > retrieving revision 1.17 > > diff -u -p -r1.17 packet.c > > --- packet.c 23 Dec 2019 07:33:49 -0000 1.17 > > +++ packet.c 30 May 2020 14:19:09 -0000 > > @@ -316,12 +316,12 @@ find_iface(struct ospfd_conf *xconf, uns > > switch (iface->type) { > > case IF_TYPE_VIRTUALLINK: > > if (IN6_ARE_ADDR_EQUAL(src, &iface->dst) && > > - !(iface->cflags & F_IFACE_PASSIVE)) > > + !iface->passive) > > return (iface); > > break; > > default: > > if (ifindex == iface->ifindex && > > - !(iface->cflags & F_IFACE_PASSIVE)) > > + !iface->passive) > > match = iface; > > break; > > } > > Index: parse.y > > =================================================================== > > RCS file: /cvs/src/usr.sbin/ospf6d/parse.y,v > > retrieving revision 1.49 > > diff -u -p -r1.49 parse.y > > --- parse.y 21 Jan 2020 20:38:52 -0000 1.49 > > +++ parse.y 30 May 2020 14:19:09 -0000 > > @@ -111,6 +111,7 @@ struct config_defaults ifacedefs; > > struct config_defaults *defs; > > > > struct area *conf_get_area(struct in_addr); > > +struct iface *conf_get_if(struct kif *, struct kif_addr *); > > int conf_check_rdomain(u_int); > > > > typedef struct { > > @@ -385,12 +386,15 @@ option : METRIC NUMBER { > > > > dependon : /* empty */ { $$ = NULL; } > > | DEPEND ON STRING { > > + struct in6_addr addr; > > + > > if (strlen($3) >= IFNAMSIZ) { > > yyerror("interface name %s too long", $3); > > free($3); > > YYERROR; > > } > > - if ((if_findname($3)) == NULL) { > > + memset(&addr, 0, sizeof(addr)); > > + if ((kif_findname($3, &addr, NULL)) == NULL) { > > yyerror("unknown interface %s", $3); > > free($3); > > YYERROR; > > @@ -530,17 +534,25 @@ areaoptsl : interface > > ; > > > > interface : INTERFACE STRING { > > - if ((iface = if_findname($2)) == NULL) { > > + struct kif *kif; > > + struct kif_addr *ka = NULL; > > + struct in6_addr addr; > > + > > + memset(&addr, 0, sizeof(addr)); > > + if ((kif = kif_findname($2, &addr, &ka)) == NULL) { > > yyerror("unknown interface %s", $2); > > free($2); > > YYERROR; > > } > > - if (IN6_IS_ADDR_UNSPECIFIED(&iface->addr)) { > > + if (ka == NULL) { > > yyerror("unnumbered interface %s", $2); > > free($2); > > YYERROR; > > } > > free($2); > > + iface = conf_get_if(kif, ka); > > + if (iface == NULL) > > + YYERROR; > > iface->area = area; > > LIST_INSERT_HEAD(&area->iface_list, iface, entry); > > > > @@ -553,7 +565,6 @@ interface : INTERFACE STRING { > > iface->rxmt_interval = defs->rxmt_interval; > > iface->metric = defs->metric; > > iface->priority = defs->priority; > > - iface->cflags |= F_IFACE_CONFIGURED; > > if (defs->p2p == 1) > > iface->type = IF_TYPE_POINTOPOINT; > > iface = NULL; > > @@ -571,7 +582,7 @@ interfaceopts_l : interfaceopts_l interf > > | interfaceoptsl optnl > > ; > > > > -interfaceoptsl : PASSIVE { iface->cflags |= > > F_IFACE_PASSIVE; } > > +interfaceoptsl : PASSIVE { iface->passive = 1; } > > | DEMOTE STRING { > > if (strlcpy(iface->demote_group, $2, > > sizeof(iface->demote_group)) >= > > @@ -590,13 +601,15 @@ interfaceoptsl : PASSIVE { > > iface->cflag > > } > > } > > | dependon { > > - struct iface *depend_if = NULL; > > + struct kif *kif = NULL; > > + struct in6_addr addr; > > > > if ($1) { > > strlcpy(iface->dependon, $1, > > sizeof(iface->dependon)); > > - depend_if = if_findname($1); > > - iface->depend_ok = ifstate_is_up(depend_if); > > + memset(&addr, 0, sizeof(addr)); > > + kif = kif_findname($1, &addr, NULL); > > + iface->depend_ok = ifstate_is_up(kif); > > } else { > > iface->dependon[0] = '\0'; > > iface->depend_ok = 1; > > @@ -1172,21 +1185,43 @@ conf_get_area(struct in_addr id) > > return (a); > > } > > > > +struct iface * > > +conf_get_if(struct kif *kif, struct kif_addr *ka) > > +{ > > + struct area *a; > > + struct iface *i; > > + > > + LIST_FOREACH(a, &conf->area_list, entry) > > + LIST_FOREACH(i, &a->iface_list, entry) > > + if (i->ifindex == kif->ifindex && > > + IN6_ARE_ADDR_EQUAL(&i->addr, &ka->addr)) { > > + yyerror("interface %s already configured", > > + kif->ifname); > > + return (NULL); > > + } > > + i = if_new(kif, ka); > > + > > + return (i); > > +} > > + > > int > > conf_check_rdomain(u_int rdomain) > > { > > struct area *a; > > - struct iface *i, *idep; > > + struct iface *i; > > + struct kif *kif; > > struct redistribute *r; > > + struct in6_addr addr; > > int errs = 0; > > > > SIMPLEQ_FOREACH(r, &conf->redist_list, entry) > > if (r->dependon[0] != '\0') { > > - idep = if_findname(r->dependon); > > - if (idep->rdomain != rdomain) { > > + memset(&addr, 0, sizeof(addr)); > > + kif = kif_findname(r->dependon, &addr, NULL); > > + if (kif->rdomain != rdomain) { > > logit(LOG_CRIT, > > "depend on %s: interface not in rdomain %u", > > - idep->name, rdomain); > > + kif->ifname, rdomain); > > errs++; > > } > > } > > @@ -1200,12 +1235,13 @@ conf_check_rdomain(u_int rdomain) > > errs++; > > } > > if (i->dependon[0] != '\0') { > > - idep = if_findname(i->dependon); > > - if (idep->rdomain != rdomain) { > > + memset(&addr, 0, sizeof(addr)); > > + kif = kif_findname(i->dependon, &addr, NULL); > > + if (kif->rdomain != rdomain) { > > logit(LOG_CRIT, > > "depend on %s: interface not in " > > "rdomain %u", > > - idep->name, rdomain); > > + kif->ifname, rdomain); > > errs++; > > } > > } > > Index: printconf.c > > =================================================================== > > RCS file: /cvs/src/usr.sbin/ospf6d/printconf.c,v > > retrieving revision 1.10 > > diff -u -p -r1.10 printconf.c > > --- printconf.c 21 Jan 2020 20:38:52 -0000 1.10 > > +++ printconf.c 30 May 2020 14:19:09 -0000 > > @@ -123,7 +123,7 @@ print_iface(struct iface *iface) > > printf("\t\thello-interval %d\n", iface->hello_interval); > > printf("\t\tmetric %d\n", iface->metric); > > > > - if (iface->cflags & F_IFACE_PASSIVE) > > + if (iface->passive) > > printf("\t\tpassive\n"); > > if (*iface->demote_group) > > printf("\t\tdemote %s\n", iface->demote_group); > > Index: rde.c > > =================================================================== > > RCS file: /cvs/src/usr.sbin/ospf6d/rde.c,v > > retrieving revision 1.88 > > diff -u -p -r1.88 rde.c > > --- rde.c 16 May 2020 15:54:12 -0000 1.88 > > +++ rde.c 30 May 2020 14:19:09 -0000 > > @@ -131,6 +131,9 @@ rde(struct ospfd_conf *xconf, int pipe_p > > return (pid); > > } > > > > + /* cleanup a bit */ > > + kif_clear(); > > + > > rdeconf = xconf; > > > > if ((pw = getpwnam(OSPF6D_USER)) == NULL) > > @@ -263,6 +266,7 @@ rde_dispatch_imsg(int fd, short event, v > > struct imsgev *iev = bula; > > struct imsgbuf *ibuf = &iev->ibuf; > > struct imsg imsg; > > + struct in6_addr addr; > > struct in_addr aid; > > struct ls_req_hdr req_hdr; > > struct lsa_hdr lsa_hdr, *db_hdr; > > @@ -312,6 +316,17 @@ rde_dispatch_imsg(int fd, short event, v > > case IMSG_NEIGHBOR_DOWN: > > rde_nbr_del(rde_nbr_find(imsg.hdr.peerid)); > > break; > > + case IMSG_NEIGHBOR_ADDR: > > + if (imsg.hdr.len - IMSG_HEADER_SIZE != sizeof(addr)) > > + fatalx("invalid size of OE request"); > > + memcpy(&addr, imsg.data, sizeof(addr)); > > + > > + nbr = rde_nbr_find(imsg.hdr.peerid); > > + if (nbr == NULL) > > + break; > > + > > + nbr->addr = addr; > > + break; > > case IMSG_NEIGHBOR_CHANGE: > > if (imsg.hdr.len - IMSG_HEADER_SIZE != sizeof(state)) > > fatalx("invalid size of OE request"); > > @@ -321,14 +336,6 @@ rde_dispatch_imsg(int fd, short event, v > > if (nbr == NULL) > > break; > > > > - if (state != nbr->state && > > - (nbr->state & NBR_STA_FULL || > > - state & NBR_STA_FULL)) { > > - nbr->state = state; > > - area_track(nbr->area); > > - orig_intra_area_prefix_lsas(nbr->area); > > - } > > - > > nbr->state = state; > > if (nbr->state & NBR_STA_FULL) > > rde_req_list_free(nbr); > > @@ -602,19 +609,6 @@ rde_dispatch_imsg(int fd, short event, v > > imsg_compose_event(iev_ospfe, IMSG_CTL_END, 0, > > imsg.hdr.pid, -1, NULL, 0); > > break; > > - case IMSG_IFINFO: > > - if (imsg.hdr.len != IMSG_HEADER_SIZE + > > - sizeof(int)) > > - fatalx("IFINFO imsg with wrong len"); > > - > > - nbr = rde_nbr_find(imsg.hdr.peerid); > > - if (nbr == NULL) > > - fatalx("IFINFO imsg with bad peerid"); > > - memcpy(&nbr->iface->state, imsg.data, sizeof(int)); > > - > > - /* Resend LSAs if interface state changes. */ > > - orig_intra_area_prefix_lsas(nbr->area); > > - break; > > case IMSG_CTL_LOG_VERBOSE: > > /* already checked by ospfe */ > > memcpy(&verbose, imsg.data, sizeof(verbose)); > > @@ -641,16 +635,12 @@ void > > rde_dispatch_parent(int fd, short event, void *bula) > > { > > static struct area *narea; > > - struct area *area; > > - struct iface *iface, *ifp, *i; > > - struct ifaddrchange *ifc; > > - struct iface_addr *ia, *nia; > > struct imsg imsg; > > struct kroute kr; > > struct imsgev *iev = bula; > > struct imsgbuf *ibuf = &iev->ibuf; > > ssize_t n; > > - int shut = 0, link_ok, prev_link_ok, orig_lsa; > > + int shut = 0; > > > > if (event & EV_READ) { > > if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN) > > @@ -690,95 +680,6 @@ rde_dispatch_parent(int fd, short event, > > memcpy(&kr, imsg.data, sizeof(kr)); > > rde_asext_put(&kr); > > break; > > - case IMSG_IFINFO: > > - if (imsg.hdr.len != IMSG_HEADER_SIZE + > > - sizeof(struct iface)) > > - fatalx("IFINFO imsg with wrong len"); > > - > > - ifp = imsg.data; > > - > > - LIST_FOREACH(area, &rdeconf->area_list, entry) { > > - orig_lsa = 0; > > - LIST_FOREACH(i, &area->iface_list, entry) { > > - if (strcmp(i->dependon, > > - ifp->name) == 0) { > > - i->depend_ok = > > - ifstate_is_up(ifp); > > - if (ifstate_is_up(i)) > > - orig_lsa = 1; > > - } > > - } > > - if (orig_lsa) > > - orig_intra_area_prefix_lsas(area); > > - } > > - > > - if (!(ifp->cflags & F_IFACE_CONFIGURED)) > > - break; > > - iface = if_find(ifp->ifindex); > > - if (iface == NULL) > > - fatalx("interface lost in rde"); > > - > > - prev_link_ok = (iface->flags & IFF_UP) && > > - LINK_STATE_IS_UP(iface->linkstate); > > - > > - if_update(iface, ifp->mtu, ifp->flags, ifp->if_type, > > - ifp->linkstate, ifp->baudrate, ifp->rdomain); > > - > > - /* Resend LSAs if interface state changes. */ > > - link_ok = (iface->flags & IFF_UP) && > > - LINK_STATE_IS_UP(iface->linkstate); > > - if (prev_link_ok == link_ok) > > - break; > > - > > - orig_intra_area_prefix_lsas(iface->area); > > - > > - break; > > - case IMSG_IFADDRNEW: > > - if (imsg.hdr.len != IMSG_HEADER_SIZE + > > - sizeof(struct ifaddrchange)) > > - fatalx("IFADDRNEW imsg with wrong len"); > > - ifc = imsg.data; > > - > > - iface = if_find(ifc->ifindex); > > - if (iface == NULL) > > - fatalx("IFADDRNEW interface lost in rde"); > > - > > - if ((ia = calloc(1, sizeof(struct iface_addr))) == > > - NULL) > > - fatal("rde_dispatch_parent IFADDRNEW"); > > - ia->addr = ifc->addr; > > - ia->dstbrd = ifc->dstbrd; > > - ia->prefixlen = ifc->prefixlen; > > - > > - TAILQ_INSERT_TAIL(&iface->ifa_list, ia, entry); > > - if (iface->area) > > - orig_intra_area_prefix_lsas(iface->area); > > - break; > > - case IMSG_IFADDRDEL: > > - if (imsg.hdr.len != IMSG_HEADER_SIZE + > > - sizeof(struct ifaddrchange)) > > - fatalx("IFADDRDEL imsg with wrong len"); > > - ifc = imsg.data; > > - > > - iface = if_find(ifc->ifindex); > > - if (iface == NULL) > > - fatalx("IFADDRDEL interface lost in rde"); > > - > > - for (ia = TAILQ_FIRST(&iface->ifa_list); ia != NULL; > > - ia = nia) { > > - nia = TAILQ_NEXT(ia, entry); > > - > > - if (IN6_ARE_ADDR_EQUAL(&ia->addr, > > - &ifc->addr)) { > > - TAILQ_REMOVE(&iface->ifa_list, ia, > > - entry); > > - free(ia); > > - break; > > - } > > - } > > - if (iface->area) > > - orig_intra_area_prefix_lsas(iface->area); > > - break; > > case IMSG_RECONF_CONF: > > if ((nconf = malloc(sizeof(struct ospfd_conf))) == > > NULL) > > @@ -1033,7 +934,11 @@ rde_nbr_new(u_int32_t peerid, struct rde > > if ((area = area_find(rdeconf, new->area_id)) == NULL) > > fatalx("rde_nbr_new: unknown area"); > > > > - if ((iface = if_find(new->ifindex)) == NULL) > > + LIST_FOREACH(iface, &area->iface_list, entry) { > > + if (iface->ifindex == new->ifindex) > > + break; > > + } > > + if (iface == NULL) > > fatalx("rde_nbr_new: unknown interface"); > > > > if ((nbr = calloc(1, sizeof(*nbr))) == NULL) > > @@ -1175,21 +1080,18 @@ rde_asext_lookup(struct in6_addr prefix, > > > > struct area *area; > > struct iface *iface; > > - struct iface_addr *ia; > > struct in6_addr ina, inb; > > > > LIST_FOREACH(area, &rdeconf->area_list, entry) { > > LIST_FOREACH(iface, &area->iface_list, entry) { > > - TAILQ_FOREACH(ia, &iface->ifa_list, entry) { > > - if (IN6_IS_ADDR_LINKLOCAL(&ia->addr)) > > - continue; > > + if (IN6_IS_ADDR_LINKLOCAL(&iface->addr)) > > + continue; > > > > - inet6applymask(&ina, &ia->addr, ia->prefixlen); > > - inet6applymask(&inb, &prefix, ia->prefixlen); > > - if (IN6_ARE_ADDR_EQUAL(&ina, &inb) && > > - (plen == -1 || plen == ia->prefixlen)) > > - return (iface); > > - } > > + inet6applymask(&ina, &iface->addr, iface->prefixlen); > > + inet6applymask(&inb, &prefix, iface->prefixlen); > > + if (IN6_ARE_ADDR_EQUAL(&ina, &inb) && > > + (plen == -1 || plen == iface->prefixlen)) > > + return (iface); > > } > > } > > return (NULL); > > @@ -1480,7 +1382,6 @@ orig_intra_lsa_rtr(struct area *area, st > > struct lsa_prefix *lsa_prefix; > > struct in6_addr *prefix; > > struct iface *iface; > > - struct iface_addr *ia; > > struct rde_nbr *nbr; > > u_int16_t len; > > u_int16_t numprefix; > > @@ -1509,7 +1410,7 @@ orig_intra_lsa_rtr(struct area *area, st > > continue; > > > > if ((iface->state & IF_STA_DOWN) && > > - !(iface->cflags & F_IFACE_PASSIVE)) > > + !iface->passive) > > /* passive interfaces stay in state DOWN */ > > continue; > > > > @@ -1533,48 +1434,45 @@ orig_intra_lsa_rtr(struct area *area, st > > > > lsa_prefix = (struct lsa_prefix *)lsa_prefix_buf; > > > > - TAILQ_FOREACH(ia, &iface->ifa_list, entry) { > > - if (IN6_IS_ADDR_LINKLOCAL(&ia->addr)) > > - continue; > > + if (IN6_IS_ADDR_LINKLOCAL(&iface->addr)) > > + continue; > > > > - bzero(lsa_prefix_buf, sizeof(lsa_prefix_buf)); > > + bzero(lsa_prefix_buf, sizeof(lsa_prefix_buf)); > > > > - if (iface->type == IF_TYPE_POINTOMULTIPOINT || > > - iface->state & IF_STA_LOOPBACK) { > > - lsa_prefix->prefixlen = 128; > > - lsa_prefix->metric = 0; > > - } else if ((iface->if_type == IFT_CARP && > > - iface->linkstate == LINK_STATE_DOWN) || > > - !(iface->depend_ok)) { > > - /* carp interfaces in state backup are > > + if (iface->type == IF_TYPE_POINTOMULTIPOINT || > > + iface->state & IF_STA_LOOPBACK) { > > + lsa_prefix->prefixlen = 128; > > + lsa_prefix->metric = 0; > > + } else if ((iface->if_type == IFT_CARP && > > + iface->linkstate == LINK_STATE_DOWN) || > > + !(iface->depend_ok)) { > > + /* carp interfaces in state backup are > > * announced with high metric for faster > > - * failover. */ > > - lsa_prefix->prefixlen = ia->prefixlen; > > - lsa_prefix->metric = MAX_METRIC; > > - } else { > > - lsa_prefix->prefixlen = ia->prefixlen; > > - lsa_prefix->metric = htons(iface->metric); > > - } > > + * failover. */ > > + lsa_prefix->prefixlen = iface->prefixlen; > > + lsa_prefix->metric = MAX_METRIC; > > + } else { > > + lsa_prefix->prefixlen = iface->prefixlen; > > + lsa_prefix->metric = htons(iface->metric); > > + } > > > > - if (lsa_prefix->prefixlen == 128) > > - lsa_prefix->options |= OSPF_PREFIX_LA; > > + if (lsa_prefix->prefixlen == 128) > > + lsa_prefix->options |= OSPF_PREFIX_LA; > > > > - log_debug("orig_intra_lsa_rtr: area %s, interface %s: " > > - "%s/%d, metric %d", inet_ntoa(area->id), > > - iface->name, log_in6addr(&ia->addr), > > - lsa_prefix->prefixlen, ntohs(lsa_prefix->metric)); > > - > > - prefix = (struct in6_addr *)(lsa_prefix + 1); > > - inet6applymask(prefix, &ia->addr, > > - lsa_prefix->prefixlen); > > - append_prefix_lsa(&lsa, &len, lsa_prefix); > > - numprefix++; > > - } > > + log_debug("orig_intra_lsa_rtr: area %s, interface %s: " > > + "%s/%d, metric %d", inet_ntoa(area->id), > > + iface->name, log_in6addr(&iface->addr), > > + lsa_prefix->prefixlen, ntohs(lsa_prefix->metric)); > > + > > + prefix = (struct in6_addr *)(lsa_prefix + 1); > > + inet6applymask(prefix, &iface->addr, > > + lsa_prefix->prefixlen); > > + append_prefix_lsa(&lsa, &len, lsa_prefix); > > + numprefix++; > > > > /* TOD: Add prefixes of directly attached hosts, too */ > > /* TOD: Add prefixes for virtual links */ > > } > > - > > /* If no prefixes were included, continue only if a copy of this > > * LSA already exists in DB. It needs to be flushed. */ > > if (numprefix == 0 && !old) { > > Index: rde_spf.c > > =================================================================== > > RCS file: /cvs/src/usr.sbin/ospf6d/rde_spf.c,v > > retrieving revision 1.28 > > diff -u -p -r1.28 rde_spf.c > > --- rde_spf.c 5 Apr 2020 18:19:04 -0000 1.28 > > +++ rde_spf.c 30 May 2020 14:19:10 -0000 > > @@ -168,6 +168,7 @@ spf_calc(struct area *area) > > /* spf_dump(area); */ > > log_debug("spf_calc: area %s calculated", inet_ntoa(area->id)); > > > > +#if 0 > > /* Dump SPF tree to log */ > > RB_FOREACH(v, lsa_tree, &area->lsa_tree) { > > struct v_nexthop *vn; > > @@ -192,6 +193,7 @@ spf_calc(struct area *area) > > v == spf_root ? "*" : " ", log_rtr_id(htonl(v->adv_rtr)), > > v->type, log_rtr_id(htonl(v->ls_id)), v->cost, hops); > > } > > +#endif > > > > area->num_spf_calc++; > > start_spf_timer(); > > >