]> git.puffer.fish Git - matthieu/frr.git/commitdiff
staticd: fix distance processing
authorIgor Ryzhov <iryzhov@nfware.com>
Tue, 25 May 2021 12:49:46 +0000 (15:49 +0300)
committerDaniil Baturin <daniil@baturin.org>
Wed, 26 May 2021 16:19:37 +0000 (23:19 +0700)
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>
staticd/static_nb.h
staticd/static_vty.c

index b293224dd1212a0c7c21254d0147ccc7c5eeda3a..f4bc1f4ed57d79c6e4c77b943fcb52d02c910852 100644 (file)
@@ -132,6 +132,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"
 
@@ -157,14 +163,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
index 0ff6f7e79033d92d4678d807134d03c3aae5edb4..dfa7fa33cdb3df510e7c5d68dfcf6eaf2db89404 100644 (file)
@@ -154,6 +154,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),
@@ -278,20 +309,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)