area is now part of struct iface Code looks cleaner and more like ospfd.
Index: area.c =================================================================== RCS file: /cvs/src/usr.sbin/ospf6d/area.c,v retrieving revision 1.4 diff -u -p -r1.4 area.c --- area.c 28 Dec 2008 20:08:31 -0000 1.4 +++ area.c 22 Dec 2019 17:18:49 -0000 @@ -88,19 +88,24 @@ area_find(struct ospfd_conf *conf, struc } void -area_track(struct area *area, int state) +area_track(struct area *area) { - int old = area->active; + int old = area->active; + struct iface *iface; - if (state & NBR_STA_FULL) - area->active++; - else if (area->active == 0) - fatalx("area_track: area already inactive"); - else - area->active--; - - if (area->active == 0 || old == 0) + area->active = 0; + LIST_FOREACH(iface, &area->iface_list, entry) { + if (iface->state & IF_STA_DOWN) + continue; + area->active = 1; + break; + } + + if (area->active != old) { + ospfe_imsg_compose_rde(IMSG_AREA_CHANGE, area->id.s_addr, 0, + &area->active, sizeof(area->active)); ospfe_demote_area(area, old == 0); + } } int @@ -110,7 +115,7 @@ area_border_router(struct ospfd_conf *co int active = 0; LIST_FOREACH(area, &conf->area_list, entry) - if (area->active > 0) + if (area->active) active++; return (active > 1); @@ -124,5 +129,5 @@ area_ospf_options(struct area *area) if (area && !area->stub) opt |= OSPF_OPTION_E; - return opt; + return (opt); } Index: database.c =================================================================== RCS file: /cvs/src/usr.sbin/ospf6d/database.c,v retrieving revision 1.17 diff -u -p -r1.17 database.c --- database.c 11 Dec 2019 21:33:56 -0000 1.17 +++ database.c 22 Dec 2019 17:18:49 -0000 @@ -134,8 +134,7 @@ send_db_description(struct nbr *nbr) fatalx("send_db_description: unknown interface type"); } - dd_hdr.opts = htonl(area_ospf_options(area_find(oeconf, - nbr->iface->area_id))); + dd_hdr.opts = htonl(area_ospf_options(nbr->iface->area)); dd_hdr.bits = bits; dd_hdr.dd_seq_num = htonl(nbr->dd_seq_num); Index: hello.c =================================================================== RCS file: /cvs/src/usr.sbin/ospf6d/hello.c,v retrieving revision 1.19 diff -u -p -r1.19 hello.c --- hello.c 11 Dec 2019 21:33:56 -0000 1.19 +++ hello.c 22 Dec 2019 17:18:49 -0000 @@ -72,7 +72,7 @@ send_hello(struct iface *iface) /* hello header */ hello.iface_id = htonl(iface->ifindex); LSA_24_SETHI(hello.opts, iface->priority); - opts = area_ospf_options(area_find(oeconf, iface->area_id)); + opts = area_ospf_options(iface->area); LSA_24_SETLO(hello.opts, opts); hello.opts = htonl(hello.opts); @@ -148,7 +148,7 @@ recv_hello(struct iface *iface, struct i return; } - if ((area = area_find(oeconf, iface->area_id)) == NULL) + if ((area = iface->area) == NULL) fatalx("interface lost area"); opts = LSA_24_GETLO(ntohl(hello.opts)); Index: interface.c =================================================================== RCS file: /cvs/src/usr.sbin/ospf6d/interface.c,v retrieving revision 1.26 diff -u -p -r1.26 interface.c --- interface.c 22 Dec 2019 15:34:52 -0000 1.26 +++ interface.c 22 Dec 2019 17:18:49 -0000 @@ -143,6 +143,7 @@ if_fsm(struct iface *iface, enum iface_e iface->state = new_state; if (iface->state != old_state) { + area_track(iface->area); orig_rtr_lsa(iface); orig_link_lsa(iface); @@ -649,7 +650,7 @@ if_to_ctl(struct iface *iface) memcpy(ictl.name, iface->name, sizeof(ictl.name)); memcpy(&ictl.addr, &iface->addr, sizeof(ictl.addr)); ictl.rtr_id.s_addr = ospfe_router_id(); - memcpy(&ictl.area, &iface->area_id, sizeof(ictl.area)); + memcpy(&ictl.area, &iface->area->id, sizeof(ictl.area)); if (iface->dr) { memcpy(&ictl.dr_id, &iface->dr->id, sizeof(ictl.dr_id)); memcpy(&ictl.dr_addr, &iface->dr->addr, sizeof(ictl.dr_addr)); Index: neighbor.c =================================================================== RCS file: /cvs/src/usr.sbin/ospf6d/neighbor.c,v retrieving revision 1.14 diff -u -p -r1.14 neighbor.c --- neighbor.c 9 Feb 2018 03:53:37 -0000 1.14 +++ neighbor.c 22 Dec 2019 17:18:49 -0000 @@ -202,8 +202,6 @@ nbr_fsm(struct nbr *nbr, enum nbr_event * neighbor changed from/to FULL * originate new rtr and net LSA */ - area_track(area_find(oeconf, nbr->iface->area_id), - nbr->state); orig_rtr_lsa(nbr->iface); if (nbr->iface->state & IF_STA_DR) orig_net_lsa(nbr->iface); @@ -319,7 +317,7 @@ nbr_new(u_int32_t nbr_id, struct iface * if (addr) rn.addr = *addr; rn.id.s_addr = nbr->id.s_addr; - rn.area_id.s_addr = nbr->iface->area_id.s_addr; + rn.area_id.s_addr = nbr->iface->area->id.s_addr; rn.ifindex = nbr->iface->ifindex; rn.iface_id = nbr->iface_id; rn.state = nbr->state; @@ -660,7 +658,7 @@ nbr_to_ctl(struct nbr *nbr) memcpy(&nctl.addr, &nbr->addr, sizeof(nctl.addr)); memcpy(&nctl.dr, &nbr->dr, sizeof(nctl.dr)); memcpy(&nctl.bdr, &nbr->bdr, sizeof(nctl.bdr)); - memcpy(&nctl.area, &nbr->iface->area_id, sizeof(nctl.area)); + memcpy(&nctl.area, &nbr->iface->area->id, sizeof(nctl.area)); /* this list is 99% of the time empty so that's OK for now */ nctl.db_sum_lst_cnt = 0; Index: ospf6d.h =================================================================== RCS file: /cvs/src/usr.sbin/ospf6d/ospf6d.h,v retrieving revision 1.41 diff -u -p -r1.41 ospf6d.h --- ospf6d.h 16 Dec 2019 08:28:33 -0000 1.41 +++ ospf6d.h 22 Dec 2019 17:18:50 -0000 @@ -112,6 +112,7 @@ enum imsg_type { IMSG_NEIGHBOR_CHANGE, IMSG_NETWORK_ADD, IMSG_NETWORK_DEL, + IMSG_AREA_CHANGE, IMSG_DD, IMSG_DD_END, IMSG_DB_SNAPSHOT, @@ -304,10 +305,10 @@ struct iface { struct in6_addr addr; struct in6_addr dst; struct in_addr abr_id; - struct in_addr area_id; struct nbr *dr; /* designated router */ struct nbr *bdr; /* backup designated router */ struct nbr *self; + struct area *area; u_int64_t baudrate; u_int32_t ls_ack_cnt; @@ -511,7 +512,7 @@ struct demote_msg { struct area *area_new(void); int area_del(struct area *); struct area *area_find(struct ospfd_conf *, struct in_addr); -void area_track(struct area *, int); +void area_track(struct area *); int area_border_router(struct ospfd_conf *); u_int32_t area_ospf_options(struct area *); Index: ospfe.c =================================================================== RCS file: /cvs/src/usr.sbin/ospf6d/ospfe.c,v retrieving revision 1.57 diff -u -p -r1.57 ospfe.c --- ospfe.c 22 Dec 2019 15:34:52 -0000 1.57 +++ ospfe.c 22 Dec 2019 17:18:50 -0000 @@ -341,8 +341,8 @@ ospfe_dispatch_main(int fd, short event, TAILQ_INIT(&iface->ls_ack_list); RB_INIT(&iface->lsa_tree); - area = area_find(oeconf, iface->area_id); - LIST_INSERT_HEAD(&area->iface_list, iface, entry); + LIST_INSERT_HEAD(&iface->area->iface_list, iface, + entry); break; case IMSG_IFDELETE: if (imsg.hdr.len != IMSG_HEADER_SIZE + @@ -600,10 +600,10 @@ ospfe_dispatch_rde(int fd, short event, * flood on all area interfaces on * area 0.0.0.0 include also virtual links. */ - if ((area = area_find(oeconf, - nbr->iface->area_id)) == NULL) + if (nbr->iface->area == NULL) fatalx("interface lost area"); - LIST_FOREACH(iface, &area->iface_list, entry) { + LIST_FOREACH(iface, + &nbr->iface->area->iface_list, entry) { noack += lsa_flood(iface, nbr, &lsa_hdr, imsg.data); } @@ -777,11 +777,8 @@ find_vlink(struct abr_rtr *ar) LIST_FOREACH(iface, &area->iface_list, entry) if (iface->abr_id.s_addr == ar->abr_id.s_addr && iface->type == IF_TYPE_VIRTUALLINK && -//XXX iface->area->id.s_addr == ar->area.s_addr) { - iface->area_id.s_addr == ar->area.s_addr) { -//XXX iface->dst.s_addr = ar->dst_ip.s_addr; + iface->area->id.s_addr == ar->area.s_addr) { iface->dst = ar->dst_ip; -//XXX iface->addr.s_addr = ar->addr.s_addr; iface->addr = ar->addr; iface->metric = ar->metric; @@ -808,11 +805,9 @@ orig_rtr_lsa_all(struct area *area) void orig_rtr_lsa(struct iface *iface) { - struct area *area; - - if ((area = area_find(oeconf, iface->area_id)) == NULL) + if (iface->area == NULL) fatalx("interface lost area"); - orig_rtr_lsa_area(area); + orig_rtr_lsa_area(iface->area); } void @@ -1155,7 +1150,7 @@ orig_link_lsa(struct iface *iface) /* LSA link header (lladdr has already been filled in above) */ LSA_24_SETHI(lsa_link.opts, iface->priority); - options = area_ospf_options(area_find(oeconf, iface->area_id)); + options = area_ospf_options(iface->area); LSA_24_SETLO(lsa_link.opts, options); lsa_link.opts = htonl(lsa_link.opts); lsa_link.numprefix = htonl(num_prefix); Index: packet.c =================================================================== RCS file: /cvs/src/usr.sbin/ospf6d/packet.c,v retrieving revision 1.16 diff -u -p -r1.16 packet.c --- packet.c 11 Dec 2019 21:33:56 -0000 1.16 +++ packet.c 22 Dec 2019 17:18:50 -0000 @@ -52,7 +52,7 @@ gen_ospf_hdr(struct ibuf *buf, struct if ospf_hdr.type = type; ospf_hdr.rtr_id = ospfe_router_id(); if (iface->type != IF_TYPE_VIRTUALLINK) - ospf_hdr.area_id = iface->area_id.s_addr; + ospf_hdr.area_id = iface->area->id.s_addr; ospf_hdr.instance = DEFAULT_INSTANCE_ID; ospf_hdr.zero = 0; /* must be zero */ @@ -270,7 +270,7 @@ ospf_hdr_sanity_check(struct ospf_hdr *o } if (iface->type != IF_TYPE_VIRTUALLINK) { - if (ospf_hdr->area_id != iface->area_id.s_addr) { + if (ospf_hdr->area_id != iface->area->id.s_addr) { id.s_addr = ospf_hdr->area_id; log_debug("recv_packet: invalid area ID %s, " "interface %s", inet_ntoa(id), iface->name); Index: parse.y =================================================================== RCS file: /cvs/src/usr.sbin/ospf6d/parse.y,v retrieving revision 1.46 diff -u -p -r1.46 parse.y --- parse.y 16 Dec 2019 08:28:33 -0000 1.46 +++ parse.y 22 Dec 2019 17:18:50 -0000 @@ -537,7 +537,7 @@ interface : INTERFACE STRING { YYERROR; } free($2); - iface->area_id.s_addr = area->id.s_addr; + iface->area = area; LIST_INSERT_HEAD(&area->iface_list, iface, entry); memcpy(&ifacedefs, defs, sizeof(ifacedefs)); Index: rde.c =================================================================== RCS file: /cvs/src/usr.sbin/ospf6d/rde.c,v retrieving revision 1.80 diff -u -p -r1.80 rde.c --- rde.c 11 Jun 2019 05:00:09 -0000 1.80 +++ rde.c 22 Dec 2019 17:18:50 -0000 @@ -319,7 +319,7 @@ rde_dispatch_imsg(int fd, short event, v (nbr->state & NBR_STA_FULL || state & NBR_STA_FULL)) { nbr->state = state; - area_track(nbr->area, state); + area_track(nbr->area); orig_intra_area_prefix_lsas(nbr->area); } @@ -327,6 +327,19 @@ rde_dispatch_imsg(int fd, short event, v if (nbr->state & NBR_STA_FULL) rde_req_list_free(nbr); break; + case IMSG_AREA_CHANGE: + if (imsg.hdr.len - IMSG_HEADER_SIZE != sizeof(state)) + fatalx("invalid size of OE request"); + + LIST_FOREACH(area, &rdeconf->area_list, entry) { + if (area->id.s_addr == imsg.hdr.peerid) + break; + } + if (area == NULL) + break; + memcpy(&state, imsg.data, sizeof(state)); + area->active = state; + break; case IMSG_DB_SNAPSHOT: nbr = rde_nbr_find(imsg.hdr.peerid); if (nbr == NULL) @@ -740,10 +753,9 @@ rde_dispatch_parent(int fd, short event, if (prev_link_ok == link_ok) break; - area = area_find(rdeconf, iface->area_id); - if (!area) + if (iface->area == NULL) fatalx("interface lost area"); - orig_intra_area_prefix_lsas(area); + orig_intra_area_prefix_lsas(iface->area); break; case IMSG_IFADD: @@ -755,8 +767,7 @@ rde_dispatch_parent(int fd, short event, TAILQ_INIT(&iface->ls_ack_list); RB_INIT(&iface->lsa_tree); - area = area_find(rdeconf, iface->area_id); - LIST_INSERT_HEAD(&area->iface_list, iface, entry); + LIST_INSERT_HEAD(&iface->area->iface_list, iface, entry); break; case IMSG_IFDELETE: if (imsg.hdr.len != IMSG_HEADER_SIZE + @@ -789,9 +800,8 @@ rde_dispatch_parent(int fd, short event, ia->prefixlen = ifc->prefixlen; TAILQ_INSERT_TAIL(&iface->ifa_list, ia, entry); - area = area_find(rdeconf, iface->area_id); - if (area) - orig_intra_area_prefix_lsas(area); + if (iface->area) + orig_intra_area_prefix_lsas(iface->area); break; case IMSG_IFADDRDEL: if (imsg.hdr.len != IMSG_HEADER_SIZE + @@ -815,9 +825,8 @@ rde_dispatch_parent(int fd, short event, break; } } - area = area_find(rdeconf, iface->area_id); - if (area) - orig_intra_area_prefix_lsas(area); + if (iface->area) + orig_intra_area_prefix_lsas(iface->area); break; case IMSG_RECONF_CONF: if ((nconf = malloc(sizeof(struct ospfd_conf))) == Index: rde_lsdb.c =================================================================== RCS file: /cvs/src/usr.sbin/ospf6d/rde_lsdb.c,v retrieving revision 1.39 diff -u -p -r1.39 rde_lsdb.c --- rde_lsdb.c 22 Dec 2019 11:19:06 -0000 1.39 +++ rde_lsdb.c 22 Dec 2019 17:18:50 -0000 @@ -574,11 +574,9 @@ lsa_find(struct iface *iface, u_int16_t if (LSA_IS_SCOPE_AS(ntohs(type))) tree = &asext_tree; else if (LSA_IS_SCOPE_AREA(ntohs(type))) { - struct area *area; - - if ((area = area_find(rdeconf, iface->area_id)) == NULL) + if (iface->area == NULL) fatalx("interface lost area"); - tree = &area->lsa_tree; + tree = &iface->area->lsa_tree; } else if (LSA_IS_SCOPE_LLOCAL(ntohs(type))) tree = &iface->lsa_tree; else