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 ?
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();