summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/user/ospf6d.rst6
-rw-r--r--ospf6d/ospf6_asbr.c89
-rw-r--r--tests/topotests/ospf6_topo2/test_ospf6_topo2.py54
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