back to topotato report
topotato coverage report
Current view: top level - staticd - static_vty.c (source / functions) Hit Total Coverage
Test: aggregated run ( view descriptions ) Lines: 119 448 26.6 %
Date: 2023-02-24 19:38:44 Functions: 2 16 12.5 %

          Line data    Source code
       1             : /*
       2             :  * STATICd - vty code
       3             :  * Copyright (C) 2018 Cumulus Networks, Inc.
       4             :  *               Donald Sharp
       5             :  *
       6             :  * This program is free software; you can redistribute it and/or modify it
       7             :  * under the terms of the GNU General Public License as published by the Free
       8             :  * Software Foundation; either version 2 of the License, or (at your option)
       9             :  * any later version.
      10             :  *
      11             :  * This program is distributed in the hope that it will be useful, but WITHOUT
      12             :  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
      13             :  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
      14             :  * more details.
      15             :  *
      16             :  * You should have received a copy of the GNU General Public License along
      17             :  * with this program; see the file COPYING; if not, write to the Free Software
      18             :  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
      19             :  */
      20             : #include <zebra.h>
      21             : 
      22             : #include "command.h"
      23             : #include "vty.h"
      24             : #include "vrf.h"
      25             : #include "prefix.h"
      26             : #include "nexthop.h"
      27             : #include "table.h"
      28             : #include "srcdest_table.h"
      29             : #include "mpls.h"
      30             : #include "northbound.h"
      31             : #include "libfrr.h"
      32             : #include "routing_nb.h"
      33             : #include "northbound_cli.h"
      34             : 
      35             : #include "static_vrf.h"
      36             : #include "static_vty.h"
      37             : #include "static_routes.h"
      38             : #include "static_debug.h"
      39             : #include "staticd/static_vty_clippy.c"
      40             : #include "static_nb.h"
      41             : 
      42             : #define STATICD_STR "Static route daemon\n"
      43             : 
      44             : /** All possible route parameters available in CLI. */
      45             : struct static_route_args {
      46             :         /** "no" command? */
      47             :         bool delete;
      48             :         /** Is VRF obtained from XPath? */
      49             :         bool xpath_vrf;
      50             : 
      51             :         bool onlink;
      52             :         afi_t afi;
      53             :         safi_t safi;
      54             : 
      55             :         const char *vrf;
      56             :         const char *nexthop_vrf;
      57             :         const char *prefix;
      58             :         const char *prefix_mask;
      59             :         const char *source;
      60             :         const char *gateway;
      61             :         const char *interface_name;
      62             :         const char *flag;
      63             :         const char *tag;
      64             :         const char *distance;
      65             :         const char *label;
      66             :         const char *table;
      67             :         const char *color;
      68             : 
      69             :         bool bfd;
      70             :         bool bfd_multi_hop;
      71             :         const char *bfd_source;
      72             :         const char *bfd_profile;
      73             : };
      74             : 
      75          25 : static int static_route_nb_run(struct vty *vty, struct static_route_args *args)
      76             : {
      77          25 :         int ret;
      78          25 :         struct prefix p, src;
      79          25 :         struct in_addr mask;
      80          25 :         enum static_nh_type type;
      81          25 :         const char *bh_type;
      82          25 :         char xpath_prefix[XPATH_MAXLEN];
      83          25 :         char xpath_nexthop[XPATH_MAXLEN];
      84          25 :         char xpath_mpls[XPATH_MAXLEN];
      85          25 :         char xpath_label[XPATH_MAXLEN];
      86          25 :         char ab_xpath[XPATH_MAXLEN];
      87          25 :         char buf_prefix[PREFIX_STRLEN];
      88          25 :         char buf_src_prefix[PREFIX_STRLEN] = {};
      89          25 :         char buf_nh_type[PREFIX_STRLEN] = {};
      90          25 :         char buf_tag[PREFIX_STRLEN];
      91          25 :         uint8_t label_stack_id = 0;
      92          25 :         const char *buf_gate_str;
      93          25 :         uint8_t distance = ZEBRA_STATIC_DISTANCE_DEFAULT;
      94          25 :         route_tag_t tag = 0;
      95          25 :         uint32_t table_id = 0;
      96          25 :         const struct lyd_node *dnode;
      97          25 :         const struct lyd_node *vrf_dnode;
      98             : 
      99          25 :         if (args->xpath_vrf) {
     100           0 :                 vrf_dnode = yang_dnode_get(vty->candidate_config->dnode,
     101           0 :                                            VTY_CURR_XPATH);
     102           0 :                 if (vrf_dnode == NULL) {
     103           0 :                         vty_out(vty,
     104             :                                 "%% Failed to get vrf dnode in candidate db\n");
     105           0 :                         return CMD_WARNING_CONFIG_FAILED;
     106             :                 }
     107             : 
     108           0 :                 args->vrf = yang_dnode_get_string(vrf_dnode, "./name");
     109             :         } else {
     110          25 :                 if (args->vrf == NULL)
     111          25 :                         args->vrf = VRF_DEFAULT_NAME;
     112             :         }
     113          25 :         if (args->nexthop_vrf == NULL)
     114          25 :                 args->nexthop_vrf = args->vrf;
     115             : 
     116          25 :         if (args->interface_name &&
     117           9 :             !strcasecmp(args->interface_name, "Null0")) {
     118           0 :                 args->flag = "Null0";
     119           0 :                 args->interface_name = NULL;
     120             :         }
     121             : 
     122          25 :         assert(!!str2prefix(args->prefix, &p));
     123             : 
     124          25 :         switch (args->afi) {
     125          16 :         case AFI_IP:
     126             :                 /* Cisco like mask notation. */
     127          16 :                 if (args->prefix_mask) {
     128           0 :                         assert(inet_pton(AF_INET, args->prefix_mask, &mask) ==
     129             :                                1);
     130           0 :                         p.prefixlen = ip_masklen(mask);
     131             :                 }
     132             :                 break;
     133           9 :         case AFI_IP6:
     134             :                 /* srcdest routing */
     135           9 :                 if (args->source)
     136           0 :                         assert(!!str2prefix(args->source, &src));
     137             :                 break;
     138             :         case AFI_L2VPN:
     139             :         case AFI_UNSPEC:
     140             :         case AFI_MAX:
     141             :                 break;
     142             :         }
     143             : 
     144             :         /* Apply mask for given prefix. */
     145          25 :         apply_mask(&p);
     146          25 :         prefix2str(&p, buf_prefix, sizeof(buf_prefix));
     147             : 
     148          25 :         if (args->bfd && args->gateway == NULL) {
     149           0 :                 vty_out(vty, "%% Route monitoring requires a gateway\n");
     150           0 :                 return CMD_WARNING_CONFIG_FAILED;
     151             :         }
     152             : 
     153          25 :         if (args->source)
     154           0 :                 prefix2str(&src, buf_src_prefix, sizeof(buf_src_prefix));
     155          25 :         if (args->gateway)
     156          25 :                 buf_gate_str = args->gateway;
     157             :         else
     158             :                 buf_gate_str = "";
     159             : 
     160          25 :         if (args->gateway == NULL && args->interface_name == NULL)
     161             :                 type = STATIC_BLACKHOLE;
     162          25 :         else if (args->gateway && args->interface_name) {
     163           9 :                 if (args->afi == AFI_IP)
     164             :                         type = STATIC_IPV4_GATEWAY_IFNAME;
     165             :                 else
     166           9 :                         type = STATIC_IPV6_GATEWAY_IFNAME;
     167          16 :         } else if (args->interface_name)
     168             :                 type = STATIC_IFNAME;
     169             :         else {
     170          16 :                 if (args->afi == AFI_IP)
     171             :                         type = STATIC_IPV4_GATEWAY;
     172             :                 else
     173           0 :                         type = STATIC_IPV6_GATEWAY;
     174             :         }
     175             : 
     176             :         /* Administrative distance. */
     177          25 :         if (args->distance)
     178           0 :                 distance = strtol(args->distance, NULL, 10);
     179             : 
     180             :         /* tag */
     181          25 :         if (args->tag)
     182           0 :                 tag = strtoul(args->tag, NULL, 10);
     183             : 
     184             :         /* TableID */
     185          25 :         if (args->table)
     186           0 :                 table_id = strtol(args->table, NULL, 10);
     187             : 
     188          25 :         static_get_nh_type(type, buf_nh_type, sizeof(buf_nh_type));
     189          25 :         if (!args->delete) {
     190          25 :                 if (args->source)
     191           0 :                         snprintf(ab_xpath, sizeof(ab_xpath),
     192             :                                  FRR_DEL_S_ROUTE_SRC_NH_KEY_NO_DISTANCE_XPATH,
     193             :                                  "frr-staticd:staticd", "staticd", args->vrf,
     194             :                                  buf_prefix,
     195             :                                  yang_afi_safi_value2identity(args->afi,
     196             :                                                               args->safi),
     197             :                                  buf_src_prefix, table_id, buf_nh_type,
     198             :                                  args->nexthop_vrf, buf_gate_str,
     199             :                                  args->interface_name);
     200             :                 else
     201          25 :                         snprintf(ab_xpath, sizeof(ab_xpath),
     202             :                                  FRR_DEL_S_ROUTE_NH_KEY_NO_DISTANCE_XPATH,
     203             :                                  "frr-staticd:staticd", "staticd", args->vrf,
     204             :                                  buf_prefix,
     205             :                                  yang_afi_safi_value2identity(args->afi,
     206             :                                                               args->safi),
     207             :                                  table_id, buf_nh_type, args->nexthop_vrf,
     208             :                                  buf_gate_str, args->interface_name);
     209             : 
     210             :                 /*
     211             :                  * If there's already the same nexthop but with a different
     212             :                  * distance, then remove it for the replacement.
     213             :                  */
     214          25 :                 dnode = yang_dnode_get(vty->candidate_config->dnode, ab_xpath);
     215          25 :                 if (dnode) {
     216           0 :                         dnode = yang_get_subtree_with_no_sibling(dnode);
     217           0 :                         assert(dnode);
     218           0 :                         yang_dnode_get_path(dnode, ab_xpath, XPATH_MAXLEN);
     219             : 
     220           0 :                         nb_cli_enqueue_change(vty, ab_xpath, NB_OP_DESTROY,
     221             :                                               NULL);
     222             :                 }
     223             : 
     224             :                 /* route + path procesing */
     225          25 :                 if (args->source)
     226           0 :                         snprintf(xpath_prefix, sizeof(xpath_prefix),
     227             :                                  FRR_S_ROUTE_SRC_INFO_KEY_XPATH,
     228             :                                  "frr-staticd:staticd", "staticd", args->vrf,
     229             :                                  buf_prefix,
     230             :                                  yang_afi_safi_value2identity(args->afi,
     231             :                                                               args->safi),
     232             :                                  buf_src_prefix, table_id, distance);
     233             :                 else
     234          25 :                         snprintf(xpath_prefix, sizeof(xpath_prefix),
     235             :                                  FRR_STATIC_ROUTE_INFO_KEY_XPATH,
     236             :                                  "frr-staticd:staticd", "staticd", args->vrf,
     237             :                                  buf_prefix,
     238             :                                  yang_afi_safi_value2identity(args->afi,
     239             :                                                               args->safi),
     240             :                                  table_id, distance);
     241             : 
     242          25 :                 nb_cli_enqueue_change(vty, xpath_prefix, NB_OP_CREATE, NULL);
     243             : 
     244             :                 /* Tag processing */
     245          25 :                 snprintf(buf_tag, sizeof(buf_tag), "%u", tag);
     246          25 :                 strlcpy(ab_xpath, xpath_prefix, sizeof(ab_xpath));
     247          25 :                 strlcat(ab_xpath, FRR_STATIC_ROUTE_PATH_TAG_XPATH,
     248             :                         sizeof(ab_xpath));
     249          25 :                 nb_cli_enqueue_change(vty, ab_xpath, NB_OP_MODIFY, buf_tag);
     250             : 
     251             :                 /* nexthop processing */
     252             : 
     253          25 :                 snprintf(ab_xpath, sizeof(ab_xpath),
     254             :                          FRR_STATIC_ROUTE_NH_KEY_XPATH, buf_nh_type,
     255             :                          args->nexthop_vrf, buf_gate_str, args->interface_name);
     256          25 :                 strlcpy(xpath_nexthop, xpath_prefix, sizeof(xpath_nexthop));
     257          25 :                 strlcat(xpath_nexthop, ab_xpath, sizeof(xpath_nexthop));
     258          25 :                 nb_cli_enqueue_change(vty, xpath_nexthop, NB_OP_CREATE, NULL);
     259             : 
     260          25 :                 if (type == STATIC_BLACKHOLE) {
     261           0 :                         strlcpy(ab_xpath, xpath_nexthop, sizeof(ab_xpath));
     262           0 :                         strlcat(ab_xpath, FRR_STATIC_ROUTE_NH_BH_XPATH,
     263             :                                 sizeof(ab_xpath));
     264             : 
     265             :                         /* Route flags */
     266           0 :                         if (args->flag) {
     267           0 :                                 switch (args->flag[0]) {
     268             :                                 case 'r':
     269             :                                         bh_type = "reject";
     270             :                                         break;
     271           0 :                                 case 'b':
     272           0 :                                         bh_type = "unspec";
     273           0 :                                         break;
     274           0 :                                 case 'N':
     275           0 :                                         bh_type = "null";
     276           0 :                                         break;
     277           0 :                                 default:
     278           0 :                                         bh_type = NULL;
     279           0 :                                         break;
     280             :                                 }
     281           0 :                                 nb_cli_enqueue_change(vty, ab_xpath,
     282             :                                                       NB_OP_MODIFY, bh_type);
     283             :                         } else {
     284           0 :                                 nb_cli_enqueue_change(vty, ab_xpath,
     285             :                                                       NB_OP_MODIFY, "null");
     286             :                         }
     287             :                 }
     288          25 :                 if (type == STATIC_IPV4_GATEWAY_IFNAME
     289          25 :                     || type == STATIC_IPV6_GATEWAY_IFNAME) {
     290           9 :                         strlcpy(ab_xpath, xpath_nexthop, sizeof(ab_xpath));
     291           9 :                         strlcat(ab_xpath, FRR_STATIC_ROUTE_NH_ONLINK_XPATH,
     292             :                                 sizeof(ab_xpath));
     293             : 
     294           9 :                         if (args->onlink)
     295           0 :                                 nb_cli_enqueue_change(vty, ab_xpath,
     296             :                                                       NB_OP_MODIFY, "true");
     297             :                         else
     298           9 :                                 nb_cli_enqueue_change(vty, ab_xpath,
     299             :                                                       NB_OP_MODIFY, "false");
     300             :                 }
     301          25 :                 if (type == STATIC_IPV4_GATEWAY
     302          25 :                     || type == STATIC_IPV6_GATEWAY
     303             :                     || type == STATIC_IPV4_GATEWAY_IFNAME
     304           9 :                     || type == STATIC_IPV6_GATEWAY_IFNAME) {
     305          25 :                         strlcpy(ab_xpath, xpath_nexthop, sizeof(ab_xpath));
     306          25 :                         strlcat(ab_xpath, FRR_STATIC_ROUTE_NH_COLOR_XPATH,
     307             :                                 sizeof(ab_xpath));
     308          25 :                         if (args->color)
     309           0 :                                 nb_cli_enqueue_change(vty, ab_xpath,
     310             :                                                       NB_OP_MODIFY,
     311             :                                                       args->color);
     312             :                 }
     313          25 :                 if (args->label) {
     314             :                         /* copy of label string (start) */
     315           0 :                         char *ostr;
     316             :                         /* pointer to next segment */
     317           0 :                         char *nump;
     318             : 
     319           0 :                         strlcpy(xpath_mpls, xpath_nexthop, sizeof(xpath_mpls));
     320           0 :                         strlcat(xpath_mpls, FRR_STATIC_ROUTE_NH_LABEL_XPATH,
     321             :                                 sizeof(xpath_mpls));
     322             : 
     323           0 :                         nb_cli_enqueue_change(vty, xpath_mpls, NB_OP_DESTROY,
     324             :                                               NULL);
     325             : 
     326           0 :                         ostr = XSTRDUP(MTYPE_TMP, args->label);
     327           0 :                         while ((nump = strsep(&ostr, "/")) != NULL) {
     328           0 :                                 snprintf(ab_xpath, sizeof(ab_xpath),
     329             :                                          FRR_STATIC_ROUTE_NHLB_KEY_XPATH,
     330             :                                          label_stack_id);
     331           0 :                                 strlcpy(xpath_label, xpath_mpls,
     332             :                                         sizeof(xpath_label));
     333           0 :                                 strlcat(xpath_label, ab_xpath,
     334             :                                         sizeof(xpath_label));
     335           0 :                                 nb_cli_enqueue_change(vty, xpath_label,
     336             :                                                       NB_OP_MODIFY, nump);
     337           0 :                                 label_stack_id++;
     338             :                         }
     339           0 :                         XFREE(MTYPE_TMP, ostr);
     340             :                 } else {
     341          25 :                         strlcpy(xpath_mpls, xpath_nexthop, sizeof(xpath_mpls));
     342          25 :                         strlcat(xpath_mpls, FRR_STATIC_ROUTE_NH_LABEL_XPATH,
     343             :                                 sizeof(xpath_mpls));
     344          25 :                         nb_cli_enqueue_change(vty, xpath_mpls, NB_OP_DESTROY,
     345             :                                               NULL);
     346             :                 }
     347             : 
     348          25 :                 if (args->bfd) {
     349           0 :                         char xpath_bfd[XPATH_MAXLEN];
     350             : 
     351           0 :                         if (args->bfd_source) {
     352           0 :                                 strlcpy(xpath_bfd, xpath_nexthop,
     353             :                                         sizeof(xpath_bfd));
     354           0 :                                 strlcat(xpath_bfd,
     355             :                                         "/frr-staticd:bfd-monitoring/source",
     356             :                                         sizeof(xpath_bfd));
     357           0 :                                 nb_cli_enqueue_change(vty, xpath_bfd,
     358             :                                                       NB_OP_MODIFY,
     359             :                                                       args->bfd_source);
     360             :                         }
     361             : 
     362           0 :                         strlcpy(xpath_bfd, xpath_nexthop, sizeof(xpath_bfd));
     363           0 :                         strlcat(xpath_bfd,
     364             :                                 "/frr-staticd:bfd-monitoring/multi-hop",
     365             :                                 sizeof(xpath_bfd));
     366           0 :                         nb_cli_enqueue_change(vty, xpath_bfd, NB_OP_MODIFY,
     367           0 :                                               args->bfd_multi_hop ? "true"
     368             :                                                                   : "false");
     369             : 
     370           0 :                         if (args->bfd_profile) {
     371           0 :                                 strlcpy(xpath_bfd, xpath_nexthop,
     372             :                                         sizeof(xpath_bfd));
     373           0 :                                 strlcat(xpath_bfd,
     374             :                                         "/frr-staticd:bfd-monitoring/profile",
     375             :                                         sizeof(xpath_bfd));
     376           0 :                                 nb_cli_enqueue_change(vty, xpath_bfd,
     377             :                                                       NB_OP_MODIFY,
     378             :                                                       args->bfd_profile);
     379             :                         }
     380             :                 }
     381             : 
     382          25 :                 ret = nb_cli_apply_changes(vty, "%s", xpath_prefix);
     383             :         } else {
     384           0 :                 if (args->source)
     385           0 :                         snprintf(ab_xpath, sizeof(ab_xpath),
     386             :                                  FRR_DEL_S_ROUTE_SRC_NH_KEY_NO_DISTANCE_XPATH,
     387             :                                  "frr-staticd:staticd", "staticd", args->vrf,
     388             :                                  buf_prefix,
     389             :                                  yang_afi_safi_value2identity(args->afi,
     390             :                                                               args->safi),
     391             :                                  buf_src_prefix, table_id, buf_nh_type,
     392             :                                  args->nexthop_vrf, buf_gate_str,
     393             :                                  args->interface_name);
     394             :                 else
     395           0 :                         snprintf(ab_xpath, sizeof(ab_xpath),
     396             :                                  FRR_DEL_S_ROUTE_NH_KEY_NO_DISTANCE_XPATH,
     397             :                                  "frr-staticd:staticd", "staticd", args->vrf,
     398             :                                  buf_prefix,
     399             :                                  yang_afi_safi_value2identity(args->afi,
     400             :                                                               args->safi),
     401             :                                  table_id, buf_nh_type, args->nexthop_vrf,
     402             :                                  buf_gate_str, args->interface_name);
     403             : 
     404           0 :                 dnode = yang_dnode_get(vty->candidate_config->dnode, ab_xpath);
     405           0 :                 if (!dnode) {
     406           0 :                         vty_out(vty,
     407             :                                 "%% Refusing to remove a non-existent route\n");
     408           0 :                         return CMD_SUCCESS;
     409             :                 }
     410             : 
     411           0 :                 dnode = yang_get_subtree_with_no_sibling(dnode);
     412           0 :                 assert(dnode);
     413           0 :                 yang_dnode_get_path(dnode, ab_xpath, XPATH_MAXLEN);
     414             : 
     415           0 :                 nb_cli_enqueue_change(vty, ab_xpath, NB_OP_DESTROY, NULL);
     416           0 :                 ret = nb_cli_apply_changes(vty, "%s", ab_xpath);
     417             :         }
     418             : 
     419             :         return ret;
     420             : }
     421             : 
     422             : /* Static unicast routes for multicast RPF lookup. */
     423           0 : DEFPY_YANG (ip_mroute_dist,
     424             :        ip_mroute_dist_cmd,
     425             :        "[no] ip mroute A.B.C.D/M$prefix <A.B.C.D$gate|INTERFACE$ifname> [{"
     426             :        "(1-255)$distance"
     427             :        "|bfd$bfd [{multi-hop$bfd_multi_hop|source A.B.C.D$bfd_source|profile BFDPROF$bfd_profile}]"
     428             :        "}]",
     429             :        NO_STR
     430             :        IP_STR
     431             :        "Configure static unicast route into MRIB for multicast RPF lookup\n"
     432             :        "IP destination prefix (e.g. 10.0.0.0/8)\n"
     433             :        "Nexthop address\n"
     434             :        "Nexthop interface name\n"
     435             :        "Distance\n"
     436             :        BFD_INTEGRATION_STR
     437             :        BFD_INTEGRATION_MULTI_HOP_STR
     438             :        BFD_INTEGRATION_SOURCE_STR
     439             :        BFD_INTEGRATION_SOURCEV4_STR
     440             :        BFD_PROFILE_STR
     441             :        BFD_PROFILE_NAME_STR)
     442             : {
     443           0 :         struct static_route_args args = {
     444           0 :                 .delete = !!no,
     445             :                 .afi = AFI_IP,
     446             :                 .safi = SAFI_MULTICAST,
     447             :                 .prefix = prefix_str,
     448             :                 .gateway = gate_str,
     449             :                 .interface_name = ifname,
     450             :                 .distance = distance_str,
     451           0 :                 .bfd = !!bfd,
     452           0 :                 .bfd_multi_hop = !!bfd_multi_hop,
     453             :                 .bfd_source = bfd_source_str,
     454             :                 .bfd_profile = bfd_profile,
     455             :         };
     456             : 
     457           0 :         return static_route_nb_run(vty, &args);
     458             : }
     459             : 
     460             : /* Static route configuration.  */
     461           0 : DEFPY_YANG(ip_route_blackhole,
     462             :       ip_route_blackhole_cmd,
     463             :       "[no] ip route\
     464             :         <A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask>                        \
     465             :         <reject|blackhole>$flag                                               \
     466             :         [{                                                                    \
     467             :           tag (1-4294967295)                                                  \
     468             :           |(1-255)$distance                                                   \
     469             :           |vrf NAME                                                           \
     470             :           |label WORD                                                         \
     471             :           |table (1-4294967295)                                               \
     472             :           }]",
     473             :       NO_STR IP_STR
     474             :       "Establish static routes\n"
     475             :       "IP destination prefix (e.g. 10.0.0.0/8)\n"
     476             :       "IP destination prefix\n"
     477             :       "IP destination prefix mask\n"
     478             :       "Emit an ICMP unreachable when matched\n"
     479             :       "Silently discard pkts when matched\n"
     480             :       "Set tag for this route\n"
     481             :       "Tag value\n"
     482             :       "Distance value for this route\n"
     483             :       VRF_CMD_HELP_STR
     484             :       MPLS_LABEL_HELPSTR
     485             :       "Table to configure\n"
     486             :       "The table number to configure\n")
     487             : {
     488           0 :         struct static_route_args args = {
     489           0 :                 .delete = !!no,
     490             :                 .afi = AFI_IP,
     491             :                 .safi = SAFI_UNICAST,
     492             :                 .prefix = prefix,
     493             :                 .prefix_mask = mask_str,
     494             :                 .flag = flag,
     495             :                 .tag = tag_str,
     496             :                 .distance = distance_str,
     497             :                 .label = label,
     498             :                 .table = table_str,
     499             :                 .vrf = vrf,
     500             :         };
     501             : 
     502           0 :         return static_route_nb_run(vty, &args);
     503             : }
     504             : 
     505           0 : DEFPY_YANG(ip_route_blackhole_vrf,
     506             :       ip_route_blackhole_vrf_cmd,
     507             :       "[no] ip route\
     508             :         <A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask>                        \
     509             :         <reject|blackhole>$flag                                               \
     510             :         [{                                                                    \
     511             :           tag (1-4294967295)                                                  \
     512             :           |(1-255)$distance                                                   \
     513             :           |label WORD                                                         \
     514             :           |table (1-4294967295)                                               \
     515             :           }]",
     516             :       NO_STR IP_STR
     517             :       "Establish static routes\n"
     518             :       "IP destination prefix (e.g. 10.0.0.0/8)\n"
     519             :       "IP destination prefix\n"
     520             :       "IP destination prefix mask\n"
     521             :       "Emit an ICMP unreachable when matched\n"
     522             :       "Silently discard pkts when matched\n"
     523             :       "Set tag for this route\n"
     524             :       "Tag value\n"
     525             :       "Distance value for this route\n"
     526             :       MPLS_LABEL_HELPSTR
     527             :       "Table to configure\n"
     528             :       "The table number to configure\n")
     529             : {
     530           0 :         struct static_route_args args = {
     531           0 :                 .delete = !!no,
     532             :                 .afi = AFI_IP,
     533             :                 .safi = SAFI_UNICAST,
     534             :                 .prefix = prefix,
     535             :                 .prefix_mask = mask_str,
     536             :                 .flag = flag,
     537             :                 .tag = tag_str,
     538             :                 .distance = distance_str,
     539             :                 .label = label,
     540             :                 .table = table_str,
     541             :                 .xpath_vrf = true,
     542             :         };
     543             : 
     544             :         /*
     545             :          * Coverity is complaining that prefix could
     546             :          * be dereferenced, but we know that prefix will
     547             :          * valid.  Add an assert to make it happy
     548             :          */
     549           0 :         assert(args.prefix);
     550             : 
     551           0 :         return static_route_nb_run(vty, &args);
     552             : }
     553             : 
     554           0 : DEFPY_YANG(ip_route_address_interface,
     555             :       ip_route_address_interface_cmd,
     556             :       "[no] ip route\
     557             :         <A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \
     558             :         A.B.C.D$gate                                   \
     559             :         <INTERFACE|Null0>$ifname                       \
     560             :         [{                                             \
     561             :           tag (1-4294967295)                           \
     562             :           |(1-255)$distance                            \
     563             :           |vrf NAME                                    \
     564             :           |label WORD                                  \
     565             :           |table (1-4294967295)                        \
     566             :           |nexthop-vrf NAME                            \
     567             :           |onlink$onlink                               \
     568             :           |color (1-4294967295)                        \
     569             :           |bfd$bfd [{multi-hop$bfd_multi_hop|source A.B.C.D$bfd_source|profile BFDPROF$bfd_profile}] \
     570             :           }]",
     571             :       NO_STR IP_STR
     572             :       "Establish static routes\n"
     573             :       "IP destination prefix (e.g. 10.0.0.0/8)\n"
     574             :       "IP destination prefix\n"
     575             :       "IP destination prefix mask\n"
     576             :       "IP gateway address\n"
     577             :       "IP gateway interface name\n"
     578             :       "Null interface\n"
     579             :       "Set tag for this route\n"
     580             :       "Tag value\n"
     581             :       "Distance value for this route\n"
     582             :       VRF_CMD_HELP_STR
     583             :       MPLS_LABEL_HELPSTR
     584             :       "Table to configure\n"
     585             :       "The table number to configure\n"
     586             :       VRF_CMD_HELP_STR
     587             :       "Treat the nexthop as directly attached to the interface\n"
     588             :       "SR-TE color\n"
     589             :       "The SR-TE color to configure\n"
     590             :       BFD_INTEGRATION_STR
     591             :       BFD_INTEGRATION_MULTI_HOP_STR
     592             :       BFD_INTEGRATION_SOURCE_STR
     593             :       BFD_INTEGRATION_SOURCEV4_STR
     594             :       BFD_PROFILE_STR
     595             :       BFD_PROFILE_NAME_STR)
     596             : {
     597           0 :         struct static_route_args args = {
     598           0 :                 .delete = !!no,
     599             :                 .afi = AFI_IP,
     600             :                 .safi = SAFI_UNICAST,
     601             :                 .prefix = prefix,
     602             :                 .prefix_mask = mask_str,
     603             :                 .gateway = gate_str,
     604             :                 .interface_name = ifname,
     605             :                 .tag = tag_str,
     606             :                 .distance = distance_str,
     607             :                 .label = label,
     608             :                 .table = table_str,
     609             :                 .color = color_str,
     610           0 :                 .onlink = !!onlink,
     611             :                 .vrf = vrf,
     612             :                 .nexthop_vrf = nexthop_vrf,
     613           0 :                 .bfd = !!bfd,
     614           0 :                 .bfd_multi_hop = !!bfd_multi_hop,
     615             :                 .bfd_source = bfd_source_str,
     616             :                 .bfd_profile = bfd_profile,
     617             :         };
     618             : 
     619           0 :         return static_route_nb_run(vty, &args);
     620             : }
     621             : 
     622           0 : DEFPY_YANG(ip_route_address_interface_vrf,
     623             :       ip_route_address_interface_vrf_cmd,
     624             :       "[no] ip route\
     625             :         <A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \
     626             :         A.B.C.D$gate                                   \
     627             :         <INTERFACE|Null0>$ifname                       \
     628             :         [{                                             \
     629             :           tag (1-4294967295)                           \
     630             :           |(1-255)$distance                            \
     631             :           |label WORD                                  \
     632             :           |table (1-4294967295)                        \
     633             :           |nexthop-vrf NAME                            \
     634             :           |onlink$onlink                               \
     635             :           |color (1-4294967295)                        \
     636             :           |bfd$bfd [{multi-hop$bfd_multi_hop|source A.B.C.D$bfd_source|profile BFDPROF$bfd_profile}] \
     637             :           }]",
     638             :       NO_STR IP_STR
     639             :       "Establish static routes\n"
     640             :       "IP destination prefix (e.g. 10.0.0.0/8)\n"
     641             :       "IP destination prefix\n"
     642             :       "IP destination prefix mask\n"
     643             :       "IP gateway address\n"
     644             :       "IP gateway interface name\n"
     645             :       "Null interface\n"
     646             :       "Set tag for this route\n"
     647             :       "Tag value\n"
     648             :       "Distance value for this route\n"
     649             :       MPLS_LABEL_HELPSTR
     650             :       "Table to configure\n"
     651             :       "The table number to configure\n"
     652             :       VRF_CMD_HELP_STR
     653             :       "Treat the nexthop as directly attached to the interface\n"
     654             :       "SR-TE color\n"
     655             :       "The SR-TE color to configure\n"
     656             :       BFD_INTEGRATION_STR
     657             :       BFD_INTEGRATION_MULTI_HOP_STR
     658             :       BFD_INTEGRATION_SOURCE_STR
     659             :       BFD_INTEGRATION_SOURCEV4_STR
     660             :       BFD_PROFILE_STR
     661             :       BFD_PROFILE_NAME_STR)
     662             : {
     663           0 :         struct static_route_args args = {
     664           0 :                 .delete = !!no,
     665             :                 .afi = AFI_IP,
     666             :                 .safi = SAFI_UNICAST,
     667             :                 .prefix = prefix,
     668             :                 .prefix_mask = mask_str,
     669             :                 .gateway = gate_str,
     670             :                 .interface_name = ifname,
     671             :                 .tag = tag_str,
     672             :                 .distance = distance_str,
     673             :                 .label = label,
     674             :                 .table = table_str,
     675             :                 .color = color_str,
     676           0 :                 .onlink = !!onlink,
     677             :                 .xpath_vrf = true,
     678             :                 .nexthop_vrf = nexthop_vrf,
     679           0 :                 .bfd = !!bfd,
     680           0 :                 .bfd_multi_hop = !!bfd_multi_hop,
     681             :                 .bfd_source = bfd_source_str,
     682             :                 .bfd_profile = bfd_profile,
     683             :         };
     684             : 
     685           0 :         return static_route_nb_run(vty, &args);
     686             : }
     687             : 
     688          16 : DEFPY_YANG(ip_route,
     689             :       ip_route_cmd,
     690             :       "[no] ip route\
     691             :         <A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \
     692             :         <A.B.C.D$gate|<INTERFACE|Null0>$ifname>        \
     693             :         [{                                             \
     694             :           tag (1-4294967295)                           \
     695             :           |(1-255)$distance                            \
     696             :           |vrf NAME                                    \
     697             :           |label WORD                                  \
     698             :           |table (1-4294967295)                        \
     699             :           |nexthop-vrf NAME                            \
     700             :           |color (1-4294967295)                        \
     701             :           |bfd$bfd [{multi-hop$bfd_multi_hop|source A.B.C.D$bfd_source|profile BFDPROF$bfd_profile}] \
     702             :           }]",
     703             :       NO_STR IP_STR
     704             :       "Establish static routes\n"
     705             :       "IP destination prefix (e.g. 10.0.0.0/8)\n"
     706             :       "IP destination prefix\n"
     707             :       "IP destination prefix mask\n"
     708             :       "IP gateway address\n"
     709             :       "IP gateway interface name\n"
     710             :       "Null interface\n"
     711             :       "Set tag for this route\n"
     712             :       "Tag value\n"
     713             :       "Distance value for this route\n"
     714             :       VRF_CMD_HELP_STR
     715             :       MPLS_LABEL_HELPSTR
     716             :       "Table to configure\n"
     717             :       "The table number to configure\n"
     718             :       VRF_CMD_HELP_STR
     719             :       "SR-TE color\n"
     720             :       "The SR-TE color to configure\n"
     721             :       BFD_INTEGRATION_STR
     722             :       BFD_INTEGRATION_MULTI_HOP_STR
     723             :       BFD_INTEGRATION_SOURCE_STR
     724             :       BFD_INTEGRATION_SOURCEV4_STR
     725             :       BFD_PROFILE_STR
     726             :       BFD_PROFILE_NAME_STR)
     727             : {
     728          16 :         struct static_route_args args = {
     729          16 :                 .delete = !!no,
     730             :                 .afi = AFI_IP,
     731             :                 .safi = SAFI_UNICAST,
     732             :                 .prefix = prefix,
     733             :                 .prefix_mask = mask_str,
     734             :                 .gateway = gate_str,
     735             :                 .interface_name = ifname,
     736             :                 .tag = tag_str,
     737             :                 .distance = distance_str,
     738             :                 .label = label,
     739             :                 .table = table_str,
     740             :                 .color = color_str,
     741             :                 .vrf = vrf,
     742             :                 .nexthop_vrf = nexthop_vrf,
     743          16 :                 .bfd = !!bfd,
     744          16 :                 .bfd_multi_hop = !!bfd_multi_hop,
     745             :                 .bfd_source = bfd_source_str,
     746             :                 .bfd_profile = bfd_profile,
     747             :         };
     748             : 
     749          16 :         return static_route_nb_run(vty, &args);
     750             : }
     751             : 
     752           0 : DEFPY_YANG(ip_route_vrf,
     753             :       ip_route_vrf_cmd,
     754             :       "[no] ip route\
     755             :         <A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \
     756             :         <A.B.C.D$gate|<INTERFACE|Null0>$ifname>        \
     757             :         [{                                             \
     758             :           tag (1-4294967295)                           \
     759             :           |(1-255)$distance                            \
     760             :           |label WORD                                  \
     761             :           |table (1-4294967295)                        \
     762             :           |nexthop-vrf NAME                            \
     763             :           |color (1-4294967295)                        \
     764             :           |bfd$bfd [{multi-hop$bfd_multi_hop|source A.B.C.D$bfd_source|profile BFDPROF$bfd_profile}] \
     765             :           }]",
     766             :       NO_STR IP_STR
     767             :       "Establish static routes\n"
     768             :       "IP destination prefix (e.g. 10.0.0.0/8)\n"
     769             :       "IP destination prefix\n"
     770             :       "IP destination prefix mask\n"
     771             :       "IP gateway address\n"
     772             :       "IP gateway interface name\n"
     773             :       "Null interface\n"
     774             :       "Set tag for this route\n"
     775             :       "Tag value\n"
     776             :       "Distance value for this route\n"
     777             :       MPLS_LABEL_HELPSTR
     778             :       "Table to configure\n"
     779             :       "The table number to configure\n"
     780             :       VRF_CMD_HELP_STR
     781             :       "SR-TE color\n"
     782             :       "The SR-TE color to configure\n"
     783             :       BFD_INTEGRATION_STR
     784             :       BFD_INTEGRATION_MULTI_HOP_STR
     785             :       BFD_INTEGRATION_SOURCE_STR
     786             :       BFD_INTEGRATION_SOURCEV4_STR
     787             :       BFD_PROFILE_STR
     788             :       BFD_PROFILE_NAME_STR)
     789             : {
     790           0 :         struct static_route_args args = {
     791           0 :                 .delete = !!no,
     792             :                 .afi = AFI_IP,
     793             :                 .safi = SAFI_UNICAST,
     794             :                 .prefix = prefix,
     795             :                 .prefix_mask = mask_str,
     796             :                 .gateway = gate_str,
     797             :                 .interface_name = ifname,
     798             :                 .tag = tag_str,
     799             :                 .distance = distance_str,
     800             :                 .label = label,
     801             :                 .table = table_str,
     802             :                 .color = color_str,
     803             :                 .xpath_vrf = true,
     804             :                 .nexthop_vrf = nexthop_vrf,
     805           0 :                 .bfd = !!bfd,
     806           0 :                 .bfd_multi_hop = !!bfd_multi_hop,
     807             :                 .bfd_source = bfd_source_str,
     808             :                 .bfd_profile = bfd_profile,
     809             :         };
     810             : 
     811           0 :         return static_route_nb_run(vty, &args);
     812             : }
     813             : 
     814           0 : DEFPY_YANG(ipv6_route_blackhole,
     815             :       ipv6_route_blackhole_cmd,
     816             :       "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \
     817             :           <reject|blackhole>$flag                          \
     818             :           [{                                               \
     819             :             tag (1-4294967295)                             \
     820             :             |(1-255)$distance                              \
     821             :             |vrf NAME                                      \
     822             :             |label WORD                                    \
     823             :             |table (1-4294967295)                          \
     824             :           }]",
     825             :       NO_STR
     826             :       IPV6_STR
     827             :       "Establish static routes\n"
     828             :       "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
     829             :       "IPv6 source-dest route\n"
     830             :       "IPv6 source prefix\n"
     831             :       "Emit an ICMP unreachable when matched\n"
     832             :       "Silently discard pkts when matched\n"
     833             :       "Set tag for this route\n"
     834             :       "Tag value\n"
     835             :       "Distance value for this prefix\n"
     836             :       VRF_CMD_HELP_STR
     837             :       MPLS_LABEL_HELPSTR
     838             :       "Table to configure\n"
     839             :       "The table number to configure\n")
     840             : {
     841           0 :         struct static_route_args args = {
     842           0 :                 .delete = !!no,
     843             :                 .afi = AFI_IP6,
     844             :                 .safi = SAFI_UNICAST,
     845             :                 .prefix = prefix_str,
     846             :                 .source = from_str,
     847             :                 .flag = flag,
     848             :                 .tag = tag_str,
     849             :                 .distance = distance_str,
     850             :                 .label = label,
     851             :                 .table = table_str,
     852             :                 .vrf = vrf,
     853             :         };
     854             : 
     855           0 :         return static_route_nb_run(vty, &args);
     856             : }
     857             : 
     858           0 : DEFPY_YANG(ipv6_route_blackhole_vrf,
     859             :       ipv6_route_blackhole_vrf_cmd,
     860             :       "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \
     861             :           <reject|blackhole>$flag                          \
     862             :           [{                                               \
     863             :             tag (1-4294967295)                             \
     864             :             |(1-255)$distance                              \
     865             :             |label WORD                                    \
     866             :             |table (1-4294967295)                          \
     867             :           }]",
     868             :       NO_STR
     869             :       IPV6_STR
     870             :       "Establish static routes\n"
     871             :       "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
     872             :       "IPv6 source-dest route\n"
     873             :       "IPv6 source prefix\n"
     874             :       "Emit an ICMP unreachable when matched\n"
     875             :       "Silently discard pkts when matched\n"
     876             :       "Set tag for this route\n"
     877             :       "Tag value\n"
     878             :       "Distance value for this prefix\n"
     879             :       MPLS_LABEL_HELPSTR
     880             :       "Table to configure\n"
     881             :       "The table number to configure\n")
     882             : {
     883           0 :         struct static_route_args args = {
     884           0 :                 .delete = !!no,
     885             :                 .afi = AFI_IP6,
     886             :                 .safi = SAFI_UNICAST,
     887             :                 .prefix = prefix_str,
     888             :                 .source = from_str,
     889             :                 .flag = flag,
     890             :                 .tag = tag_str,
     891             :                 .distance = distance_str,
     892             :                 .label = label,
     893             :                 .table = table_str,
     894             :                 .xpath_vrf = true,
     895             :         };
     896             : 
     897             :         /*
     898             :          * Coverity is complaining that prefix could
     899             :          * be dereferenced, but we know that prefix will
     900             :          * valid.  Add an assert to make it happy
     901             :          */
     902           0 :         assert(args.prefix);
     903             : 
     904           0 :         return static_route_nb_run(vty, &args);
     905             : }
     906             : 
     907           9 : DEFPY_YANG(ipv6_route_address_interface,
     908             :       ipv6_route_address_interface_cmd,
     909             :       "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \
     910             :           X:X::X:X$gate                                    \
     911             :           <INTERFACE|Null0>$ifname                         \
     912             :           [{                                               \
     913             :             tag (1-4294967295)                             \
     914             :             |(1-255)$distance                              \
     915             :             |vrf NAME                                      \
     916             :             |label WORD                                    \
     917             :             |table (1-4294967295)                          \
     918             :             |nexthop-vrf NAME                              \
     919             :             |onlink$onlink                                 \
     920             :             |color (1-4294967295)                          \
     921             :             |bfd$bfd [{multi-hop$bfd_multi_hop|source X:X::X:X$bfd_source|profile BFDPROF$bfd_profile}] \
     922             :           }]",
     923             :       NO_STR
     924             :       IPV6_STR
     925             :       "Establish static routes\n"
     926             :       "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
     927             :       "IPv6 source-dest route\n"
     928             :       "IPv6 source prefix\n"
     929             :       "IPv6 gateway address\n"
     930             :       "IPv6 gateway interface name\n"
     931             :       "Null interface\n"
     932             :       "Set tag for this route\n"
     933             :       "Tag value\n"
     934             :       "Distance value for this prefix\n"
     935             :       VRF_CMD_HELP_STR
     936             :       MPLS_LABEL_HELPSTR
     937             :       "Table to configure\n"
     938             :       "The table number to configure\n"
     939             :       VRF_CMD_HELP_STR
     940             :       "Treat the nexthop as directly attached to the interface\n"
     941             :       "SR-TE color\n"
     942             :       "The SR-TE color to configure\n"
     943             :       BFD_INTEGRATION_STR
     944             :       BFD_INTEGRATION_MULTI_HOP_STR
     945             :       BFD_INTEGRATION_SOURCE_STR
     946             :       BFD_INTEGRATION_SOURCEV4_STR
     947             :       BFD_PROFILE_STR
     948             :       BFD_PROFILE_NAME_STR)
     949             : {
     950           9 :         struct static_route_args args = {
     951           9 :                 .delete = !!no,
     952             :                 .afi = AFI_IP6,
     953             :                 .safi = SAFI_UNICAST,
     954             :                 .prefix = prefix_str,
     955             :                 .source = from_str,
     956             :                 .gateway = gate_str,
     957             :                 .interface_name = ifname,
     958             :                 .tag = tag_str,
     959             :                 .distance = distance_str,
     960             :                 .label = label,
     961             :                 .table = table_str,
     962             :                 .color = color_str,
     963           9 :                 .onlink = !!onlink,
     964             :                 .vrf = vrf,
     965             :                 .nexthop_vrf = nexthop_vrf,
     966           9 :                 .bfd = !!bfd,
     967           9 :                 .bfd_multi_hop = !!bfd_multi_hop,
     968             :                 .bfd_source = bfd_source_str,
     969             :                 .bfd_profile = bfd_profile,
     970             :         };
     971             : 
     972           9 :         return static_route_nb_run(vty, &args);
     973             : }
     974             : 
     975           0 : DEFPY_YANG(ipv6_route_address_interface_vrf,
     976             :       ipv6_route_address_interface_vrf_cmd,
     977             :       "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \
     978             :           X:X::X:X$gate                                    \
     979             :           <INTERFACE|Null0>$ifname                         \
     980             :           [{                                               \
     981             :             tag (1-4294967295)                             \
     982             :             |(1-255)$distance                              \
     983             :             |label WORD                                    \
     984             :             |table (1-4294967295)                          \
     985             :             |nexthop-vrf NAME                              \
     986             :             |onlink$onlink                                 \
     987             :             |color (1-4294967295)                          \
     988             :             |bfd$bfd [{multi-hop$bfd_multi_hop|source X:X::X:X$bfd_source|profile BFDPROF$bfd_profile}] \
     989             :           }]",
     990             :       NO_STR
     991             :       IPV6_STR
     992             :       "Establish static routes\n"
     993             :       "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
     994             :       "IPv6 source-dest route\n"
     995             :       "IPv6 source prefix\n"
     996             :       "IPv6 gateway address\n"
     997             :       "IPv6 gateway interface name\n"
     998             :       "Null interface\n"
     999             :       "Set tag for this route\n"
    1000             :       "Tag value\n"
    1001             :       "Distance value for this prefix\n"
    1002             :       MPLS_LABEL_HELPSTR
    1003             :       "Table to configure\n"
    1004             :       "The table number to configure\n"
    1005             :       VRF_CMD_HELP_STR
    1006             :       "Treat the nexthop as directly attached to the interface\n"
    1007             :       "SR-TE color\n"
    1008             :       "The SR-TE color to configure\n"
    1009             :       BFD_INTEGRATION_STR
    1010             :       BFD_INTEGRATION_MULTI_HOP_STR
    1011             :       BFD_INTEGRATION_SOURCE_STR
    1012             :       BFD_INTEGRATION_SOURCEV4_STR
    1013             :       BFD_PROFILE_STR
    1014             :       BFD_PROFILE_NAME_STR)
    1015             : {
    1016           0 :         struct static_route_args args = {
    1017           0 :                 .delete = !!no,
    1018             :                 .afi = AFI_IP6,
    1019             :                 .safi = SAFI_UNICAST,
    1020             :                 .prefix = prefix_str,
    1021             :                 .source = from_str,
    1022             :                 .gateway = gate_str,
    1023             :                 .interface_name = ifname,
    1024             :                 .tag = tag_str,
    1025             :                 .distance = distance_str,
    1026             :                 .label = label,
    1027             :                 .table = table_str,
    1028             :                 .color = color_str,
    1029           0 :                 .onlink = !!onlink,
    1030             :                 .xpath_vrf = true,
    1031             :                 .nexthop_vrf = nexthop_vrf,
    1032           0 :                 .bfd = !!bfd,
    1033           0 :                 .bfd_multi_hop = !!bfd_multi_hop,
    1034             :                 .bfd_source = bfd_source_str,
    1035             :                 .bfd_profile = bfd_profile,
    1036             :         };
    1037             : 
    1038           0 :         return static_route_nb_run(vty, &args);
    1039             : }
    1040             : 
    1041           0 : DEFPY_YANG(ipv6_route,
    1042             :       ipv6_route_cmd,
    1043             :       "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \
    1044             :           <X:X::X:X$gate|<INTERFACE|Null0>$ifname>         \
    1045             :           [{                                               \
    1046             :             tag (1-4294967295)                             \
    1047             :             |(1-255)$distance                              \
    1048             :             |vrf NAME                                      \
    1049             :             |label WORD                                    \
    1050             :             |table (1-4294967295)                          \
    1051             :             |nexthop-vrf NAME                              \
    1052             :             |color (1-4294967295)                          \
    1053             :             |bfd$bfd [{multi-hop$bfd_multi_hop|source X:X::X:X$bfd_source|profile BFDPROF$bfd_profile}] \
    1054             :           }]",
    1055             :       NO_STR
    1056             :       IPV6_STR
    1057             :       "Establish static routes\n"
    1058             :       "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
    1059             :       "IPv6 source-dest route\n"
    1060             :       "IPv6 source prefix\n"
    1061             :       "IPv6 gateway address\n"
    1062             :       "IPv6 gateway interface name\n"
    1063             :       "Null interface\n"
    1064             :       "Set tag for this route\n"
    1065             :       "Tag value\n"
    1066             :       "Distance value for this prefix\n"
    1067             :       VRF_CMD_HELP_STR
    1068             :       MPLS_LABEL_HELPSTR
    1069             :       "Table to configure\n"
    1070             :       "The table number to configure\n"
    1071             :       VRF_CMD_HELP_STR
    1072             :       "SR-TE color\n"
    1073             :       "The SR-TE color to configure\n"
    1074             :       BFD_INTEGRATION_STR
    1075             :       BFD_INTEGRATION_MULTI_HOP_STR
    1076             :       BFD_INTEGRATION_SOURCE_STR
    1077             :       BFD_INTEGRATION_SOURCEV4_STR
    1078             :       BFD_PROFILE_STR
    1079             :       BFD_PROFILE_NAME_STR)
    1080             : {
    1081           0 :         struct static_route_args args = {
    1082           0 :                 .delete = !!no,
    1083             :                 .afi = AFI_IP6,
    1084             :                 .safi = SAFI_UNICAST,
    1085             :                 .prefix = prefix_str,
    1086             :                 .source = from_str,
    1087             :                 .gateway = gate_str,
    1088             :                 .interface_name = ifname,
    1089             :                 .tag = tag_str,
    1090             :                 .distance = distance_str,
    1091             :                 .label = label,
    1092             :                 .table = table_str,
    1093             :                 .color = color_str,
    1094             :                 .vrf = vrf,
    1095             :                 .nexthop_vrf = nexthop_vrf,
    1096           0 :                 .bfd = !!bfd,
    1097           0 :                 .bfd_multi_hop = !!bfd_multi_hop,
    1098             :                 .bfd_source = bfd_source_str,
    1099             :                 .bfd_profile = bfd_profile,
    1100             :         };
    1101             : 
    1102           0 :         return static_route_nb_run(vty, &args);
    1103             : }
    1104             : 
    1105           0 : DEFPY_YANG(ipv6_route_vrf,
    1106             :       ipv6_route_vrf_cmd,
    1107             :       "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \
    1108             :           <X:X::X:X$gate|<INTERFACE|Null0>$ifname>                 \
    1109             :           [{                                               \
    1110             :             tag (1-4294967295)                             \
    1111             :             |(1-255)$distance                              \
    1112             :             |label WORD                                    \
    1113             :             |table (1-4294967295)                          \
    1114             :             |nexthop-vrf NAME                              \
    1115             :             |color (1-4294967295)                          \
    1116             :             |bfd$bfd [{multi-hop$bfd_multi_hop|source X:X::X:X$bfd_source|profile BFDPROF$bfd_profile}] \
    1117             :           }]",
    1118             :       NO_STR
    1119             :       IPV6_STR
    1120             :       "Establish static routes\n"
    1121             :       "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
    1122             :       "IPv6 source-dest route\n"
    1123             :       "IPv6 source prefix\n"
    1124             :       "IPv6 gateway address\n"
    1125             :       "IPv6 gateway interface name\n"
    1126             :       "Null interface\n"
    1127             :       "Set tag for this route\n"
    1128             :       "Tag value\n"
    1129             :       "Distance value for this prefix\n"
    1130             :       MPLS_LABEL_HELPSTR
    1131             :       "Table to configure\n"
    1132             :       "The table number to configure\n"
    1133             :       VRF_CMD_HELP_STR
    1134             :       "SR-TE color\n"
    1135             :       "The SR-TE color to configure\n"
    1136             :       BFD_INTEGRATION_STR
    1137             :       BFD_INTEGRATION_MULTI_HOP_STR
    1138             :       BFD_INTEGRATION_SOURCE_STR
    1139             :       BFD_INTEGRATION_SOURCEV4_STR
    1140             :       BFD_PROFILE_STR
    1141             :       BFD_PROFILE_NAME_STR)
    1142             : {
    1143           0 :         struct static_route_args args = {
    1144           0 :                 .delete = !!no,
    1145             :                 .afi = AFI_IP6,
    1146             :                 .safi = SAFI_UNICAST,
    1147             :                 .prefix = prefix_str,
    1148             :                 .source = from_str,
    1149             :                 .gateway = gate_str,
    1150             :                 .interface_name = ifname,
    1151             :                 .tag = tag_str,
    1152             :                 .distance = distance_str,
    1153             :                 .label = label,
    1154             :                 .table = table_str,
    1155             :                 .color = color_str,
    1156             :                 .xpath_vrf = true,
    1157             :                 .nexthop_vrf = nexthop_vrf,
    1158           0 :                 .bfd = !!bfd,
    1159           0 :                 .bfd_multi_hop = !!bfd_multi_hop,
    1160             :                 .bfd_source = bfd_source_str,
    1161             :                 .bfd_profile = bfd_profile,
    1162             :         };
    1163             : 
    1164           0 :         return static_route_nb_run(vty, &args);
    1165             : }
    1166             : 
    1167           0 : void static_cli_show(struct vty *vty, const struct lyd_node *dnode,
    1168             :                      bool show_defaults)
    1169             : {
    1170           0 :         const char *vrf;
    1171             : 
    1172           0 :         vrf = yang_dnode_get_string(dnode, "../vrf");
    1173           0 :         if (strcmp(vrf, VRF_DEFAULT_NAME))
    1174           0 :                 vty_out(vty, "vrf %s\n", vrf);
    1175           0 : }
    1176             : 
    1177           0 : void static_cli_show_end(struct vty *vty, const struct lyd_node *dnode)
    1178             : {
    1179           0 :         const char *vrf;
    1180             : 
    1181           0 :         vrf = yang_dnode_get_string(dnode, "../vrf");
    1182           0 :         if (strcmp(vrf, VRF_DEFAULT_NAME))
    1183           0 :                 vty_out(vty, "exit-vrf\n");
    1184           0 : }
    1185             : 
    1186             : struct mpls_label_iter {
    1187             :         struct vty *vty;
    1188             :         bool first;
    1189             : };
    1190             : 
    1191           0 : static int mpls_label_iter_cb(const struct lyd_node *dnode, void *arg)
    1192             : {
    1193           0 :         struct mpls_label_iter *iter = arg;
    1194             : 
    1195           0 :         if (yang_dnode_exists(dnode, "./label")) {
    1196           0 :                 if (iter->first)
    1197           0 :                         vty_out(iter->vty, " label %s",
    1198             :                                 yang_dnode_get_string(dnode, "./label"));
    1199             :                 else
    1200           0 :                         vty_out(iter->vty, "/%s",
    1201             :                                 yang_dnode_get_string(dnode, "./label"));
    1202           0 :                 iter->first = false;
    1203             :         }
    1204             : 
    1205           0 :         return YANG_ITER_CONTINUE;
    1206             : }
    1207             : 
    1208           0 : static void nexthop_cli_show(struct vty *vty, const struct lyd_node *route,
    1209             :                              const struct lyd_node *src,
    1210             :                              const struct lyd_node *path,
    1211             :                              const struct lyd_node *nexthop, bool show_defaults)
    1212             : {
    1213           0 :         const char *vrf;
    1214           0 :         const char *afi_safi;
    1215           0 :         afi_t afi;
    1216           0 :         safi_t safi;
    1217           0 :         enum static_nh_type nh_type;
    1218           0 :         enum static_blackhole_type bh_type;
    1219           0 :         uint32_t tag;
    1220           0 :         uint8_t distance;
    1221           0 :         struct mpls_label_iter iter;
    1222           0 :         const char *nexthop_vrf;
    1223           0 :         uint32_t table_id;
    1224           0 :         bool onlink;
    1225             : 
    1226           0 :         vrf = yang_dnode_get_string(route, "../../vrf");
    1227             : 
    1228           0 :         afi_safi = yang_dnode_get_string(route, "./afi-safi");
    1229           0 :         yang_afi_safi_identity2value(afi_safi, &afi, &safi);
    1230             : 
    1231           0 :         if (afi == AFI_IP)
    1232           0 :                 vty_out(vty, "%sip",
    1233           0 :                         strmatch(vrf, VRF_DEFAULT_NAME) ? "" : " ");
    1234             :         else
    1235           0 :                 vty_out(vty, "%sipv6",
    1236           0 :                         strmatch(vrf, VRF_DEFAULT_NAME) ? "" : " ");
    1237             : 
    1238           0 :         if (safi == SAFI_UNICAST)
    1239           0 :                 vty_out(vty, " route");
    1240             :         else
    1241           0 :                 vty_out(vty, " mroute");
    1242             : 
    1243           0 :         vty_out(vty, " %s", yang_dnode_get_string(route, "./prefix"));
    1244             : 
    1245           0 :         if (src)
    1246           0 :                 vty_out(vty, " from %s",
    1247             :                         yang_dnode_get_string(src, "./src-prefix"));
    1248             : 
    1249           0 :         nh_type = yang_dnode_get_enum(nexthop, "./nh-type");
    1250           0 :         switch (nh_type) {
    1251           0 :         case STATIC_IFNAME:
    1252           0 :                 vty_out(vty, " %s",
    1253             :                         yang_dnode_get_string(nexthop, "./interface"));
    1254           0 :                 break;
    1255           0 :         case STATIC_IPV4_GATEWAY:
    1256             :         case STATIC_IPV6_GATEWAY:
    1257           0 :                 vty_out(vty, " %s",
    1258             :                         yang_dnode_get_string(nexthop, "./gateway"));
    1259           0 :                 break;
    1260           0 :         case STATIC_IPV4_GATEWAY_IFNAME:
    1261             :         case STATIC_IPV6_GATEWAY_IFNAME:
    1262           0 :                 vty_out(vty, " %s",
    1263             :                         yang_dnode_get_string(nexthop, "./gateway"));
    1264           0 :                 vty_out(vty, " %s",
    1265             :                         yang_dnode_get_string(nexthop, "./interface"));
    1266           0 :                 break;
    1267           0 :         case STATIC_BLACKHOLE:
    1268           0 :                 bh_type = yang_dnode_get_enum(nexthop, "./bh-type");
    1269           0 :                 switch (bh_type) {
    1270           0 :                 case STATIC_BLACKHOLE_DROP:
    1271           0 :                         vty_out(vty, " blackhole");
    1272           0 :                         break;
    1273           0 :                 case STATIC_BLACKHOLE_NULL:
    1274           0 :                         vty_out(vty, " Null0");
    1275           0 :                         break;
    1276           0 :                 case STATIC_BLACKHOLE_REJECT:
    1277           0 :                         vty_out(vty, " reject");
    1278           0 :                         break;
    1279             :                 }
    1280             :                 break;
    1281             :         }
    1282             : 
    1283           0 :         if (yang_dnode_exists(path, "./tag")) {
    1284           0 :                 tag = yang_dnode_get_uint32(path, "./tag");
    1285           0 :                 if (tag != 0 || show_defaults)
    1286           0 :                         vty_out(vty, " tag %" PRIu32, tag);
    1287             :         }
    1288             : 
    1289           0 :         distance = yang_dnode_get_uint8(path, "./distance");
    1290           0 :         if (distance != ZEBRA_STATIC_DISTANCE_DEFAULT || show_defaults)
    1291           0 :                 vty_out(vty, " %" PRIu8, distance);
    1292             : 
    1293           0 :         iter.vty = vty;
    1294           0 :         iter.first = true;
    1295           0 :         yang_dnode_iterate(mpls_label_iter_cb, &iter, nexthop,
    1296             :                            "./mpls-label-stack/entry");
    1297             : 
    1298           0 :         nexthop_vrf = yang_dnode_get_string(nexthop, "./vrf");
    1299           0 :         if (strcmp(vrf, nexthop_vrf))
    1300           0 :                 vty_out(vty, " nexthop-vrf %s", nexthop_vrf);
    1301             : 
    1302           0 :         table_id = yang_dnode_get_uint32(path, "./table-id");
    1303           0 :         if (table_id || show_defaults)
    1304           0 :                 vty_out(vty, " table %" PRIu32, table_id);
    1305             : 
    1306           0 :         if (yang_dnode_exists(nexthop, "./onlink")) {
    1307           0 :                 onlink = yang_dnode_get_bool(nexthop, "./onlink");
    1308           0 :                 if (onlink)
    1309           0 :                         vty_out(vty, " onlink");
    1310             :         }
    1311             : 
    1312           0 :         if (yang_dnode_exists(nexthop, "./srte-color"))
    1313           0 :                 vty_out(vty, " color %s",
    1314             :                         yang_dnode_get_string(nexthop, "./srte-color"));
    1315             : 
    1316           0 :         if (yang_dnode_exists(nexthop, "./bfd-monitoring")) {
    1317           0 :                 const struct lyd_node *bfd_dnode =
    1318           0 :                         yang_dnode_get(nexthop, "./bfd-monitoring");
    1319             : 
    1320           0 :                 if (yang_dnode_get_bool(bfd_dnode, "./multi-hop")) {
    1321           0 :                         vty_out(vty, " bfd multi-hop");
    1322             : 
    1323           0 :                         if (yang_dnode_exists(bfd_dnode, "./source"))
    1324           0 :                                 vty_out(vty, " source %s",
    1325             :                                         yang_dnode_get_string(bfd_dnode,
    1326             :                                                               "./source"));
    1327             :                 } else
    1328           0 :                         vty_out(vty, " bfd");
    1329             : 
    1330           0 :                 if (yang_dnode_exists(bfd_dnode, "./profile"))
    1331           0 :                         vty_out(vty, " profile %s",
    1332             :                                 yang_dnode_get_string(bfd_dnode, "./profile"));
    1333             :         }
    1334             : 
    1335           0 :         vty_out(vty, "\n");
    1336           0 : }
    1337             : 
    1338           0 : void static_nexthop_cli_show(struct vty *vty, const struct lyd_node *dnode,
    1339             :                              bool show_defaults)
    1340             : {
    1341           0 :         const struct lyd_node *path = yang_dnode_get_parent(dnode, "path-list");
    1342           0 :         const struct lyd_node *route =
    1343           0 :                 yang_dnode_get_parent(path, "route-list");
    1344             : 
    1345           0 :         nexthop_cli_show(vty, route, NULL, path, dnode, show_defaults);
    1346           0 : }
    1347             : 
    1348           0 : void static_src_nexthop_cli_show(struct vty *vty, const struct lyd_node *dnode,
    1349             :                                  bool show_defaults)
    1350             : {
    1351           0 :         const struct lyd_node *path = yang_dnode_get_parent(dnode, "path-list");
    1352           0 :         const struct lyd_node *src = yang_dnode_get_parent(path, "src-list");
    1353           0 :         const struct lyd_node *route = yang_dnode_get_parent(src, "route-list");
    1354             : 
    1355           0 :         nexthop_cli_show(vty, route, src, path, dnode, show_defaults);
    1356           0 : }
    1357             : 
    1358           0 : int static_nexthop_cli_cmp(const struct lyd_node *dnode1,
    1359             :                            const struct lyd_node *dnode2)
    1360             : {
    1361           0 :         enum static_nh_type nh_type1, nh_type2;
    1362           0 :         struct prefix prefix1, prefix2;
    1363           0 :         int ret = 0;
    1364             : 
    1365           0 :         nh_type1 = yang_dnode_get_enum(dnode1, "./nh-type");
    1366           0 :         nh_type2 = yang_dnode_get_enum(dnode2, "./nh-type");
    1367             : 
    1368           0 :         if (nh_type1 != nh_type2)
    1369           0 :                 return (int)nh_type1 - (int)nh_type2;
    1370             : 
    1371           0 :         switch (nh_type1) {
    1372           0 :         case STATIC_IFNAME:
    1373           0 :                 ret = if_cmp_name_func(
    1374             :                         yang_dnode_get_string(dnode1, "./interface"),
    1375             :                         yang_dnode_get_string(dnode2, "./interface"));
    1376           0 :                 break;
    1377           0 :         case STATIC_IPV4_GATEWAY:
    1378             :         case STATIC_IPV6_GATEWAY:
    1379           0 :                 yang_dnode_get_prefix(&prefix1, dnode1, "./gateway");
    1380           0 :                 yang_dnode_get_prefix(&prefix2, dnode2, "./gateway");
    1381           0 :                 ret = prefix_cmp(&prefix1, &prefix2);
    1382           0 :                 break;
    1383           0 :         case STATIC_IPV4_GATEWAY_IFNAME:
    1384             :         case STATIC_IPV6_GATEWAY_IFNAME:
    1385           0 :                 yang_dnode_get_prefix(&prefix1, dnode1, "./gateway");
    1386           0 :                 yang_dnode_get_prefix(&prefix2, dnode2, "./gateway");
    1387           0 :                 ret = prefix_cmp(&prefix1, &prefix2);
    1388           0 :                 if (!ret)
    1389           0 :                         ret = if_cmp_name_func(
    1390             :                                 yang_dnode_get_string(dnode1, "./interface"),
    1391             :                                 yang_dnode_get_string(dnode2, "./interface"));
    1392             :                 break;
    1393             :         case STATIC_BLACKHOLE:
    1394             :                 /* There's only one blackhole nexthop per route */
    1395             :                 ret = 0;
    1396             :                 break;
    1397             :         }
    1398             : 
    1399           0 :         if (ret)
    1400           0 :                 return ret;
    1401             : 
    1402           0 :         return if_cmp_name_func(yang_dnode_get_string(dnode1, "./vrf"),
    1403             :                                 yang_dnode_get_string(dnode2, "./vrf"));
    1404             : }
    1405             : 
    1406           0 : int static_route_list_cli_cmp(const struct lyd_node *dnode1,
    1407             :                               const struct lyd_node *dnode2)
    1408             : {
    1409           0 :         const char *afi_safi1, *afi_safi2;
    1410           0 :         afi_t afi1, afi2;
    1411           0 :         safi_t safi1, safi2;
    1412           0 :         struct prefix prefix1, prefix2;
    1413             : 
    1414           0 :         afi_safi1 = yang_dnode_get_string(dnode1, "./afi-safi");
    1415           0 :         yang_afi_safi_identity2value(afi_safi1, &afi1, &safi1);
    1416             : 
    1417           0 :         afi_safi2 = yang_dnode_get_string(dnode2, "./afi-safi");
    1418           0 :         yang_afi_safi_identity2value(afi_safi2, &afi2, &safi2);
    1419             : 
    1420           0 :         if (afi1 != afi2)
    1421           0 :                 return (int)afi1 - (int)afi2;
    1422             : 
    1423           0 :         if (safi1 != safi2)
    1424           0 :                 return (int)safi1 - (int)safi2;
    1425             : 
    1426           0 :         yang_dnode_get_prefix(&prefix1, dnode1, "./prefix");
    1427           0 :         yang_dnode_get_prefix(&prefix2, dnode2, "./prefix");
    1428             : 
    1429           0 :         return prefix_cmp(&prefix1, &prefix2);
    1430             : }
    1431             : 
    1432           0 : int static_src_list_cli_cmp(const struct lyd_node *dnode1,
    1433             :                             const struct lyd_node *dnode2)
    1434             : {
    1435           0 :         struct prefix prefix1, prefix2;
    1436             : 
    1437           0 :         yang_dnode_get_prefix(&prefix1, dnode1, "./src-prefix");
    1438           0 :         yang_dnode_get_prefix(&prefix2, dnode2, "./src-prefix");
    1439             : 
    1440           0 :         return prefix_cmp(&prefix1, &prefix2);
    1441             : }
    1442             : 
    1443           0 : int static_path_list_cli_cmp(const struct lyd_node *dnode1,
    1444             :                              const struct lyd_node *dnode2)
    1445             : {
    1446           0 :         uint32_t table_id1, table_id2;
    1447           0 :         uint8_t distance1, distance2;
    1448             : 
    1449           0 :         table_id1 = yang_dnode_get_uint32(dnode1, "./table-id");
    1450           0 :         table_id2 = yang_dnode_get_uint32(dnode2, "./table-id");
    1451             : 
    1452           0 :         if (table_id1 != table_id2)
    1453           0 :                 return (int)table_id1 - (int)table_id2;
    1454             : 
    1455           0 :         distance1 = yang_dnode_get_uint8(dnode1, "./distance");
    1456           0 :         distance2 = yang_dnode_get_uint8(dnode2, "./distance");
    1457             : 
    1458           0 :         return (int)distance1 - (int)distance2;
    1459             : }
    1460             : 
    1461           0 : DEFPY_YANG(debug_staticd, debug_staticd_cmd,
    1462             :            "[no] debug static [{events$events|route$route|bfd$bfd}]",
    1463             :            NO_STR DEBUG_STR STATICD_STR
    1464             :            "Debug events\n"
    1465             :            "Debug route\n"
    1466             :            "Debug bfd\n")
    1467             : {
    1468             :         /* If no specific category, change all */
    1469           0 :         if (strmatch(argv[argc - 1]->text, "static"))
    1470           0 :                 static_debug_set(vty->node, !no, true, true, true);
    1471             :         else
    1472           0 :                 static_debug_set(vty->node, !no, !!events, !!route, !!bfd);
    1473             : 
    1474           0 :         return CMD_SUCCESS;
    1475             : }
    1476             : 
    1477           0 : DEFPY(staticd_show_bfd_routes, staticd_show_bfd_routes_cmd,
    1478             :       "show bfd static route [json]$isjson",
    1479             :       SHOW_STR
    1480             :       BFD_INTEGRATION_STR
    1481             :       STATICD_STR
    1482             :       ROUTE_STR
    1483             :       JSON_STR)
    1484             : {
    1485           0 :         static_bfd_show(vty, !!isjson);
    1486           0 :         return CMD_SUCCESS;
    1487             : }
    1488             : 
    1489           0 : DEFUN_NOSH (show_debugging_static,
    1490             :             show_debugging_static_cmd,
    1491             :             "show debugging [static]",
    1492             :             SHOW_STR
    1493             :             DEBUG_STR
    1494             :             "Static Information\n")
    1495             : {
    1496           0 :         vty_out(vty, "Staticd debugging status\n");
    1497             : 
    1498           0 :         static_debug_status_write(vty);
    1499             : 
    1500           0 :         cmd_show_lib_debugs(vty);
    1501             : 
    1502           0 :         return CMD_SUCCESS;
    1503             : }
    1504             : 
    1505             : static struct cmd_node debug_node = {
    1506             :         .name = "debug",
    1507             :         .node = DEBUG_NODE,
    1508             :         .prompt = "",
    1509             :         .config_write = static_config_write_debug,
    1510             : };
    1511             : 
    1512          17 : void static_vty_init(void)
    1513             : {
    1514          17 :         install_node(&debug_node);
    1515             : 
    1516          17 :         install_element(CONFIG_NODE, &ip_mroute_dist_cmd);
    1517             : 
    1518          17 :         install_element(CONFIG_NODE, &ip_route_blackhole_cmd);
    1519          17 :         install_element(VRF_NODE, &ip_route_blackhole_vrf_cmd);
    1520          17 :         install_element(CONFIG_NODE, &ip_route_address_interface_cmd);
    1521          17 :         install_element(VRF_NODE, &ip_route_address_interface_vrf_cmd);
    1522          17 :         install_element(CONFIG_NODE, &ip_route_cmd);
    1523          17 :         install_element(VRF_NODE, &ip_route_vrf_cmd);
    1524             : 
    1525          17 :         install_element(CONFIG_NODE, &ipv6_route_blackhole_cmd);
    1526          17 :         install_element(VRF_NODE, &ipv6_route_blackhole_vrf_cmd);
    1527          17 :         install_element(CONFIG_NODE, &ipv6_route_address_interface_cmd);
    1528          17 :         install_element(VRF_NODE, &ipv6_route_address_interface_vrf_cmd);
    1529          17 :         install_element(CONFIG_NODE, &ipv6_route_cmd);
    1530          17 :         install_element(VRF_NODE, &ipv6_route_vrf_cmd);
    1531             : 
    1532          17 :         install_element(ENABLE_NODE, &show_debugging_static_cmd);
    1533          17 :         install_element(ENABLE_NODE, &debug_staticd_cmd);
    1534          17 :         install_element(CONFIG_NODE, &debug_staticd_cmd);
    1535             : 
    1536          17 :         install_element(ENABLE_NODE, &staticd_show_bfd_routes_cmd);
    1537          17 : }

Generated by: LCOV version v1.16-topotato