diff options
Diffstat (limited to 'ospf6d/ospf6_top.c')
| -rw-r--r-- | ospf6d/ospf6_top.c | 520 |
1 files changed, 373 insertions, 147 deletions
diff --git a/ospf6d/ospf6_top.c b/ospf6d/ospf6_top.c index 1f906cadd1..cbfa8ba3d5 100644 --- a/ospf6d/ospf6_top.c +++ b/ospf6d/ospf6_top.c @@ -29,6 +29,7 @@ #include "thread.h" #include "command.h" #include "defaults.h" +#include "lib/json.h" #include "lib_errors.h" #include "ospf6_proto.h" @@ -59,17 +60,76 @@ FRR_CFG_DEFAULT_BOOL(OSPF6_LOG_ADJACENCY_CHANGES, ) /* global ospf6d variable */ -struct ospf6 *ospf6; static struct ospf6_master ospf6_master; struct ospf6_master *om6; static void ospf6_disable(struct ospf6 *o); +static void ospf6_add(struct ospf6 *ospf6) +{ + listnode_add(om6->ospf6, ospf6); +} + +static void ospf6_del(struct ospf6 *ospf6) +{ + listnode_delete(om6->ospf6, ospf6); +} + +const char *ospf6_vrf_id_to_name(vrf_id_t vrf_id) +{ + struct vrf *vrf = vrf_lookup_by_id(vrf_id); + + return vrf ? vrf->name : "NIL"; +} + +/* Link OSPF instance to VRF. */ +void ospf6_vrf_link(struct ospf6 *ospf6, struct vrf *vrf) +{ + ospf6->vrf_id = vrf->vrf_id; + if (vrf->info != (void *)ospf6) + vrf->info = (void *)ospf6; +} + +/* Unlink OSPF instance from VRF. */ +void ospf6_vrf_unlink(struct ospf6 *ospf6, struct vrf *vrf) +{ + if (vrf->info == (void *)ospf6) + vrf->info = NULL; + ospf6->vrf_id = VRF_UNKNOWN; +} + +struct ospf6 *ospf6_lookup_by_vrf_id(vrf_id_t vrf_id) +{ + struct vrf *vrf = NULL; + + vrf = vrf_lookup_by_id(vrf_id); + if (!vrf) + return NULL; + return (vrf->info) ? (struct ospf6 *)vrf->info : NULL; +} + +struct ospf6 *ospf6_lookup_by_vrf_name(const char *name) +{ + struct ospf6 *o = NULL; + struct listnode *node, *nnode; + + for (ALL_LIST_ELEMENTS(om6->ospf6, node, nnode, o)) { + if (((o->name == NULL && name == NULL) + || (o->name && name && strcmp(o->name, name) == 0))) + return o; + } + return NULL; +} + + static void ospf6_top_lsdb_hook_add(struct ospf6_lsa *lsa) { + struct ospf6 *ospf6 = NULL; + switch (ntohs(lsa->header->type)) { case OSPF6_LSTYPE_AS_EXTERNAL: - ospf6_asbr_lsa_add(lsa); + ospf6 = ospf6_get_by_lsdb(lsa); + ospf6_asbr_lsa_add(lsa, ospf6); break; default: @@ -89,20 +149,23 @@ static void ospf6_top_lsdb_hook_remove(struct ospf6_lsa *lsa) } } -static void ospf6_top_route_hook_add(struct ospf6_route *route) +static void ospf6_top_route_hook_add(struct ospf6_route *route, + struct ospf6 *ospf6) { - ospf6_abr_originate_summary(route); - ospf6_zebra_route_update_add(route); + ospf6_abr_originate_summary(route, ospf6); + ospf6_zebra_route_update_add(route, ospf6); } -static void ospf6_top_route_hook_remove(struct ospf6_route *route) +static void ospf6_top_route_hook_remove(struct ospf6_route *route, + struct ospf6 *ospf6) { route->flag |= OSPF6_ROUTE_REMOVE; - ospf6_abr_originate_summary(route); - ospf6_zebra_route_update_remove(route); + ospf6_abr_originate_summary(route, ospf6); + ospf6_zebra_route_update_remove(route, ospf6); } -static void ospf6_top_brouter_hook_add(struct ospf6_route *route) +static void ospf6_top_brouter_hook_add(struct ospf6_route *route, + struct ospf6 *ospf6) { if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL) || IS_OSPF6_DEBUG_BROUTER) { @@ -117,12 +180,14 @@ static void ospf6_top_brouter_hook_add(struct ospf6_route *route) route->path.origin.adv_router, listcount(route->nh_list)); } - ospf6_abr_examin_brouter(ADV_ROUTER_IN_PREFIX(&route->prefix)); - ospf6_asbr_lsentry_add(route); - ospf6_abr_originate_summary(route); + ospf6_abr_examin_brouter(ADV_ROUTER_IN_PREFIX(&route->prefix), route, + ospf6); + ospf6_asbr_lsentry_add(route, ospf6); + ospf6_abr_originate_summary(route, ospf6); } -static void ospf6_top_brouter_hook_remove(struct ospf6_route *route) +static void ospf6_top_brouter_hook_remove(struct ospf6_route *route, + struct ospf6 *ospf6) { if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL) || IS_OSPF6_DEBUG_BROUTER) { @@ -138,9 +203,10 @@ static void ospf6_top_brouter_hook_remove(struct ospf6_route *route) listcount(route->nh_list)); } route->flag |= OSPF6_ROUTE_REMOVE; - ospf6_abr_examin_brouter(ADV_ROUTER_IN_PREFIX(&route->prefix)); - ospf6_asbr_lsentry_remove(route); - ospf6_abr_originate_summary(route); + ospf6_abr_examin_brouter(ADV_ROUTER_IN_PREFIX(&route->prefix), route, + ospf6); + ospf6_asbr_lsentry_remove(route, ospf6); + ospf6_abr_originate_summary(route, ospf6); } static struct ospf6 *ospf6_create(const char *name) @@ -153,9 +219,16 @@ static struct ospf6 *ospf6_create(const char *name) vrf = vrf_lookup_by_name(name); if (vrf) { o->vrf_id = vrf->vrf_id; - /* Freed in ospf6_delete */ - o->name = XSTRDUP(MTYPE_OSPF6_TOP, name); - } + } else + o->vrf_id = VRF_UNKNOWN; + + /* Freed in ospf6_delete */ + o->name = XSTRDUP(MTYPE_OSPF6_TOP, name); + if (vrf) + ospf6_vrf_link(o, vrf); + + ospf6_zebra_vrf_register(o); + /* initialize */ monotime(&o->starttime); o->area_list = list_new(); @@ -201,16 +274,20 @@ static struct ospf6 *ospf6_create(const char *name) return o; } -void ospf6_instance_create(const char *name) +struct ospf6 *ospf6_instance_create(const char *name) { + struct ospf6 *ospf6; + ospf6 = ospf6_create(name); if (DFLT_OSPF6_LOG_ADJACENCY_CHANGES) SET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_CHANGES); if (ospf6->router_id == 0) - ospf6_router_id_update(); - + ospf6_router_id_update(ospf6); + ospf6_add(ospf6); thread_add_read(master, ospf6_receive, ospf6, ospf6->fd, &ospf6->t_ospf6_receive); + + return ospf6; } void ospf6_delete(struct ospf6 *o) @@ -220,8 +297,9 @@ void ospf6_delete(struct ospf6 *o) QOBJ_UNREG(o); - ospf6_flush_self_originated_lsas_now(); - ospf6_disable(ospf6); + ospf6_flush_self_originated_lsas_now(o); + ospf6_disable(o); + ospf6_del(o); for (ALL_LIST_ELEMENTS(o->area_list, node, nnode, oa)) ospf6_area_delete(oa); @@ -232,10 +310,10 @@ void ospf6_delete(struct ospf6 *o) ospf6_lsdb_delete(o->lsdb); ospf6_lsdb_delete(o->lsdb_self); - ospf6_route_table_delete(o->route_table); - ospf6_route_table_delete(o->brouter_table); + ospf6_route_table_delete(o->route_table, o); + ospf6_route_table_delete(o->brouter_table, o); - ospf6_route_table_delete(o->external_table); + ospf6_route_table_delete(o->external_table, o); route_table_finish(o->external_id_table); ospf6_distance_reset(o); @@ -260,8 +338,8 @@ static void ospf6_disable(struct ospf6 *o) ospf6_asbr_redistribute_reset(o->vrf_id); ospf6_lsdb_remove_all(o->lsdb); - ospf6_route_remove_all(o->route_table); - ospf6_route_remove_all(o->brouter_table); + ospf6_route_remove_all(o->route_table, o); + ospf6_route_remove_all(o->brouter_table, o); THREAD_OFF(o->maxage_remover); THREAD_OFF(o->t_spf_calc); @@ -271,11 +349,13 @@ static void ospf6_disable(struct ospf6 *o) } } -void ospf6_master_init(void) +void ospf6_master_init(struct thread_master *master) { memset(&ospf6_master, 0, sizeof(struct ospf6_master)); om6 = &ospf6_master; + om6->ospf6 = list_new(); + om6->master = master; } static int ospf6_maxage_remover(struct thread *thread) @@ -333,7 +413,7 @@ void ospf6_maxage_remove(struct ospf6 *o) &o->maxage_remover); } -void ospf6_router_id_update(void) +void ospf6_router_id_update(struct ospf6 *ospf6) { if (!ospf6) return; @@ -351,8 +431,11 @@ DEFUN_NOSH (router_ospf6, ROUTER_STR OSPF6_STR) { + struct ospf6 *ospf6; + + ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME); if (ospf6 == NULL) - ospf6_instance_create(VRF_DEFAULT_NAME); + ospf6 = ospf6_instance_create(VRF_DEFAULT_NAME); /* set current ospf point. */ VTY_PUSH_CONTEXT(OSPF6_NODE, ospf6); @@ -368,6 +451,9 @@ DEFUN (no_router_ospf6, ROUTER_STR OSPF6_STR) { + struct ospf6 *ospf6; + + ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME); if (ospf6 == NULL) vty_out(vty, "OSPFv3 is not configured\n"); else { @@ -672,13 +758,14 @@ DEFUN (ospf6_interface_area, "OSPF6 area ID in decimal notation\n" ) { - VTY_DECLVAR_CONTEXT(ospf6, o); int idx_ifname = 1; int idx_ipv4 = 3; struct ospf6_area *oa; struct ospf6_interface *oi; struct interface *ifp; + VTY_DECLVAR_CONTEXT(ospf6, ospf6); + /* find/create ospf6 interface */ ifp = if_get_by_name(argv[idx_ifname]->arg, VRF_DEFAULT); oi = (struct ospf6_interface *)ifp->info; @@ -691,7 +778,7 @@ DEFUN (ospf6_interface_area, } /* parse Area-ID */ - OSPF6_CMD_AREA_GET(argv[idx_ipv4]->arg, oa); + OSPF6_CMD_AREA_GET(argv[idx_ipv4]->arg, oa, ospf6); /* attach interface to area */ listnode_add(oa->if_list, oi); /* sort ?? */ @@ -700,14 +787,14 @@ DEFUN (ospf6_interface_area, SET_FLAG(oa->flag, OSPF6_AREA_ENABLE); /* ospf6 process is currently disabled, not much more to do */ - if (CHECK_FLAG(o->flag, OSPF6_DISABLED)) + if (CHECK_FLAG(ospf6->flag, OSPF6_DISABLED)) return CMD_SUCCESS; /* start up */ ospf6_interface_enable(oi); /* If the router is ABR, originate summary routes */ - if (ospf6_is_router_abr(o)) + if (ospf6_is_router_abr(ospf6)) ospf6_abr_enable_area(oa); return CMD_SUCCESS; @@ -783,6 +870,8 @@ DEFUN (ospf6_stub_router_admin, struct listnode *node; struct ospf6_area *oa; + VTY_DECLVAR_CONTEXT(ospf6, ospf6); + if (!CHECK_FLAG(ospf6->flag, OSPF6_STUB_ROUTER)) { for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, node, oa)) { OSPF6_OPT_CLEAR(oa->options, OSPF6_OPT_V6); @@ -805,6 +894,7 @@ DEFUN (no_ospf6_stub_router_admin, struct listnode *node; struct ospf6_area *oa; + VTY_DECLVAR_CONTEXT(ospf6, ospf6); if (CHECK_FLAG(ospf6->flag, OSPF6_STUB_ROUTER)) { for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, node, oa)) { OSPF6_OPT_SET(oa->options, OSPF6_OPT_V6); @@ -865,88 +955,207 @@ DEFUN (no_ospf6_stub_router_shutdown, } #endif -static void ospf6_show(struct vty *vty, struct ospf6 *o) + +static void ospf6_show(struct vty *vty, struct ospf6 *o, json_object *json, + bool use_json) { struct listnode *n; struct ospf6_area *oa; char router_id[16], duration[32]; struct timeval now, running, result; char buf[32], rbuf[32]; + json_object *json_areas = NULL; + const char *adjacency; + + if (use_json) { + json_areas = json_object_new_object(); + + /* process id, router id */ + inet_ntop(AF_INET, &o->router_id, router_id, sizeof(router_id)); + json_object_string_add(json, "routerId", router_id); + + /* running time */ + monotime(&now); + timersub(&now, &o->starttime, &running); + timerstring(&running, duration, sizeof(duration)); + json_object_string_add(json, "running", duration); + + /* Redistribute configuration */ + /* XXX */ + json_object_int_add(json, "lsaMinimumArrivalMsecs", + o->lsa_minarrival); + + /* Show SPF parameters */ + json_object_int_add(json, "spfScheduleDelayMsecs", + o->spf_delay); + json_object_int_add(json, "holdTimeMinMsecs", o->spf_holdtime); + json_object_int_add(json, "holdTimeMaxMsecs", + o->spf_max_holdtime); + json_object_int_add(json, "holdTimeMultiplier", + o->spf_hold_multiplier); + + + if (o->ts_spf.tv_sec || o->ts_spf.tv_usec) { + timersub(&now, &o->ts_spf, &result); + timerstring(&result, buf, sizeof(buf)); + ospf6_spf_reason_string(o->last_spf_reason, rbuf, + sizeof(rbuf)); + json_object_boolean_true_add(json, "spfHasRun"); + json_object_string_add(json, "spfLastExecutedMsecs", + buf); + json_object_string_add(json, "spfLastExecutedReason", + rbuf); + + json_object_int_add( + json, "spfLastDurationSecs", + (long long)o->ts_spf_duration.tv_sec); + + json_object_int_add( + json, "spfLastDurationMsecs", + (long long)o->ts_spf_duration.tv_usec); + } else + json_object_boolean_false_add(json, "spfHasRun"); + + + threadtimer_string(now, o->t_spf_calc, buf, sizeof(buf)); + if (o->t_spf_calc) { + long time_store; + + json_object_boolean_true_add(json, "spfTimerActive"); + time_store = + monotime_until(&o->t_spf_calc->u.sands, NULL) + / 1000LL; + json_object_int_add(json, "spfTimerDueInMsecs", + time_store); + } else + json_object_boolean_false_add(json, "spfTimerActive"); + + json_object_boolean_add(json, "routerIsStubRouter", + CHECK_FLAG(o->flag, OSPF6_STUB_ROUTER)); + + /* LSAs */ + json_object_int_add(json, "numberOfAsScopedLsa", + o->lsdb->count); + /* Areas */ + json_object_int_add(json, "numberOfAreaInRouter", + listcount(o->area_list)); + + if (CHECK_FLAG(o->config_flags, OSPF6_LOG_ADJACENCY_CHANGES)) { + if (CHECK_FLAG(o->config_flags, + OSPF6_LOG_ADJACENCY_DETAIL)) + adjacency = "LoggedAll"; + else + adjacency = "Logged"; + } else + adjacency = "NotLogged"; + json_object_string_add(json, "adjacencyChanges", adjacency); + + for (ALL_LIST_ELEMENTS_RO(o->area_list, n, oa)) + ospf6_area_show(vty, oa, json_areas, use_json); + + json_object_object_add(json, "areas", json_areas); + + vty_out(vty, "%s\n", + json_object_to_json_string_ext( + json, JSON_C_TO_STRING_PRETTY)); + + } else { + /* process id, router id */ + inet_ntop(AF_INET, &o->router_id, router_id, sizeof(router_id)); + vty_out(vty, " OSPFv3 Routing Process (0) with Router-ID %s\n", + router_id); + + /* running time */ + monotime(&now); + timersub(&now, &o->starttime, &running); + timerstring(&running, duration, sizeof(duration)); + vty_out(vty, " Running %s\n", duration); + + /* Redistribute configuration */ + /* XXX */ + vty_out(vty, " LSA minimum arrival %d msecs\n", + o->lsa_minarrival); + + + /* Show SPF parameters */ + vty_out(vty, + " Initial SPF scheduling delay %d millisec(s)\n" + " Minimum hold time between consecutive SPFs %d millsecond(s)\n" + " Maximum hold time between consecutive SPFs %d millsecond(s)\n" + " Hold time multiplier is currently %d\n", + o->spf_delay, o->spf_holdtime, o->spf_max_holdtime, + o->spf_hold_multiplier); + + + vty_out(vty, " SPF algorithm "); + if (o->ts_spf.tv_sec || o->ts_spf.tv_usec) { + timersub(&now, &o->ts_spf, &result); + timerstring(&result, buf, sizeof(buf)); + ospf6_spf_reason_string(o->last_spf_reason, rbuf, + sizeof(rbuf)); + vty_out(vty, "last executed %s ago, reason %s\n", buf, + rbuf); + vty_out(vty, " Last SPF duration %lld sec %lld usec\n", + (long long)o->ts_spf_duration.tv_sec, + (long long)o->ts_spf_duration.tv_usec); + } else + vty_out(vty, "has not been run\n"); + + threadtimer_string(now, o->t_spf_calc, buf, sizeof(buf)); + vty_out(vty, " SPF timer %s%s\n", + (o->t_spf_calc ? "due in " : "is "), buf); + + if (CHECK_FLAG(o->flag, OSPF6_STUB_ROUTER)) + vty_out(vty, " Router Is Stub Router\n"); + + /* LSAs */ + vty_out(vty, " Number of AS scoped LSAs is %u\n", + o->lsdb->count); + + /* Areas */ + vty_out(vty, " Number of areas in this router is %u\n", + listcount(o->area_list)); + + if (CHECK_FLAG(o->config_flags, OSPF6_LOG_ADJACENCY_CHANGES)) { + if (CHECK_FLAG(o->config_flags, + OSPF6_LOG_ADJACENCY_DETAIL)) + vty_out(vty, + " All adjacency changes are logged\n"); + else + vty_out(vty, " Adjacency changes are logged\n"); + } - /* process id, router id */ - inet_ntop(AF_INET, &o->router_id, router_id, sizeof(router_id)); - vty_out(vty, " OSPFv3 Routing Process (0) with Router-ID %s\n", - router_id); - - /* running time */ - monotime(&now); - timersub(&now, &o->starttime, &running); - timerstring(&running, duration, sizeof(duration)); - vty_out(vty, " Running %s\n", duration); - - /* Redistribute configuration */ - /* XXX */ - - vty_out(vty, " LSA minimum arrival %d msecs\n", o->lsa_minarrival); - - /* Show SPF parameters */ - vty_out(vty, - " Initial SPF scheduling delay %d millisec(s)\n" - " Minimum hold time between consecutive SPFs %d millsecond(s)\n" - " Maximum hold time between consecutive SPFs %d millsecond(s)\n" - " Hold time multiplier is currently %d\n", - o->spf_delay, o->spf_holdtime, o->spf_max_holdtime, - o->spf_hold_multiplier); - - vty_out(vty, " SPF algorithm "); - if (o->ts_spf.tv_sec || o->ts_spf.tv_usec) { - timersub(&now, &o->ts_spf, &result); - timerstring(&result, buf, sizeof(buf)); - ospf6_spf_reason_string(o->last_spf_reason, rbuf, sizeof(rbuf)); - vty_out(vty, "last executed %s ago, reason %s\n", buf, rbuf); - vty_out(vty, " Last SPF duration %lld sec %lld usec\n", - (long long)o->ts_spf_duration.tv_sec, - (long long)o->ts_spf_duration.tv_usec); - } else - vty_out(vty, "has not been run\n"); - threadtimer_string(now, o->t_spf_calc, buf, sizeof(buf)); - vty_out(vty, " SPF timer %s%s\n", (o->t_spf_calc ? "due in " : "is "), - buf); - - if (CHECK_FLAG(o->flag, OSPF6_STUB_ROUTER)) - vty_out(vty, " Router Is Stub Router\n"); - - /* LSAs */ - vty_out(vty, " Number of AS scoped LSAs is %u\n", o->lsdb->count); - - /* Areas */ - vty_out(vty, " Number of areas in this router is %u\n", - listcount(o->area_list)); - - if (CHECK_FLAG(o->config_flags, OSPF6_LOG_ADJACENCY_CHANGES)) { - if (CHECK_FLAG(o->config_flags, OSPF6_LOG_ADJACENCY_DETAIL)) - vty_out(vty, " All adjacency changes are logged\n"); - else - vty_out(vty, " Adjacency changes are logged\n"); - } - vty_out(vty, "\n"); + vty_out(vty, "\n"); - for (ALL_LIST_ELEMENTS_RO(o->area_list, n, oa)) - ospf6_area_show(vty, oa); + for (ALL_LIST_ELEMENTS_RO(o->area_list, n, oa)) + ospf6_area_show(vty, oa, json_areas, use_json); + } } /* show top level structures */ -DEFUN (show_ipv6_ospf6, - show_ipv6_ospf6_cmd, - "show ipv6 ospf6", - SHOW_STR - IP6_STR - OSPF6_STR) +DEFUN(show_ipv6_ospf6, + show_ipv6_ospf6_cmd, + "show ipv6 ospf6 [json]", + SHOW_STR + IP6_STR + OSPF6_STR + JSON_STR) { - OSPF6_CMD_CHECK_RUNNING(); + struct ospf6 *ospf6; + bool uj = use_json(argc, argv); + json_object *json = NULL; + + ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME); + OSPF6_CMD_CHECK_RUNNING(ospf6); + + if (uj) + json = json_object_new_object(); - ospf6_show(vty, ospf6); + ospf6_show(vty, ospf6, json, uj); + + if (uj) + json_object_free(json); return CMD_SUCCESS; } @@ -966,7 +1175,10 @@ DEFUN (show_ipv6_ospf6_route, "Detailed information\n" "Summary of route table\n") { - OSPF6_CMD_CHECK_RUNNING(); + struct ospf6 *ospf6; + + ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME); + OSPF6_CMD_CHECK_RUNNING(ospf6); ospf6_route_table_show(vty, 4, argc, argv, ospf6->route_table); return CMD_SUCCESS; @@ -983,9 +1195,13 @@ DEFUN (show_ipv6_ospf6_route_match, "Display routes which match the specified route\n" "Display routes longer than the specified route\n") { - OSPF6_CMD_CHECK_RUNNING(); + struct ospf6 *ospf6; + + ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME); + OSPF6_CMD_CHECK_RUNNING(ospf6); ospf6_route_table_show(vty, 4, argc, argv, ospf6->route_table); + return CMD_SUCCESS; } @@ -1001,7 +1217,10 @@ DEFUN (show_ipv6_ospf6_route_match_detail, "Detailed information\n" ) { - OSPF6_CMD_CHECK_RUNNING(); + struct ospf6 *ospf6; + + ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME); + OSPF6_CMD_CHECK_RUNNING(ospf6); ospf6_route_table_show(vty, 4, argc, argv, ospf6->route_table); return CMD_SUCCESS; @@ -1022,13 +1241,16 @@ DEFUN (show_ipv6_ospf6_route_type_detail, "Detailed information\n" ) { - OSPF6_CMD_CHECK_RUNNING(); + struct ospf6 *ospf6; + + ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME); + OSPF6_CMD_CHECK_RUNNING(ospf6); ospf6_route_table_show(vty, 4, argc, argv, ospf6->route_table); return CMD_SUCCESS; } -static void ospf6_stub_router_config_write(struct vty *vty) +static void ospf6_stub_router_config_write(struct vty *vty, struct ospf6 *ospf6) { if (CHECK_FLAG(ospf6->flag, OSPF6_STUB_ROUTER)) { vty_out(vty, " stub-router administrative\n"); @@ -1036,7 +1258,7 @@ static void ospf6_stub_router_config_write(struct vty *vty) return; } -static int ospf6_distance_config_write(struct vty *vty) +static int ospf6_distance_config_write(struct vty *vty, struct ospf6 *ospf6) { struct route_node *rn; struct ospf6_distance *odistance; @@ -1070,52 +1292,56 @@ static int ospf6_distance_config_write(struct vty *vty) /* OSPF configuration write function. */ static int config_write_ospf6(struct vty *vty) { - char router_id[16]; struct listnode *j, *k; struct ospf6_area *oa; struct ospf6_interface *oi; + struct ospf6 *ospf6; + struct listnode *node, *nnode; /* OSPFv3 configuration. */ - if (ospf6 == NULL) + if (om6 == NULL) return CMD_SUCCESS; - inet_ntop(AF_INET, &ospf6->router_id_static, router_id, - sizeof(router_id)); - vty_out(vty, "router ospf6\n"); - if (ospf6->router_id_static != 0) - vty_out(vty, " ospf6 router-id %s\n", router_id); - - /* log-adjacency-changes flag print. */ - if (CHECK_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_CHANGES)) { - if (CHECK_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_DETAIL)) - vty_out(vty, " log-adjacency-changes detail\n"); - else if (!SAVE_OSPF6_LOG_ADJACENCY_CHANGES) - vty_out(vty, " log-adjacency-changes\n"); - } else if (SAVE_OSPF6_LOG_ADJACENCY_CHANGES) { - vty_out(vty, " no log-adjacency-changes\n"); - } + for (ALL_LIST_ELEMENTS(om6->ospf6, node, nnode, ospf6)) { + vty_out(vty, "router ospf6\n"); + if (ospf6->router_id_static != 0) + vty_out(vty, " ospf6 router-id %pI4\n", + &ospf6->router_id_static); + + /* log-adjacency-changes flag print. */ + if (CHECK_FLAG(ospf6->config_flags, + OSPF6_LOG_ADJACENCY_CHANGES)) { + if (CHECK_FLAG(ospf6->config_flags, + OSPF6_LOG_ADJACENCY_DETAIL)) + vty_out(vty, " log-adjacency-changes detail\n"); + else if (!SAVE_OSPF6_LOG_ADJACENCY_CHANGES) + vty_out(vty, " log-adjacency-changes\n"); + } else if (SAVE_OSPF6_LOG_ADJACENCY_CHANGES) { + vty_out(vty, " no log-adjacency-changes\n"); + } - if (ospf6->ref_bandwidth != OSPF6_REFERENCE_BANDWIDTH) - vty_out(vty, " auto-cost reference-bandwidth %d\n", - ospf6->ref_bandwidth); - - /* LSA timers print. */ - if (ospf6->lsa_minarrival != OSPF_MIN_LS_ARRIVAL) - vty_out(vty, " timers lsa min-arrival %d\n", - ospf6->lsa_minarrival); - - ospf6_stub_router_config_write(vty); - ospf6_redistribute_config_write(vty); - ospf6_area_config_write(vty); - ospf6_spf_config_write(vty); - ospf6_distance_config_write(vty); - - for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, j, oa)) { - for (ALL_LIST_ELEMENTS_RO(oa->if_list, k, oi)) - vty_out(vty, " interface %s area %s\n", - oi->interface->name, oa->name); + if (ospf6->ref_bandwidth != OSPF6_REFERENCE_BANDWIDTH) + vty_out(vty, " auto-cost reference-bandwidth %d\n", + ospf6->ref_bandwidth); + + /* LSA timers print. */ + if (ospf6->lsa_minarrival != OSPF_MIN_LS_ARRIVAL) + vty_out(vty, " timers lsa min-arrival %d\n", + ospf6->lsa_minarrival); + + ospf6_stub_router_config_write(vty, ospf6); + ospf6_redistribute_config_write(vty, ospf6); + ospf6_area_config_write(vty, ospf6); + ospf6_spf_config_write(vty, ospf6); + ospf6_distance_config_write(vty, ospf6); + + for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, j, oa)) { + for (ALL_LIST_ELEMENTS_RO(oa->if_list, k, oi)) + vty_out(vty, " interface %s area %s\n", + oi->interface->name, oa->name); + } + vty_out(vty, "!\n"); } - vty_out(vty, "!\n"); return 0; } |
