diff options
-rw-r--r-- | doc/user/ospf6d.rst | 6 | ||||
-rw-r--r-- | ospf6d/ospf6_asbr.c | 89 | ||||
-rw-r--r-- | tests/topotests/ospf6_topo2/test_ospf6_topo2.py | 54 |
3 files changed, 95 insertions, 54 deletions
diff --git a/doc/user/ospf6d.rst b/doc/user/ospf6d.rst index dd4e7d6dc..499788ae8 100644 --- a/doc/user/ospf6d.rst +++ b/doc/user/ospf6d.rst @@ -248,9 +248,11 @@ Usage of *ospfd6*'s route-map support. Redistribute routes to OSPF6 ============================ -.. clicmd:: redistribute <babel|bgp|connected|isis|kernel|openfabric|ripng|sharp|static|table> [route-map WORD] +.. clicmd:: redistribute <babel|bgp|connected|isis|kernel|openfabric|ripng|sharp|static|table> [metric-type (1-2)] [metric (0-16777214)] [route-map WORD] - Redistribute routes from other protocols into OSPFv3. + Redistribute routes of the specified protocol or kind into OSPFv3, with the + metric type and metric set if specified, filtering the routes using the + given route-map if specified. .. clicmd:: default-information originate [{always|metric (0-16777214)|metric-type (1-2)|route-map WORD}] diff --git a/ospf6d/ospf6_asbr.c b/ospf6d/ospf6_asbr.c index acecf9002..f16a1975a 100644 --- a/ospf6d/ospf6_asbr.c +++ b/ospf6d/ospf6_asbr.c @@ -1641,72 +1641,55 @@ void ospf6_asbr_redistribute_remove(int type, ifindex_t ifindex, ospf6_asbr_status_update(ospf6, ospf6->redistribute); } -DEFUN (ospf6_redistribute, +DEFPY (ospf6_redistribute, ospf6_redistribute_cmd, - "redistribute " FRR_REDIST_STR_OSPF6D, - "Redistribute\n" - FRR_REDIST_HELP_STR_OSPF6D) -{ - int type; - struct ospf6_redist *red; - - VTY_DECLVAR_CONTEXT(ospf6, ospf6); - - char *proto = argv[argc - 1]->text; - - type = proto_redistnum(AFI_IP6, proto); - if (type < 0) - return CMD_WARNING_CONFIG_FAILED; - - red = ospf6_redist_lookup(ospf6, type, 0); - if (!red) { - ospf6_redist_add(ospf6, type, 0); - } else { - /* To check, if user is providing same config */ - if (ROUTEMAP_NAME(red) == NULL) - return CMD_SUCCESS; - - ospf6_asbr_redistribute_unset(ospf6, red, type); - } - - ospf6_asbr_redistribute_set(ospf6, type); - - return CMD_SUCCESS; -} - -DEFUN (ospf6_redistribute_routemap, - ospf6_redistribute_routemap_cmd, - "redistribute " FRR_REDIST_STR_OSPF6D " route-map WORD", + "redistribute " FRR_REDIST_STR_OSPF6D "[{metric (0-16777214)|metric-type (1-2)$metric_type|route-map WORD$rmap_str}]", "Redistribute\n" FRR_REDIST_HELP_STR_OSPF6D + "Metric for redistributed routes\n" + "OSPF default metric\n" + "OSPF exterior metric type for redistributed routes\n" + "Set OSPF External Type 1/2 metrics\n" "Route map reference\n" "Route map name\n") { - int idx_protocol = 1; - int idx_word = 3; int type; struct ospf6_redist *red; + int idx_protocol = 1; + char *proto = argv[idx_protocol]->text; VTY_DECLVAR_CONTEXT(ospf6, ospf6); - char *proto = argv[idx_protocol]->text; type = proto_redistnum(AFI_IP6, proto); if (type < 0) return CMD_WARNING_CONFIG_FAILED; + if (!metric_str) + metric = -1; + if (!metric_type_str) + metric_type = -1; + red = ospf6_redist_lookup(ospf6, type, 0); if (!red) { red = ospf6_redist_add(ospf6, type, 0); } else { - /* To check, if user is providing same route map */ - if ((ROUTEMAP_NAME(red) != NULL) - && (strcmp(argv[idx_word]->arg, ROUTEMAP_NAME(red)) == 0)) + /* Check if nothing has changed. */ + if (red->dmetric.value == metric + && red->dmetric.type == metric_type + && ((!ROUTEMAP_NAME(red) && !rmap_str) + || (ROUTEMAP_NAME(red) && rmap_str + && strmatch(ROUTEMAP_NAME(red), rmap_str)))) return CMD_SUCCESS; ospf6_asbr_redistribute_unset(ospf6, red, type); } - ospf6_asbr_routemap_set(red, argv[idx_word]->arg); + red->dmetric.value = metric; + red->dmetric.type = metric_type; + if (rmap_str) + ospf6_asbr_routemap_set(red, rmap_str); + else + ospf6_asbr_routemap_unset(red); ospf6_asbr_redistribute_set(ospf6, type); return CMD_SUCCESS; @@ -1714,20 +1697,24 @@ DEFUN (ospf6_redistribute_routemap, DEFUN (no_ospf6_redistribute, no_ospf6_redistribute_cmd, - "no redistribute " FRR_REDIST_STR_OSPF6D " [route-map WORD]", + "no redistribute " FRR_REDIST_STR_OSPF6D "[{metric (0-16777214)|metric-type (1-2)|route-map WORD}]", NO_STR "Redistribute\n" FRR_REDIST_HELP_STR_OSPF6D + "Metric for redistributed routes\n" + "OSPF default metric\n" + "OSPF exterior metric type for redistributed routes\n" + "Set OSPF External Type 1/2 metrics\n" "Route map reference\n" "Route map name\n") { - int idx_protocol = 2; int type; struct ospf6_redist *red; + int idx_protocol = 2; + char *proto = argv[idx_protocol]->text; VTY_DECLVAR_CONTEXT(ospf6, ospf6); - char *proto = argv[idx_protocol]->text; type = proto_redistnum(AFI_IP6, proto); if (type < 0) return CMD_WARNING_CONFIG_FAILED; @@ -1754,11 +1741,14 @@ int ospf6_redistribute_config_write(struct vty *vty, struct ospf6 *ospf6) if (type == ZEBRA_ROUTE_OSPF6) continue; + vty_out(vty, " redistribute %s", ZROUTE_NAME(type)); + if (red->dmetric.value >= 0) + vty_out(vty, " metric %d", red->dmetric.value); + if (red->dmetric.type != DEFAULT_METRIC_TYPE) + vty_out(vty, " metric-type 1"); if (ROUTEMAP_NAME(red)) - vty_out(vty, " redistribute %s route-map %s\n", - ZROUTE_NAME(type), ROUTEMAP_NAME(red)); - else - vty_out(vty, " redistribute %s\n", ZROUTE_NAME(type)); + vty_out(vty, " route-map %s", ROUTEMAP_NAME(red)); + vty_out(vty, "\n"); } return 0; @@ -2566,7 +2556,6 @@ void ospf6_asbr_init(void) install_element(OSPF6_NODE, &no_ospf6_default_information_originate_cmd); install_element(OSPF6_NODE, &ospf6_redistribute_cmd); - install_element(OSPF6_NODE, &ospf6_redistribute_routemap_cmd); install_element(OSPF6_NODE, &no_ospf6_redistribute_cmd); } diff --git a/tests/topotests/ospf6_topo2/test_ospf6_topo2.py b/tests/topotests/ospf6_topo2/test_ospf6_topo2.py index b6c8cf3e7..8c5f1e6f6 100644 --- a/tests/topotests/ospf6_topo2/test_ospf6_topo2.py +++ b/tests/topotests/ospf6_topo2/test_ospf6_topo2.py @@ -73,15 +73,20 @@ def expect_lsas(router, area, lsas, wait=5, extra_params=""): assert result is None, assertmsg -def expect_ospfv3_routes(router, routes, wait=5): +def expect_ospfv3_routes(router, routes, wait=5, detail=False): "Run command `ipv6 ospf6 route` and expect route with type." tgen = get_topogen() + if detail == False: + cmd = "show ipv6 ospf6 route json" + else: + cmd = "show ipv6 ospf6 route detail json" + logger.info("waiting OSPFv3 router '{}' route".format(router)) test_func = partial( topotest.router_json_cmp, tgen.gears[router], - "show ipv6 ospf6 route json", + cmd, {"routes": routes} ) _, result = topotest.run_and_expect(test_func, None, count=wait, wait=1) @@ -236,6 +241,51 @@ def test_ospf6_default_route(): expect_route("r1", "::/0", metric + 10) +def test_redistribute_metrics(): + """ + Test that the configured metrics are honored when a static route is + redistributed. + """ + tgen = get_topogen() + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + # Add new static route on r3. + config = """ + configure terminal + ipv6 route 2001:db8:500::/64 Null0 + """ + tgen.gears["r3"].vtysh_cmd(config) + + route = { + "2001:db8:500::/64": { + "metricType":2, + "metricCost":10, + } + } + logger.info("Expecting AS-external route 2001:db8:500::/64 to show up with default metrics") + expect_ospfv3_routes("r2", route, wait=30, detail=True) + + # Change the metric of redistributed routes of the static type on r3. + config = """ + configure terminal + router ospf6 + redistribute static metric 50 metric-type 1 + """ + tgen.gears["r3"].vtysh_cmd(config) + + # Check if r3 reinstalled 2001:db8:500::/64 using the new metric type and value. + route = { + "2001:db8:500::/64": { + "metricType":1, + "metricCost":60, + } + } + logger.info("Expecting AS-external route 2001:db8:500::/64 to show up with updated metric type and value") + expect_ospfv3_routes("r2", route, wait=30, detail=True) + + + def test_nssa_lsa_type7(): """ Test that static route gets announced as external route when redistributed |