Merge pull request #7069 from opensourcerouting/fix-set-metric

lib: fix the "set metric" route-map command
This commit is contained in:
Donald Sharp 2020-09-19 08:06:36 -04:00 committed by GitHub
commit 0b8125588a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 1197 additions and 22 deletions

View File

@ -299,10 +299,13 @@ Route Map Set Command
Set the route's weight. Set the route's weight.
.. index:: set metric METRIC .. index:: [no] set metric <[+|-](1-4294967295)|rtt|+rtt|-rtt>
.. clicmd:: set metric METRIC .. clicmd:: [no] set metric <[+|-](1-4294967295)|rtt|+rtt|-rtt>
Set the BGP attribute MED. Set the BGP attribute MED to a specific value. Use `+`/`-` to add or subtract
the specified value to/from the 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.
.. index:: set as-path prepend AS_PATH .. index:: set as-path prepend AS_PATH
.. clicmd:: set as-path prepend AS_PATH .. clicmd:: set as-path prepend AS_PATH

View File

@ -719,15 +719,13 @@ DEFPY_YANG(
DEFPY_YANG( DEFPY_YANG(
set_metric, set_metric_cmd, set_metric, set_metric_cmd,
"set metric <(0-4294967295)$metric|rtt$rtt|+rtt$artt|-rtt$srtt|+metric$ametric|-metric$smetric>", "set metric <(-4294967295-4294967295)$metric|rtt$rtt|+rtt$artt|-rtt$srtt>",
SET_STR SET_STR
"Metric value for destination routing protocol\n" "Metric value for destination routing protocol\n"
"Metric value\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")
"Add metric\n"
"Subtract metric\n")
{ {
const char *xpath = "./set-action[action='metric']"; const char *xpath = "./set-action[action='metric']";
char xpath_value[XPATH_MAXLEN]; char xpath_value[XPATH_MAXLEN];
@ -746,17 +744,17 @@ DEFPY_YANG(
snprintf(xpath_value, sizeof(xpath_value), snprintf(xpath_value, sizeof(xpath_value),
"%s/subtract-round-trip-time", xpath); "%s/subtract-round-trip-time", xpath);
snprintf(value, sizeof(value), "true"); snprintf(value, sizeof(value), "true");
} else if (ametric) { } else if (metric_str && metric_str[0] == '+') {
snprintf(xpath_value, sizeof(xpath_value), "%s/add-metric", snprintf(xpath_value, sizeof(xpath_value), "%s/add-metric",
xpath); xpath);
snprintf(value, sizeof(value), "true"); snprintf(value, sizeof(value), "%s", ++metric_str);
} else if (smetric) { } else if (metric_str && metric_str[0] == '-') {
snprintf(xpath_value, sizeof(xpath_value), "%s/subtract-metric", snprintf(xpath_value, sizeof(xpath_value), "%s/subtract-metric",
xpath); xpath);
snprintf(value, sizeof(value), "true"); snprintf(value, sizeof(value), "%s", ++metric_str);
} else { } else {
snprintf(xpath_value, sizeof(xpath_value), "%s/value", xpath); snprintf(xpath_value, sizeof(xpath_value), "%s/value", xpath);
snprintf(value, sizeof(value), "%lu", metric); snprintf(value, sizeof(value), "%s", metric_str);
} }
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, value); nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, value);
@ -765,7 +763,7 @@ DEFPY_YANG(
DEFPY_YANG( DEFPY_YANG(
no_set_metric, no_set_metric_cmd, no_set_metric, no_set_metric_cmd,
"no set metric [(0-4294967295)]", "no set metric [OPTVAL]",
NO_STR NO_STR
SET_STR SET_STR
"Metric value for destination routing protocol\n" "Metric value for destination routing protocol\n"
@ -831,9 +829,12 @@ void route_map_action_show(struct vty *vty, struct lyd_node *dnode,
} else if (yang_dnode_get(dnode, "./subtract-round-trip-time")) { } else if (yang_dnode_get(dnode, "./subtract-round-trip-time")) {
vty_out(vty, " set metric -rtt\n"); vty_out(vty, " set metric -rtt\n");
} else if (yang_dnode_get(dnode, "./add-metric")) { } else if (yang_dnode_get(dnode, "./add-metric")) {
vty_out(vty, " set metric +metric\n"); vty_out(vty, " set metric +%s\n",
yang_dnode_get_string(dnode, "./add-metric"));
} else if (yang_dnode_get(dnode, "./subtract-metric")) { } else if (yang_dnode_get(dnode, "./subtract-metric")) {
vty_out(vty, " set metric -metric\n"); vty_out(vty, " set metric -%s\n",
yang_dnode_get_string(dnode,
"./subtract-metric"));
} else { } else {
vty_out(vty, " set metric %s\n", vty_out(vty, " set metric %s\n",
yang_dnode_get_string(dnode, "./value")); yang_dnode_get_string(dnode, "./value"));

View File

@ -983,8 +983,19 @@ lib_route_map_entry_set_action_value_destroy(struct nb_cb_destroy_args *args)
static int static int
lib_route_map_entry_set_action_add_metric_modify(struct nb_cb_modify_args *args) lib_route_map_entry_set_action_add_metric_modify(struct nb_cb_modify_args *args)
{ {
char metric_str[16];
if (args->event == NB_EV_VALIDATE
&& yang_dnode_get_uint32(args->dnode, NULL) == 0) {
snprintf(args->errmsg, args->errmsg_len,
"Can't add zero to metric");
return NB_ERR_VALIDATION;
}
snprintf(metric_str, sizeof(metric_str), "+%s",
yang_dnode_get_string(args->dnode, NULL));
return set_action_modify(args->event, args->dnode, args->resource, return set_action_modify(args->event, args->dnode, args->resource,
"+metric"); metric_str);
} }
static int lib_route_map_entry_set_action_add_metric_destroy( static int lib_route_map_entry_set_action_add_metric_destroy(
@ -999,8 +1010,19 @@ static int lib_route_map_entry_set_action_add_metric_destroy(
static int lib_route_map_entry_set_action_subtract_metric_modify( static int lib_route_map_entry_set_action_subtract_metric_modify(
struct nb_cb_modify_args *args) struct nb_cb_modify_args *args)
{ {
char metric_str[16];
if (args->event == NB_EV_VALIDATE
&& yang_dnode_get_uint32(args->dnode, NULL) == 0) {
snprintf(args->errmsg, args->errmsg_len,
"Can't subtract zero from metric");
return NB_ERR_VALIDATION;
}
snprintf(metric_str, sizeof(metric_str), "-%s",
yang_dnode_get_string(args->dnode, NULL));
return set_action_modify(args->event, args->dnode, args->resource, return set_action_modify(args->event, args->dnode, args->resource,
"-metric"); metric_str);
} }
static int lib_route_map_entry_set_action_subtract_metric_destroy( static int lib_route_map_entry_set_action_subtract_metric_destroy(

View File

@ -0,0 +1,351 @@
{
"vrfId": 0,
"vrfName": "default",
"routerId": "192.168.0.1",
"defaultLocPrf": 100,
"localAS": 65000,
"routes": { "0.0.0.0/0": [
{
"valid":true,
"bestpath":true,
"pathFrom":"external",
"prefix":"0.0.0.0",
"prefixLen":0,
"network":"0.0.0.0\/0",
"weight":0,
"peerId":"192.168.101.2",
"path":"65100",
"origin":"IGP",
"nexthops":[
{
"ip":"192.168.101.2",
"hostname":"r4",
"afi":"ipv4",
"used":true
}
]
}
],"192.168.0.0/24": [
{
"pathFrom":"external",
"prefix":"192.168.0.0",
"prefixLen":24,
"network":"192.168.0.0\/24",
"metric":0,
"weight":32768,
"peerId":"(unspec)",
"path":"",
"origin":"IGP",
"nexthops":[
{
"ip":"0.0.0.0",
"hostname":"r1",
"afi":"ipv4",
"used":true
}
]
}
],"192.168.1.0/24": [
{
"valid":true,
"pathFrom":"internal",
"prefix":"192.168.1.0",
"prefixLen":24,
"network":"192.168.1.0\/24",
"metric":0,
"locPrf":100,
"weight":0,
"peerId":"192.168.0.2",
"path":"",
"origin":"IGP",
"nexthops":[
{
"ip":"192.168.0.2",
"hostname":"r2",
"afi":"ipv4",
"used":true
}
]
},
{
"valid":true,
"bestpath":true,
"pathFrom":"external",
"prefix":"192.168.1.0",
"prefixLen":24,
"network":"192.168.1.0\/24",
"metric":0,
"weight":32768,
"peerId":"(unspec)",
"path":"",
"origin":"IGP",
"nexthops":[
{
"ip":"0.0.0.0",
"hostname":"r1",
"afi":"ipv4",
"used":true
}
]
}
],"192.168.2.0/24": [
{
"valid":true,
"pathFrom":"internal",
"prefix":"192.168.2.0",
"prefixLen":24,
"network":"192.168.2.0\/24",
"metric":0,
"locPrf":100,
"weight":0,
"peerId":"192.168.0.2",
"path":"",
"origin":"IGP",
"nexthops":[
{
"ip":"192.168.0.2",
"hostname":"r2",
"afi":"ipv4",
"used":true
}
]
},
{
"valid":true,
"bestpath":true,
"pathFrom":"external",
"prefix":"192.168.2.0",
"prefixLen":24,
"network":"192.168.2.0\/24",
"metric":0,
"weight":32768,
"peerId":"(unspec)",
"path":"",
"origin":"IGP",
"nexthops":[
{
"ip":"0.0.0.0",
"hostname":"r1",
"afi":"ipv4",
"used":true
}
]
}
],"192.168.3.0/24": [
{
"valid":true,
"pathFrom":"internal",
"prefix":"192.168.3.0",
"prefixLen":24,
"network":"192.168.3.0\/24",
"metric":0,
"locPrf":100,
"weight":0,
"peerId":"192.168.0.2",
"path":"",
"origin":"IGP",
"nexthops":[
{
"ip":"192.168.0.2",
"hostname":"r2",
"afi":"ipv4",
"used":true
}
]
},
{
"valid":true,
"bestpath":true,
"pathFrom":"external",
"prefix":"192.168.3.0",
"prefixLen":24,
"network":"192.168.3.0\/24",
"metric":0,
"weight":32768,
"peerId":"(unspec)",
"path":"",
"origin":"IGP",
"nexthops":[
{
"ip":"0.0.0.0",
"hostname":"r1",
"afi":"ipv4",
"used":true
}
]
}
],"192.168.6.0/24": [
{
"valid":true,
"bestpath":true,
"pathFrom":"external",
"prefix":"192.168.6.0",
"prefixLen":24,
"network":"192.168.6.0\/24",
"metric":0,
"weight":32768,
"peerId":"(unspec)",
"path":"",
"origin":"IGP",
"nexthops":[
{
"ip":"0.0.0.0",
"hostname":"r1",
"afi":"ipv4",
"used":true
}
]
}
],"192.168.7.0/24": [
{
"valid":true,
"bestpath":true,
"pathFrom":"internal",
"prefix":"192.168.7.0",
"prefixLen":24,
"network":"192.168.7.0\/24",
"metric":0,
"locPrf":100,
"weight":0,
"peerId":"192.168.0.2",
"path":"",
"origin":"IGP",
"nexthops":[
{
"ip":"192.168.0.2",
"hostname":"r2",
"afi":"ipv4",
"used":true
}
]
}
],"192.168.8.0/24": [
{
"valid":true,
"pathFrom":"internal",
"prefix":"192.168.8.0",
"prefixLen":24,
"network":"192.168.8.0\/24",
"metric":0,
"locPrf":100,
"weight":0,
"peerId":"192.168.0.2",
"path":"",
"origin":"IGP",
"nexthops":[
{
"ip":"192.168.0.2",
"hostname":"r2",
"afi":"ipv4",
"used":true
}
]
},
{
"valid":true,
"bestpath":true,
"pathFrom":"external",
"prefix":"192.168.8.0",
"prefixLen":24,
"network":"192.168.8.0\/24",
"metric":0,
"weight":32768,
"peerId":"(unspec)",
"path":"",
"origin":"IGP",
"nexthops":[
{
"ip":"0.0.0.0",
"hostname":"r1",
"afi":"ipv4",
"used":true
}
]
}
],"192.168.101.0/24": [
{
"valid":true,
"bestpath":true,
"pathFrom":"external",
"prefix":"192.168.101.0",
"prefixLen":24,
"network":"192.168.101.0\/24",
"metric":0,
"weight":0,
"peerId":"192.168.101.2",
"path":"65100",
"origin":"IGP",
"nexthops":[
{
"ip":"192.168.101.2",
"hostname":"r4",
"afi":"ipv4",
"used":true
}
]
}
],"192.168.102.0/24": [
{
"valid":true,
"bestpath":true,
"pathFrom":"external",
"prefix":"192.168.102.0",
"prefixLen":24,
"network":"192.168.102.0\/24",
"metric":0,
"weight":0,
"peerId":"192.168.101.2",
"path":"65100",
"origin":"IGP",
"nexthops":[
{
"ip":"192.168.101.2",
"hostname":"r4",
"afi":"ipv4",
"used":true
}
]
}
],"192.168.201.0/24": [
{
"pathFrom":"internal",
"prefix":"192.168.201.0",
"prefixLen":24,
"network":"192.168.201.0\/24",
"metric":0,
"locPrf":100,
"weight":0,
"peerId":"192.168.0.2",
"path":"65200",
"origin":"IGP",
"nexthops":[
{
"ip":"192.168.201.2",
"hostname":"r2",
"afi":"ipv4",
"used":true
}
]
}
],"192.168.202.0/24": [
{
"pathFrom":"internal",
"prefix":"192.168.202.0",
"prefixLen":24,
"network":"192.168.202.0\/24",
"metric":0,
"locPrf":100,
"weight":0,
"peerId":"192.168.0.2",
"path":"65200",
"origin":"IGP",
"nexthops":[
{
"ip":"192.168.201.2",
"hostname":"r2",
"afi":"ipv4",
"used":true
}
]
}
] } }

View File

@ -0,0 +1,57 @@
{
"routerId": "192.168.0.1",
"routes": {
"192.168.1.0/24": [
{
"valid":true,
"prefix":"192.168.1.0",
"prefixLen":24,
"metric":11,
"nexthops":[
{
"ip":"192.168.0.2",
"used":true
}
]
},
{
"valid":true,
"prefix":"192.168.1.0",
"prefixLen":24,
"metric":0,
"nexthops":[
{
"ip":"0.0.0.0",
"used":true
}
]
}
],"192.168.101.0/24": [
{
"prefix":"192.168.101.0",
"prefixLen":24,
"metric":111,
"peerId":"192.168.101.2"
}
],"192.168.102.0/24": [
{
"prefix":"192.168.102.0",
"prefixLen":24,
"metric":0,
"peerId":"192.168.101.2"
}
],"192.168.201.0/24": [
{
"prefix":"192.168.201.0",
"prefixLen":24,
"metric":210,
"peerId":"192.168.0.2"
}
],"192.168.202.0/24": [
{
"prefix":"192.168.202.0",
"prefixLen":24,
"metric":11,
"peerId":"192.168.0.2"
}
] } }

View File

@ -0,0 +1,350 @@
{
"vrfId": 0,
"vrfName": "default",
"routerId": "192.168.0.2",
"defaultLocPrf": 100,
"localAS": 65000,
"routes": { "0.0.0.0/0": [
{
"pathFrom":"internal",
"prefix":"0.0.0.0",
"prefixLen":0,
"network":"0.0.0.0\/0",
"locPrf":100,
"weight":0,
"peerId":"192.168.0.1",
"path":"65100",
"origin":"IGP",
"nexthops":[
{
"ip":"192.168.101.2",
"hostname":"r1",
"afi":"ipv4",
"used":true
}
]
}
],"192.168.0.0/24": [
{
"pathFrom":"external",
"prefix":"192.168.0.0",
"prefixLen":24,
"network":"192.168.0.0\/24",
"metric":0,
"weight":32768,
"peerId":"(unspec)",
"path":"",
"origin":"IGP",
"nexthops":[
{
"ip":"0.0.0.0",
"hostname":"r2",
"afi":"ipv4",
"used":true
}
]
}
],"192.168.1.0/24": [
{
"valid":true,
"pathFrom":"internal",
"prefix":"192.168.1.0",
"prefixLen":24,
"network":"192.168.1.0\/24",
"metric":0,
"locPrf":100,
"weight":0,
"peerId":"192.168.0.1",
"path":"",
"origin":"IGP",
"nexthops":[
{
"ip":"192.168.0.1",
"hostname":"r1",
"afi":"ipv4",
"used":true
}
]
},
{
"valid":true,
"bestpath":true,
"pathFrom":"external",
"prefix":"192.168.1.0",
"prefixLen":24,
"network":"192.168.1.0\/24",
"metric":0,
"weight":32768,
"peerId":"(unspec)",
"path":"",
"origin":"IGP",
"nexthops":[
{
"ip":"0.0.0.0",
"hostname":"r2",
"afi":"ipv4",
"used":true
}
]
}
],"192.168.2.0/24": [
{
"valid":true,
"pathFrom":"internal",
"prefix":"192.168.2.0",
"prefixLen":24,
"network":"192.168.2.0\/24",
"metric":0,
"locPrf":100,
"weight":0,
"peerId":"192.168.0.1",
"path":"",
"origin":"IGP",
"nexthops":[
{
"ip":"192.168.0.1",
"hostname":"r1",
"afi":"ipv4",
"used":true
}
]
},
{
"valid":true,
"bestpath":true,
"pathFrom":"external",
"prefix":"192.168.2.0",
"prefixLen":24,
"network":"192.168.2.0\/24",
"metric":0,
"weight":32768,
"peerId":"(unspec)",
"path":"",
"origin":"IGP",
"nexthops":[
{
"ip":"0.0.0.0",
"hostname":"r2",
"afi":"ipv4",
"used":true
}
]
}
],"192.168.3.0/24": [
{
"valid":true,
"pathFrom":"internal",
"prefix":"192.168.3.0",
"prefixLen":24,
"network":"192.168.3.0\/24",
"metric":0,
"locPrf":100,
"weight":0,
"peerId":"192.168.0.1",
"path":"",
"origin":"IGP",
"nexthops":[
{
"ip":"192.168.0.1",
"hostname":"r1",
"afi":"ipv4",
"used":true
}
]
},
{
"valid":true,
"bestpath":true,
"pathFrom":"external",
"prefix":"192.168.3.0",
"prefixLen":24,
"network":"192.168.3.0\/24",
"metric":0,
"weight":32768,
"peerId":"(unspec)",
"path":"",
"origin":"IGP",
"nexthops":[
{
"ip":"0.0.0.0",
"hostname":"r2",
"afi":"ipv4",
"used":true
}
]
}
],"192.168.6.0/24": [
{
"valid":true,
"bestpath":true,
"pathFrom":"internal",
"prefix":"192.168.6.0",
"prefixLen":24,
"network":"192.168.6.0\/24",
"metric":0,
"locPrf":100,
"weight":0,
"peerId":"192.168.0.1",
"path":"",
"origin":"IGP",
"nexthops":[
{
"ip":"192.168.0.1",
"hostname":"r1",
"afi":"ipv4",
"used":true
}
]
}
],"192.168.7.0/24": [
{
"valid":true,
"bestpath":true,
"pathFrom":"external",
"prefix":"192.168.7.0",
"prefixLen":24,
"network":"192.168.7.0\/24",
"metric":0,
"weight":32768,
"peerId":"(unspec)",
"path":"",
"origin":"IGP",
"nexthops":[
{
"ip":"0.0.0.0",
"hostname":"r2",
"afi":"ipv4",
"used":true
}
]
}
],"192.168.8.0/24": [
{
"valid":true,
"pathFrom":"internal",
"prefix":"192.168.8.0",
"prefixLen":24,
"network":"192.168.8.0\/24",
"metric":0,
"locPrf":100,
"weight":0,
"peerId":"192.168.0.1",
"path":"",
"origin":"IGP",
"nexthops":[
{
"ip":"192.168.0.1",
"hostname":"r1",
"afi":"ipv4",
"used":true
}
]
},
{
"valid":true,
"bestpath":true,
"pathFrom":"external",
"prefix":"192.168.8.0",
"prefixLen":24,
"network":"192.168.8.0\/24",
"metric":0,
"weight":32768,
"peerId":"(unspec)",
"path":"",
"origin":"IGP",
"nexthops":[
{
"ip":"0.0.0.0",
"hostname":"r2",
"afi":"ipv4",
"used":true
}
]
}
],"192.168.101.0/24": [
{
"pathFrom":"internal",
"prefix":"192.168.101.0",
"prefixLen":24,
"network":"192.168.101.0\/24",
"metric":0,
"locPrf":100,
"weight":0,
"peerId":"192.168.0.1",
"path":"65100",
"origin":"IGP",
"nexthops":[
{
"ip":"192.168.101.2",
"hostname":"r1",
"afi":"ipv4",
"used":true
}
]
}
],"192.168.102.0/24": [
{
"pathFrom":"internal",
"prefix":"192.168.102.0",
"prefixLen":24,
"network":"192.168.102.0\/24",
"metric":0,
"locPrf":100,
"weight":0,
"peerId":"192.168.0.1",
"path":"65100",
"origin":"IGP",
"nexthops":[
{
"ip":"192.168.101.2",
"hostname":"r1",
"afi":"ipv4",
"used":true
}
]
}
],"192.168.201.0/24": [
{
"valid":true,
"bestpath":true,
"pathFrom":"external",
"prefix":"192.168.201.0",
"prefixLen":24,
"network":"192.168.201.0\/24",
"metric":0,
"weight":0,
"peerId":"192.168.201.2",
"path":"65200",
"origin":"IGP",
"nexthops":[
{
"ip":"192.168.201.2",
"hostname":"r5",
"afi":"ipv4",
"used":true
}
]
}
],"192.168.202.0/24": [
{
"valid":true,
"bestpath":true,
"pathFrom":"external",
"prefix":"192.168.202.0",
"prefixLen":24,
"network":"192.168.202.0\/24",
"metric":0,
"weight":0,
"peerId":"192.168.201.2",
"path":"65200",
"origin":"IGP",
"nexthops":[
{
"ip":"192.168.201.2",
"hostname":"r5",
"afi":"ipv4",
"used":true
}
]
}
] } }

View File

@ -0,0 +1,57 @@
{
"routerId": "192.168.0.2",
"routes": {
"192.168.2.0/24": [
{
"valid":true,
"prefix":"192.168.2.0",
"prefixLen":24,
"metric":0,
"nexthops":[
{
"ip":"192.168.0.1",
"used":true
}
]
},
{
"valid":true,
"prefix":"192.168.2.0",
"prefixLen":24,
"metric":0,
"nexthops":[
{
"ip":"0.0.0.0",
"used":true
}
]
}
],"192.168.101.0/24": [
{
"prefix":"192.168.101.0",
"prefixLen":24,
"metric":101,
"peerId":"192.168.0.1"
}
],"192.168.102.0/24": [
{
"prefix":"192.168.102.0",
"prefixLen":24,
"metric":0,
"peerId":"192.168.0.1"
}
],"192.168.201.0/24": [
{
"prefix":"192.168.201.0",
"prefixLen":24,
"metric":222,
"peerId":"192.168.201.2"
}
],"192.168.202.0/24": [
{
"prefix":"192.168.202.0",
"prefixLen":24,
"metric":0,
"peerId":"192.168.201.2"
}
] } }

View File

@ -0,0 +1,27 @@
{
"routerId": "192.168.100.1",
"localAS": 65100,
"routes": {
"192.168.1.0/24": [
{
"valid":true,
"bestpath":true,
"pathFrom":"external",
"prefix":"192.168.1.0",
"prefixLen":24,
"network":"192.168.1.0\/24",
"metric":1011,
"weight":0,
"peerId":"192.168.101.1",
"path":"65000",
"origin":"IGP",
"nexthops":[
{
"ip":"192.168.101.1",
"hostname":"r1",
"afi":"ipv4",
"used":true
}
]
}
] } }

View File

@ -0,0 +1,27 @@
{
"routerId": "192.168.200.1",
"localAS": 65200,
"routes": {
"192.168.2.0/24": [
{
"valid":true,
"bestpath":true,
"pathFrom":"external",
"prefix":"192.168.2.0",
"prefixLen":24,
"network":"192.168.2.0\/24",
"metric":2022,
"weight":0,
"peerId":"192.168.201.1",
"path":"65000",
"origin":"IGP",
"nexthops":[
{
"ip":"192.168.201.1",
"hostname":"r2",
"afi":"ipv4",
"used":true
}
]
}
] } }

View File

@ -261,6 +261,282 @@ def test_bgp_no_shutdown():
assert res is None, assertmsg assert res is None, assertmsg
def test_bgp_metric_config():
"Test BGP Changing metric values in route-maps"
tgen = get_topogen()
# Skip if previous fatal error condition is raised
if tgen.routers_have_failure():
pytest.skip(tgen.errors)
logger.info("Configuring bgp route-maps on router r1 and r2 to update metric")
# # Adding the following configuration to r1:
# router bgp 65000
# address-family ipv4 unicast
# neighbor 192.168.0.2 route-map addmetric-in in
# neighbor 192.168.0.2 route-map addmetric-out out
# neighbor 192.168.101.2 route-map setmetric-in in
# neighbor 192.168.101.2 route-map setmetric-out out
# exit-address-family
# !
# ip prefix-list net1 seq 10 permit 192.168.101.0/24
# ip prefix-list net2 seq 20 permit 192.168.1.0/24
# !
# route-map setmetric-in permit 10
# match ip address prefix-list net1
# set metric 111
# !
# route-map setmetric-in permit 20
# !
# route-map setmetric-out permit 10
# match ip address prefix-list net2
# set metric 1011
# !
# route-map setmetric-out permit 20
# !
# route-map addmetric-in permit 10
# set metric +11
# !
# route-map addmetric-out permit 10
# set metric +12
# !
tgen.net['r1'].cmd('vtysh -c "conf t" -c "router bgp 65000" '+
'-c "address-family ipv4 unicast" '+
'-c "neighbor 192.168.0.2 route-map addmetric-in in" '+
'-c "neighbor 192.168.0.2 route-map addmetric-out out" '+
'-c "neighbor 192.168.101.2 route-map setmetric-in in" '+
'-c "neighbor 192.168.101.2 route-map setmetric-out out" ')
tgen.net['r1'].cmd('vtysh -c "conf t" '+
'-c "ip prefix-list net1 seq 10 permit 192.168.101.0/24" '+
'-c "ip prefix-list net2 seq 20 permit 192.168.1.0/24"')
tgen.net['r1'].cmd('vtysh -c "conf t" '+
'-c "route-map setmetric-in permit 10" '+
'-c "match ip address prefix-list net1" '+
'-c "set metric 111" '+
'-c "route-map setmetric-in permit 20"')
tgen.net['r1'].cmd('vtysh -c "conf t" '+
'-c "route-map setmetric-out permit 10" '+
'-c "match ip address prefix-list net2" '+
'-c "set metric 1011" '+
'-c "route-map setmetric-out permit 20"')
tgen.net['r1'].cmd('vtysh -c "conf t" '+
'-c "route-map addmetric-in permit 10" '+
'-c "set metric +11"')
tgen.net['r1'].cmd('vtysh -c "conf t" '+
'-c "route-map addmetric-out permit 10" '+
'-c "set metric +12"')
# # Adding the following configuration to r2:
# router bgp 65000
# address-family ipv4 unicast
# neighbor 192.168.0.1 route-map subtractmetric-in in
# neighbor 192.168.0.1 route-map subtractmetric-out out
# neighbor 192.168.201.2 route-map setmetric-in in
# neighbor 192.168.201.2 route-map setmetric-out out
# exit-address-family
# !
# ip prefix-list net1 seq 10 permit 192.168.201.0/24
# ip prefix-list net2 seq 20 permit 192.168.2.0/24
# !
# route-map setmetric-in permit 10
# match ip address prefix-list net1
# set metric 222
# !
# route-map setmetric-in permit 20
# !
# route-map setmetric-out permit 10
# match ip address prefix-list net2
# set metric 2022
# !
# route-map setmetric-out permit 20
# !
# route-map subtractmetric-in permit 10
# set metric -22
# !
# route-map subtractmetric-out permit 10
# set metric -23
# !
tgen.net['r2'].cmd('vtysh -c "conf t" -c "router bgp 65000" '+
'-c "address-family ipv4 unicast" '+
'-c "neighbor 192.168.0.1 route-map subtractmetric-in in" '+
'-c "neighbor 192.168.0.1 route-map subtractmetric-out out" '+
'-c "neighbor 192.168.201.2 route-map setmetric-in in" ' +
'-c "neighbor 192.168.201.2 route-map setmetric-out out" ')
tgen.net['r2'].cmd('vtysh -c "conf t" '+
'-c "ip prefix-list net1 seq 10 permit 192.168.201.0/24" '+
'-c "ip prefix-list net2 seq 20 permit 192.168.2.0/24" ')
tgen.net['r2'].cmd('vtysh -c "conf t" '+
'-c "route-map setmetric-in permit 10" '+
'-c "match ip address prefix-list net1" '+
'-c "set metric 222" '+
'-c "route-map setmetric-in permit 20"')
tgen.net['r2'].cmd('vtysh -c "conf t" '+
'-c "route-map setmetric-out permit 10" '+
'-c "match ip address prefix-list net2" '+
'-c "set metric 2022" '+
'-c "route-map setmetric-out permit 20"')
tgen.net['r2'].cmd('vtysh -c "conf t" '+
'-c "route-map subtractmetric-in permit 10" '+
'-c "set metric -22"')
tgen.net['r2'].cmd('vtysh -c "conf t" '+
'-c "route-map subtractmetric-out permit 10" '+
'-c "set metric -23"')
# Clear IN the bgp neighbors to make sure the route-maps are applied
tgen.net['r1'].cmd('vtysh -c "clear ip bgp 192.168.0.2 in" '+
'-c "clear ip bgp 192.168.101.2 in"')
tgen.net['r2'].cmd('vtysh -c "clear ip bgp 192.168.0.1 in" '+
'-c "clear ip bgp 192.168.201.2 in"')
# tgen.mininet_cli()
# Checking BGP config - should show the bgp metric settings in the route-maps
logger.info("Checking BGP configuration for correct 'set metric' values")
setmetric111 = tgen.net['r1'].cmd('vtysh -c "show running" | grep "^ set metric 111"').rstrip()
assertmsg = "'set metric 111' configuration applied to R1, but not visible in configuration"
assert setmetric111 == ' set metric 111', assertmsg
setmetric222 = tgen.net['r2'].cmd('vtysh -c "show running" | grep "^ set metric 222"').rstrip()
assertmsg = "'set metric 222' configuration applied to R2, but not visible in configuration"
assert setmetric222 == ' set metric 222', assertmsg
def test_bgp_metric_add_config():
"Test BGP Changing metric values in route-maps"
tgen = get_topogen()
# Skip if previous fatal error condition is raised
if tgen.routers_have_failure():
pytest.skip(tgen.errors)
logger.info("Checking BGP configuration for correct 'set metric' ADD value")
setmetricP11 = tgen.net['r1'].cmd('vtysh -c "show running" | grep "^ set metric +11"').rstrip()
assertmsg = "'set metric +11' configuration applied to R1, but not visible in configuration"
assert setmetricP11 == ' set metric +11', assertmsg
def test_bgp_metric_subtract_config():
"Test BGP Changing metric values in route-maps"
tgen = get_topogen()
# Skip if previous fatal error condition is raised
if tgen.routers_have_failure():
pytest.skip(tgen.errors)
logger.info("Checking BGP configuration for correct 'set metric' SUBTRACT value")
setmetricM22 = tgen.net['r2'].cmd('vtysh -c "show running" | grep "^ set metric -22"').rstrip()
assertmsg = "'set metric -22' configuration applied to R2, but not visible in configuration"
assert setmetricM22 == ' set metric -22', assertmsg
def test_bgp_set_metric():
"Test setting metrics"
tgen = get_topogen()
# Skip if previous fatal error condition is raised
if tgen.routers_have_failure():
pytest.skip(tgen.errors)
logger.info("Test absolute metric")
# Check BGP Summary on local and remote routers
for rtrNum in [1, 2, 4, 5]:
logger.info("Checking metrics of BGP router on r{}".format(rtrNum))
router = tgen.gears["r{}".format(rtrNum)]
reffile = os.path.join(CWD, "r{}/show_bgp_metric_test.json".format(rtrNum))
expected = json.loads(open(reffile).read())
test_func = functools.partial(
topotest.router_json_cmp, router, "show ip bgp json", expected
)
_, res = topotest.run_and_expect(test_func, None, count=60, wait=2)
assertmsg = "BGP metrics on router r{} wrong".format(rtrNum)
assert res is None, assertmsg
def test_bgp_remove_metric_rmaps():
"Test removing route-maps with metric changes again"
tgen = get_topogen()
# Skip if previous fatal error condition is raised
if tgen.routers_have_failure():
pytest.skip(tgen.errors)
logger.info("Test absolute metric")
# Remove metric route-maps and relevant comfiguration
tgen.net['r1'].cmd('vtysh -c "conf t" -c "router bgp 65000" '+
'-c "address-family ipv4 unicast" '+
'-c "no neighbor 192.168.0.2 route-map addmetric-in in" '+
'-c "no neighbor 192.168.0.2 route-map addmetric-out out" '+
'-c "no neighbor 192.168.101.2 route-map setmetric-in in" '+
'-c "no neighbor 192.168.101.2 route-map setmetric-out out" ')
tgen.net['r1'].cmd('vtysh -c "conf t" '+
'-c "no ip prefix-list net1" '+
'-c "no ip prefix-list net2"')
tgen.net['r1'].cmd('vtysh -c "conf t" '+
'-c "no route-map setmetric-in" ')
tgen.net['r1'].cmd('vtysh -c "conf t" '+
'-c "no route-map setmetric-out" ')
tgen.net['r1'].cmd('vtysh -c "conf t" '+
'-c "no route-map addmetric-in" ')
tgen.net['r1'].cmd('vtysh -c "conf t" '+
'-c "no route-map addmetric-out" ')
tgen.net['r2'].cmd('vtysh -c "conf t" -c "router bgp 65000" '+
'-c "address-family ipv4 unicast" '+
'-c "no neighbor 192.168.0.1 route-map subtractmetric-in in" '+
'-c "no neighbor 192.168.0.1 route-map subtractmetric-out out" '+
'-c "no neighbor 192.168.201.2 route-map setmetric-in in" ' +
'-c "no neighbor 192.168.201.2 route-map setmetric-out out" ')
tgen.net['r2'].cmd('vtysh -c "conf t" '+
'-c "no ip prefix-list net1" '+
'-c "no ip prefix-list net2" ')
tgen.net['r2'].cmd('vtysh -c "conf t" '+
'-c "no route-map setmetric-in" ')
tgen.net['r2'].cmd('vtysh -c "conf t" '+
'-c "no route-map setmetric-out" ')
tgen.net['r2'].cmd('vtysh -c "conf t" '+
'-c "no route-map addmetric-in" ')
tgen.net['r2'].cmd('vtysh -c "conf t" '+
'-c "no route-map addmetric-out" ')
# Clear IN the bgp neighbors to make sure the route-maps are applied
tgen.net['r1'].cmd('vtysh -c "clear ip bgp 192.168.0.2 in" '+
'-c "clear ip bgp 192.168.101.2 in"')
tgen.net['r2'].cmd('vtysh -c "clear ip bgp 192.168.0.1 in" '+
'-c "clear ip bgp 192.168.201.2 in"')
# tgen.mininet_cli()
# Check BGP Summary on local and remote routers
for rtrNum in [1, 2]:
logger.info("Checking metrics of BGP router on r{}".format(rtrNum))
router = tgen.gears["r{}".format(rtrNum)]
reffile = os.path.join(CWD, "r{}/show_bgp.json".format(rtrNum))
expected = json.loads(open(reffile).read())
test_func = functools.partial(
topotest.router_json_cmp, router, "show ip bgp json", expected
)
_, res = topotest.run_and_expect(test_func, None, count=60, wait=2)
assertmsg = "BGP routes on router r{} are wrong after removing metric route-maps".format(rtrNum)
assert res is None, assertmsg
if __name__ == "__main__": if __name__ == "__main__":
args = ["-s"] + sys.argv[1:] args = ["-s"] + sys.argv[1:]

View File

@ -373,15 +373,19 @@ module frr-route-map {
case add-metric { case add-metric {
leaf add-metric { leaf add-metric {
description "Add unit to metric."; description "Add value to metric.";
type boolean; type uint32 {
range "0..4294967295";
}
} }
} }
case subtract-metric { case subtract-metric {
leaf subtract-metric { leaf subtract-metric {
description "Subtract unit from metric."; description "Subtract value from metric.";
type boolean; type uint32 {
range "0..4294967295";
}
} }
} }