diff options
Diffstat (limited to 'ospf6d/ospf6_area.c')
| -rw-r--r-- | ospf6d/ospf6_area.c | 230 |
1 files changed, 177 insertions, 53 deletions
diff --git a/ospf6d/ospf6_area.c b/ospf6d/ospf6_area.c index 355b8441bd..996892c49c 100644 --- a/ospf6d/ospf6_area.c +++ b/ospf6d/ospf6_area.c @@ -43,9 +43,13 @@ #include "ospf6_intra.h" #include "ospf6_abr.h" #include "ospf6_asbr.h" +#include "ospf6_zebra.h" #include "ospf6d.h" #include "lib/json.h" #include "ospf6_nssa.h" +#ifndef VTYSH_EXTRACT_PL +#include "ospf6d/ospf6_area_clippy.c" +#endif DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_AREA, "OSPF6 area"); DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_PLISTNAME, "Prefix list name"); @@ -189,6 +193,9 @@ static void ospf6_area_stub_update(struct ospf6_area *area) static int ospf6_area_stub_set(struct ospf6 *ospf6, struct ospf6_area *area) { if (!IS_AREA_STUB(area)) { + /* Disable NSSA first. */ + ospf6_area_nssa_unset(ospf6, area); + SET_FLAG(area->flag, OSPF6_AREA_STUB); ospf6_area_stub_update(area); } @@ -196,7 +203,7 @@ static int ospf6_area_stub_set(struct ospf6 *ospf6, struct ospf6_area *area) return 1; } -static void ospf6_area_stub_unset(struct ospf6 *ospf6, struct ospf6_area *area) +void ospf6_area_stub_unset(struct ospf6 *ospf6, struct ospf6_area *area) { if (IS_AREA_STUB(area)) { UNSET_FLAG(area->flag, OSPF6_AREA_STUB); @@ -228,6 +235,36 @@ static void ospf6_area_no_summary_unset(struct ospf6 *ospf6, } } +static void ospf6_nssa_default_originate_set(struct ospf6 *ospf6, + struct ospf6_area *area, + int metric, int metric_type) +{ + if (!area->nssa_default_originate.enabled) { + area->nssa_default_originate.enabled = true; + if (++ospf6->nssa_default_import_check.refcnt == 1) { + ospf6->nssa_default_import_check.status = false; + ospf6_zebra_import_default_route(ospf6, false); + } + } + + area->nssa_default_originate.metric_value = metric; + area->nssa_default_originate.metric_type = metric_type; +} + +static void ospf6_nssa_default_originate_unset(struct ospf6 *ospf6, + struct ospf6_area *area) +{ + if (area->nssa_default_originate.enabled) { + area->nssa_default_originate.enabled = false; + if (--ospf6->nssa_default_import_check.refcnt == 0) { + ospf6->nssa_default_import_check.status = false; + ospf6_zebra_import_default_route(ospf6, true); + } + area->nssa_default_originate.metric_value = -1; + area->nssa_default_originate.metric_type = -1; + } +} + /** * Make new area structure. * @@ -269,7 +306,8 @@ struct ospf6_area *ospf6_area_create(uint32_t area_id, struct ospf6 *o, int df) oa->range_table = OSPF6_ROUTE_TABLE_CREATE(AREA, PREFIX_RANGES); oa->range_table->scope = oa; - bf_init(oa->range_table->idspace, 32); + oa->nssa_range_table = OSPF6_ROUTE_TABLE_CREATE(AREA, PREFIX_RANGES); + oa->nssa_range_table->scope = oa; oa->summary_prefix = OSPF6_ROUTE_TABLE_CREATE(AREA, SUMMARY_PREFIXES); oa->summary_prefix->scope = oa; oa->summary_router = OSPF6_ROUTE_TABLE_CREATE(AREA, SUMMARY_ROUTERS); @@ -324,6 +362,7 @@ void ospf6_area_delete(struct ospf6_area *oa) ospf6_route_table_delete(oa->route_table); ospf6_route_table_delete(oa->range_table); + ospf6_route_table_delete(oa->nssa_range_table); ospf6_route_table_delete(oa->summary_prefix); ospf6_route_table_delete(oa->summary_router); @@ -504,7 +543,7 @@ DEFUN (area_range, struct ospf6_area *oa; struct prefix prefix; struct ospf6_route *range; - uint32_t cost = OSPF_AREA_RANGE_COST_UNSPEC; + uint32_t cost; VTY_DECLVAR_CONTEXT(ospf6, ospf6); @@ -519,29 +558,26 @@ DEFUN (area_range, range = ospf6_route_lookup(&prefix, oa->range_table); if (range == NULL) { - range = ospf6_route_create(); + range = ospf6_route_create(ospf6); range->type = OSPF6_DEST_TYPE_RANGE; range->prefix = prefix; range->path.area_id = oa->area_id; range->path.cost = OSPF_AREA_RANGE_COST_UNSPEC; } + /* default settings */ + cost = OSPF_AREA_RANGE_COST_UNSPEC; + UNSET_FLAG(range->flag, OSPF6_ROUTE_DO_NOT_ADVERTISE); + if (argc > idx_type) { - if (strmatch(argv[idx_type]->text, "not-advertise")) { + if (strmatch(argv[idx_type]->text, "not-advertise")) SET_FLAG(range->flag, OSPF6_ROUTE_DO_NOT_ADVERTISE); - } else if (strmatch(argv[idx_type]->text, "advertise")) { - UNSET_FLAG(range->flag, OSPF6_ROUTE_DO_NOT_ADVERTISE); - cost = range->path.u.cost_config; - } else { + else if (strmatch(argv[idx_type]->text, "cost")) cost = strtoul(argv[5]->arg, NULL, 10); - UNSET_FLAG(range->flag, OSPF6_ROUTE_DO_NOT_ADVERTISE); - } } range->path.u.cost_config = cost; - zlog_debug("%s: for prefix %s, flag = %x", __func__, - argv[idx_ipv6_prefixlen]->arg, range->flag); if (range->rnode == NULL) { ospf6_route_add(range, oa->range_table); } @@ -641,8 +677,39 @@ void ospf6_area_config_write(struct vty *vty, struct ospf6 *ospf6) else vty_out(vty, " area %s stub\n", oa->name); } - if (IS_AREA_NSSA(oa)) - vty_out(vty, " area %s nssa\n", oa->name); + if (IS_AREA_NSSA(oa)) { + vty_out(vty, " area %s nssa", oa->name); + if (oa->nssa_default_originate.enabled) { + vty_out(vty, " default-information-originate"); + if (oa->nssa_default_originate.metric_value + != -1) + vty_out(vty, " metric %d", + oa->nssa_default_originate + .metric_value); + if (oa->nssa_default_originate.metric_type + != DEFAULT_METRIC_TYPE) + vty_out(vty, " metric-type 1"); + } + if (oa->no_summary) + vty_out(vty, " no-summary"); + vty_out(vty, "\n"); + } + for (range = ospf6_route_head(oa->nssa_range_table); range; + range = ospf6_route_next(range)) { + vty_out(vty, " area %s nssa range %pFX", oa->name, + &range->prefix); + + if (CHECK_FLAG(range->flag, + OSPF6_ROUTE_DO_NOT_ADVERTISE)) { + vty_out(vty, " not-advertise"); + } else { + if (range->path.u.cost_config + != OSPF_AREA_RANGE_COST_UNSPEC) + vty_out(vty, " cost %u", + range->path.u.cost_config); + } + vty_out(vty, "\n"); + } if (PREFIX_NAME_IN(oa)) vty_out(vty, " area %s filter-list prefix %s in\n", oa->name, PREFIX_NAME_IN(oa)); @@ -687,17 +754,17 @@ DEFUN (area_filter_list, XFREE(MTYPE_OSPF6_PLISTNAME, PREFIX_NAME_IN(area)); PREFIX_NAME_IN(area) = XSTRDUP(MTYPE_OSPF6_PLISTNAME, plistname); - ospf6_abr_reimport(area); } else { PREFIX_LIST_OUT(area) = plist; XFREE(MTYPE_OSPF6_PLISTNAME, PREFIX_NAME_OUT(area)); PREFIX_NAME_OUT(area) = XSTRDUP(MTYPE_OSPF6_PLISTNAME, plistname); - - /* Redo summaries if required */ - ospf6_abr_reexport(area); } + /* Redo summaries if required */ + if (ospf6_check_and_set_router_abr(area->ospf6)) + ospf6_schedule_abr_task(ospf6); + return CMD_SUCCESS; } @@ -730,7 +797,6 @@ DEFUN (no_area_filter_list, PREFIX_LIST_IN(area) = NULL; XFREE(MTYPE_OSPF6_PLISTNAME, PREFIX_NAME_IN(area)); - ospf6_abr_reimport(area); } else { if (PREFIX_NAME_OUT(area)) if (!strmatch(PREFIX_NAME_OUT(area), plistname)) @@ -738,9 +804,12 @@ DEFUN (no_area_filter_list, XFREE(MTYPE_OSPF6_PLISTNAME, PREFIX_NAME_OUT(area)); PREFIX_LIST_OUT(area) = NULL; - ospf6_abr_reexport(area); } + /* Redo summaries if required */ + if (ospf6_check_and_set_router_abr(area->ospf6)) + ospf6_schedule_abr_task(ospf6); + return CMD_SUCCESS; } @@ -751,19 +820,30 @@ void ospf6_filter_update(struct access_list *access) struct ospf6 *ospf6; for (ALL_LIST_ELEMENTS(om6->ospf6, node, nnode, ospf6)) { + bool update = false; + for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, n, oa)) { if (IMPORT_NAME(oa) - && strcmp(IMPORT_NAME(oa), access->name) == 0) - ospf6_abr_reimport(oa); + && strcmp(IMPORT_NAME(oa), access->name) == 0) { + IMPORT_LIST(oa) = access_list_lookup( + AFI_IP6, IMPORT_NAME(oa)); + update = true; + } if (EXPORT_NAME(oa) - && strcmp(EXPORT_NAME(oa), access->name) == 0) - ospf6_abr_reexport(oa); + && strcmp(EXPORT_NAME(oa), access->name) == 0) { + EXPORT_LIST(oa) = access_list_lookup( + AFI_IP6, EXPORT_NAME(oa)); + update = true; + } } + + if (update && ospf6_check_and_set_router_abr(ospf6)) + ospf6_schedule_abr_task(ospf6); } } -void ospf6_area_plist_update(struct prefix_list *plist, int add) +void ospf6_plist_update(struct prefix_list *plist) { struct listnode *node, *nnode; struct ospf6_area *oa; @@ -771,23 +851,29 @@ void ospf6_area_plist_update(struct prefix_list *plist, int add) const char *name = prefix_list_name(plist); struct ospf6 *ospf6 = NULL; - - if (!om6->ospf6) + if (prefix_list_afi(plist) != AFI_IP6) return; for (ALL_LIST_ELEMENTS(om6->ospf6, node, nnode, ospf6)) { + bool update = false; + for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, n, oa)) { if (PREFIX_NAME_IN(oa) && !strcmp(PREFIX_NAME_IN(oa), name)) { - PREFIX_LIST_IN(oa) = add ? plist : NULL; - ospf6_abr_reexport(oa); + PREFIX_LIST_IN(oa) = prefix_list_lookup( + AFI_IP6, PREFIX_NAME_IN(oa)); + update = true; } if (PREFIX_NAME_OUT(oa) && !strcmp(PREFIX_NAME_OUT(oa), name)) { - PREFIX_LIST_OUT(oa) = add ? plist : NULL; - ospf6_abr_reexport(oa); + PREFIX_LIST_OUT(oa) = prefix_list_lookup( + AFI_IP6, PREFIX_NAME_OUT(oa)); + update = true; } } + + if (update && ospf6_check_and_set_router_abr(ospf6)) + ospf6_schedule_abr_task(ospf6); } } @@ -817,7 +903,8 @@ DEFUN (area_import_list, free(IMPORT_NAME(area)); IMPORT_NAME(area) = strdup(argv[idx_name]->arg); - ospf6_abr_reimport(area); + if (ospf6_check_and_set_router_abr(area->ospf6)) + ospf6_schedule_abr_task(ospf6); return CMD_SUCCESS; } @@ -839,13 +926,14 @@ DEFUN (no_area_import_list, OSPF6_CMD_AREA_GET(argv[idx_ipv4]->arg, area, ospf6); - IMPORT_LIST(area) = 0; + IMPORT_LIST(area) = NULL; if (IMPORT_NAME(area)) free(IMPORT_NAME(area)); IMPORT_NAME(area) = NULL; - ospf6_abr_reimport(area); + if (ospf6_check_and_set_router_abr(area->ospf6)) + ospf6_schedule_abr_task(ospf6); return CMD_SUCCESS; } @@ -878,7 +966,8 @@ DEFUN (area_export_list, EXPORT_NAME(area) = strdup(argv[idx_name]->arg); /* Redo summaries if required */ - ospf6_abr_reexport(area); + if (ospf6_check_and_set_router_abr(area->ospf6)) + ospf6_schedule_abr_task(ospf6); return CMD_SUCCESS; } @@ -900,13 +989,14 @@ DEFUN (no_area_export_list, OSPF6_CMD_AREA_GET(argv[idx_ipv4]->arg, area, ospf6); - EXPORT_LIST(area) = 0; + EXPORT_LIST(area) = NULL; if (EXPORT_NAME(area)) free(EXPORT_NAME(area)); EXPORT_NAME(area) = NULL; - ospf6_abr_reexport(area); + if (ospf6_check_and_set_router_abr(area->ospf6)) + ospf6_schedule_abr_task(ospf6); return CMD_SUCCESS; } @@ -979,7 +1069,6 @@ DEFUN(show_ipv6_ospf6_spf_tree, show_ipv6_ospf6_spf_tree_cmd, int idx_vrf = 0; bool uj = use_json(argc, argv); - OSPF6_CMD_CHECK_RUNNING(); OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf); for (ALL_LIST_ELEMENTS_RO(om6->ospf6, node, ospf6)) { @@ -1039,7 +1128,6 @@ DEFUN(show_ipv6_ospf6_area_spf_tree, show_ipv6_ospf6_area_spf_tree_cmd, bool all_vrf = false; int idx_vrf = 0; - OSPF6_CMD_CHECK_RUNNING(); OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf); if (idx_vrf > 0) idx_ipv4 += 2; @@ -1123,7 +1211,6 @@ DEFUN(show_ipv6_ospf6_simulate_spf_tree_root, bool all_vrf = false; int idx_vrf = 0; - OSPF6_CMD_CHECK_RUNNING(); OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf); if (idx_vrf > 0) { idx_ipv4 += 2; @@ -1248,18 +1335,27 @@ DEFUN (no_ospf6_area_stub_no_summary, return CMD_SUCCESS; } -DEFUN(ospf6_area_nssa, ospf6_area_nssa_cmd, - "area <A.B.C.D|(0-4294967295)> nssa", +DEFPY(ospf6_area_nssa, ospf6_area_nssa_cmd, + "area <A.B.C.D|(0-4294967295)>$area_str nssa\ + [{\ + default-information-originate$dflt_originate [{metric (0-16777214)$mval|metric-type (1-2)$mtype}]\ + |no-summary$no_summary\ + }]", "OSPF6 area parameters\n" "OSPF6 area ID in IP address format\n" "OSPF6 area ID as a decimal value\n" - "Configure OSPF6 area as nssa\n") + "Configure OSPF6 area as nssa\n" + "Originate Type 7 default into NSSA area\n" + "OSPFv3 default metric\n" + "OSPFv3 metric\n" + "OSPFv3 metric type for default routes\n" + "Set OSPFv3 External Type 1/2 metrics\n" + "Do not inject inter-area routes into area\n") { - int idx_ipv4_number = 1; struct ospf6_area *area; VTY_DECLVAR_CONTEXT(ospf6, ospf6); - OSPF6_CMD_AREA_GET(argv[idx_ipv4_number]->arg, area, ospf6); + OSPF6_CMD_AREA_GET(area_str, area, ospf6); if (!ospf6_area_nssa_set(ospf6, area)) { vty_out(vty, @@ -1267,24 +1363,54 @@ DEFUN(ospf6_area_nssa, ospf6_area_nssa_cmd, return CMD_WARNING_CONFIG_FAILED; } + if (dflt_originate) { + if (mval_str == NULL) + mval = -1; + if (mtype_str == NULL) + mtype = DEFAULT_METRIC_TYPE; + ospf6_nssa_default_originate_set(ospf6, area, mval, mtype); + } else + ospf6_nssa_default_originate_unset(ospf6, area); + + if (no_summary) + ospf6_area_no_summary_set(ospf6, area); + else + ospf6_area_no_summary_unset(ospf6, area); + + if (ospf6_check_and_set_router_abr(ospf6)) { + ospf6_abr_defaults_to_stub(ospf6); + ospf6_abr_nssa_type_7_defaults(ospf6); + } + return CMD_SUCCESS; } -DEFUN(no_ospf6_area_nssa, no_ospf6_area_nssa_cmd, - "no area <A.B.C.D|(0-4294967295)> nssa", +DEFPY(no_ospf6_area_nssa, no_ospf6_area_nssa_cmd, + "no area <A.B.C.D|(0-4294967295)>$area_str nssa\ + [{\ + default-information-originate [{metric (0-16777214)|metric-type (1-2)}]\ + |no-summary\ + }]", NO_STR "OSPF6 area parameters\n" "OSPF6 area ID in IP address format\n" "OSPF6 area ID as a decimal value\n" - "Configure OSPF6 area as nssa\n") + "Configure OSPF6 area as nssa\n" + "Originate Type 7 default into NSSA area\n" + "OSPFv3 default metric\n" + "OSPFv3 metric\n" + "OSPFv3 metric type for default routes\n" + "Set OSPFv3 External Type 1/2 metrics\n" + "Do not inject inter-area routes into area\n") { - int idx_ipv4_number = 2; struct ospf6_area *area; VTY_DECLVAR_CONTEXT(ospf6, ospf6); - OSPF6_CMD_AREA_GET(argv[idx_ipv4_number]->arg, area, ospf6); + OSPF6_CMD_AREA_GET(area_str, area, ospf6); ospf6_area_nssa_unset(ospf6, area); + ospf6_area_no_summary_unset(ospf6, area); + ospf6_nssa_default_originate_unset(ospf6, area); return CMD_SUCCESS; } @@ -1323,8 +1449,6 @@ void ospf6_area_interface_delete(struct ospf6_interface *oi) struct listnode *node, *nnode; struct ospf6 *ospf6; - if (!om6->ospf6) - return; for (ALL_LIST_ELEMENTS(om6->ospf6, node, nnode, ospf6)) { for (ALL_LIST_ELEMENTS(ospf6->area_list, node, nnode, oa)) if (listnode_lookup(oa->if_list, oi)) |
