From: Carmine Scarpitta Date: Thu, 3 Nov 2022 07:40:23 +0000 (+0100) Subject: zebra, lib, vtysh: Add CLI cmd to set/unset SRv6 encap source address X-Git-Tag: base_10.0~163^2~6 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=69bff19c43c8f263aeb0fb3211ee0e3faf37ec5c;p=matthieu%2Ffrr.git zebra, lib, vtysh: Add CLI cmd to set/unset SRv6 encap source address - Add a new node `SRV6_ENCAP_NODE` to the CLI graph. This node allows users to configure encapsulation parameters for SRv6, including the source address of the outer encapsulating IPv6 header. - Install a new CLI command `source-address` under the `SRV6_ENCAP_NODE` node. This command is used to configure the source address of the outer encapsulating IPv6 header. - Install a new CLI command `no source-address` under the `SRV6_ENCAP_NODE` node. This command is used to unset the source address of the outer encapsulating IPv6 header and restore the default source address. Examples: ``` router# segment-routing router(sr)# srv6 router(srv6)# encapsulation router(srv6-encap)# source-address fc00:0:1::1 ``` ``` router# segment-routing router(sr)# srv6 router(srv6)# encapsulation router(srv6-encap)# no source-address ``` Signed-off-by: Carmine Scarpitta --- diff --git a/lib/command.h b/lib/command.h index 30982c4fe9..b6419e6fec 100644 --- a/lib/command.h +++ b/lib/command.h @@ -160,6 +160,7 @@ enum node_type { SRV6_NODE, /* SRv6 node */ SRV6_LOCS_NODE, /* SRv6 locators node */ SRV6_LOC_NODE, /* SRv6 locator node */ + SRV6_ENCAP_NODE, /* SRv6 encapsulation node */ VTY_NODE, /* Vty node. */ FPM_NODE, /* Dataplane FPM node. */ LINK_PARAMS_NODE, /* Link-parameters node */ diff --git a/vtysh/vtysh.c b/vtysh/vtysh.c index ac1079bbb1..29358336e8 100644 --- a/vtysh/vtysh.c +++ b/vtysh/vtysh.c @@ -1335,6 +1335,13 @@ static struct cmd_node srv6_loc_node = { .prompt = "%s(config-srv6-locator)# ", }; +static struct cmd_node srv6_encap_node = { + .name = "srv6-encap", + .node = SRV6_ENCAP_NODE, + .parent_node = SRV6_NODE, + .prompt = "%s(config-srv6-encap)# " +}; + #ifdef HAVE_PBRD static struct cmd_node pbr_map_node = { .name = "pbr-map", @@ -1692,6 +1699,14 @@ DEFUNSH(VTYSH_ZEBRA, srv6_locator, srv6_locator_cmd, return CMD_SUCCESS; } +DEFUNSH(VTYSH_ZEBRA, srv6_encap, srv6_encap_cmd, + "encapsulation", + "Segment Routing SRv6 encapsulation\n") +{ + vty->node = SRV6_ENCAP_NODE; + return CMD_SUCCESS; +} + #ifdef HAVE_BGPD DEFUNSH(VTYSH_BGPD, router_bgp, router_bgp_cmd, "router bgp [ASNUM [ VIEWVRFNAME] [as-notation ]]", @@ -2507,6 +2522,14 @@ DEFUNSH(VTYSH_ZEBRA, exit_srv6_loc_config, exit_srv6_loc_config_cmd, "exit", return CMD_SUCCESS; } +DEFUNSH(VTYSH_ZEBRA, exit_srv6_encap, exit_srv6_encap_cmd, "exit", + "Exit from SRv6-encapsulation configuration mode\n") +{ + if (vty->node == SRV6_ENCAP_NODE) + vty->node = SRV6_NODE; + return CMD_SUCCESS; +} + #ifdef HAVE_RIPD DEFUNSH(VTYSH_RIPD, vtysh_exit_ripd, vtysh_exit_ripd_cmd, "exit", "Exit current mode and down to previous mode\n") @@ -5090,6 +5113,7 @@ void vtysh_init_vty(void) install_element(SRV6_NODE, &srv6_locators_cmd); install_element(SRV6_NODE, &exit_srv6_config_cmd); install_element(SRV6_NODE, &vtysh_end_all_cmd); + install_element(SRV6_NODE, &srv6_encap_cmd); install_node(&srv6_locs_node); install_element(SRV6_LOCS_NODE, &srv6_locator_cmd); @@ -5100,6 +5124,10 @@ void vtysh_init_vty(void) install_element(SRV6_LOC_NODE, &exit_srv6_loc_config_cmd); install_element(SRV6_LOC_NODE, &vtysh_end_all_cmd); + install_node(&srv6_encap_node); + install_element(SRV6_ENCAP_NODE, &exit_srv6_encap_cmd); + install_element(SRV6_ENCAP_NODE, &vtysh_end_all_cmd); + install_element(ENABLE_NODE, &vtysh_show_running_config_cmd); install_element(ENABLE_NODE, &vtysh_copy_running_config_cmd); install_element(ENABLE_NODE, &vtysh_copy_to_running_cmd); diff --git a/zebra/zebra_srv6.c b/zebra/zebra_srv6.c index ee463c76a8..adc7d32aae 100644 --- a/zebra/zebra_srv6.c +++ b/zebra/zebra_srv6.c @@ -409,6 +409,23 @@ int release_daemon_srv6_locator_chunks(struct zserv *client) return count; } +void zebra_srv6_encap_src_addr_set(struct in6_addr *encap_src_addr) +{ + struct zebra_srv6 *srv6 = zebra_srv6_get_default(); + + if (!encap_src_addr) + return; + + memcpy(&srv6->encap_src_addr, encap_src_addr, sizeof(struct in6_addr)); +} + +void zebra_srv6_encap_src_addr_unset(void) +{ + struct zebra_srv6 *srv6 = zebra_srv6_get_default(); + + memset(&srv6->encap_src_addr, 0, sizeof(struct in6_addr)); +} + void zebra_srv6_terminate(void) { struct srv6_locator *locator; diff --git a/zebra/zebra_srv6.h b/zebra/zebra_srv6.h index 73876741fd..21936c3323 100644 --- a/zebra/zebra_srv6.h +++ b/zebra/zebra_srv6.h @@ -19,6 +19,9 @@ /* SRv6 instance structure. */ struct zebra_srv6 { struct list *locators; + + /* Source address for SRv6 encapsulation */ + struct in6_addr encap_src_addr; }; /* declare hooks for the basic API, so that it can be specialized or served @@ -68,4 +71,7 @@ extern void srv6_manager_release_locator_chunk_call(struct zserv *client, extern int srv6_manager_client_disconnect_cb(struct zserv *client); extern int release_daemon_srv6_locator_chunks(struct zserv *client); +extern void zebra_srv6_encap_src_addr_set(struct in6_addr *src_addr); +extern void zebra_srv6_encap_src_addr_unset(void); + #endif /* _ZEBRA_SRV6_H */ diff --git a/zebra/zebra_srv6_vty.c b/zebra/zebra_srv6_vty.c index 3775d3dcdf..ffc67fc8a1 100644 --- a/zebra/zebra_srv6_vty.c +++ b/zebra/zebra_srv6_vty.c @@ -61,6 +61,13 @@ static struct cmd_node srv6_loc_node = { .prompt = "%s(config-srv6-locator)# " }; +static struct cmd_node srv6_encap_node = { + .name = "srv6-encap", + .node = SRV6_ENCAP_NODE, + .parent_node = SRV6_NODE, + .prompt = "%s(config-srv6-encap)# " +}; + DEFUN (show_srv6_locator, show_srv6_locator_cmd, "show segment-routing srv6 locator [json]", @@ -391,6 +398,38 @@ DEFPY (locator_behavior, return CMD_SUCCESS; } +DEFUN_NOSH (srv6_encap, + srv6_encap_cmd, + "encapsulation", + "Segment Routing SRv6 encapsulation\n") +{ + vty->node = SRV6_ENCAP_NODE; + return CMD_SUCCESS; +} + +DEFPY (srv6_src_addr, + srv6_src_addr_cmd, + "source-address X:X::X:X$encap_src_addr", + "Segment Routing SRv6 source address\n" + "Specify source address for SRv6 encapsulation\n") +{ + zebra_srv6_encap_src_addr_set(&encap_src_addr); + dplane_srv6_encap_srcaddr_set(&encap_src_addr, NS_DEFAULT); + return CMD_SUCCESS; +} + +DEFPY (no_srv6_src_addr, + no_srv6_src_addr_cmd, + "no source-address [X:X::X:X$encap_src_addr]", + NO_STR + "Segment Routing SRv6 source address\n" + "Specify source address for SRv6 encapsulation\n") +{ + zebra_srv6_encap_src_addr_unset(); + dplane_srv6_encap_srcaddr_set(&in6addr_any, NS_DEFAULT); + return CMD_SUCCESS; +} + static int zebra_sr_config(struct vty *vty) { struct zebra_srv6 *srv6 = zebra_srv6_get_default(); @@ -444,22 +483,27 @@ void zebra_srv6_vty_init(void) install_node(&srv6_node); install_node(&srv6_locs_node); install_node(&srv6_loc_node); + install_node(&srv6_encap_node); install_default(SEGMENT_ROUTING_NODE); install_default(SRV6_NODE); install_default(SRV6_LOCS_NODE); install_default(SRV6_LOC_NODE); + install_default(SRV6_ENCAP_NODE); /* Command for change node */ install_element(CONFIG_NODE, &segment_routing_cmd); install_element(SEGMENT_ROUTING_NODE, &srv6_cmd); install_element(SEGMENT_ROUTING_NODE, &no_srv6_cmd); install_element(SRV6_NODE, &srv6_locators_cmd); + install_element(SRV6_NODE, &srv6_encap_cmd); install_element(SRV6_LOCS_NODE, &srv6_locator_cmd); install_element(SRV6_LOCS_NODE, &no_srv6_locator_cmd); /* Command for configuration */ install_element(SRV6_LOC_NODE, &locator_prefix_cmd); install_element(SRV6_LOC_NODE, &locator_behavior_cmd); + install_element(SRV6_ENCAP_NODE, &srv6_src_addr_cmd); + install_element(SRV6_ENCAP_NODE, &no_srv6_src_addr_cmd); /* Command for operation */ install_element(VIEW_NODE, &show_srv6_locator_cmd);