mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-03 05:21:31 +00:00
Merge pull request #1075 from donaldsharp/rip_metric
lib, ospfd, ripd, ripngd: Fix 'set metric'
This commit is contained in:
commit
c6fe740998
@ -194,7 +194,15 @@ extern int route_map_delete_set(struct route_map_index *index,
|
||||
/* 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. */
|
||||
|
@ -336,6 +336,10 @@ static struct route_map_rule_cmd route_match_tag_cmd = {
|
||||
route_map_rule_tag_free,
|
||||
};
|
||||
|
||||
struct ospf_metric {
|
||||
bool used;
|
||||
u_int32_t metric;
|
||||
};
|
||||
|
||||
/* `set metric METRIC' */
|
||||
/* Set metric to attribute. */
|
||||
@ -343,7 +347,7 @@ static route_map_result_t route_set_metric(void *rule, struct prefix *prefix,
|
||||
route_map_object_t type,
|
||||
void *object)
|
||||
{
|
||||
u_int32_t *metric;
|
||||
struct ospf_metric *metric;
|
||||
struct external_info *ei;
|
||||
|
||||
if (type == RMAP_OSPF) {
|
||||
@ -352,7 +356,8 @@ static route_map_result_t route_set_metric(void *rule, struct prefix *prefix,
|
||||
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;
|
||||
}
|
||||
@ -360,7 +365,10 @@ static route_map_result_t route_set_metric(void *rule, struct prefix *prefix,
|
||||
/* 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
|
||||
@ -373,11 +381,12 @@ static void *route_set_metric_compile(const char *arg)
|
||||
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;
|
||||
}
|
||||
|
@ -36,8 +36,8 @@
|
||||
|
||||
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. */
|
||||
@ -365,6 +365,9 @@ static route_map_result_t route_set_metric(void *rule, struct prefix *prefix,
|
||||
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)
|
||||
@ -387,43 +390,49 @@ static void *route_set_metric_compile(const char *arg)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
@ -32,8 +32,8 @@
|
||||
|
||||
struct rip_metric_modifier {
|
||||
enum { metric_increment, metric_decrement, metric_absolute } type;
|
||||
|
||||
u_char metric;
|
||||
bool used;
|
||||
u_int8_t metric;
|
||||
};
|
||||
|
||||
/* `match metric METRIC' */
|
||||
@ -168,6 +168,9 @@ static route_map_result_t route_set_metric(void *rule, struct prefix *prefix,
|
||||
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)
|
||||
@ -190,7 +193,6 @@ static void *route_set_metric_compile(const char *arg)
|
||||
{
|
||||
int len;
|
||||
const char *pnt;
|
||||
int type;
|
||||
long metric;
|
||||
char *endptr = NULL;
|
||||
struct rip_metric_modifier *mod;
|
||||
@ -198,38 +200,42 @@ static void *route_set_metric_compile(const char *arg)
|
||||
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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user