mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-06 09:00:55 +00:00
Merge pull request #9331 from idryzhov/explicit-exit
*: explicitly print "exit" at the end of every node config
This commit is contained in:
commit
d448e2c5f9
@ -1362,7 +1362,7 @@ interface_config_write (struct vty *vty)
|
||||
write++;
|
||||
}
|
||||
}
|
||||
vty_endframe (vty, "!\n");
|
||||
vty_endframe (vty, "exit\n!\n");
|
||||
write++;
|
||||
}
|
||||
return write;
|
||||
|
@ -132,6 +132,8 @@ babel_config_write (struct vty *vty)
|
||||
|
||||
lines += config_write_distribute (vty, babel_routing_process->distribute_ctx);
|
||||
|
||||
vty_out (vty, "exit\n");
|
||||
|
||||
return lines;
|
||||
}
|
||||
|
||||
|
@ -101,6 +101,7 @@ void bfd_cli_show_header(struct vty *vty,
|
||||
void bfd_cli_show_header_end(struct vty *vty,
|
||||
struct lyd_node *dnode __attribute__((__unused__)))
|
||||
{
|
||||
vty_out(vty, "exit\n");
|
||||
vty_out(vty, "!\n");
|
||||
}
|
||||
|
||||
@ -275,6 +276,7 @@ void bfd_cli_show_multi_hop_peer(struct vty *vty,
|
||||
void bfd_cli_show_peer_end(struct vty *vty,
|
||||
struct lyd_node *dnode __attribute__((__unused__)))
|
||||
{
|
||||
vty_out(vty, " exit\n");
|
||||
vty_out(vty, " !\n");
|
||||
}
|
||||
|
||||
|
@ -2400,6 +2400,8 @@ static int bmp_config_write(struct bgp *bgp, struct vty *vty)
|
||||
frr_each (bmp_actives, &bt->actives, ba)
|
||||
vty_out(vty, " bmp connect %s port %u min-retry %u max-retry %u\n",
|
||||
ba->hostname, ba->port, ba->minretry, ba->maxretry);
|
||||
|
||||
vty_out(vty, " exit\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -932,7 +932,7 @@ static int config_write(struct vty *vty)
|
||||
|
||||
vty_out(vty, "preference %hhu\n", cache->preference);
|
||||
}
|
||||
vty_out(vty, " exit\n");
|
||||
vty_out(vty, "exit\n");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -17213,6 +17213,7 @@ int bgp_config_write(struct vty *vty)
|
||||
bgp_rfapi_cfg_write(vty, bgp);
|
||||
#endif
|
||||
|
||||
vty_out(vty, "exit\n");
|
||||
vty_out(vty, "!\n");
|
||||
}
|
||||
return 0;
|
||||
|
@ -4043,7 +4043,7 @@ int bgp_rfapi_cfg_write(struct vty *vty, struct bgp *bgp)
|
||||
rfg->routemap_redist_name
|
||||
[ZEBRA_ROUTE_BGP_DIRECT_EXT]);
|
||||
}
|
||||
vty_out(vty, " exit-vrf-policy\n");
|
||||
vty_out(vty, " exit-vrf-policy\n");
|
||||
vty_out(vty, "!\n");
|
||||
}
|
||||
if (hc->flags & BGP_VNC_CONFIG_ADV_UN_METHOD_ENCAP) {
|
||||
@ -4121,7 +4121,7 @@ int bgp_rfapi_cfg_write(struct vty *vty, struct bgp *bgp)
|
||||
vty, bgp->rfapi->rfp,
|
||||
RFAPI_RFP_CFG_GROUP_L2,
|
||||
rfgc->name, rfgc->rfp_cfg);
|
||||
vty_out(vty, " exit-vnc\n");
|
||||
vty_out(vty, " exit-vnc\n");
|
||||
vty_out(vty, "!\n");
|
||||
}
|
||||
}
|
||||
@ -4199,7 +4199,7 @@ int bgp_rfapi_cfg_write(struct vty *vty, struct bgp *bgp)
|
||||
vty, bgp->rfapi->rfp,
|
||||
RFAPI_RFP_CFG_GROUP_DEFAULT, NULL,
|
||||
bgp->rfapi_cfg->default_rfp_cfg);
|
||||
vty_out(vty, " exit-vnc\n");
|
||||
vty_out(vty, " exit-vnc\n");
|
||||
vty_out(vty, "!\n");
|
||||
}
|
||||
|
||||
@ -4364,7 +4364,7 @@ int bgp_rfapi_cfg_write(struct vty *vty, struct bgp *bgp)
|
||||
vty, bgp->rfapi->rfp,
|
||||
RFAPI_RFP_CFG_GROUP_NVE,
|
||||
rfg->name, rfg->rfp_cfg);
|
||||
vty_out(vty, " exit-vnc\n");
|
||||
vty_out(vty, " exit-vnc\n");
|
||||
vty_out(vty, "!\n");
|
||||
}
|
||||
} /* have listen ports */
|
||||
|
@ -96,6 +96,7 @@ void eigrp_cli_show_header(struct vty *vty, struct lyd_node *dnode,
|
||||
|
||||
void eigrp_cli_show_end_header(struct vty *vty, struct lyd_node *dnode)
|
||||
{
|
||||
vty_out(vty, "exit\n");
|
||||
vty_out(vty, "!\n");
|
||||
}
|
||||
|
||||
|
@ -1290,7 +1290,7 @@ static int isis_interface_config_write(struct vty *vty)
|
||||
write += hook_call(isis_circuit_config_write,
|
||||
circuit, vty);
|
||||
}
|
||||
vty_endframe(vty, "!\n");
|
||||
vty_endframe(vty, "exit\n!\n");
|
||||
}
|
||||
|
||||
return write;
|
||||
|
@ -146,6 +146,11 @@ void cli_show_router_isis(struct vty *vty, struct lyd_node *dnode,
|
||||
vty_out(vty, "\n");
|
||||
}
|
||||
|
||||
void cli_show_router_isis_end(struct vty *vty, struct lyd_node *dnode)
|
||||
{
|
||||
vty_out(vty, "exit\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* XPath: /frr-interface:lib/interface/frr-isisd:isis/
|
||||
* XPath: /frr-interface:lib/interface/frr-isisd:isis/ipv4-routing
|
||||
|
@ -32,6 +32,7 @@ const struct frr_yang_module_info frr_isisd_info = {
|
||||
.xpath = "/frr-isisd:isis/instance",
|
||||
.cbs = {
|
||||
.cli_show = cli_show_router_isis,
|
||||
.cli_show_end = cli_show_router_isis_end,
|
||||
.create = isis_instance_create,
|
||||
.destroy = isis_instance_destroy,
|
||||
},
|
||||
|
@ -415,6 +415,7 @@ void isis_instance_segment_routing_prefix_sid_map_prefix_sid_apply_finish(
|
||||
/* Optional 'cli_show' callbacks. */
|
||||
void cli_show_router_isis(struct vty *vty, struct lyd_node *dnode,
|
||||
bool show_defaults);
|
||||
void cli_show_router_isis_end(struct vty *vty, struct lyd_node *dnode);
|
||||
void cli_show_ip_isis_ipv4(struct vty *vty, struct lyd_node *dnode,
|
||||
bool show_defaults);
|
||||
void cli_show_ip_isis_ipv6(struct vty *vty, struct lyd_node *dnode,
|
||||
|
@ -3011,6 +3011,8 @@ static int isis_config_write(struct vty *vty)
|
||||
|
||||
write += area_write_mt_settings(area, vty);
|
||||
write += fabricd_write_settings(area, vty);
|
||||
|
||||
vty_out(vty, "exit\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -133,6 +133,8 @@ ldp_af_iface_config_write(struct vty *vty, int af)
|
||||
ia->hello_interval != 0)
|
||||
vty_out (vty, " discovery hello interval %u\n",
|
||||
ia->hello_interval);
|
||||
|
||||
vty_out (vty, " exit\n");
|
||||
}
|
||||
}
|
||||
|
||||
@ -314,6 +316,7 @@ ldp_config_write(struct vty *vty)
|
||||
ldp_af_config_write(vty, AF_INET, ldpd_conf, &ldpd_conf->ipv4);
|
||||
ldp_af_config_write(vty, AF_INET6, ldpd_conf, &ldpd_conf->ipv6);
|
||||
vty_out (vty, " !\n");
|
||||
vty_out (vty, "exit\n");
|
||||
vty_out (vty, "!\n");
|
||||
|
||||
return (1);
|
||||
@ -353,6 +356,8 @@ ldp_l2vpn_pw_config_write(struct vty *vty, struct l2vpn_pw *pw)
|
||||
" ! Incomplete config, specify a neighbor lsr-id\n");
|
||||
if (missing_pwid)
|
||||
vty_out (vty," ! Incomplete config, specify a pw-id\n");
|
||||
|
||||
vty_out (vty, " exit\n");
|
||||
}
|
||||
|
||||
static int
|
||||
@ -383,6 +388,7 @@ ldp_l2vpn_config_write(struct vty *vty)
|
||||
ldp_l2vpn_pw_config_write(vty, pw);
|
||||
|
||||
vty_out (vty, " !\n");
|
||||
vty_out (vty, "exit\n");
|
||||
vty_out (vty, "!\n");
|
||||
}
|
||||
|
||||
|
6
lib/if.c
6
lib/if.c
@ -1291,6 +1291,11 @@ static void cli_show_interface(struct vty *vty, struct lyd_node *dnode,
|
||||
vty_out(vty, "\n");
|
||||
}
|
||||
|
||||
static void cli_show_interface_end(struct vty *vty, struct lyd_node *dnode)
|
||||
{
|
||||
vty_out(vty, "exit\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* XPath: /frr-interface:lib/interface/description
|
||||
*/
|
||||
@ -1652,6 +1657,7 @@ const struct frr_yang_module_info frr_interface_info = {
|
||||
.create = lib_interface_create,
|
||||
.destroy = lib_interface_destroy,
|
||||
.cli_show = cli_show_interface,
|
||||
.cli_show_end = cli_show_interface_end,
|
||||
.get_next = lib_interface_get_next,
|
||||
.get_keys = lib_interface_get_keys,
|
||||
.lookup_entry = lib_interface_lookup_entry,
|
||||
|
@ -1044,6 +1044,7 @@ static int keychain_config_write(struct vty *vty)
|
||||
|
||||
vty_out(vty, " exit\n");
|
||||
}
|
||||
vty_out(vty, "exit\n");
|
||||
vty_out(vty, "!\n");
|
||||
}
|
||||
|
||||
|
@ -1156,6 +1156,7 @@ static int nexthop_group_write(struct vty *vty)
|
||||
nexthop_group_write_nexthop_internal(vty, nh);
|
||||
}
|
||||
|
||||
vty_out(vty, "exit\n");
|
||||
vty_out(vty, "!\n");
|
||||
}
|
||||
|
||||
|
@ -124,6 +124,7 @@ void route_map_instance_show(struct vty *vty, struct lyd_node *dnode,
|
||||
|
||||
void route_map_instance_show_end(struct vty *vty, struct lyd_node *dnode)
|
||||
{
|
||||
vty_out(vty, "exit\n");
|
||||
vty_out(vty, "!\n");
|
||||
}
|
||||
|
||||
|
@ -3040,7 +3040,7 @@ DEFPY (log_commands,
|
||||
/* Display current configuration. */
|
||||
static int vty_config_write(struct vty *vty)
|
||||
{
|
||||
vty_out(vty, "line vty\n");
|
||||
vty_frame(vty, "line vty\n");
|
||||
|
||||
if (vty_accesslist_name)
|
||||
vty_out(vty, " access-class %s\n", vty_accesslist_name);
|
||||
@ -3058,6 +3058,8 @@ static int vty_config_write(struct vty *vty)
|
||||
if (no_password_check)
|
||||
vty_out(vty, " no login\n");
|
||||
|
||||
vty_endframe(vty, "exit\n");
|
||||
|
||||
if (do_log_commands)
|
||||
vty_out(vty, "log commands\n");
|
||||
|
||||
|
@ -1225,7 +1225,7 @@ static int interface_config_write(struct vty *vty)
|
||||
}
|
||||
}
|
||||
|
||||
vty_endframe(vty, "!\n");
|
||||
vty_endframe(vty, "exit\n!\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -2593,7 +2593,7 @@ static int config_write_ospf6_interface(struct vty *vty, struct vrf *vrf)
|
||||
|
||||
ospf6_bfd_write_config(vty, oi);
|
||||
|
||||
vty_endframe(vty, "!\n");
|
||||
vty_endframe(vty, "exit\n!\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -2237,6 +2237,8 @@ static int config_write_ospf6(struct vty *vty)
|
||||
ospf6_distribute_config_write(vty, ospf6);
|
||||
ospf6_asbr_summary_config_write(vty, ospf6);
|
||||
config_write_ospf6_gr_helper(vty, ospf6);
|
||||
|
||||
vty_out(vty, "exit\n");
|
||||
vty_out(vty, "!\n");
|
||||
}
|
||||
return 0;
|
||||
|
@ -11970,7 +11970,7 @@ static int config_write_interface_one(struct vty *vty, struct vrf *vrf)
|
||||
|
||||
ospf_opaque_config_write_if(vty, ifp);
|
||||
|
||||
vty_endframe(vty, NULL);
|
||||
vty_endframe(vty, "exit\n!\n");
|
||||
}
|
||||
|
||||
return write;
|
||||
@ -12546,6 +12546,8 @@ static int ospf_config_write_one(struct vty *vty, struct ospf *ospf)
|
||||
/* LDP-Sync print */
|
||||
ospf_ldp_sync_write_config(vty, ospf);
|
||||
|
||||
vty_out(vty, "exit\n");
|
||||
|
||||
write++;
|
||||
return write;
|
||||
}
|
||||
|
@ -45,9 +45,6 @@
|
||||
|
||||
|
||||
static int config_write_segment_routing(struct vty *vty);
|
||||
static int config_write_traffic_eng(struct vty *vty);
|
||||
static int config_write_segment_lists(struct vty *vty);
|
||||
static int config_write_sr_policies(struct vty *vty);
|
||||
static int segment_list_has_src_dst(
|
||||
struct vty *vty, char *xpath, long index, const char *index_str,
|
||||
struct in_addr adj_src_ipv4, struct in_addr adj_dst_ipv4,
|
||||
@ -63,6 +60,8 @@ static int segment_list_has_prefix(
|
||||
|
||||
DEFINE_MTYPE_STATIC(PATHD, PATH_CLI, "Client");
|
||||
|
||||
DEFINE_HOOK(pathd_srte_config_write, (struct vty *vty), (vty));
|
||||
|
||||
/* Vty node structures. */
|
||||
static struct cmd_node segment_routing_node = {
|
||||
.name = "segment-routing",
|
||||
@ -77,7 +76,6 @@ static struct cmd_node sr_traffic_eng_node = {
|
||||
.node = SR_TRAFFIC_ENG_NODE,
|
||||
.parent_node = SEGMENT_ROUTING_NODE,
|
||||
.prompt = "%s(config-sr-te)# ",
|
||||
.config_write = config_write_traffic_eng,
|
||||
};
|
||||
|
||||
static struct cmd_node srte_segment_list_node = {
|
||||
@ -85,7 +83,6 @@ static struct cmd_node srte_segment_list_node = {
|
||||
.node = SR_SEGMENT_LIST_NODE,
|
||||
.parent_node = SR_TRAFFIC_ENG_NODE,
|
||||
.prompt = "%s(config-sr-te-segment-list)# ",
|
||||
.config_write = config_write_segment_lists,
|
||||
};
|
||||
|
||||
static struct cmd_node srte_policy_node = {
|
||||
@ -93,7 +90,6 @@ static struct cmd_node srte_policy_node = {
|
||||
.node = SR_POLICY_NODE,
|
||||
.parent_node = SR_TRAFFIC_ENG_NODE,
|
||||
.prompt = "%s(config-sr-te-policy)# ",
|
||||
.config_write = config_write_sr_policies,
|
||||
};
|
||||
|
||||
static struct cmd_node srte_candidate_dyn_node = {
|
||||
@ -309,6 +305,11 @@ void cli_show_srte_segment_list(struct vty *vty, struct lyd_node *dnode,
|
||||
yang_dnode_get_string(dnode, "./name"));
|
||||
}
|
||||
|
||||
void cli_show_srte_segment_list_end(struct vty *vty, struct lyd_node *dnode)
|
||||
{
|
||||
vty_out(vty, " exit\n");
|
||||
}
|
||||
|
||||
static int segment_list_has_src_dst(
|
||||
struct vty *vty, char *xpath, long index, const char *index_str,
|
||||
struct in_addr adj_src_ipv4, struct in_addr adj_dst_ipv4,
|
||||
@ -666,6 +667,11 @@ void cli_show_srte_policy(struct vty *vty, struct lyd_node *dnode,
|
||||
yang_dnode_get_string(dnode, "./endpoint"));
|
||||
}
|
||||
|
||||
void cli_show_srte_policy_end(struct vty *vty, struct lyd_node *dnode)
|
||||
{
|
||||
vty_out(vty, " exit\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* XPath: /frr-pathd:pathd/srte/policy/name
|
||||
*/
|
||||
@ -1237,6 +1243,15 @@ void cli_show_srte_policy_candidate_path(struct vty *vty,
|
||||
}
|
||||
}
|
||||
|
||||
void cli_show_srte_policy_candidate_path_end(struct vty *vty,
|
||||
struct lyd_node *dnode)
|
||||
{
|
||||
const char *type = yang_dnode_get_string(dnode, "./type");
|
||||
|
||||
if (strmatch(type, "dynamic"))
|
||||
vty_out(vty, " exit\n");
|
||||
}
|
||||
|
||||
static int config_write_dnode(const struct lyd_node *dnode, void *arg)
|
||||
{
|
||||
struct vty *vty = arg;
|
||||
@ -1249,29 +1264,20 @@ static int config_write_dnode(const struct lyd_node *dnode, void *arg)
|
||||
int config_write_segment_routing(struct vty *vty)
|
||||
{
|
||||
vty_out(vty, "segment-routing\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
int config_write_traffic_eng(struct vty *vty)
|
||||
{
|
||||
vty_out(vty, " traffic-eng\n");
|
||||
path_ted_config_write(vty);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int config_write_segment_lists(struct vty *vty)
|
||||
{
|
||||
path_ted_config_write(vty);
|
||||
|
||||
yang_dnode_iterate(config_write_dnode, vty, running_config->dnode,
|
||||
"/frr-pathd:pathd/srte/segment-list");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int config_write_sr_policies(struct vty *vty)
|
||||
{
|
||||
yang_dnode_iterate(config_write_dnode, vty, running_config->dnode,
|
||||
"/frr-pathd:pathd/srte/policy");
|
||||
|
||||
hook_call(pathd_srte_config_write, vty);
|
||||
|
||||
vty_out(vty, " exit\n");
|
||||
vty_out(vty, "exit\n");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -56,6 +56,7 @@ const struct frr_yang_module_info frr_pathd_info = {
|
||||
.cbs = {
|
||||
.create = pathd_srte_segment_list_create,
|
||||
.cli_show = cli_show_srte_segment_list,
|
||||
.cli_show_end = cli_show_srte_segment_list_end,
|
||||
.destroy = pathd_srte_segment_list_destroy,
|
||||
.get_next = pathd_srte_segment_list_get_next,
|
||||
.get_keys = pathd_srte_segment_list_get_keys,
|
||||
@ -136,6 +137,7 @@ const struct frr_yang_module_info frr_pathd_info = {
|
||||
.cbs = {
|
||||
.create = pathd_srte_policy_create,
|
||||
.cli_show = cli_show_srte_policy,
|
||||
.cli_show_end = cli_show_srte_policy_end,
|
||||
.destroy = pathd_srte_policy_destroy,
|
||||
.get_next = pathd_srte_policy_get_next,
|
||||
.get_keys = pathd_srte_policy_get_keys,
|
||||
@ -169,6 +171,7 @@ const struct frr_yang_module_info frr_pathd_info = {
|
||||
.cbs = {
|
||||
.create = pathd_srte_policy_candidate_path_create,
|
||||
.cli_show = cli_show_srte_policy_candidate_path,
|
||||
.cli_show_end = cli_show_srte_policy_candidate_path_end,
|
||||
.destroy = pathd_srte_policy_candidate_path_destroy,
|
||||
.get_next = pathd_srte_policy_candidate_path_get_next,
|
||||
.get_keys = pathd_srte_policy_candidate_path_get_keys,
|
||||
|
@ -112,10 +112,12 @@ void pathd_apply_finish(struct nb_cb_apply_finish_args *args);
|
||||
/* Optional 'cli_show' callbacks. */
|
||||
void cli_show_srte_segment_list(struct vty *vty, struct lyd_node *dnode,
|
||||
bool show_defaults);
|
||||
void cli_show_srte_segment_list_end(struct vty *vty, struct lyd_node *dnode);
|
||||
void cli_show_srte_segment_list_segment(struct vty *vty, struct lyd_node *dnode,
|
||||
bool show_defaults);
|
||||
void cli_show_srte_policy(struct vty *vty, struct lyd_node *dnode,
|
||||
bool show_defaults);
|
||||
void cli_show_srte_policy_end(struct vty *vty, struct lyd_node *dnode);
|
||||
void cli_show_srte_policy_name(struct vty *vty, struct lyd_node *dnode,
|
||||
bool show_defaults);
|
||||
void cli_show_srte_policy_binding_sid(struct vty *vty, struct lyd_node *dnode,
|
||||
@ -123,6 +125,8 @@ void cli_show_srte_policy_binding_sid(struct vty *vty, struct lyd_node *dnode,
|
||||
void cli_show_srte_policy_candidate_path(struct vty *vty,
|
||||
struct lyd_node *dnode,
|
||||
bool show_defaults);
|
||||
void cli_show_srte_policy_candidate_path_end(struct vty *vty,
|
||||
struct lyd_node *dnode);
|
||||
|
||||
/* Utility functions */
|
||||
typedef void (*of_pref_cp_t)(enum objfun_type type, void *arg);
|
||||
|
@ -175,7 +175,6 @@ static struct cmd_node pcep_node = {
|
||||
.name = "srte pcep",
|
||||
.node = PCEP_NODE,
|
||||
.parent_node = SR_TRAFFIC_ENG_NODE,
|
||||
.config_write = pcep_cli_pcep_config_write,
|
||||
.prompt = "%s(config-sr-te-pcep)# "
|
||||
};
|
||||
|
||||
@ -183,7 +182,6 @@ static struct cmd_node pcep_pcc_node = {
|
||||
.name = "srte pcep pcc",
|
||||
.node = PCEP_PCC_NODE,
|
||||
.parent_node = PCEP_NODE,
|
||||
.config_write = pcep_cli_pcc_config_write,
|
||||
.prompt = "%s(config-sr-te-pcep-pcc)# "
|
||||
};
|
||||
|
||||
@ -191,7 +189,6 @@ static struct cmd_node pcep_pce_node = {
|
||||
.name = "srte pcep pce",
|
||||
.node = PCEP_PCE_NODE,
|
||||
.parent_node = PCEP_NODE,
|
||||
.config_write = pcep_cli_pce_config_write,
|
||||
.prompt = "%s(config-sr-te-pcep-pce)# "
|
||||
};
|
||||
|
||||
@ -199,7 +196,6 @@ static struct cmd_node pcep_pce_config_node = {
|
||||
.name = "srte pcep pce-config",
|
||||
.node = PCEP_PCE_CONFIG_NODE,
|
||||
.parent_node = PCEP_NODE,
|
||||
.config_write = pcep_cli_pcep_pce_config_write,
|
||||
.prompt = "%s(pce-sr-te-pcep-pce-config)# "
|
||||
};
|
||||
|
||||
@ -1444,6 +1440,10 @@ int pcep_cli_debug_set_all(uint32_t flags, bool set)
|
||||
int pcep_cli_pcep_config_write(struct vty *vty)
|
||||
{
|
||||
vty_out(vty, " pcep\n");
|
||||
pcep_cli_pcep_pce_config_write(vty);
|
||||
pcep_cli_pce_config_write(vty);
|
||||
pcep_cli_pcc_config_write(vty);
|
||||
vty_out(vty, " exit\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -1468,7 +1468,7 @@ int pcep_cli_pcc_config_write(struct vty *vty)
|
||||
}
|
||||
|
||||
if (pce_connections_g.num_connections == 0) {
|
||||
return lines;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
buf[0] = 0;
|
||||
@ -1495,6 +1495,8 @@ int pcep_cli_pcc_config_write(struct vty *vty)
|
||||
lines++;
|
||||
buf[0] = 0;
|
||||
}
|
||||
exit:
|
||||
vty_out(vty, " exit\n");
|
||||
|
||||
return lines;
|
||||
}
|
||||
@ -1655,6 +1657,8 @@ int pcep_cli_pce_config_write(struct vty *vty)
|
||||
|
||||
vty_out(vty, "%s", buf);
|
||||
buf[0] = '\0';
|
||||
|
||||
vty_out(vty, " exit\n");
|
||||
}
|
||||
|
||||
return lines;
|
||||
@ -1679,6 +1683,8 @@ int pcep_cli_pcep_pce_config_write(struct vty *vty)
|
||||
pcep_cli_print_pce_config(group_opts, buf, sizeof(buf));
|
||||
vty_out(vty, "%s", buf);
|
||||
buf[0] = 0;
|
||||
|
||||
vty_out(vty, " exit\n");
|
||||
}
|
||||
|
||||
return lines;
|
||||
@ -1999,6 +2005,7 @@ DEFPY(pcep_cli_clear_srte_pcep_session,
|
||||
|
||||
void pcep_cli_init(void)
|
||||
{
|
||||
hook_register(pathd_srte_config_write, pcep_cli_pcep_config_write);
|
||||
hook_register(nb_client_debug_config_write,
|
||||
pcep_cli_debug_config_write);
|
||||
hook_register(nb_client_debug_set_all, pcep_cli_debug_set_all);
|
||||
|
@ -34,6 +34,8 @@
|
||||
|
||||
DECLARE_MGROUP(PATHD);
|
||||
|
||||
DECLARE_HOOK(pathd_srte_config_write, (struct vty *vty), (vty));
|
||||
|
||||
enum srte_protocol_origin {
|
||||
SRTE_ORIGIN_UNDEFINED = 0,
|
||||
SRTE_ORIGIN_PCEP = 1,
|
||||
|
@ -1118,7 +1118,7 @@ static int pbr_interface_config_write(struct vty *vty)
|
||||
|
||||
pbr_map_write_interfaces(vty, ifp);
|
||||
|
||||
vty_endframe(vty, "!\n");
|
||||
vty_endframe(vty, "exit\n!\n");
|
||||
}
|
||||
}
|
||||
|
||||
@ -1184,6 +1184,7 @@ static int pbr_vty_map_config_write_sequence(struct vty *vty,
|
||||
pbrms_nexthop_group_write_individual_nexthop(vty, pbrms);
|
||||
}
|
||||
|
||||
vty_out(vty, "exit\n");
|
||||
vty_out(vty, "!\n");
|
||||
return 1;
|
||||
}
|
||||
|
@ -220,7 +220,7 @@ static int pim_vrf_config_write(struct vty *vty)
|
||||
pim_global_config_write_worker(pim, vty);
|
||||
|
||||
if (vrf->vrf_id != VRF_DEFAULT)
|
||||
vty_endframe(vty, " exit-vrf\n!\n");
|
||||
vty_endframe(vty, "exit-vrf\n!\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -451,7 +451,7 @@ int pim_interface_config_write(struct vty *vty)
|
||||
pim_bfd_write_config(vty, ifp);
|
||||
++writes;
|
||||
}
|
||||
vty_endframe(vty, "!\n");
|
||||
vty_endframe(vty, "exit\n!\n");
|
||||
++writes;
|
||||
}
|
||||
}
|
||||
|
@ -3281,6 +3281,8 @@ static int config_write_rip(struct vty *vty)
|
||||
/* Interface routemap configuration */
|
||||
config_write_if_rmap(vty, rip->if_rmap_ctx);
|
||||
|
||||
vty_out(vty, "exit\n");
|
||||
|
||||
write = 1;
|
||||
}
|
||||
|
||||
|
@ -2270,6 +2270,8 @@ static int ripng_config_write(struct vty *vty)
|
||||
config_write_distribute(vty, ripng->distribute_ctx);
|
||||
config_write_if_rmap(vty, ripng->if_rmap_ctx);
|
||||
|
||||
vty_out(vty, "exit\n");
|
||||
|
||||
write = 1;
|
||||
}
|
||||
|
||||
|
@ -164,7 +164,7 @@ static int static_vrf_config_write(struct vty *vty)
|
||||
SAFI_UNICAST, "ipv6 route");
|
||||
|
||||
if (vrf->vrf_id != VRF_DEFAULT)
|
||||
vty_endframe(vty, " exit-vrf\n!\n");
|
||||
vty_endframe(vty, "exit-vrf\n!\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -315,7 +315,6 @@ domainname test.domain
|
||||
!
|
||||
!
|
||||
!
|
||||
line vty
|
||||
!
|
||||
end
|
||||
test# conf t
|
||||
@ -332,7 +331,6 @@ domainname test.domain
|
||||
!
|
||||
!
|
||||
!
|
||||
line vty
|
||||
!
|
||||
end
|
||||
foohost(config)#
|
||||
|
@ -513,9 +513,6 @@ class Config(object):
|
||||
Parse the configuration and create contexts for each appropriate block
|
||||
"""
|
||||
|
||||
current_context_lines = []
|
||||
ctx_keys = []
|
||||
|
||||
"""
|
||||
The end of a context is flagged via the 'end' keyword:
|
||||
|
||||
@ -574,43 +571,80 @@ end
|
||||
# key of the context. So "router bgp 10" is the key for the non-address
|
||||
# family part of bgp, "router bgp 10, address-family ipv6 unicast" is
|
||||
# the key for the subcontext and so on.
|
||||
ctx_keys = []
|
||||
main_ctx_key = []
|
||||
new_ctx = True
|
||||
|
||||
# the keywords that we know are single line contexts. bgp in this case
|
||||
# is not the main router bgp block, but enabling multi-instance
|
||||
oneline_ctx_keywords = (
|
||||
"access-list ",
|
||||
"agentx",
|
||||
"allow-external-route-update",
|
||||
"bgp ",
|
||||
"debug ",
|
||||
"domainname ",
|
||||
"dump ",
|
||||
"enable ",
|
||||
"evpn mh",
|
||||
"frr ",
|
||||
"fpm ",
|
||||
"hostname ",
|
||||
"ip ",
|
||||
"ipv6 ",
|
||||
"log ",
|
||||
"mac access-list ",
|
||||
"mpls lsp",
|
||||
"mpls label",
|
||||
"no ",
|
||||
"password ",
|
||||
"pbr ",
|
||||
"ptm-enable",
|
||||
"router-id ",
|
||||
"service ",
|
||||
"table ",
|
||||
"username ",
|
||||
"vni ",
|
||||
"vrrp autoconfigure",
|
||||
"zebra "
|
||||
)
|
||||
# This dictionary contains a tree of all commands that we know start a
|
||||
# new multi-line context. All other commands are treated either as
|
||||
# commands inside a multi-line context or as single-line contexts. This
|
||||
# dictionary should be updated whenever a new node is added to FRR.
|
||||
ctx_keywords = {
|
||||
"router bgp ": {
|
||||
"address-family ": {
|
||||
"vni ": {},
|
||||
},
|
||||
"vnc ": {},
|
||||
"vrf-policy ": {},
|
||||
"bmp ": {},
|
||||
"segment-routing srv6": {},
|
||||
},
|
||||
"router rip": {},
|
||||
"router ripng": {},
|
||||
"router isis ": {},
|
||||
"router openfabric ": {},
|
||||
"router ospf": {},
|
||||
"router ospf6": {},
|
||||
"router eigrp ": {},
|
||||
"router babel": {},
|
||||
"mpls ldp": {
|
||||
"address-family ": {
|
||||
"interface ": {}
|
||||
}
|
||||
},
|
||||
"l2vpn ": {
|
||||
"member pseudowire ": {}
|
||||
},
|
||||
"key chain ": {
|
||||
"key ": {}
|
||||
},
|
||||
"vrf ": {},
|
||||
"interface ": {
|
||||
"link-params": {}
|
||||
},
|
||||
"pseudowire ": {},
|
||||
"segment-routing": {
|
||||
"traffic-eng": {
|
||||
"segment-list ": {},
|
||||
"policy ": {
|
||||
"candidate-path ": {}
|
||||
},
|
||||
"pcep": {
|
||||
"pcc": {},
|
||||
"pce ": {},
|
||||
"pce-config ": {}
|
||||
}
|
||||
},
|
||||
"srv6": {
|
||||
"locators": {
|
||||
"locator ": {}
|
||||
}
|
||||
}
|
||||
},
|
||||
"nexthop-group ": {},
|
||||
"route-map ": {},
|
||||
"pbr-map ": {},
|
||||
"rpki": {},
|
||||
"bfd": {
|
||||
"peer ": {},
|
||||
"profile ": {}
|
||||
},
|
||||
"line vty": {}
|
||||
}
|
||||
|
||||
# stack of context keys
|
||||
ctx_keys = []
|
||||
# stack of context keywords
|
||||
cur_ctx_keywords = [ctx_keywords]
|
||||
# list of stored commands
|
||||
cur_ctx_lines = []
|
||||
|
||||
for line in self.lines:
|
||||
|
||||
@ -620,357 +654,77 @@ end
|
||||
if line.startswith("!") or line.startswith("#"):
|
||||
continue
|
||||
|
||||
if (
|
||||
len(ctx_keys) == 2
|
||||
and ctx_keys[0].startswith("bfd")
|
||||
and ctx_keys[1].startswith("profile ")
|
||||
and line == "end"
|
||||
):
|
||||
log.debug("LINE %-50s: popping from sub context, %-50s", line, ctx_keys)
|
||||
|
||||
if main_ctx_key:
|
||||
self.save_contexts(ctx_keys, current_context_lines)
|
||||
ctx_keys = copy.deepcopy(main_ctx_key)
|
||||
current_context_lines = []
|
||||
if line.startswith("exit"):
|
||||
# ignore on top level
|
||||
if len(ctx_keys) == 0:
|
||||
continue
|
||||
|
||||
# one line contexts
|
||||
# there is one exception though: ldpd accepts a 'router-id' clause
|
||||
# as part of its 'mpls ldp' config context. If we are processing
|
||||
# ldp configuration and encounter a router-id we should NOT switch
|
||||
# to a new context
|
||||
if (
|
||||
new_ctx is True
|
||||
and any(line.startswith(keyword) for keyword in oneline_ctx_keywords)
|
||||
and not (
|
||||
ctx_keys
|
||||
and ctx_keys[0].startswith("mpls ldp")
|
||||
and line.startswith("router-id ")
|
||||
)
|
||||
):
|
||||
self.save_contexts(ctx_keys, current_context_lines)
|
||||
# save current context
|
||||
self.save_contexts(ctx_keys, cur_ctx_lines)
|
||||
|
||||
# Start a new context
|
||||
main_ctx_key = []
|
||||
ctx_keys = [
|
||||
line,
|
||||
]
|
||||
current_context_lines = []
|
||||
# exit current context
|
||||
log.debug("LINE %-50s: exit context %-50s", line, ctx_keys)
|
||||
|
||||
log.debug("LINE %-50s: entering new context, %-50s", line, ctx_keys)
|
||||
self.save_contexts(ctx_keys, current_context_lines)
|
||||
new_ctx = True
|
||||
ctx_keys.pop()
|
||||
cur_ctx_keywords.pop()
|
||||
cur_ctx_lines = []
|
||||
|
||||
elif line == "end":
|
||||
self.save_contexts(ctx_keys, current_context_lines)
|
||||
log.debug("LINE %-50s: exiting old context, %-50s", line, ctx_keys)
|
||||
continue
|
||||
|
||||
# Start a new context
|
||||
new_ctx = True
|
||||
main_ctx_key = []
|
||||
ctx_keys = []
|
||||
current_context_lines = []
|
||||
if line.startswith("end"):
|
||||
# exit all contexts
|
||||
while len(ctx_keys) > 0:
|
||||
# save current context
|
||||
self.save_contexts(ctx_keys, cur_ctx_lines)
|
||||
|
||||
elif line == "exit" and ctx_keys[0].startswith("rpki"):
|
||||
self.save_contexts(ctx_keys, current_context_lines)
|
||||
log.debug("LINE %-50s: exiting old context, %-50s", line, ctx_keys)
|
||||
# exit current context
|
||||
log.debug("LINE %-50s: exit context %-50s", line, ctx_keys)
|
||||
|
||||
# Start a new context
|
||||
new_ctx = True
|
||||
main_ctx_key = []
|
||||
ctx_keys = []
|
||||
current_context_lines = []
|
||||
ctx_keys.pop()
|
||||
cur_ctx_keywords.pop()
|
||||
cur_ctx_lines = []
|
||||
|
||||
elif line == "exit-vrf":
|
||||
self.save_contexts(ctx_keys, current_context_lines)
|
||||
current_context_lines.append(line)
|
||||
log.debug(
|
||||
"LINE %-50s: append to current_context_lines, %-50s", line, ctx_keys
|
||||
)
|
||||
continue
|
||||
|
||||
# Start a new context
|
||||
new_ctx = True
|
||||
main_ctx_key = []
|
||||
ctx_keys = []
|
||||
current_context_lines = []
|
||||
new_ctx = False
|
||||
|
||||
elif (
|
||||
line == "exit"
|
||||
and len(ctx_keys) > 1
|
||||
and ctx_keys[0].startswith("segment-routing")
|
||||
):
|
||||
self.save_contexts(ctx_keys, current_context_lines)
|
||||
# check if the line is a context-entering keyword
|
||||
for k, v in cur_ctx_keywords[-1].items():
|
||||
if line.startswith(k):
|
||||
# candidate-path is a special case. It may be a node and
|
||||
# may be a single-line command. The distinguisher is the
|
||||
# word "dynamic" or "explicit" at the middle of the line.
|
||||
# It was perhaps not the best choice by the pathd authors
|
||||
# but we have what we have.
|
||||
if k == "candidate-path " and "explicit" in line:
|
||||
# this is a single-line command
|
||||
break
|
||||
|
||||
# Start a new context
|
||||
ctx_keys = ctx_keys[:-1]
|
||||
current_context_lines = []
|
||||
log.debug(
|
||||
"LINE %-50s: popping segment routing sub-context to ctx%-50s",
|
||||
line,
|
||||
ctx_keys,
|
||||
)
|
||||
# save current context
|
||||
self.save_contexts(ctx_keys, cur_ctx_lines)
|
||||
|
||||
elif line in ["exit-address-family", "exit", "exit-vnc"]:
|
||||
# if this exit is for address-family ipv4 unicast, ignore the pop
|
||||
if main_ctx_key:
|
||||
self.save_contexts(ctx_keys, current_context_lines)
|
||||
|
||||
# Start a new context
|
||||
ctx_keys = copy.deepcopy(main_ctx_key)
|
||||
current_context_lines = []
|
||||
log.debug(
|
||||
"LINE %-50s: popping from subcontext to ctx%-50s",
|
||||
line,
|
||||
ctx_keys,
|
||||
)
|
||||
|
||||
elif line in ["exit-vni", "exit-ldp-if"]:
|
||||
if sub_main_ctx_key:
|
||||
self.save_contexts(ctx_keys, current_context_lines)
|
||||
|
||||
# Start a new context
|
||||
ctx_keys = copy.deepcopy(sub_main_ctx_key)
|
||||
current_context_lines = []
|
||||
log.debug(
|
||||
"LINE %-50s: popping from sub-subcontext to ctx%-50s",
|
||||
line,
|
||||
ctx_keys,
|
||||
)
|
||||
|
||||
elif new_ctx is True:
|
||||
if not main_ctx_key:
|
||||
ctx_keys = [
|
||||
line,
|
||||
]
|
||||
else:
|
||||
ctx_keys = copy.deepcopy(main_ctx_key)
|
||||
main_ctx_key = []
|
||||
|
||||
current_context_lines = []
|
||||
new_ctx = False
|
||||
log.debug("LINE %-50s: entering new context, %-50s", line, ctx_keys)
|
||||
|
||||
elif (
|
||||
line.startswith("address-family ")
|
||||
or line.startswith("vnc defaults")
|
||||
or line.startswith("vnc l2-group")
|
||||
or line.startswith("vnc nve-group")
|
||||
or line.startswith("peer")
|
||||
or line.startswith("key ")
|
||||
or line.startswith("member pseudowire")
|
||||
):
|
||||
main_ctx_key = []
|
||||
|
||||
# Save old context first
|
||||
self.save_contexts(ctx_keys, current_context_lines)
|
||||
current_context_lines = []
|
||||
main_ctx_key = copy.deepcopy(ctx_keys)
|
||||
log.debug("LINE %-50s: entering sub-context, append to ctx_keys", line)
|
||||
|
||||
if line == "address-family ipv6" and not ctx_keys[0].startswith(
|
||||
"mpls ldp"
|
||||
):
|
||||
ctx_keys.append("address-family ipv6 unicast")
|
||||
elif line == "address-family ipv4" and not ctx_keys[0].startswith(
|
||||
"mpls ldp"
|
||||
):
|
||||
ctx_keys.append("address-family ipv4 unicast")
|
||||
elif line == "address-family evpn":
|
||||
ctx_keys.append("address-family l2vpn evpn")
|
||||
else:
|
||||
# enter new context
|
||||
new_ctx = True
|
||||
ctx_keys.append(line)
|
||||
cur_ctx_keywords.append(v)
|
||||
cur_ctx_lines = []
|
||||
|
||||
elif (
|
||||
line.startswith("vni ")
|
||||
and len(ctx_keys) == 2
|
||||
and ctx_keys[0].startswith("router bgp")
|
||||
and ctx_keys[1] == "address-family l2vpn evpn"
|
||||
):
|
||||
log.debug("LINE %-50s: enter context %-50s", line, ctx_keys)
|
||||
break
|
||||
|
||||
# Save old context first
|
||||
self.save_contexts(ctx_keys, current_context_lines)
|
||||
current_context_lines = []
|
||||
sub_main_ctx_key = copy.deepcopy(ctx_keys)
|
||||
log.debug(
|
||||
"LINE %-50s: entering sub-sub-context, append to ctx_keys", line
|
||||
)
|
||||
ctx_keys.append(line)
|
||||
|
||||
elif (
|
||||
line.startswith("interface ")
|
||||
and len(ctx_keys) == 2
|
||||
and ctx_keys[0].startswith("mpls ldp")
|
||||
and ctx_keys[1].startswith("address-family")
|
||||
):
|
||||
|
||||
# Save old context first
|
||||
self.save_contexts(ctx_keys, current_context_lines)
|
||||
current_context_lines = []
|
||||
sub_main_ctx_key = copy.deepcopy(ctx_keys)
|
||||
log.debug(
|
||||
"LINE %-50s: entering sub-sub-context, append to ctx_keys", line
|
||||
)
|
||||
ctx_keys.append(line)
|
||||
|
||||
elif (
|
||||
line.startswith("traffic-eng")
|
||||
and len(ctx_keys) == 1
|
||||
and ctx_keys[0].startswith("segment-routing")
|
||||
):
|
||||
|
||||
# Save old context first
|
||||
self.save_contexts(ctx_keys, current_context_lines)
|
||||
current_context_lines = []
|
||||
log.debug(
|
||||
"LINE %-50s: entering segment routing sub-context, append to ctx_keys",
|
||||
line,
|
||||
)
|
||||
ctx_keys.append(line)
|
||||
|
||||
elif (
|
||||
line.startswith("segment-list ")
|
||||
and len(ctx_keys) == 2
|
||||
and ctx_keys[0].startswith("segment-routing")
|
||||
and ctx_keys[1].startswith("traffic-eng")
|
||||
):
|
||||
|
||||
# Save old context first
|
||||
self.save_contexts(ctx_keys, current_context_lines)
|
||||
current_context_lines = []
|
||||
log.debug(
|
||||
"LINE %-50s: entering segment routing sub-context, append to ctx_keys",
|
||||
line,
|
||||
)
|
||||
ctx_keys.append(line)
|
||||
|
||||
elif (
|
||||
line.startswith("policy ")
|
||||
and len(ctx_keys) == 2
|
||||
and ctx_keys[0].startswith("segment-routing")
|
||||
and ctx_keys[1].startswith("traffic-eng")
|
||||
):
|
||||
|
||||
# Save old context first
|
||||
self.save_contexts(ctx_keys, current_context_lines)
|
||||
current_context_lines = []
|
||||
log.debug(
|
||||
"LINE %-50s: entering segment routing sub-context, append to ctx_keys",
|
||||
line,
|
||||
)
|
||||
ctx_keys.append(line)
|
||||
|
||||
elif (
|
||||
line.startswith("candidate-path ")
|
||||
and line.endswith(" dynamic")
|
||||
and len(ctx_keys) == 3
|
||||
and ctx_keys[0].startswith("segment-routing")
|
||||
and ctx_keys[1].startswith("traffic-eng")
|
||||
and ctx_keys[2].startswith("policy")
|
||||
):
|
||||
|
||||
# Save old context first
|
||||
self.save_contexts(ctx_keys, current_context_lines)
|
||||
current_context_lines = []
|
||||
main_ctx_key = copy.deepcopy(ctx_keys)
|
||||
log.debug(
|
||||
"LINE %-50s: entering candidate-path sub-context, append to ctx_keys",
|
||||
line,
|
||||
)
|
||||
ctx_keys.append(line)
|
||||
|
||||
elif (
|
||||
line.startswith("pcep")
|
||||
and len(ctx_keys) == 2
|
||||
and ctx_keys[0].startswith("segment-routing")
|
||||
and ctx_keys[1].startswith("traffic-eng")
|
||||
):
|
||||
|
||||
# Save old context first
|
||||
self.save_contexts(ctx_keys, current_context_lines)
|
||||
current_context_lines = []
|
||||
main_ctx_key = copy.deepcopy(ctx_keys)
|
||||
log.debug(
|
||||
"LINE %-50s: entering pcep sub-context, append to ctx_keys", line
|
||||
)
|
||||
ctx_keys.append(line)
|
||||
|
||||
elif (
|
||||
line.startswith("pce-config ")
|
||||
and len(ctx_keys) == 3
|
||||
and ctx_keys[0].startswith("segment-routing")
|
||||
and ctx_keys[1].startswith("traffic-eng")
|
||||
and ctx_keys[2].startswith("pcep")
|
||||
):
|
||||
|
||||
# Save old context first
|
||||
self.save_contexts(ctx_keys, current_context_lines)
|
||||
current_context_lines = []
|
||||
main_ctx_key = copy.deepcopy(ctx_keys)
|
||||
log.debug(
|
||||
"LINE %-50s: entering pce-config sub-context, append to ctx_keys",
|
||||
line,
|
||||
)
|
||||
ctx_keys.append(line)
|
||||
|
||||
elif (
|
||||
line.startswith("pce ")
|
||||
and len(ctx_keys) == 3
|
||||
and ctx_keys[0].startswith("segment-routing")
|
||||
and ctx_keys[1].startswith("traffic-eng")
|
||||
and ctx_keys[2].startswith("pcep")
|
||||
):
|
||||
|
||||
# Save old context first
|
||||
self.save_contexts(ctx_keys, current_context_lines)
|
||||
current_context_lines = []
|
||||
main_ctx_key = copy.deepcopy(ctx_keys)
|
||||
log.debug(
|
||||
"LINE %-50s: entering pce sub-context, append to ctx_keys", line
|
||||
)
|
||||
ctx_keys.append(line)
|
||||
|
||||
elif (
|
||||
line.startswith("pcc")
|
||||
and len(ctx_keys) == 3
|
||||
and ctx_keys[0].startswith("segment-routing")
|
||||
and ctx_keys[1].startswith("traffic-eng")
|
||||
and ctx_keys[2].startswith("pcep")
|
||||
):
|
||||
|
||||
# Save old context first
|
||||
self.save_contexts(ctx_keys, current_context_lines)
|
||||
current_context_lines = []
|
||||
main_ctx_key = copy.deepcopy(ctx_keys)
|
||||
log.debug(
|
||||
"LINE %-50s: entering pcc sub-context, append to ctx_keys", line
|
||||
)
|
||||
ctx_keys.append(line)
|
||||
|
||||
elif (
|
||||
line.startswith("profile ")
|
||||
and len(ctx_keys) == 1
|
||||
and ctx_keys[0].startswith("bfd")
|
||||
):
|
||||
|
||||
# Save old context first
|
||||
self.save_contexts(ctx_keys, current_context_lines)
|
||||
current_context_lines = []
|
||||
main_ctx_key = copy.deepcopy(ctx_keys)
|
||||
log.debug(
|
||||
"LINE %-50s: entering BFD profile sub-context, append to ctx_keys",
|
||||
line,
|
||||
)
|
||||
ctx_keys.append(line)
|
||||
if new_ctx:
|
||||
continue
|
||||
|
||||
if len(ctx_keys) == 0:
|
||||
log.debug("LINE %-50s: single-line context", line)
|
||||
self.save_contexts([line], [])
|
||||
else:
|
||||
# Continuing in an existing context, add non-commented lines to it
|
||||
current_context_lines.append(line)
|
||||
log.debug(
|
||||
"LINE %-50s: append to current_context_lines, %-50s", line, ctx_keys
|
||||
)
|
||||
log.debug("LINE %-50s: add to current context %-50s", line, ctx_keys)
|
||||
cur_ctx_lines.append(line)
|
||||
|
||||
# Save the context of the last one
|
||||
self.save_contexts(ctx_keys, current_context_lines)
|
||||
if len(ctx_keys) > 0:
|
||||
self.save_contexts(ctx_keys, cur_ctx_lines)
|
||||
|
||||
|
||||
def lines_to_config(ctx_keys, line, delete):
|
||||
|
@ -272,16 +272,11 @@ void vtysh_config_parse_line(void *arg, const char *line)
|
||||
strlen(" ip igmp query-interval")) == 0) {
|
||||
config_add_line_uniq_end(config->line, line);
|
||||
} else if (config->index == LINK_PARAMS_NODE
|
||||
&& strncmp(line, " exit-link-params",
|
||||
strlen(" exit"))
|
||||
&& strncmp(line, " exit-link-params",
|
||||
strlen(" exit"))
|
||||
== 0) {
|
||||
config_add_line(config->line, line);
|
||||
config->index = INTERFACE_NODE;
|
||||
} else if (config->index == VRF_NODE
|
||||
&& strncmp(line, " exit-vrf",
|
||||
strlen(" exit-vrf"))
|
||||
== 0) {
|
||||
config_add_line_uniq_end(config->line, line);
|
||||
} else if (!strncmp(line, " vrrp", strlen(" vrrp"))
|
||||
|| !strncmp(line, " no vrrp",
|
||||
strlen(" no vrrp"))) {
|
||||
@ -300,7 +295,10 @@ void vtysh_config_parse_line(void *arg, const char *line)
|
||||
config_add_line(config_top, line);
|
||||
break;
|
||||
default:
|
||||
if (strncmp(line, "interface", strlen("interface")) == 0)
|
||||
if (strncmp(line, "exit", strlen("exit")) == 0) {
|
||||
if (config)
|
||||
config_add_line_uniq_end(config->line, line);
|
||||
} else if (strncmp(line, "interface", strlen("interface")) == 0)
|
||||
config = config_get(INTERFACE_NODE, line);
|
||||
else if (strncmp(line, "pseudowire", strlen("pseudowire")) == 0)
|
||||
config = config_get(PW_NODE, line);
|
||||
@ -496,7 +494,9 @@ void vtysh_config_dump(void)
|
||||
* are not under the VRF node.
|
||||
*/
|
||||
if (config->index == INTERFACE_NODE
|
||||
&& list_isempty(config->line)) {
|
||||
&& (listcount(config->line) == 1)
|
||||
&& (line = listnode_head(config->line))
|
||||
&& strmatch(line, "exit")) {
|
||||
config_del(config);
|
||||
continue;
|
||||
}
|
||||
|
@ -4096,7 +4096,7 @@ static int link_params_config_write(struct vty *vty, struct interface *ifp)
|
||||
if (IS_PARAM_SET(iflp, LP_RMT_AS))
|
||||
vty_out(vty, " neighbor %pI4 as %u\n", &iflp->rmt_ip,
|
||||
iflp->rmt_as);
|
||||
vty_out(vty, " exit-link-params\n");
|
||||
vty_out(vty, " exit-link-params\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -4188,7 +4188,7 @@ static int if_config_write(struct vty *vty)
|
||||
zebra_evpn_mh_if_write(vty, ifp);
|
||||
link_params_config_write(vty, ifp);
|
||||
|
||||
vty_endframe(vty, "!\n");
|
||||
vty_endframe(vty, "exit\n!\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -836,6 +836,7 @@ static int zebra_pw_config(struct vty *vty)
|
||||
if (!(pw->flags & F_PSEUDOWIRE_CWORD))
|
||||
vty_out(vty, " control-word exclude\n");
|
||||
|
||||
vty_out(vty, "exit\n");
|
||||
vty_out(vty, "!\n");
|
||||
write = 1;
|
||||
}
|
||||
|
@ -320,10 +320,14 @@ static int zebra_sr_config(struct vty *vty)
|
||||
vty_out(vty, " locator %s\n", locator->name);
|
||||
vty_out(vty, " prefix %s/%u\n", str,
|
||||
locator->prefix.prefixlen);
|
||||
vty_out(vty, " exit\n");
|
||||
vty_out(vty, " !\n");
|
||||
}
|
||||
vty_out(vty, " exit\n");
|
||||
vty_out(vty, " !\n");
|
||||
vty_out(vty, " exit\n");
|
||||
vty_out(vty, " !\n");
|
||||
vty_out(vty, "exit\n");
|
||||
vty_out(vty, "!\n");
|
||||
}
|
||||
return 0;
|
||||
|
@ -524,7 +524,7 @@ static int vrf_config_write(struct vty *vty)
|
||||
router_id_write(vty, zvrf);
|
||||
|
||||
if (zvrf_id(zvrf) != VRF_DEFAULT)
|
||||
vty_endframe(vty, " exit-vrf\n!\n");
|
||||
vty_endframe(vty, "exit-vrf\n!\n");
|
||||
else
|
||||
vty_out(vty, "!\n");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user