Still working towards bringing ospf6d and ospfd closer. area is now part of struct iface. redist_list is part of struct area.
Some changes, related to reloading, are not in use now but it feels like the right time to get it in. Denis 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 13 Dec 2019 22:24:09 -0000 @@ -39,6 +39,7 @@ area_new(void) LIST_INIT(&area->iface_list); LIST_INIT(&area->nbr_list); RB_INIT(&area->lsa_tree); + SIMPLEQ_INIT(&area->redist_list); return (area); } @@ -46,9 +47,10 @@ area_new(void) int area_del(struct area *area) { - struct iface *iface = NULL; - struct vertex *v, *nv; - struct rde_nbr *n; + struct iface *iface = NULL; + struct vertex *v, *nv; + struct rde_nbr *n; + struct redistribute *r; /* area is removed so neutralize the demotion done by the area */ if (area->active == 0) @@ -68,6 +70,11 @@ area_del(struct area *area) vertex_free(v); } + while ((r = SIMPLEQ_FIRST(&area->redist_list)) != NULL) { + SIMPLEQ_REMOVE_HEAD(&area->redist_list, entry); + free(r); + } + free(area); return (0); @@ -88,19 +95,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--; + area->active = 0; + LIST_FOREACH(iface, &area->iface_list, entry) { + if (iface->state & IF_STA_DOWN) + continue; + area->active = 1; + break; + } - if (area->active == 0 || old == 0) + 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 +122,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 +136,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 13 Dec 2019 22:24:09 -0000 @@ -135,7 +135,7 @@ send_db_description(struct nbr *nbr) } dd_hdr.opts = htonl(area_ospf_options(area_find(oeconf, - nbr->iface->area_id))); + nbr->iface->area->id))); 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 13 Dec 2019 22:24:09 -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); @@ -120,7 +120,6 @@ recv_hello(struct iface *iface, struct i { struct hello_hdr hello; struct nbr *nbr = NULL, *dr; - struct area *area; u_int32_t nbr_id, opts; int nbr_change = 0; @@ -148,12 +147,12 @@ recv_hello(struct iface *iface, struct i return; } - if ((area = area_find(oeconf, iface->area_id)) == NULL) + if (iface->area == NULL) fatalx("interface lost area"); opts = LSA_24_GETLO(ntohl(hello.opts)); - if ((opts & OSPF_OPTION_E && area->stub) || - ((opts & OSPF_OPTION_E) == 0 && !area->stub)) { + if ((opts & OSPF_OPTION_E && iface->area->stub) || + ((opts & OSPF_OPTION_E) == 0 && !iface->area->stub)) { log_warnx("recv_hello: ExternalRoutingCapability mismatch, " "interface %s", iface->name); return; Index: interface.c =================================================================== RCS file: /cvs/src/usr.sbin/ospf6d/interface.c,v retrieving revision 1.25 diff -u -p -r1.25 interface.c --- interface.c 28 Jun 2019 13:32:49 -0000 1.25 +++ interface.c 13 Dec 2019 22:24:10 -0000 @@ -649,7 +649,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: kroute.c =================================================================== RCS file: /cvs/src/usr.sbin/ospf6d/kroute.c,v retrieving revision 1.61 diff -u -p -r1.61 kroute.c --- kroute.c 12 Dec 2019 08:21:34 -0000 1.61 +++ kroute.c 13 Dec 2019 22:24:10 -0000 @@ -97,10 +97,11 @@ RB_PROTOTYPE(kroute_tree, kroute_node, e RB_GENERATE(kroute_tree, kroute_node, entry, kroute_compare) int -kr_init(int fs, u_int rdomain, u_int8_t fib_prio) +kr_init(int fs, u_int rdomain, int redis_label_or_prefix, u_int8_t fib_prio) { int opt = 0, rcvbuf, default_rcvbuf; socklen_t optlen; + int filter_prio = fib_prio; kr_state.fib_sync = fs; kr_state.rdomain = rdomain; @@ -117,6 +118,18 @@ kr_init(int fs, u_int rdomain, u_int8_t &opt, sizeof(opt)) == -1) log_warn("kr_init: setsockopt"); /* not fatal */ + if (redis_label_or_prefix) { + filter_prio = 0; + log_info("%s: priority filter disabled", __func__); + } else + log_debug("%s: priority filter enabled", __func__); + + if (setsockopt(kr_state.fd, AF_ROUTE, ROUTE_PRIOFILTER, &filter_prio, + sizeof(filter_prio)) == -1) { + log_warn("%s: setsockopt AF_ROUTE ROUTE_PRIOFILTER", __func__); + /* not fatal */ + } + /* grow receive buffer, don't wanna miss messages */ optlen = sizeof(default_rcvbuf); if (getsockopt(kr_state.fd, SOL_SOCKET, SO_RCVBUF, @@ -522,11 +535,25 @@ kr_redistribute(struct kroute_node *kh) } void -kr_reload(void) +kr_reload(int redis_label_or_prefix) { struct kroute_node *kr, *kn; u_int32_t dummy; int r; + int filter_prio = kr_state.fib_prio; + + /* update the priority filter */ + if (redis_label_or_prefix) { + filter_prio = 0; + log_info("%s: priority filter disabled", __func__); + } else + log_debug("%s: priority filter enabled", __func__); + + if (setsockopt(kr_state.fd, AF_ROUTE, ROUTE_PRIOFILTER, &filter_prio, + sizeof(filter_prio)) == -1) { + log_warn("%s: setsockopt AF_ROUTE ROUTE_PRIOFILTER", __func__); + /* not fatal */ + } RB_FOREACH(kr, kroute_tree, &krt) { for (kn = kr; kn; kn = kn->next) { 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 13 Dec 2019 22:24:10 -0000 @@ -202,8 +202,7 @@ 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); + area_track(nbr->iface->area); orig_rtr_lsa(nbr->iface); if (nbr->iface->state & IF_STA_DR) orig_net_lsa(nbr->iface); @@ -319,7 +318,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 +659,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.c =================================================================== RCS file: /cvs/src/usr.sbin/ospf6d/ospf6d.c,v retrieving revision 1.44 diff -u -p -r1.44 ospf6d.c --- ospf6d.c 25 Mar 2019 20:53:33 -0000 1.44 +++ ospf6d.c 13 Dec 2019 22:24:10 -0000 @@ -280,7 +280,8 @@ main(int argc, char *argv[]) fatal("unveil"); if (kr_init(!(ospfd_conf->flags & OSPFD_FLAG_NO_FIB_UPDATE), - ospfd_conf->rdomain, ospfd_conf->fib_priority) == -1) + ospfd_conf->rdomain, ospfd_conf->redist_label_or_prefix, + ospfd_conf->fib_priority) == -1) fatalx("kr_init failed"); event_dispatch(); @@ -293,8 +294,9 @@ main(int argc, char *argv[]) __dead void ospfd_shutdown(void) { - pid_t pid; - int status; + pid_t pid; + int status; + struct redistribute *r; /* close pipes */ msgbuf_clear(&iev_ospfe->ibuf.w); @@ -303,6 +305,10 @@ ospfd_shutdown(void) close(iev_rde->ibuf.fd); control_cleanup(ospfd_conf->csock); + while ((r = SIMPLEQ_FIRST(&ospfd_conf->redist_list)) != NULL) { + SIMPLEQ_REMOVE_HEAD(&ospfd_conf->redist_list, entry); + free(r); + } kr_shutdown(); carp_demote_shutdown(); @@ -622,6 +628,11 @@ ospf_reload(void) LIST_FOREACH(area, &xconf->area_list, entry) { if (ospf_sendboth(IMSG_RECONF_AREA, area, sizeof(*area)) == -1) return (-1); + + SIMPLEQ_FOREACH(r, &area->redist_list, entry) { + main_imsg_compose_rde(IMSG_RECONF_REDIST, 0, r, + sizeof(*r)); + } } if (ospf_sendboth(IMSG_RECONF_END, NULL, 0) == -1) @@ -631,7 +642,7 @@ ospf_reload(void) merge_config(ospfd_conf, xconf); /* update redistribute lists */ - kr_reload(); + kr_reload(ospfd_conf->redist_label_or_prefix); return (0); #else return (-1); @@ -654,12 +665,16 @@ merge_config(struct ospfd_conf *conf, st struct area *a, *xa, *na; struct iface *iface; struct redistribute *r; + int rchange = 0; /* change of rtr_id needs a restart */ conf->flags = xconf->flags; conf->spf_delay = xconf->spf_delay; conf->spf_hold_time = xconf->spf_hold_time; - conf->redistribute = xconf->redistribute; + if (SIMPLEQ_EMPTY(&conf->redist_list) != + SIMPLEQ_EMPTY(&xconf->redist_list)) + rchange = 1; + conf->redist_label_or_prefix = xconf->redist_label_or_prefix; if (ospfd_process == PROC_MAIN) { /* main process does neither use areas nor interfaces */ @@ -706,6 +721,20 @@ merge_config(struct ospfd_conf *conf, st * stub is not yet used but switching between stub and normal * will be another painful job. */ + if (a->stub != xa->stub && ospfd_process == PROC_OSPF_ENGINE) + a->dirty = 1; /* force rtr LSA update */ + if (xa->stub && ospfd_process == PROC_RDE_ENGINE) { + while ((r = SIMPLEQ_FIRST(&a->redist_list)) != NULL) { + SIMPLEQ_REMOVE_HEAD(&a->redist_list, entry); + free(r); + } + + while ((r = SIMPLEQ_FIRST(&xa->redist_list)) != NULL) { + SIMPLEQ_REMOVE_HEAD(&xa->redist_list, entry); + SIMPLEQ_INSERT_TAIL(&a->redist_list, r, entry); + } + } + a->stub = xa->stub; a->stub_default_cost = xa->stub_default_cost; if (ospfd_process == PROC_RDE_ENGINE) Index: ospf6d.h =================================================================== RCS file: /cvs/src/usr.sbin/ospf6d/ospf6d.h,v retrieving revision 1.40 diff -u -p -r1.40 ospf6d.h --- ospf6d.h 11 Jun 2019 05:00:09 -0000 1.40 +++ ospf6d.h 13 Dec 2019 22:24:10 -0000 @@ -125,12 +125,32 @@ enum imsg_type { IMSG_LS_MAXAGE, IMSG_ABR_UP, IMSG_ABR_DOWN, + IMSG_AREA_CHANGE, IMSG_RECONF_CONF, IMSG_RECONF_AREA, + IMSG_RECONF_REDIST, IMSG_RECONF_END, IMSG_DEMOTE }; +#define REDIST_CONNECTED 0x01 +#define REDIST_STATIC 0x02 +#define REDIST_LABEL 0x04 +#define REDIST_ADDR 0x08 +#define REDIST_NO 0x10 +#define REDIST_DEFAULT 0x20 + +struct redistribute { + SIMPLEQ_ENTRY(redistribute) entry; + struct in6_addr addr; + u_int32_t metric; + u_int16_t label; + u_int16_t type; + u_int8_t prefixlen; + char dependon[IFNAMSIZ]; +}; +SIMPLEQ_HEAD(redist_list, redistribute); + /* area */ struct vertex; struct rde_nbr; @@ -143,7 +163,7 @@ struct area { LIST_HEAD(, iface) iface_list; LIST_HEAD(, rde_nbr) nbr_list; -/* list addr_range_list; */ + struct redist_list redist_list; char demote_group[IFNAMSIZ]; u_int32_t stub_default_cost; u_int32_t num_spf_calc; @@ -304,10 +324,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; @@ -348,24 +368,6 @@ enum { PROC_RDE_ENGINE } ospfd_process; -#define REDIST_CONNECTED 0x01 -#define REDIST_STATIC 0x02 -#define REDIST_LABEL 0x04 -#define REDIST_ADDR 0x08 -#define REDIST_NO 0x10 -#define REDIST_DEFAULT 0x20 - -struct redistribute { - SIMPLEQ_ENTRY(redistribute) entry; - struct in6_addr addr; - u_int32_t metric; - u_int16_t label; - u_int16_t type; - u_int8_t prefixlen; - char dependon[IFNAMSIZ]; -}; -SIMPLEQ_HEAD(redist_list, redistribute); - struct ospfd_conf { struct event ev; struct in_addr rtr_id; @@ -385,6 +387,7 @@ struct ospfd_conf { int spf_state; int ospf_socket; int flags; + int redist_label_or_prefix; u_int8_t border; u_int8_t redistribute; u_int8_t fib_priority; @@ -510,7 +513,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 *); @@ -540,7 +543,7 @@ u_int16_t in_cksum(void *, size_t); u_int16_t iso_cksum(void *, u_int16_t, u_int16_t); /* kroute.c */ -int kr_init(int, u_int, u_int8_t); +int kr_init(int, u_int, int, u_int8_t); int kr_change(struct kroute *, int); int kr_delete(struct kroute *); void kr_shutdown(void); @@ -548,7 +551,7 @@ void kr_fib_couple(void); void kr_fib_decouple(void); void kr_dispatch_msg(int, short, void *); void kr_show_route(struct imsg *); -void kr_reload(void); +void kr_reload(int); void embedscope(struct sockaddr_in6 *); void recoverscope(struct sockaddr_in6 *); Index: ospfe.c =================================================================== RCS file: /cvs/src/usr.sbin/ospf6d/ospfe.c,v retrieving revision 1.56 diff -u -p -r1.56 ospfe.c --- ospfe.c 11 Jun 2019 05:00:09 -0000 1.56 +++ ospfe.c 13 Dec 2019 22:24:10 -0000 @@ -72,11 +72,12 @@ pid_t ospfe(struct ospfd_conf *xconf, int pipe_parent2ospfe[2], int pipe_ospfe2rde[2], int pipe_parent2rde[2]) { - struct area *area; - struct iface *iface; - struct passwd *pw; - struct event ev_sigint, ev_sigterm; - pid_t pid; + struct area *area; + struct iface *iface; + struct redistribute *r; + struct passwd *pw; + struct event ev_sigint, ev_sigterm; + pid_t pid; switch (pid = fork()) { case -1: @@ -174,6 +175,12 @@ ospfe(struct ospfd_conf *xconf, int pipe /* remove unneeded config stuff */ conf_clear_redist_list(&oeconf->redist_list); + LIST_FOREACH(area, &oeconf->area_list, entry) { + while ((r = SIMPLEQ_FIRST(&area->redist_list)) != NULL) { + SIMPLEQ_REMOVE_HEAD(&area->redist_list, entry); + free(r); + } + } /* listen on ospfd control socket */ TAILQ_INIT(&ctl_conns); @@ -341,8 +348,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 + @@ -418,6 +425,7 @@ ospfe_dispatch_main(int fd, short event, LIST_INIT(&narea->iface_list); LIST_INIT(&narea->nbr_list); RB_INIT(&narea->lsa_tree); + SIMPLEQ_INIT(&narea->redist_list); LIST_INSERT_HEAD(&nconf->area_list, narea, entry); break; @@ -600,10 +608,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); } @@ -778,7 +786,7 @@ find_vlink(struct abr_rtr *ar) 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) { + iface->area->id.s_addr == ar->area.s_addr) { //XXX iface->dst.s_addr = ar->dst_ip.s_addr; iface->dst = ar->dst_ip; //XXX iface->addr.s_addr = ar->addr.s_addr; @@ -808,11 +816,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 +1161,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 13 Dec 2019 22:24:10 -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.45 diff -u -p -r1.45 parse.y --- parse.y 11 Jun 2019 05:00:09 -0000 1.45 +++ parse.y 13 Dec 2019 22:24:10 -0000 @@ -289,8 +289,10 @@ redistribute : no REDISTRIBUTE STRING op r->type = REDIST_STATIC; else if (!strcmp($3, "connected")) r->type = REDIST_CONNECTED; - else if (prefix($3, &r->addr, &r->prefixlen)) + else if (prefix($3, &r->addr, &r->prefixlen)) { r->type = REDIST_ADDR; + conf->redist_label_or_prefix = !$1; + } else { yyerror("unknown redistribute type"); free($3); @@ -318,6 +320,8 @@ redistribute : no REDISTRIBUTE STRING op r->label = rtlabel_name2id($4); if ($1) r->type |= REDIST_NO; + else + conf->redist_label_or_prefix = 1; r->metric = $5; if ($6) strlcpy(r->dependon, $6, sizeof(r->dependon)); @@ -519,6 +523,20 @@ areaoptsl : interface } } | defaults + | STUB { area->stub = 1; } + | STUB redistribute { + area->stub = 1; + if ($2->type != REDIST_DEFAULT) { + yyerror("bad redistribute option"); + YYERROR; + } + if (!SIMPLEQ_EMPTY(&area->redist_list)) { + yyerror("area redistribute option only " + "allowed once"); + YYERROR; + } + SIMPLEQ_INSERT_TAIL(&area->redist_list, $2, entry); + } ; interface : INTERFACE STRING { @@ -533,7 +551,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: printconf.c =================================================================== RCS file: /cvs/src/usr.sbin/ospf6d/printconf.c,v retrieving revision 1.8 diff -u -p -r1.8 printconf.c --- printconf.c 29 Dec 2018 16:04:31 -0000 1.8 +++ printconf.c 13 Dec 2019 22:24:10 -0000 @@ -31,7 +31,7 @@ void print_mainconf(struct ospfd_conf *); const char *print_no(u_int16_t); -void print_redistribute(struct ospfd_conf *); +void print_redistribute(struct redist_list *); void print_rtlabel(struct ospfd_conf *); void print_iface(struct iface *); @@ -53,7 +53,7 @@ print_mainconf(struct ospfd_conf *conf) if (conf->flags & OSPFD_FLAG_STUB_ROUTER) printf("stub router yes\n"); - print_redistribute(conf); + print_redistribute(&conf->redist_list); print_rtlabel(conf); printf("spf-delay %u\n", conf->spf_delay); @@ -70,11 +70,11 @@ print_no(u_int16_t type) } void -print_redistribute(struct ospfd_conf *conf) +print_redistribute(struct redist_list *rlh) { struct redistribute *r; - SIMPLEQ_FOREACH(r, &conf->redist_list, entry) { + SIMPLEQ_FOREACH(r, rlh, entry) { switch (r->type & ~REDIST_NO) { case REDIST_STATIC: printf("%sredistribute static ", print_no(r->type)); @@ -150,6 +150,15 @@ print_config(struct ospfd_conf *conf) LIST_FOREACH(area, &conf->area_list, entry) { printf("area %s {\n", inet_ntoa(area->id)); + if (area->stub) { + printf("\tstub"); + if (SIMPLEQ_EMPTY(&area->redist_list)) + printf("\n"); + else { + printf(" "); + print_redistribute(&area->redist_list); + } + } if (*area->demote_group) printf("\tdemote %s %d\n", area->demote_group, area->demote_level); 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 13 Dec 2019 22:24:10 -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) @@ -637,6 +650,7 @@ rde_dispatch_parent(int fd, short event, struct kroute kr; struct imsgev *iev = bula; struct imsgbuf *ibuf = &iev->ibuf; + struct redistribute *nred; struct lsa *lsa; struct vertex *v; ssize_t n; @@ -740,10 +754,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 +768,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 +801,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 +826,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))) == @@ -836,8 +846,16 @@ rde_dispatch_parent(int fd, short event, LIST_INIT(&narea->iface_list); LIST_INIT(&narea->nbr_list); RB_INIT(&narea->lsa_tree); + SIMPLEQ_INIT(&narea->redist_list); LIST_INSERT_HEAD(&nconf->area_list, narea, entry); + break; + case IMSG_RECONF_REDIST: + if ((nred= malloc(sizeof(struct redistribute))) == NULL) + fatal(NULL); + memcpy(nred, imsg.data, sizeof(struct redistribute)); + + SIMPLEQ_INSERT_TAIL(&narea->redist_list, nred, entry); break; case IMSG_RECONF_END: merge_config(rdeconf, nconf); Index: rde_lsdb.c =================================================================== RCS file: /cvs/src/usr.sbin/ospf6d/rde_lsdb.c,v retrieving revision 1.38 diff -u -p -r1.38 rde_lsdb.c --- rde_lsdb.c 18 Oct 2013 11:16:52 -0000 1.38 +++ rde_lsdb.c 13 Dec 2019 22:24:10 -0000 @@ -544,11 +544,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