/* Install rule command to the match list. */
extern void route_map_install_match(struct route_map_rule_cmd *cmd);
-/* Install rule command to the set list. */
+/*
+ * Install rule command to the set list.
+ *
+ * When installing a particular item, Allow a difference of handling
+ * of bad cli inputted(return NULL) -vs- this particular daemon cannot use
+ * this form of the command(return a pointer and handle it appropriately
+ * in the apply command). See 'set metric' command
+ * as it is handled in ripd/ripngd and ospfd.
+ */
extern void route_map_install_set(struct route_map_rule_cmd *cmd);
/* Lookup route map by name. */
route_map_rule_tag_free,
};
+struct ospf_metric {
+ bool used;
+ u_int32_t metric;
+};
/* `set metric METRIC' */
/* Set metric to attribute. */
route_map_object_t type,
void *object)
{
- u_int32_t *metric;
+ struct ospf_metric *metric;
struct external_info *ei;
if (type == RMAP_OSPF) {
ei = object;
/* Set metric out value. */
- ei->route_map_set.metric = *metric;
+ if (metric->used)
+ ei->route_map_set.metric = metric->metric;
}
return RMAP_OKAY;
}
/* set metric compilation. */
static void *route_set_metric_compile(const char *arg)
{
- u_int32_t *metric;
+ struct ospf_metric *metric;
+
+ metric = XCALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(u_int32_t));
+ metric->used = false;
/* OSPF doesn't support the +/- in
set metric <+/-metric> check
if (strmatch(arg, "+rtt") || strmatch(arg, "-rtt"))
zlog_warn(
"OSPF does not support 'set metric +rtt / -rtt'");
- return NULL;
+
+ return metric;
}
}
- metric = XCALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(u_int32_t));
- *metric = strtoul(arg, NULL, 10);
+ metric->metric = strtoul(arg, NULL, 10);
+ metric->used = true;
return metric;
}
struct rip_metric_modifier {
enum { metric_increment, metric_decrement, metric_absolute } type;
-
- u_char metric;
+ bool used;
+ u_int8_t metric;
};
/* Hook function for updating route_map assignment. */
mod = rule;
rinfo = object;
+ if (!mod->used)
+ return RMAP_OKAY;
+
if (mod->type == metric_increment)
rinfo->metric_out += mod->metric;
else if (mod->type == metric_decrement)
{
int len;
const char *pnt;
- int type;
long metric;
char *endptr = NULL;
struct rip_metric_modifier *mod;
+ mod = XMALLOC(MTYPE_ROUTE_MAP_COMPILED,
+ sizeof(struct rip_metric_modifier));
+ mod->used = false;
+
len = strlen(arg);
pnt = arg;
if (len == 0)
- return NULL;
+ return mod;
/* Examine first character. */
if (arg[0] == '+') {
- type = metric_increment;
+ mod->type = metric_increment;
pnt++;
} else if (arg[0] == '-') {
- type = metric_decrement;
+ mod->type = metric_decrement;
pnt++;
} else
- type = metric_absolute;
+ mod->type = metric_absolute;
/* Check beginning with digit string. */
if (*pnt < '0' || *pnt > '9')
- return NULL;
+ return mod;
/* Convert string to integer. */
metric = strtol(pnt, &endptr, 10);
- if (metric == LONG_MAX || *endptr != '\0')
- return NULL;
- if (metric < 0 || metric > RIP_METRIC_INFINITY)
- return NULL;
+ if (*endptr != '\0' || mod->metric < 0) {
+ metric = 0;
+ return mod;
+ }
+ if (metric > RIP_METRIC_INFINITY) {
+ zlog_info("%s: Metric specified: %ld is greater than RIP_METRIC_INFINITY, using INFINITY instead",
+ __PRETTY_FUNCTION__, metric);
+ mod->metric = RIP_METRIC_INFINITY;
+ } else
+ mod->metric = metric;
- mod = XMALLOC(MTYPE_ROUTE_MAP_COMPILED,
- sizeof(struct rip_metric_modifier));
- mod->type = type;
- mod->metric = metric;
+ mod->used = true;
return mod;
}
struct rip_metric_modifier {
enum { metric_increment, metric_decrement, metric_absolute } type;
-
- u_char metric;
+ bool used;
+ u_int8_t metric;
};
/* `match metric METRIC' */
mod = rule;
rinfo = object;
+ if (!mod->used)
+ return RMAP_OKAY;
+
if (mod->type == metric_increment)
rinfo->metric_out += mod->metric;
else if (mod->type == metric_decrement)
{
int len;
const char *pnt;
- int type;
long metric;
char *endptr = NULL;
struct rip_metric_modifier *mod;
len = strlen(arg);
pnt = arg;
+ mod = XMALLOC(MTYPE_ROUTE_MAP_COMPILED,
+ sizeof(struct rip_metric_modifier));
+ mod->used = false;
+
if (len == 0)
- return NULL;
+ return mod;
/* Examine first character. */
if (arg[0] == '+') {
- type = metric_increment;
+ mod->type = metric_increment;
pnt++;
} else if (arg[0] == '-') {
- type = metric_decrement;
+ mod->type = metric_decrement;
pnt++;
} else
- type = metric_absolute;
+ mod->type = metric_absolute;
/* Check beginning with digit string. */
if (*pnt < '0' || *pnt > '9')
- return NULL;
+ return mod;
/* Convert string to integer. */
metric = strtol(pnt, &endptr, 10);
- if (metric == LONG_MAX || *endptr != '\0')
- return NULL;
- /* Commented out by Hasso Tepper, to avoid problems in vtysh. */
- /* if (metric < 0 || metric > RIPNG_METRIC_INFINITY) */
- if (metric < 0)
- return NULL;
+ if (*endptr != '\0' || metric < 0)
+ return mod;
- mod = XMALLOC(MTYPE_ROUTE_MAP_COMPILED,
- sizeof(struct rip_metric_modifier));
- mod->type = type;
- mod->metric = metric;
+ if (metric > RIPNG_METRIC_INFINITY) {
+ zlog_info("%s: Metric specified: %ld is being converted into METRIC_INFINITY",
+ __PRETTY_FUNCTION__,
+ metric);
+ mod->metric = RIPNG_METRIC_INFINITY;
+ } else
+ mod->metric = metric;
+ mod->used = true;
return mod;
}