diff options
author | Dmytro Shytyi <dmytro.shytyi@6wind.com> | 2023-07-26 18:44:23 +0200 |
---|---|---|
committer | Dmytro Shytyi <dmytro.shytyi@6wind.com> | 2023-09-20 15:07:15 +0200 |
commit | d91a38a4db39ddf756ce03c41ced78b3e6c70992 (patch) | |
tree | cec5c5320d60c606f8b986a249fcb7fb9b6cb926 /staticd | |
parent | staticd: northbound srv6 hooks for segs stack yang model (diff) | |
download | frr-d91a38a4db39ddf756ce03c41ced78b3e6c70992.tar.xz frr-d91a38a4db39ddf756ce03c41ced78b3e6c70992.zip |
staticd: add vtysh srv6 multiple segs SIDs
Append staticd vty with multiple segs SIDs.
Signed-off-by: Dmytro Shytyi <dmytro.shytyi@6wind.com>
Diffstat (limited to 'staticd')
-rw-r--r-- | staticd/static_vty.c | 280 |
1 files changed, 169 insertions, 111 deletions
diff --git a/staticd/static_vty.c b/staticd/static_vty.c index 16e4cb7d8..b07878f06 100644 --- a/staticd/static_vty.c +++ b/staticd/static_vty.c @@ -47,6 +47,7 @@ struct static_route_args { const char *source; const char *gateway; const char *interface_name; + const char *segs; const char *flag; const char *tag; const char *distance; @@ -73,12 +74,16 @@ static int static_route_nb_run(struct vty *vty, struct static_route_args *args) char xpath_nexthop[XPATH_MAXLEN]; char xpath_mpls[XPATH_MAXLEN]; char xpath_label[XPATH_MAXLEN]; + char xpath_segs[XPATH_MAXLEN]; + char xpath_seg[XPATH_MAXLEN]; char ab_xpath[XPATH_MAXLEN]; char buf_prefix[PREFIX_STRLEN]; char buf_src_prefix[PREFIX_STRLEN] = {}; char buf_nh_type[PREFIX_STRLEN] = {}; char buf_tag[PREFIX_STRLEN]; uint8_t label_stack_id = 0; + uint8_t segs_stack_id = 0; + const char *buf_gate_str; uint8_t distance = ZEBRA_STATIC_DISTANCE_DEFAULT; route_tag_t tag = 0; @@ -345,7 +350,39 @@ static int static_route_nb_run(struct vty *vty, struct static_route_args *args) nb_cli_enqueue_change(vty, xpath_mpls, NB_OP_DESTROY, NULL); } + if (args->segs) { + /* copy of seg string (start) */ + char *ostr; + /* pointer to next segment */ + char *nump; + strlcpy(xpath_segs, xpath_nexthop, sizeof(xpath_segs)); + strlcat(xpath_segs, FRR_STATIC_ROUTE_NH_SRV6_SEGS_XPATH, + sizeof(xpath_segs)); + + nb_cli_enqueue_change(vty, xpath_segs, NB_OP_DESTROY, + NULL); + + ostr = XSTRDUP(MTYPE_TMP, args->segs); + while ((nump = strsep(&ostr, "/")) != NULL) { + snprintf(ab_xpath, sizeof(ab_xpath), + FRR_STATIC_ROUTE_NH_SRV6_KEY_SEG_XPATH, + segs_stack_id); + strlcpy(xpath_seg, xpath_segs, + sizeof(xpath_seg)); + strlcat(xpath_seg, ab_xpath, sizeof(xpath_seg)); + nb_cli_enqueue_change(vty, xpath_seg, + NB_OP_MODIFY, nump); + segs_stack_id++; + } + XFREE(MTYPE_TMP, ostr); + } else { + strlcpy(xpath_segs, xpath_nexthop, sizeof(xpath_segs)); + strlcat(xpath_segs, FRR_STATIC_ROUTE_NH_SRV6_SEGS_XPATH, + sizeof(xpath_segs)); + nb_cli_enqueue_change(vty, xpath_segs, NB_OP_DESTROY, + NULL); + } if (args->bfd) { char xpath_bfd[XPATH_MAXLEN]; @@ -951,9 +988,8 @@ DEFPY_YANG(ipv6_route_blackhole_vrf, return static_route_nb_run(vty, &args); } -DEFPY_YANG(ipv6_route_address_interface, - ipv6_route_address_interface_cmd, - "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \ +DEFPY_YANG(ipv6_route_address_interface, ipv6_route_address_interface_cmd, + "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \ X:X::X:X$gate \ <INTERFACE|Null0>$ifname \ [{ \ @@ -966,33 +1002,28 @@ DEFPY_YANG(ipv6_route_address_interface, |onlink$onlink \ |color (1-4294967295) \ |bfd$bfd [{multi-hop$bfd_multi_hop|source X:X::X:X$bfd_source|profile BFDPROF$bfd_profile}] \ + |segments WORD \ }]", - NO_STR - IPV6_STR - "Establish static routes\n" - "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" - "IPv6 source-dest route\n" - "IPv6 source prefix\n" - "IPv6 gateway address\n" - "IPv6 gateway interface name\n" - "Null interface\n" - "Set tag for this route\n" - "Tag value\n" - "Distance value for this prefix\n" - VRF_CMD_HELP_STR - MPLS_LABEL_HELPSTR - "Table to configure\n" - "The table number to configure\n" - VRF_CMD_HELP_STR - "Treat the nexthop as directly attached to the interface\n" - "SR-TE color\n" - "The SR-TE color to configure\n" - BFD_INTEGRATION_STR - BFD_INTEGRATION_MULTI_HOP_STR - BFD_INTEGRATION_SOURCE_STR - BFD_INTEGRATION_SOURCEV4_STR - BFD_PROFILE_STR - BFD_PROFILE_NAME_STR) + NO_STR IPV6_STR + "Establish static routes\n" + "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" + "IPv6 source-dest route\n" + "IPv6 source prefix\n" + "IPv6 gateway address\n" + "IPv6 gateway interface name\n" + "Null interface\n" + "Set tag for this route\n" + "Tag value\n" + "Distance value for this prefix\n" VRF_CMD_HELP_STR MPLS_LABEL_HELPSTR + "Table to configure\n" + "The table number to configure\n" VRF_CMD_HELP_STR + "Treat the nexthop as directly attached to the interface\n" + "SR-TE color\n" + "The SR-TE color to configure\n" BFD_INTEGRATION_STR + BFD_INTEGRATION_MULTI_HOP_STR BFD_INTEGRATION_SOURCE_STR + BFD_INTEGRATION_SOURCEV4_STR BFD_PROFILE_STR + BFD_PROFILE_NAME_STR "Value of segs\n" + "Segs (SIDs)\n") { struct static_route_args args = { .delete = !!no, @@ -1014,14 +1045,15 @@ DEFPY_YANG(ipv6_route_address_interface, .bfd_multi_hop = !!bfd_multi_hop, .bfd_source = bfd_source_str, .bfd_profile = bfd_profile, + .segs = segments, }; return static_route_nb_run(vty, &args); } DEFPY_YANG(ipv6_route_address_interface_vrf, - ipv6_route_address_interface_vrf_cmd, - "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \ + ipv6_route_address_interface_vrf_cmd, + "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \ X:X::X:X$gate \ <INTERFACE|Null0>$ifname \ [{ \ @@ -1033,32 +1065,28 @@ DEFPY_YANG(ipv6_route_address_interface_vrf, |onlink$onlink \ |color (1-4294967295) \ |bfd$bfd [{multi-hop$bfd_multi_hop|source X:X::X:X$bfd_source|profile BFDPROF$bfd_profile}] \ + |segments WORD \ }]", - NO_STR - IPV6_STR - "Establish static routes\n" - "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" - "IPv6 source-dest route\n" - "IPv6 source prefix\n" - "IPv6 gateway address\n" - "IPv6 gateway interface name\n" - "Null interface\n" - "Set tag for this route\n" - "Tag value\n" - "Distance value for this prefix\n" - MPLS_LABEL_HELPSTR - "Table to configure\n" - "The table number to configure\n" - VRF_CMD_HELP_STR - "Treat the nexthop as directly attached to the interface\n" - "SR-TE color\n" - "The SR-TE color to configure\n" - BFD_INTEGRATION_STR - BFD_INTEGRATION_MULTI_HOP_STR - BFD_INTEGRATION_SOURCE_STR - BFD_INTEGRATION_SOURCEV4_STR - BFD_PROFILE_STR - BFD_PROFILE_NAME_STR) + NO_STR IPV6_STR + "Establish static routes\n" + "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" + "IPv6 source-dest route\n" + "IPv6 source prefix\n" + "IPv6 gateway address\n" + "IPv6 gateway interface name\n" + "Null interface\n" + "Set tag for this route\n" + "Tag value\n" + "Distance value for this prefix\n" MPLS_LABEL_HELPSTR + "Table to configure\n" + "The table number to configure\n" VRF_CMD_HELP_STR + "Treat the nexthop as directly attached to the interface\n" + "SR-TE color\n" + "The SR-TE color to configure\n" BFD_INTEGRATION_STR + BFD_INTEGRATION_MULTI_HOP_STR BFD_INTEGRATION_SOURCE_STR + BFD_INTEGRATION_SOURCEV4_STR BFD_PROFILE_STR + BFD_PROFILE_NAME_STR "Value of segs\n" + "Segs (SIDs)\n") { struct static_route_args args = { .delete = !!no, @@ -1080,14 +1108,14 @@ DEFPY_YANG(ipv6_route_address_interface_vrf, .bfd_multi_hop = !!bfd_multi_hop, .bfd_source = bfd_source_str, .bfd_profile = bfd_profile, + .segs = segments, }; return static_route_nb_run(vty, &args); } -DEFPY_YANG(ipv6_route, - ipv6_route_cmd, - "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \ +DEFPY_YANG(ipv6_route, ipv6_route_cmd, + "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \ <X:X::X:X$gate|<INTERFACE|Null0>$ifname> \ [{ \ tag (1-4294967295) \ @@ -1098,32 +1126,26 @@ DEFPY_YANG(ipv6_route, |nexthop-vrf NAME \ |color (1-4294967295) \ |bfd$bfd [{multi-hop$bfd_multi_hop|source X:X::X:X$bfd_source|profile BFDPROF$bfd_profile}] \ + |segments WORD \ }]", - NO_STR - IPV6_STR - "Establish static routes\n" - "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" - "IPv6 source-dest route\n" - "IPv6 source prefix\n" - "IPv6 gateway address\n" - "IPv6 gateway interface name\n" - "Null interface\n" - "Set tag for this route\n" - "Tag value\n" - "Distance value for this prefix\n" - VRF_CMD_HELP_STR - MPLS_LABEL_HELPSTR - "Table to configure\n" - "The table number to configure\n" - VRF_CMD_HELP_STR - "SR-TE color\n" - "The SR-TE color to configure\n" - BFD_INTEGRATION_STR - BFD_INTEGRATION_MULTI_HOP_STR - BFD_INTEGRATION_SOURCE_STR - BFD_INTEGRATION_SOURCEV4_STR - BFD_PROFILE_STR - BFD_PROFILE_NAME_STR) + NO_STR IPV6_STR + "Establish static routes\n" + "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" + "IPv6 source-dest route\n" + "IPv6 source prefix\n" + "IPv6 gateway address\n" + "IPv6 gateway interface name\n" + "Null interface\n" + "Set tag for this route\n" + "Tag value\n" + "Distance value for this prefix\n" VRF_CMD_HELP_STR MPLS_LABEL_HELPSTR + "Table to configure\n" + "The table number to configure\n" VRF_CMD_HELP_STR "SR-TE color\n" + "The SR-TE color to configure\n" BFD_INTEGRATION_STR + BFD_INTEGRATION_MULTI_HOP_STR BFD_INTEGRATION_SOURCE_STR + BFD_INTEGRATION_SOURCEV4_STR BFD_PROFILE_STR + BFD_PROFILE_NAME_STR "Value of segs\n" + "Segs (SIDs)\n") { struct static_route_args args = { .delete = !!no, @@ -1144,14 +1166,15 @@ DEFPY_YANG(ipv6_route, .bfd_multi_hop = !!bfd_multi_hop, .bfd_source = bfd_source_str, .bfd_profile = bfd_profile, + .segs = segments, + }; return static_route_nb_run(vty, &args); } -DEFPY_YANG(ipv6_route_vrf, - ipv6_route_vrf_cmd, - "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \ +DEFPY_YANG(ipv6_route_vrf, ipv6_route_vrf_cmd, + "[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \ <X:X::X:X$gate|<INTERFACE|Null0>$ifname> \ [{ \ tag (1-4294967295) \ @@ -1161,31 +1184,26 @@ DEFPY_YANG(ipv6_route_vrf, |nexthop-vrf NAME \ |color (1-4294967295) \ |bfd$bfd [{multi-hop$bfd_multi_hop|source X:X::X:X$bfd_source|profile BFDPROF$bfd_profile}] \ + |segments WORD \ }]", - NO_STR - IPV6_STR - "Establish static routes\n" - "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" - "IPv6 source-dest route\n" - "IPv6 source prefix\n" - "IPv6 gateway address\n" - "IPv6 gateway interface name\n" - "Null interface\n" - "Set tag for this route\n" - "Tag value\n" - "Distance value for this prefix\n" - MPLS_LABEL_HELPSTR - "Table to configure\n" - "The table number to configure\n" - VRF_CMD_HELP_STR - "SR-TE color\n" - "The SR-TE color to configure\n" - BFD_INTEGRATION_STR - BFD_INTEGRATION_MULTI_HOP_STR - BFD_INTEGRATION_SOURCE_STR - BFD_INTEGRATION_SOURCEV4_STR - BFD_PROFILE_STR - BFD_PROFILE_NAME_STR) + NO_STR IPV6_STR + "Establish static routes\n" + "IPv6 destination prefix (e.g. 3ffe:506::/32)\n" + "IPv6 source-dest route\n" + "IPv6 source prefix\n" + "IPv6 gateway address\n" + "IPv6 gateway interface name\n" + "Null interface\n" + "Set tag for this route\n" + "Tag value\n" + "Distance value for this prefix\n" MPLS_LABEL_HELPSTR + "Table to configure\n" + "The table number to configure\n" VRF_CMD_HELP_STR "SR-TE color\n" + "The SR-TE color to configure\n" BFD_INTEGRATION_STR + BFD_INTEGRATION_MULTI_HOP_STR BFD_INTEGRATION_SOURCE_STR + BFD_INTEGRATION_SOURCEV4_STR BFD_PROFILE_STR + BFD_PROFILE_NAME_STR "Value of segs\n" + "Segs (SIDs)\n") { struct static_route_args args = { .delete = !!no, @@ -1206,6 +1224,7 @@ DEFPY_YANG(ipv6_route_vrf, .bfd_multi_hop = !!bfd_multi_hop, .bfd_source = bfd_source_str, .bfd_profile = bfd_profile, + .segs = segments, }; return static_route_nb_run(vty, &args); @@ -1252,6 +1271,39 @@ static int mpls_label_iter_cb(const struct lyd_node *dnode, void *arg) return YANG_ITER_CONTINUE; } +struct srv6_seg_iter { + struct vty *vty; + bool first; +}; + +static int srv6_seg_iter_cb(const struct lyd_node *dnode, void *arg) +{ + struct srv6_seg_iter *iter = arg; + char buffer[INET6_ADDRSTRLEN]; + struct in6_addr cli_seg; + + if (yang_dnode_exists(dnode, "./seg")) { + if (iter->first) { + yang_dnode_get_ipv6(&cli_seg, dnode, "./seg"); + if (inet_ntop(AF_INET6, &cli_seg, buffer, + INET6_ADDRSTRLEN) == NULL) { + return 1; + } + vty_out(iter->vty, " segments %s", buffer); + } else { + yang_dnode_get_ipv6(&cli_seg, dnode, "./seg"); + if (inet_ntop(AF_INET6, &cli_seg, buffer, + INET6_ADDRSTRLEN) == NULL) { + return 1; + } + vty_out(iter->vty, "/%s", buffer); + } + iter->first = false; + } + + return YANG_ITER_CONTINUE; +} + static void nexthop_cli_show(struct vty *vty, const struct lyd_node *route, const struct lyd_node *src, const struct lyd_node *path, @@ -1266,6 +1318,7 @@ static void nexthop_cli_show(struct vty *vty, const struct lyd_node *route, uint32_t tag; uint8_t distance; struct mpls_label_iter iter; + struct srv6_seg_iter seg_iter; const char *nexthop_vrf; uint32_t table_id; bool onlink; @@ -1342,6 +1395,11 @@ static void nexthop_cli_show(struct vty *vty, const struct lyd_node *route, yang_dnode_iterate(mpls_label_iter_cb, &iter, nexthop, "./mpls-label-stack/entry"); + seg_iter.vty = vty; + seg_iter.first = true; + yang_dnode_iterate(srv6_seg_iter_cb, &seg_iter, nexthop, + "./srv6-segs-stack/entry"); + nexthop_vrf = yang_dnode_get_string(nexthop, "./vrf"); if (strcmp(vrf, nexthop_vrf)) vty_out(vty, " nexthop-vrf %s", nexthop_vrf); |