staticd: fix distance processing

When the user adds the route + nexthop pair that already exists with a
different distance, we should replace it instead of adding a new one.

Likewise, when the user wants to delete the route + nexthop pair without
explicitly entering the distance, we should delete the route.

Fixes #8695.

Signed-off-by: Igor Ryzhov <iryzhov@nfware.com>
This commit is contained in:
Igor Ryzhov 2021-05-25 15:49:46 +03:00
parent 7b4e9d3cfc
commit e1ea6b20df
2 changed files with 59 additions and 6 deletions

View File

@ -124,6 +124,12 @@ int routing_control_plane_protocols_name_validate(
"frr-staticd:staticd/route-list[prefix='%s'][afi-safi='%s']/" \
"path-list[table-id='%u'][distance='%u']"
#define FRR_STATIC_ROUTE_INFO_KEY_NO_DISTANCE_XPATH \
"/frr-routing:routing/control-plane-protocols/" \
"control-plane-protocol[type='%s'][name='%s'][vrf='%s']/" \
"frr-staticd:staticd/route-list[prefix='%s'][afi-safi='%s']/" \
"path-list[table-id='%u']"
#define FRR_STATIC_ROUTE_PATH_TAG_XPATH "/tag"
@ -149,14 +155,30 @@ int routing_control_plane_protocols_name_validate(
"frr-staticd:staticd/route-list[prefix='%s'][afi-safi='%s']/" \
"src-list[src-prefix='%s']/path-list[table-id='%u'][distance='%u']"
#define FRR_S_ROUTE_SRC_INFO_KEY_NO_DISTANCE_XPATH \
"/frr-routing:routing/control-plane-protocols/" \
"control-plane-protocol[type='%s'][name='%s'][vrf='%s']/" \
"frr-staticd:staticd/route-list[prefix='%s'][afi-safi='%s']/" \
"src-list[src-prefix='%s']/path-list[table-id='%u']"
/* route-list/frr-nexthops */
#define FRR_DEL_S_ROUTE_NH_KEY_XPATH \
FRR_STATIC_ROUTE_INFO_KEY_XPATH \
FRR_STATIC_ROUTE_NH_KEY_XPATH
/* route-list/frr-nexthops */
#define FRR_DEL_S_ROUTE_NH_KEY_NO_DISTANCE_XPATH \
FRR_STATIC_ROUTE_INFO_KEY_NO_DISTANCE_XPATH \
FRR_STATIC_ROUTE_NH_KEY_XPATH
/* route-list/src/src-list/frr-nexthops*/
#define FRR_DEL_S_ROUTE_SRC_NH_KEY_XPATH \
FRR_S_ROUTE_SRC_INFO_KEY_XPATH \
FRR_STATIC_ROUTE_NH_KEY_XPATH
/* route-list/src/src-list/frr-nexthops*/
#define FRR_DEL_S_ROUTE_SRC_NH_KEY_NO_DISTANCE_XPATH \
FRR_S_ROUTE_SRC_INFO_KEY_NO_DISTANCE_XPATH \
FRR_STATIC_ROUTE_NH_KEY_XPATH
#endif

View File

@ -153,6 +153,37 @@ static int static_route_leak(struct vty *vty, const char *svrf,
static_get_nh_type(type, buf_nh_type, PREFIX_STRLEN);
if (!negate) {
if (src_str)
snprintf(ab_xpath, sizeof(ab_xpath),
FRR_DEL_S_ROUTE_SRC_NH_KEY_NO_DISTANCE_XPATH,
"frr-staticd:staticd", "staticd", svrf,
buf_prefix,
yang_afi_safi_value2identity(afi, safi),
buf_src_prefix, table_id, buf_nh_type, nh_svrf,
buf_gate_str, ifname);
else
snprintf(ab_xpath, sizeof(ab_xpath),
FRR_DEL_S_ROUTE_NH_KEY_NO_DISTANCE_XPATH,
"frr-staticd:staticd", "staticd", svrf,
buf_prefix,
yang_afi_safi_value2identity(afi, safi),
table_id, buf_nh_type, nh_svrf, buf_gate_str,
ifname);
/*
* If there's already the same nexthop but with a different
* distance, then remove it for the replacement.
*/
dnode = yang_dnode_get(vty->candidate_config->dnode, ab_xpath);
if (dnode) {
dnode = yang_get_subtree_with_no_sibling(dnode);
assert(dnode);
yang_dnode_get_path(dnode, ab_xpath, XPATH_MAXLEN);
nb_cli_enqueue_change(vty, ab_xpath, NB_OP_DESTROY,
NULL);
}
/* route + path procesing */
if (src_str)
snprintf(xpath_prefix, sizeof(xpath_prefix),
@ -277,20 +308,20 @@ static int static_route_leak(struct vty *vty, const char *svrf,
} else {
if (src_str)
snprintf(ab_xpath, sizeof(ab_xpath),
FRR_DEL_S_ROUTE_SRC_NH_KEY_XPATH,
FRR_DEL_S_ROUTE_SRC_NH_KEY_NO_DISTANCE_XPATH,
"frr-staticd:staticd", "staticd", svrf,
buf_prefix,
yang_afi_safi_value2identity(afi, safi),
buf_src_prefix, table_id, distance,
buf_nh_type, nh_svrf, buf_gate_str, ifname);
buf_src_prefix, table_id, buf_nh_type, nh_svrf,
buf_gate_str, ifname);
else
snprintf(ab_xpath, sizeof(ab_xpath),
FRR_DEL_S_ROUTE_NH_KEY_XPATH,
FRR_DEL_S_ROUTE_NH_KEY_NO_DISTANCE_XPATH,
"frr-staticd:staticd", "staticd", svrf,
buf_prefix,
yang_afi_safi_value2identity(afi, safi),
table_id, distance, buf_nh_type, nh_svrf,
buf_gate_str, ifname);
table_id, buf_nh_type, nh_svrf, buf_gate_str,
ifname);
dnode = yang_dnode_get(vty->candidate_config->dnode, ab_xpath);
if (!dnode) {