diff options
Diffstat (limited to 'ospf6d/ospf6_area.c')
| -rw-r--r-- | ospf6d/ospf6_area.c | 186 |
1 files changed, 145 insertions, 41 deletions
diff --git a/ospf6d/ospf6_area.c b/ospf6d/ospf6_area.c index 098132b1f6..999266b8d1 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"); @@ -231,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. * @@ -643,8 +677,23 @@ 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"); + } if (PREFIX_NAME_IN(oa)) vty_out(vty, " area %s filter-list prefix %s in\n", oa->name, PREFIX_NAME_IN(oa)); @@ -689,17 +738,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; } @@ -732,7 +781,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)) @@ -740,9 +788,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; } @@ -753,19 +804,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; @@ -773,23 +835,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); } } @@ -819,7 +887,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; } @@ -841,13 +910,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; } @@ -880,7 +950,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; } @@ -902,13 +973,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; } @@ -981,7 +1053,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)) { @@ -1041,7 +1112,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; @@ -1125,7 +1195,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; @@ -1250,18 +1319,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, @@ -1269,26 +1347,54 @@ DEFUN(ospf6_area_nssa, ospf6_area_nssa_cmd, return CMD_WARNING_CONFIG_FAILED; } - ospf6_area_no_summary_unset(ospf6, area); + 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; } @@ -1327,8 +1433,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)) |
