bgpd: Implement set metric igp command

Set metric automatically from the path info (IGP protocol).

Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
This commit is contained in:
Donatas Abraitis 2024-10-08 20:57:49 +03:00
parent 5a05dbeb13
commit f677fc8db3
5 changed files with 57 additions and 12 deletions

View File

@ -125,6 +125,9 @@ o Local extensions
#define RMAP_VALUE_ADD 1 #define RMAP_VALUE_ADD 1
#define RMAP_VALUE_SUB 2 #define RMAP_VALUE_SUB 2
#define RMAP_VALUE_TYPE_RTT 1
#define RMAP_VALUE_TYPE_IGP 2
struct rmap_value { struct rmap_value {
uint8_t action; uint8_t action;
uint8_t variable; uint8_t variable;
@ -140,14 +143,18 @@ static int route_value_match(struct rmap_value *rv, uint32_t value)
} }
static uint32_t route_value_adjust(struct rmap_value *rv, uint32_t current, static uint32_t route_value_adjust(struct rmap_value *rv, uint32_t current,
struct peer *peer) struct bgp_path_info *bpi)
{ {
uint32_t value; uint32_t value;
struct peer *peer = bpi->peer;
switch (rv->variable) { switch (rv->variable) {
case 1: case RMAP_VALUE_TYPE_RTT:
value = peer->rtt; value = peer->rtt;
break; break;
case RMAP_VALUE_TYPE_IGP:
value = bpi->extra ? bpi->extra->igpmetric : 0;
break;
default: default:
value = rv->value; value = rv->value;
break; break;
@ -187,10 +194,11 @@ static void *route_value_compile(const char *arg)
larg = strtoul(arg, &endptr, 10); larg = strtoul(arg, &endptr, 10);
if (*arg == 0 || *endptr != 0 || errno || larg > UINT32_MAX) if (*arg == 0 || *endptr != 0 || errno || larg > UINT32_MAX)
return NULL; return NULL;
} else if (strmatch(arg, "rtt")) {
var = RMAP_VALUE_TYPE_RTT;
} else if (strmatch(arg, "igp")) {
var = RMAP_VALUE_TYPE_IGP;
} else { } else {
if (strcmp(arg, "rtt") == 0)
var = 1;
else
return NULL; return NULL;
} }
@ -2145,7 +2153,7 @@ route_set_local_pref(void *rule, const struct prefix *prefix, void *object)
locpref = path->attr->local_pref; locpref = path->attr->local_pref;
path->attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF); path->attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
path->attr->local_pref = route_value_adjust(rv, locpref, path->peer); path->attr->local_pref = route_value_adjust(rv, locpref, path);
return RMAP_OKAY; return RMAP_OKAY;
} }
@ -2172,7 +2180,7 @@ route_set_weight(void *rule, const struct prefix *prefix, void *object)
path = object; path = object;
/* Set weight value. */ /* Set weight value. */
path->attr->weight = route_value_adjust(rv, 0, path->peer); path->attr->weight = route_value_adjust(rv, 0, path);
return RMAP_OKAY; return RMAP_OKAY;
} }
@ -2222,7 +2230,7 @@ route_set_metric(void *rule, const struct prefix *prefix, void *object)
if (path->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) if (path->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
med = path->attr->med; med = path->attr->med;
bgp_attr_set_med(path->attr, route_value_adjust(rv, med, path->peer)); bgp_attr_set_med(path->attr, route_value_adjust(rv, med, path));
return RMAP_OKAY; return RMAP_OKAY;
} }

View File

@ -305,13 +305,15 @@ Route Map Set Command
Set the route's weight. Set the route's weight.
.. clicmd:: set metric <[+|-](1-4294967295)|rtt|+rtt|-rtt> .. clicmd:: set metric <[+|-](1-4294967295)|rtt|+rtt|-rtt|igp>
Set the route metric. When used with BGP, set the BGP attribute MED to a Set the route metric. When used with BGP, set the BGP attribute MED to a
specific value. Use `+`/`-` to add or subtract the specified value to/from specific value. Use `+`/`-` to add or subtract the specified value to/from
the existing/MED. Use `rtt` to set the MED to the round trip time or the existing/MED. Use `rtt` to set the MED to the round trip time or
`+rtt`/`-rtt` to add/subtract the round trip time to/from the MED. `+rtt`/`-rtt` to add/subtract the round trip time to/from the MED.
If ``igp`` is specified, then the actual value from the IGP protocol is used.
.. clicmd:: set min-metric <(0-4294967295)> .. clicmd:: set min-metric <(0-4294967295)>
Set the minimum metric for the route. Set the minimum metric for the route.

View File

