{
rmap_match_set_hook.no_set_metric = func;
}
+/* set min-metric */
+void route_map_set_min_metric_hook(int (*func)(struct route_map_index *index,
+ const char *command,
+ const char *arg, char *errmsg,
+ size_t errmsg_len))
+{
+ rmap_match_set_hook.set_min_metric = func;
+}
+
+/* no set min-metric */
+void route_map_no_set_min_metric_hook(int (*func)(struct route_map_index *index,
+ const char *command,
+ const char *arg, char *errmsg,
+ size_t errmsg_len))
+{
+ rmap_match_set_hook.no_set_min_metric = func;
+}
+/* set max-metric */
+void route_map_set_max_metric_hook(int (*func)(struct route_map_index *index,
+ const char *command,
+ const char *arg, char *errmsg,
+ size_t errmsg_len))
+{
+ rmap_match_set_hook.set_max_metric = func;
+}
+
+/* no set max-metric */
+void route_map_no_set_max_metric_hook(int (*func)(struct route_map_index *index,
+ const char *command,
+ const char *arg, char *errmsg,
+ size_t errmsg_len))
+{
+ rmap_match_set_hook.no_set_max_metric = func;
+}
/* set tag */
void route_map_set_tag_hook(int (*func)(struct route_map_index *index,
(strmatch(A, "frr-route-map:ipv6-next-hop"))
#define IS_SET_METRIC(A) \
(strmatch(A, "frr-route-map:set-metric"))
+#define IS_SET_MIN_METRIC(A) (strmatch(A, "frr-route-map:set-min-metric"))
+#define IS_SET_MAX_METRIC(A) (strmatch(A, "frr-route-map:set-max-metric"))
#define IS_SET_TAG(A) (strmatch(A, "frr-route-map:set-tag"))
#define IS_SET_SR_TE_COLOR(A) \
(strmatch(A, "frr-route-map:set-sr-te-color"))
int (*func)(struct route_map_index *index,
const char *command, const char *arg,
char *errmsg, size_t errmsg_len));
+/* set metric */
+extern void route_map_set_max_metric_hook(
+ int (*func)(struct route_map_index *index, const char *command,
+ const char *arg, char *errmsg, size_t errmsg_len));
+/* no set metric */
+extern void route_map_no_set_max_metric_hook(
+ int (*func)(struct route_map_index *index, const char *command,
+ const char *arg, char *errmsg, size_t errmsg_len));
+/* set metric */
+extern void route_map_set_min_metric_hook(
+ int (*func)(struct route_map_index *index, const char *command,
+ const char *arg, char *errmsg, size_t errmsg_len));
+/* no set metric */
+extern void route_map_no_set_min_metric_hook(
+ int (*func)(struct route_map_index *index, const char *command,
+ const char *arg, char *errmsg, size_t errmsg_len));
/* set tag */
extern void route_map_set_tag_hook(int (*func)(struct route_map_index *index,
const char *command,
int (*no_set_metric)(struct route_map_index *index,
const char *command, const char *arg,
char *errmsg, size_t errmsg_len);
+ /* set min-metric */
+ int (*set_min_metric)(struct route_map_index *index,
+ const char *command, const char *arg,
+ char *errmsg, size_t errmsg_len);
+
+ /* no set min-metric */
+ int (*no_set_min_metric)(struct route_map_index *index,
+ const char *command, const char *arg,
+ char *errmsg, size_t errmsg_len);
+
+ /* set max-metric */
+ int (*set_max_metric)(struct route_map_index *index,
+ const char *command, const char *arg,
+ char *errmsg, size_t errmsg_len);
+
+ /* no set max-metric */
+ int (*no_set_max_metric)(struct route_map_index *index,
+ const char *command, const char *arg,
+ char *errmsg, size_t errmsg_len);
/* set tag */
int (*set_tag)(struct route_map_index *index,
return nb_cli_apply_changes(vty, NULL);
}
+DEFPY_YANG(set_min_metric, set_min_metric_cmd,
+ "set min-metric <(0-4294967295)$metric>",
+ SET_STR
+ "Minimum metric value for destination routing protocol\n"
+ "Minimum metric value\n")
+{
+ const char *xpath =
+ "./set-action[action='frr-route-map:set-min-metric']";
+ char xpath_value[XPATH_MAXLEN];
+ char value[64];
+
+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+
+ snprintf(xpath_value, sizeof(xpath_value),
+ "%s/rmap-set-action/min-metric", xpath);
+ snprintf(value, sizeof(value), "%s", metric_str);
+
+ nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, value);
+
+ return nb_cli_apply_changes(vty, NULL);
+}
+
+DEFPY_YANG(no_set_min_metric, no_set_min_metric_cmd,
+ "no set min-metric [(0-4294967295)]",
+ NO_STR SET_STR
+ "Minimum metric value for destination routing protocol\n"
+ "Minumum metric value\n")
+{
+ const char *xpath =
+ "./set-action[action='frr-route-map:set-min-metric']";
+
+ nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
+ return nb_cli_apply_changes(vty, NULL);
+}
+
+DEFPY_YANG(set_max_metric, set_max_metric_cmd,
+ "set max-metric <(0-4294967295)$metric>",
+ SET_STR
+ "Maximum metric value for destination routing protocol\n"
+ "Miximum metric value\n")
+{
+ const char *xpath =
+ "./set-action[action='frr-route-map:set-max-metric']";
+ char xpath_value[XPATH_MAXLEN];
+ char value[64];
+
+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+
+ snprintf(xpath_value, sizeof(xpath_value),
+ "%s/rmap-set-action/max-metric", xpath);
+ snprintf(value, sizeof(value), "%s", metric_str);
+
+ nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, value);
+
+ return nb_cli_apply_changes(vty, NULL);
+}
+
+DEFPY_YANG(no_set_max_metric, no_set_max_metric_cmd,
+ "no set max-metric [(0-4294967295)]",
+ NO_STR SET_STR
+ "Maximum Metric value for destination routing protocol\n"
+ "Maximum metric value\n")
+{
+ const char *xpath =
+ "./set-action[action='frr-route-map:set-max-metric']";
+
+ nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
+ return nb_cli_apply_changes(vty, NULL);
+}
+
DEFPY_YANG(
set_tag, set_tag_cmd,
"set tag (1-4294967295)$tag",
yang_dnode_get_string(
dnode, "./rmap-set-action/value"));
}
+ } else if (IS_SET_MIN_METRIC(action)) {
+ vty_out(vty, " set min-metric %s\n",
+ yang_dnode_get_string(dnode,
+ "./rmap-set-action/min-metric"));
+ } else if (IS_SET_MAX_METRIC(action)) {
+ vty_out(vty, " set max-metric %s\n",
+ yang_dnode_get_string(dnode,
+ "./rmap-set-action/max-metric"));
} else if (IS_SET_TAG(action)) {
vty_out(vty, " set tag %s\n",
yang_dnode_get_string(dnode, "./rmap-set-action/tag"));
install_element(RMAP_NODE, &set_metric_cmd);
install_element(RMAP_NODE, &no_set_metric_cmd);
+ install_element(RMAP_NODE, &set_min_metric_cmd);
+ install_element(RMAP_NODE, &no_set_min_metric_cmd);
+
+ install_element(RMAP_NODE, &set_max_metric_cmd);
+ install_element(RMAP_NODE, &no_set_max_metric_cmd);
+
install_element(RMAP_NODE, &set_tag_cmd);
install_element(RMAP_NODE, &no_set_tag_cmd);
return lib_route_map_entry_set_destroy(args);
}
+/*
+ * XPath: /frr-route-map:lib/route-map/entry/set-action/min-metric
+ */
+static int set_action_min_metric_modify(enum nb_event event,
+ const struct lyd_node *dnode,
+ union nb_resource *resource,
+ const char *value, char *errmsg,
+ size_t errmsg_len)
+{
+ struct routemap_hook_context *rhc;
+ int rv;
+
+ if (event != NB_EV_APPLY)
+ return NB_OK;
+
+ /* Check for hook function. */
+ if (rmap_match_set_hook.set_min_metric == NULL)
+ return NB_OK;
+
+ /* Add configuration. */
+ rhc = nb_running_get_entry(dnode, NULL, true);
+
+ /* Set destroy information. */
+ rhc->rhc_shook = rmap_match_set_hook.no_set_min_metric;
+ rhc->rhc_rule = "min-metric";
+
+ rv = rmap_match_set_hook.set_min_metric(rhc->rhc_rmi, "min-metric",
+ value, errmsg, errmsg_len);
+ if (rv != CMD_SUCCESS) {
+ rhc->rhc_shook = NULL;
+ return NB_ERR_INCONSISTENCY;
+ }
+
+ return NB_OK;
+}
+
+static int
+lib_route_map_entry_set_action_min_metric_modify(struct nb_cb_modify_args *args)
+{
+ const char *min_metric = yang_dnode_get_string(args->dnode, NULL);
+
+ return set_action_min_metric_modify(args->event, args->dnode,
+ args->resource, min_metric,
+ args->errmsg, args->errmsg_len);
+}
+
+static int lib_route_map_entry_set_action_min_metric_destroy(
+ struct nb_cb_destroy_args *args)
+{
+ return lib_route_map_entry_set_destroy(args);
+}
+
+/*
+ * XPath: /frr-route-map:lib/route-map/entry/set-action/max-metric
+ */
+static int set_action_max_metric_modify(enum nb_event event,
+ const struct lyd_node *dnode,
+ union nb_resource *resource,
+ const char *value, char *errmsg,
+ size_t errmsg_len)
+{
+ struct routemap_hook_context *rhc;
+ int rv;
+
+ if (event != NB_EV_APPLY)
+ return NB_OK;
+
+ /* Check for hook function. */
+ if (rmap_match_set_hook.set_max_metric == NULL)
+ return NB_OK;
+
+ /* Add configuration. */
+ rhc = nb_running_get_entry(dnode, NULL, true);
+
+ /* Set destroy information. */
+ rhc->rhc_shook = rmap_match_set_hook.no_set_max_metric;
+ rhc->rhc_rule = "max-metric";
+
+ rv = rmap_match_set_hook.set_max_metric(rhc->rhc_rmi, "max-metric",
+ value, errmsg, errmsg_len);
+ if (rv != CMD_SUCCESS) {
+ rhc->rhc_shook = NULL;
+ return NB_ERR_INCONSISTENCY;
+ }
+
+ return NB_OK;
+}
+
+static int
+lib_route_map_entry_set_action_max_metric_modify(struct nb_cb_modify_args *args)
+{
+ const char *max_metric = yang_dnode_get_string(args->dnode, NULL);
+
+ return set_action_max_metric_modify(args->event, args->dnode,
+ args->resource, max_metric,
+ args->errmsg, args->errmsg_len);
+}
+
+static int lib_route_map_entry_set_action_max_metric_destroy(
+ struct nb_cb_destroy_args *args)
+{
+ return lib_route_map_entry_set_destroy(args);
+}
+
/*
* XPath: /frr-route-map:lib/route-map/entry/set-action/add-metric
*/
.destroy = lib_route_map_entry_set_action_value_destroy,
}
},
+ {
+ .xpath = "/frr-route-map:lib/route-map/entry/set-action/rmap-set-action/min-metric",
+ .cbs = {
+ .modify = lib_route_map_entry_set_action_min_metric_modify,
+ .destroy = lib_route_map_entry_set_action_min_metric_destroy,
+ }
+ },
+ {
+ .xpath = "/frr-route-map:lib/route-map/entry/set-action/rmap-set-action/max-metric",
+ .cbs = {
+ .modify = lib_route_map_entry_set_action_max_metric_modify,
+ .destroy = lib_route_map_entry_set_action_max_metric_destroy,
+ }
+ },
{
.xpath = "/frr-route-map:lib/route-map/entry/set-action/rmap-set-action/add-metric",
.cbs = {
new->orig_tag = tag;
new->aggr_route = NULL;
new->metric = metric;
+ new->min_metric = 0;
+ new->max_metric = OSPF_LS_INFINITY;
/* we don't unlock rn from the get() because we're attaching the info */
if (rn)
route_tag_t orig_tag;
uint32_t metric;
+ uint32_t min_metric;
+ uint32_t max_metric;
struct route_map_set_values route_map_set;
#define ROUTEMAP_METRIC(E) (E)->route_map_set.metric
if (!metric->used)
return RMAP_OKAY;
- ei->route_map_set.metric = ei->metric;
+ ROUTEMAP_METRIC(ei) = ei->metric;
if (metric->type == metric_increment)
- ei->route_map_set.metric += metric->metric;
+ ROUTEMAP_METRIC(ei) += metric->metric;
else if (metric->type == metric_decrement)
- ei->route_map_set.metric -= metric->metric;
+ ROUTEMAP_METRIC(ei) -= metric->metric;
else if (metric->type == metric_absolute)
- ei->route_map_set.metric = metric->metric;
+ ROUTEMAP_METRIC(ei) = metric->metric;
- if (ei->route_map_set.metric > OSPF_LS_INFINITY)
- ei->route_map_set.metric = OSPF_LS_INFINITY;
+ if ((uint32_t)ROUTEMAP_METRIC(ei) < ei->min_metric)
+ ROUTEMAP_METRIC(ei) = ei->min_metric;
+ if ((uint32_t)ROUTEMAP_METRIC(ei) > ei->max_metric)
+ ROUTEMAP_METRIC(ei) = ei->max_metric;
return RMAP_OKAY;
}
route_set_metric_free,
};
+/* `set min-metric METRIC' */
+/* Set min-metric to attribute. */
+static enum route_map_cmd_result_t
+route_set_min_metric(void *rule, const struct prefix *prefix, void *object)
+{
+ uint32_t *min_metric;
+ struct external_info *ei;
+
+ /* Fetch routemap's rule information. */
+ min_metric = rule;
+ ei = object;
+
+ ei->min_metric = *min_metric;
+
+ if (ei->min_metric > OSPF_LS_INFINITY)
+ ei->min_metric = OSPF_LS_INFINITY;
+
+ if ((uint32_t)ROUTEMAP_METRIC(ei) < ei->min_metric)
+ ROUTEMAP_METRIC(ei) = ei->min_metric;
+
+ return RMAP_OKAY;
+}
+
+/* set min-metric compilation. */
+static void *route_set_min_metric_compile(const char *arg)
+{
+
+ uint32_t *min_metric;
+
+ min_metric = XCALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(uint32_t));
+
+ *min_metric = strtoul(arg, NULL, 10);
+
+ if (*min_metric)
+ return min_metric;
+
+ XFREE(MTYPE_ROUTE_MAP_COMPILED, min_metric);
+ return NULL;
+}
+
+/* Free route map's compiled `set min-metric' value. */
+static void route_set_min_metric_free(void *rule)
+{
+ XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
+}
+
+/* Set metric rule structure. */
+static const struct route_map_rule_cmd route_set_min_metric_cmd = {
+ "min-metric",
+ route_set_min_metric,
+ route_set_min_metric_compile,
+ route_set_min_metric_free,
+};
+
+
+/* `set max-metric METRIC' */
+/* Set max-metric to attribute. */
+static enum route_map_cmd_result_t
+route_set_max_metric(void *rule, const struct prefix *prefix, void *object)
+{
+ uint32_t *max_metric;
+ struct external_info *ei;
+
+ /* Fetch routemap's rule information. */
+ max_metric = rule;
+ ei = object;
+
+ ei->max_metric = *max_metric;
+
+ if (ei->max_metric > OSPF_LS_INFINITY)
+ ei->max_metric = OSPF_LS_INFINITY;
+
+ if ((uint32_t)ROUTEMAP_METRIC(ei) > ei->max_metric)
+ ROUTEMAP_METRIC(ei) = ei->max_metric;
+
+ return RMAP_OKAY;
+}
+
+/* set max-metric compilation. */
+static void *route_set_max_metric_compile(const char *arg)
+{
+
+ uint32_t *max_metric;
+
+ max_metric = XCALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(uint32_t));
+
+ *max_metric = strtoul(arg, NULL, 10);
+
+ if (*max_metric)
+ return max_metric;
+
+ XFREE(MTYPE_ROUTE_MAP_COMPILED, max_metric);
+ return NULL;
+}
+
+/* Free route map's compiled `set max-metric' value. */
+static void route_set_max_metric_free(void *rule)
+{
+ XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
+}
+
+/* Set metric rule structure. */
+static const struct route_map_rule_cmd route_set_max_metric_cmd = {
+ "max-metric",
+ route_set_max_metric,
+ route_set_max_metric_compile,
+ route_set_max_metric_free,
+};
+
/* `set metric-type TYPE' */
/* Set metric-type to attribute. */
static enum route_map_cmd_result_t
ei = object;
/* Set metric out value. */
- ei->route_map_set.metric_type = *metric_type;
+ ROUTEMAP_METRIC_TYPE(ei) = *metric_type;
return RMAP_OKAY;
}
route_map_delete_hook(ospf_route_map_update);
route_map_event_hook(ospf_route_map_event);
- route_map_set_metric_hook(generic_set_add);
- route_map_no_set_metric_hook(generic_set_delete);
-
route_map_match_ip_next_hop_hook(generic_match_add);
route_map_no_match_ip_next_hop_hook(generic_match_delete);
route_map_set_metric_hook(generic_set_add);
route_map_no_set_metric_hook(generic_set_delete);
+ route_map_set_min_metric_hook(generic_set_add);
+ route_map_no_set_min_metric_hook(generic_set_delete);
+
+ route_map_set_max_metric_hook(generic_set_add);
+ route_map_no_set_max_metric_hook(generic_set_delete);
+
route_map_set_tag_hook(generic_set_add);
route_map_no_set_tag_hook(generic_set_delete);
route_map_install_match(&route_match_tag_cmd);
route_map_install_set(&route_set_metric_cmd);
+ route_map_install_set(&route_set_min_metric_cmd);
+ route_map_install_set(&route_set_max_metric_cmd);
route_map_install_set(&route_set_metric_type_cmd);
route_map_install_set(&route_set_tag_cmd);
"Set prefix/route metric";
}
+ identity set-min-metric {
+ base rmap-set-type;
+ description
+ "Set minimum prefix/route metric";
+ }
+
+ identity set-max-metric {
+ base rmap-set-type;
+ description
+ "Set maximum prefix/route metric";
+ }
+
identity set-tag {
base rmap-set-type;
description
}
}
+ case set-min-metric {
+ when "derived-from-or-self(../action, 'set-min-metric')";
+ choice minimun-metric-value {
+ description
+ "Mimimum metric to set or use";
+ case min-metric {
+ leaf min-metric {
+ type uint32 {
+ range "0..4294967295";
+ }
+ description
+ "Use the following mimumn metric value";
+ }
+ }
+ }
+ }
+
+ case set-max-metric {
+ when "derived-from-or-self(../action, 'set-max-metric')";
+ choice maximum-metric-value {
+ description
+ "Maximum metric to set or use";
+ case max-metric {
+ leaf max-metric {
+ type uint32 {
+ range "0..4294967295";
+ }
+ description
+ "Use the following maximum metric value";
+ }
+ }
+ }
+ }
case set-tag {
when "derived-from-or-self(../action, 'set-tag')";
leaf tag {