@ -922,13 +922,14 @@ DEFPY_YANG(
DEFPY_YANG( DEFPY_YANG(
set_metric, set_metric_cmd, set_metric, set_metric_cmd,
"set metric <(-4294967295-4294967295)$metric|rtt$rtt|+rtt$artt|-rtt$srtt>", "set metric <(-4294967295-4294967295)$metric|rtt$rtt|+rtt$artt|-rtt$srtt|igp$igp>",
SET_STR SET_STR
"Metric value for destination routing protocol\n" "Metric value for destination routing protocol\n"
"Metric value (use +/- for additions or subtractions)\n" "Metric value (use +/- for additions or subtractions)\n"
"Assign round trip time\n" "Assign round trip time\n"
"Add round trip time\n" "Add round trip time\n"
"Subtract round trip time\n") "Subtract round trip time\n"
"Metric value from IGP protocol\n")
{ {
const char *xpath = "./set-action[action='frr-route-map:set-metric']"; const char *xpath = "./set-action[action='frr-route-map:set-metric']";
char xpath_value[XPATH_MAXLEN]; char xpath_value[XPATH_MAXLEN];
@ -939,6 +940,9 @@ DEFPY_YANG(
snprintf(xpath_value, sizeof(xpath_value), snprintf(xpath_value, sizeof(xpath_value),
"%s/rmap-set-action/use-round-trip-time", xpath); "%s/rmap-set-action/use-round-trip-time", xpath);
snprintf(value, sizeof(value), "true"); snprintf(value, sizeof(value), "true");
} else if (igp) {
snprintf(xpath_value, sizeof(xpath_value), "%s/rmap-set-action/use-igp", xpath);
snprintf(value, sizeof(value), "true");
} else if (artt) { } else if (artt) {
snprintf(xpath_value, sizeof(xpath_value), snprintf(xpath_value, sizeof(xpath_value),
"%s/rmap-set-action/add-round-trip-time", xpath); "%s/rmap-set-action/add-round-trip-time", xpath);
@ -1148,6 +1152,8 @@ void route_map_action_show(struct vty *vty, const struct lyd_node *dnode,
if (yang_dnode_get(dnode, if (yang_dnode_get(dnode,
"./rmap-set-action/use-round-trip-time")) { "./rmap-set-action/use-round-trip-time")) {
vty_out(vty, " set metric rtt\n"); vty_out(vty, " set metric rtt\n");
} else if (yang_dnode_get(dnode, "./rmap-set-action/use-igp")) {
vty_out(vty, " set metric igp\n");
} else if (yang_dnode_get( } else if (yang_dnode_get(
dnode, dnode,
"./rmap-set-action/add-round-trip-time")) { "./rmap-set-action/add-round-trip-time")) {

View File

@ -1213,6 +1213,20 @@ static int lib_route_map_entry_set_action_use_round_trip_time_destroy(
return lib_route_map_entry_set_action_value_destroy(args); return lib_route_map_entry_set_action_value_destroy(args);
} }
/*
* XPath: /frr-route-map:lib/route-map/entry/set-action/use-igp
*/
static int lib_route_map_entry_set_action_use_igp_modify(struct nb_cb_modify_args *args)
{
return set_action_modify(args->event, args->dnode, args->resource, "igp", args->errmsg,
args->errmsg_len);
}
static int lib_route_map_entry_set_action_use_igp_destroy(struct nb_cb_destroy_args *args)
{
return lib_route_map_entry_set_action_value_destroy(args);
}
/* /*
* XPath: /frr-route-map:lib/route-map/entry/set-action/add-round-trip-time * XPath: /frr-route-map:lib/route-map/entry/set-action/add-round-trip-time
*/ */
@ -1516,6 +1530,13 @@ const struct frr_yang_module_info frr_route_map_info = {
.destroy = lib_route_map_entry_set_action_use_round_trip_time_destroy, .destroy = lib_route_map_entry_set_action_use_round_trip_time_destroy,
} }
}, },
{
.xpath = "/frr-route-map:lib/route-map/entry/set-action/rmap-set-action/use-igp",
.cbs = {
.modify = lib_route_map_entry_set_action_use_igp_modify,
.destroy = lib_route_map_entry_set_action_use_igp_destroy,
}
},
{ {
.xpath = "/frr-route-map:lib/route-map/entry/set-action/rmap-set-action/add-round-trip-time", .xpath = "/frr-route-map:lib/route-map/entry/set-action/rmap-set-action/add-round-trip-time",
.cbs = { .cbs = {

View File

@ -355,6 +355,14 @@ module frr-route-map {
"Subtract round trip time to metric"; "Subtract round trip time to metric";
} }
} }
case use-igp {
leaf use-igp {
type boolean;
description
"Use metric from IGP procotol";
}
}
} }
} }