diff options
51 files changed, 372 insertions, 547 deletions
diff --git a/babeld/babel_interface.c b/babeld/babel_interface.c index c1e5ffde3c..615ed9fee3 100644 --- a/babeld/babel_interface.c +++ b/babeld/babel_interface.c @@ -1362,7 +1362,7 @@ interface_config_write (struct vty *vty) write++; } } - vty_endframe (vty, "!\n"); + vty_endframe (vty, "exit\n!\n"); write++; } return write; diff --git a/babeld/babeld.c b/babeld/babeld.c index b9623b64b5..f61eac000f 100644 --- a/babeld/babeld.c +++ b/babeld/babeld.c @@ -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; } @@ -819,7 +821,7 @@ babeld_quagga_init(void) install_element(BABEL_NODE, &babel_ipv6_distribute_list_cmd); install_element(BABEL_NODE, &babel_no_ipv6_distribute_list_cmd); - vrf_cmd_init(NULL, &babeld_privs); + vrf_cmd_init(NULL); babel_if_init(); diff --git a/bfdd/bfdd_cli.c b/bfdd/bfdd_cli.c index 26ff4a758a..384bb26fd7 100644 --- a/bfdd/bfdd_cli.c +++ b/bfdd/bfdd_cli.c @@ -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"); } diff --git a/bgpd/bgp_bmp.c b/bgpd/bgp_bmp.c index dbc35de80b..1bc3fd0dba 100644 --- a/bgpd/bgp_bmp.c +++ b/bgpd/bgp_bmp.c @@ -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; diff --git a/bgpd/bgp_rpki.c b/bgpd/bgp_rpki.c index 286612da15..ca3f93899b 100644 --- a/bgpd/bgp_rpki.c +++ b/bgpd/bgp_rpki.c @@ -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; } diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 27f147a4aa..715a768fd8 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -1662,7 +1662,7 @@ DEFPY (no_bgp_send_extra_data, DEFUN (bgp_confederation_identifier, bgp_confederation_identifier_cmd, "bgp confederation identifier (1-4294967295)", - "BGP specific commands\n" + BGP_STR "AS confederation parameters\n" "AS number\n" "Set routing domain confederation AS\n") @@ -1682,7 +1682,7 @@ DEFUN (no_bgp_confederation_identifier, no_bgp_confederation_identifier_cmd, "no bgp confederation identifier [(1-4294967295)]", NO_STR - "BGP specific commands\n" + BGP_STR "AS confederation parameters\n" "AS number\n" "Set routing domain confederation AS\n") @@ -1696,7 +1696,7 @@ DEFUN (no_bgp_confederation_identifier, DEFUN (bgp_confederation_peers, bgp_confederation_peers_cmd, "bgp confederation peers (1-4294967295)...", - "BGP specific commands\n" + BGP_STR "AS confederation parameters\n" "Peer ASs in BGP confederation\n" AS_STR) @@ -1724,7 +1724,7 @@ DEFUN (no_bgp_confederation_peers, no_bgp_confederation_peers_cmd, "no bgp confederation peers (1-4294967295)...", NO_STR - "BGP specific commands\n" + BGP_STR "AS confederation parameters\n" "Peer ASs in BGP confederation\n" AS_STR) @@ -2336,7 +2336,7 @@ DEFUN (no_bgp_timers, DEFUN (bgp_client_to_client_reflection, bgp_client_to_client_reflection_cmd, "bgp client-to-client reflection", - "BGP specific commands\n" + BGP_STR "Configure client to client route reflection\n" "reflection of routes allowed\n") { @@ -2351,7 +2351,7 @@ DEFUN (no_bgp_client_to_client_reflection, no_bgp_client_to_client_reflection_cmd, "no bgp client-to-client reflection", NO_STR - "BGP specific commands\n" + BGP_STR "Configure client to client route reflection\n" "reflection of routes allowed\n") { @@ -2366,7 +2366,7 @@ DEFUN (no_bgp_client_to_client_reflection, DEFUN (bgp_always_compare_med, bgp_always_compare_med_cmd, "bgp always-compare-med", - "BGP specific commands\n" + BGP_STR "Allow comparing MED from different neighbors\n") { VTY_DECLVAR_CONTEXT(bgp, bgp); @@ -2380,7 +2380,7 @@ DEFUN (no_bgp_always_compare_med, no_bgp_always_compare_med_cmd, "no bgp always-compare-med", NO_STR - "BGP specific commands\n" + BGP_STR "Allow comparing MED from different neighbors\n") { VTY_DECLVAR_CONTEXT(bgp, bgp); @@ -2393,7 +2393,7 @@ DEFUN (no_bgp_always_compare_med, DEFUN(bgp_ebgp_requires_policy, bgp_ebgp_requires_policy_cmd, "bgp ebgp-requires-policy", - "BGP specific commands\n" + BGP_STR "Require in and out policy for eBGP peers (RFC8212)\n") { VTY_DECLVAR_CONTEXT(bgp, bgp); @@ -2404,7 +2404,7 @@ DEFUN(bgp_ebgp_requires_policy, bgp_ebgp_requires_policy_cmd, DEFUN(no_bgp_ebgp_requires_policy, no_bgp_ebgp_requires_policy_cmd, "no bgp ebgp-requires-policy", NO_STR - "BGP specific commands\n" + BGP_STR "Require in and out policy for eBGP peers (RFC8212)\n") { VTY_DECLVAR_CONTEXT(bgp, bgp); @@ -2414,7 +2414,7 @@ DEFUN(no_bgp_ebgp_requires_policy, no_bgp_ebgp_requires_policy_cmd, DEFUN(bgp_suppress_duplicates, bgp_suppress_duplicates_cmd, "bgp suppress-duplicates", - "BGP specific commands\n" + BGP_STR "Suppress duplicate updates if the route actually not changed\n") { VTY_DECLVAR_CONTEXT(bgp, bgp); @@ -2425,7 +2425,7 @@ DEFUN(bgp_suppress_duplicates, bgp_suppress_duplicates_cmd, DEFUN(no_bgp_suppress_duplicates, no_bgp_suppress_duplicates_cmd, "no bgp suppress-duplicates", NO_STR - "BGP specific commands\n" + BGP_STR "Suppress duplicate updates if the route actually not changed\n") { VTY_DECLVAR_CONTEXT(bgp, bgp); @@ -2435,7 +2435,7 @@ DEFUN(no_bgp_suppress_duplicates, no_bgp_suppress_duplicates_cmd, DEFUN(bgp_reject_as_sets, bgp_reject_as_sets_cmd, "bgp reject-as-sets", - "BGP specific commands\n" + BGP_STR "Reject routes with AS_SET or AS_CONFED_SET flag\n") { VTY_DECLVAR_CONTEXT(bgp, bgp); @@ -2461,7 +2461,7 @@ DEFUN(bgp_reject_as_sets, bgp_reject_as_sets_cmd, DEFUN(no_bgp_reject_as_sets, no_bgp_reject_as_sets_cmd, "no bgp reject-as-sets", NO_STR - "BGP specific commands\n" + BGP_STR "Reject routes with AS_SET or AS_CONFED_SET flag\n") { VTY_DECLVAR_CONTEXT(bgp, bgp); @@ -2488,7 +2488,7 @@ DEFUN(no_bgp_reject_as_sets, no_bgp_reject_as_sets_cmd, DEFUN (bgp_deterministic_med, bgp_deterministic_med_cmd, "bgp deterministic-med", - "BGP specific commands\n" + BGP_STR "Pick the best-MED path among paths advertised from the neighboring AS\n") { VTY_DECLVAR_CONTEXT(bgp, bgp); @@ -2505,7 +2505,7 @@ DEFUN (no_bgp_deterministic_med, no_bgp_deterministic_med_cmd, "no bgp deterministic-med", NO_STR - "BGP specific commands\n" + BGP_STR "Pick the best-MED path among paths advertised from the neighboring AS\n") { VTY_DECLVAR_CONTEXT(bgp, bgp); @@ -2547,7 +2547,7 @@ DEFUN (no_bgp_deterministic_med, DEFUN (bgp_graceful_restart, bgp_graceful_restart_cmd, "bgp graceful-restart", - "BGP specific commands\n" + BGP_STR GR_CMD ) { @@ -2574,7 +2574,7 @@ DEFUN (no_bgp_graceful_restart, no_bgp_graceful_restart_cmd, "no bgp graceful-restart", NO_STR - "BGP specific commands\n" + BGP_STR NO_GR_CMD ) { @@ -2601,7 +2601,7 @@ DEFUN (no_bgp_graceful_restart, DEFUN (bgp_graceful_restart_stalepath_time, bgp_graceful_restart_stalepath_time_cmd, "bgp graceful-restart stalepath-time (1-4095)", - "BGP specific commands\n" + BGP_STR "Graceful restart capability parameters\n" "Set the max time to hold onto restarting peer's stale paths\n" "Delay value (seconds)\n") @@ -2618,7 +2618,7 @@ DEFUN (bgp_graceful_restart_stalepath_time, DEFUN (bgp_graceful_restart_restart_time, bgp_graceful_restart_restart_time_cmd, "bgp graceful-restart restart-time (1-4095)", - "BGP specific commands\n" + BGP_STR "Graceful restart capability parameters\n" "Set the time to wait to delete stale routes before a BGP open message is received\n" "Delay value (seconds)\n") @@ -2635,7 +2635,7 @@ DEFUN (bgp_graceful_restart_restart_time, DEFUN (bgp_graceful_restart_select_defer_time, bgp_graceful_restart_select_defer_time_cmd, "bgp graceful-restart select-defer-time (0-3600)", - "BGP specific commands\n" + BGP_STR "Graceful restart capability parameters\n" "Set the time to defer the BGP route selection after restart\n" "Delay value (seconds, 0 - disable)\n") @@ -2658,7 +2658,7 @@ DEFUN (no_bgp_graceful_restart_stalepath_time, no_bgp_graceful_restart_stalepath_time_cmd, "no bgp graceful-restart stalepath-time [(1-4095)]", NO_STR - "BGP specific commands\n" + BGP_STR "Graceful restart capability parameters\n" "Set the max time to hold onto restarting peer's stale paths\n" "Delay value (seconds)\n") @@ -2673,7 +2673,7 @@ DEFUN (no_bgp_graceful_restart_restart_time, no_bgp_graceful_restart_restart_time_cmd, "no bgp graceful-restart restart-time [(1-4095)]", NO_STR - "BGP specific commands\n" + BGP_STR "Graceful restart capability parameters\n" "Set the time to wait to delete stale routes before a BGP open message is received\n" "Delay value (seconds)\n") @@ -2688,7 +2688,7 @@ DEFUN (no_bgp_graceful_restart_select_defer_time, no_bgp_graceful_restart_select_defer_time_cmd, "no bgp graceful-restart select-defer-time [(0-3600)]", NO_STR - "BGP specific commands\n" + BGP_STR "Graceful restart capability parameters\n" "Set the time to defer the BGP route selection after restart\n" "Delay value (seconds)\n") @@ -2704,7 +2704,7 @@ DEFUN (no_bgp_graceful_restart_select_defer_time, DEFUN (bgp_graceful_restart_preserve_fw, bgp_graceful_restart_preserve_fw_cmd, "bgp graceful-restart preserve-fw-state", - "BGP specific commands\n" + BGP_STR "Graceful restart capability parameters\n" "Sets F-bit indication that fib is preserved while doing Graceful Restart\n") { @@ -2717,7 +2717,7 @@ DEFUN (no_bgp_graceful_restart_preserve_fw, no_bgp_graceful_restart_preserve_fw_cmd, "no bgp graceful-restart preserve-fw-state", NO_STR - "BGP specific commands\n" + BGP_STR "Graceful restart capability parameters\n" "Unsets F-bit indication that fib is preserved while doing Graceful Restart\n") { @@ -2729,7 +2729,7 @@ DEFUN (no_bgp_graceful_restart_preserve_fw, DEFUN (bgp_graceful_restart_disable, bgp_graceful_restart_disable_cmd, "bgp graceful-restart-disable", - "BGP specific commands\n" + BGP_STR GR_DISABLE) { int ret = BGP_GR_FAILURE; @@ -2758,7 +2758,7 @@ DEFUN (no_bgp_graceful_restart_disable, no_bgp_graceful_restart_disable_cmd, "no bgp graceful-restart-disable", NO_STR - "BGP specific commands\n" + BGP_STR NO_GR_DISABLE ) { @@ -3011,7 +3011,7 @@ DEFUN (no_bgp_neighbor_graceful_restart_disable, DEFUN_HIDDEN (bgp_graceful_restart_disable_eor, bgp_graceful_restart_disable_eor_cmd, "bgp graceful-restart disable-eor", - "BGP specific commands\n" + BGP_STR "Graceful restart configuration parameters\n" "Disable EOR Check\n") { @@ -3025,7 +3025,7 @@ DEFUN_HIDDEN (no_bgp_graceful_restart_disable_eor, no_bgp_graceful_restart_disable_eor_cmd, "no bgp graceful-restart disable-eor", NO_STR - "BGP specific commands\n" + BGP_STR "Graceful restart configuration parameters\n" "Disable EOR Check\n") { @@ -3038,7 +3038,7 @@ DEFUN_HIDDEN (no_bgp_graceful_restart_disable_eor, DEFUN (bgp_graceful_restart_rib_stale_time, bgp_graceful_restart_rib_stale_time_cmd, "bgp graceful-restart rib-stale-time (1-3600)", - "BGP specific commands\n" + BGP_STR "Graceful restart configuration parameters\n" "Specify the stale route removal timer in rib\n" "Delay value (seconds)\n") @@ -3060,7 +3060,7 @@ DEFUN (no_bgp_graceful_restart_rib_stale_time, no_bgp_graceful_restart_rib_stale_time_cmd, "no bgp graceful-restart rib-stale-time [(1-3600)]", NO_STR - "BGP specific commands\n" + BGP_STR "Graceful restart configuration parameters\n" "Specify the stale route removal timer in rib\n" "Delay value (seconds)\n") @@ -3220,7 +3220,7 @@ DEFUN (no_bgp_fast_external_failover, DEFUN (bgp_bestpath_compare_router_id, bgp_bestpath_compare_router_id_cmd, "bgp bestpath compare-routerid", - "BGP specific commands\n" + BGP_STR "Change the default bestpath selection\n" "Compare router-id for identical EBGP paths\n") { @@ -3235,7 +3235,7 @@ DEFUN (no_bgp_bestpath_compare_router_id, no_bgp_bestpath_compare_router_id_cmd, "no bgp bestpath compare-routerid", NO_STR - "BGP specific commands\n" + BGP_STR "Change the default bestpath selection\n" "Compare router-id for identical EBGP paths\n") { @@ -3250,7 +3250,7 @@ DEFUN (no_bgp_bestpath_compare_router_id, DEFUN (bgp_bestpath_aspath_ignore, bgp_bestpath_aspath_ignore_cmd, "bgp bestpath as-path ignore", - "BGP specific commands\n" + BGP_STR "Change the default bestpath selection\n" "AS-path attribute\n" "Ignore as-path length in selecting a route\n") @@ -3266,7 +3266,7 @@ DEFUN (no_bgp_bestpath_aspath_ignore, no_bgp_bestpath_aspath_ignore_cmd, "no bgp bestpath as-path ignore", NO_STR - "BGP specific commands\n" + BGP_STR "Change the default bestpath selection\n" "AS-path attribute\n" "Ignore as-path length in selecting a route\n") @@ -3282,7 +3282,7 @@ DEFUN (no_bgp_bestpath_aspath_ignore, DEFUN (bgp_bestpath_aspath_confed, bgp_bestpath_aspath_confed_cmd, "bgp bestpath as-path confed", - "BGP specific commands\n" + BGP_STR "Change the default bestpath selection\n" "AS-path attribute\n" "Compare path lengths including confederation sets & sequences in selecting a route\n") @@ -3298,7 +3298,7 @@ DEFUN (no_bgp_bestpath_aspath_confed, no_bgp_bestpath_aspath_confed_cmd, "no bgp bestpath as-path confed", NO_STR - "BGP specific commands\n" + BGP_STR "Change the default bestpath selection\n" "AS-path attribute\n" "Compare path lengths including confederation sets & sequences in selecting a route\n") @@ -3314,7 +3314,7 @@ DEFUN (no_bgp_bestpath_aspath_confed, DEFUN (bgp_bestpath_aspath_multipath_relax, bgp_bestpath_aspath_multipath_relax_cmd, "bgp bestpath as-path multipath-relax [<as-set|no-as-set>]", - "BGP specific commands\n" + BGP_STR "Change the default bestpath selection\n" "AS-path attribute\n" "Allow load sharing across routes that have different AS paths (but same length)\n" @@ -3341,7 +3341,7 @@ DEFUN (no_bgp_bestpath_aspath_multipath_relax, no_bgp_bestpath_aspath_multipath_relax_cmd, "no bgp bestpath as-path multipath-relax [<as-set|no-as-set>]", NO_STR - "BGP specific commands\n" + BGP_STR "Change the default bestpath selection\n" "AS-path attribute\n" "Allow load sharing across routes that have different AS paths (but same length)\n" @@ -3391,7 +3391,7 @@ DEFUN(no_bgp_bestpath_peer_type_multipath_relax, DEFUN (bgp_log_neighbor_changes, bgp_log_neighbor_changes_cmd, "bgp log-neighbor-changes", - "BGP specific commands\n" + BGP_STR "Log neighbor up/down and reset reason\n") { VTY_DECLVAR_CONTEXT(bgp, bgp); @@ -3403,7 +3403,7 @@ DEFUN (no_bgp_log_neighbor_changes, no_bgp_log_neighbor_changes_cmd, "no bgp log-neighbor-changes", NO_STR - "BGP specific commands\n" + BGP_STR "Log neighbor up/down and reset reason\n") { VTY_DECLVAR_CONTEXT(bgp, bgp); @@ -3415,7 +3415,7 @@ DEFUN (no_bgp_log_neighbor_changes, DEFUN (bgp_bestpath_med, bgp_bestpath_med_cmd, "bgp bestpath med <confed [missing-as-worst]|missing-as-worst [confed]>", - "BGP specific commands\n" + BGP_STR "Change the default bestpath selection\n" "MED attribute\n" "Compare MED among confederation paths\n" @@ -3441,7 +3441,7 @@ DEFUN (no_bgp_bestpath_med, no_bgp_bestpath_med_cmd, "no bgp bestpath med <confed [missing-as-worst]|missing-as-worst [confed]>", NO_STR - "BGP specific commands\n" + BGP_STR "Change the default bestpath selection\n" "MED attribute\n" "Compare MED among confederation paths\n" @@ -3467,7 +3467,7 @@ DEFUN (no_bgp_bestpath_med, DEFPY (bgp_bestpath_bw, bgp_bestpath_bw_cmd, "bgp bestpath bandwidth <ignore|skip-missing|default-weight-for-missing>$bw_cfg", - "BGP specific commands\n" + BGP_STR "Change the default bestpath selection\n" "Link Bandwidth attribute\n" "Ignore link bandwidth (i.e., do regular ECMP, not weighted)\n" @@ -3505,7 +3505,7 @@ DEFPY (no_bgp_bestpath_bw, no_bgp_bestpath_bw_cmd, "no bgp bestpath bandwidth [<ignore|skip-missing|default-weight-for-missing>$bw_cfg]", NO_STR - "BGP specific commands\n" + BGP_STR "Change the default bestpath selection\n" "Link Bandwidth attribute\n" "Ignore link bandwidth (i.e., do regular ECMP, not weighted)\n" @@ -3540,7 +3540,7 @@ DEFPY(bgp_default_afi_safi, bgp_default_afi_safi_cmd, "ipv6-flowspec|" "l2vpn-evpn>$afi_safi", NO_STR - "BGP specific commands\n" + BGP_STR "Configure BGP defaults\n" "Activate ipv4-unicast for a peer by default\n" "Activate ipv4-multicast for a peer by default\n" @@ -3588,7 +3588,7 @@ DEFPY(bgp_default_afi_safi, bgp_default_afi_safi_cmd, DEFUN (bgp_default_show_hostname, bgp_default_show_hostname_cmd, "bgp default show-hostname", - "BGP specific commands\n" + BGP_STR "Configure BGP defaults\n" "Show hostname in certain command outputs\n") { @@ -3601,7 +3601,7 @@ DEFUN (no_bgp_default_show_hostname, no_bgp_default_show_hostname_cmd, "no bgp default show-hostname", NO_STR - "BGP specific commands\n" + BGP_STR "Configure BGP defaults\n" "Show hostname in certain command outputs\n") { @@ -3614,7 +3614,7 @@ DEFUN (no_bgp_default_show_hostname, DEFUN (bgp_default_show_nexthop_hostname, bgp_default_show_nexthop_hostname_cmd, "bgp default show-nexthop-hostname", - "BGP specific commands\n" + BGP_STR "Configure BGP defaults\n" "Show hostname for nexthop in certain command outputs\n") { @@ -3627,7 +3627,7 @@ DEFUN (no_bgp_default_show_nexthop_hostname, no_bgp_default_show_nexthop_hostname_cmd, "no bgp default show-nexthop-hostname", NO_STR - "BGP specific commands\n" + BGP_STR "Configure BGP defaults\n" "Show hostname for nexthop in certain command outputs\n") { @@ -3640,7 +3640,7 @@ DEFUN (no_bgp_default_show_nexthop_hostname, DEFUN (bgp_network_import_check, bgp_network_import_check_cmd, "bgp network import-check", - "BGP specific commands\n" + BGP_STR "BGP network command\n" "Check BGP network route exists in IGP\n") { @@ -3655,7 +3655,7 @@ DEFUN (bgp_network_import_check, ALIAS_HIDDEN(bgp_network_import_check, bgp_network_import_check_exact_cmd, "bgp network import-check exact", - "BGP specific commands\n" + BGP_STR "BGP network command\n" "Check BGP network route exists in IGP\n" "Match route precisely\n") @@ -3664,7 +3664,7 @@ DEFUN (no_bgp_network_import_check, no_bgp_network_import_check_cmd, "no bgp network import-check", NO_STR - "BGP specific commands\n" + BGP_STR "BGP network command\n" "Check BGP network route exists in IGP\n") { @@ -3680,7 +3680,7 @@ DEFUN (no_bgp_network_import_check, DEFUN (bgp_default_local_preference, bgp_default_local_preference_cmd, "bgp default local-preference (0-4294967295)", - "BGP specific commands\n" + BGP_STR "Configure BGP defaults\n" "local preference (higher=more preferred)\n" "Configure default local preference value\n") @@ -3701,7 +3701,7 @@ DEFUN (no_bgp_default_local_preference, no_bgp_default_local_preference_cmd, "no bgp default local-preference [(0-4294967295)]", NO_STR - "BGP specific commands\n" + BGP_STR "Configure BGP defaults\n" "local preference (higher=more preferred)\n" "Configure default local preference value\n") @@ -3717,7 +3717,7 @@ DEFUN (no_bgp_default_local_preference, DEFUN (bgp_default_subgroup_pkt_queue_max, bgp_default_subgroup_pkt_queue_max_cmd, "bgp default subgroup-pkt-queue-max (20-100)", - "BGP specific commands\n" + BGP_STR "Configure BGP defaults\n" "subgroup-pkt-queue-max\n" "Configure subgroup packet queue max\n") @@ -3737,7 +3737,7 @@ DEFUN (no_bgp_default_subgroup_pkt_queue_max, no_bgp_default_subgroup_pkt_queue_max_cmd, "no bgp default subgroup-pkt-queue-max [(20-100)]", NO_STR - "BGP specific commands\n" + BGP_STR "Configure BGP defaults\n" "subgroup-pkt-queue-max\n" "Configure subgroup packet queue max\n") @@ -3751,7 +3751,7 @@ DEFUN (no_bgp_default_subgroup_pkt_queue_max, DEFUN (bgp_rr_allow_outbound_policy, bgp_rr_allow_outbound_policy_cmd, "bgp route-reflector allow-outbound-policy", - "BGP specific commands\n" + BGP_STR "Allow modifications made by out route-map\n" "on ibgp neighbors\n") { @@ -3770,7 +3770,7 @@ DEFUN (no_bgp_rr_allow_outbound_policy, no_bgp_rr_allow_outbound_policy_cmd, "no bgp route-reflector allow-outbound-policy", NO_STR - "BGP specific commands\n" + BGP_STR "Allow modifications made by out route-map\n" "on ibgp neighbors\n") { @@ -3788,7 +3788,7 @@ DEFUN (no_bgp_rr_allow_outbound_policy, DEFUN (bgp_listen_limit, bgp_listen_limit_cmd, "bgp listen limit (1-65535)", - "BGP specific commands\n" + BGP_STR "BGP Dynamic Neighbors listen commands\n" "Maximum number of BGP Dynamic Neighbors that can be created\n" "Configure Dynamic Neighbors listen limit value\n") @@ -3808,7 +3808,7 @@ DEFUN (no_bgp_listen_limit, no_bgp_listen_limit_cmd, "no bgp listen limit [(1-65535)]", NO_STR - "BGP specific commands\n" + BGP_STR "BGP Dynamic Neighbors listen commands\n" "Maximum number of BGP Dynamic Neighbors that can be created\n" "Configure Dynamic Neighbors listen limit value\n") @@ -3853,7 +3853,7 @@ static struct peer_group *listen_range_exists(struct bgp *bgp, DEFUN (bgp_listen_range, bgp_listen_range_cmd, "bgp listen range <A.B.C.D/M|X:X::X:X/M> peer-group PGNAME", - "BGP specific commands\n" + BGP_STR "Configure BGP dynamic neighbors listen range\n" "Configure BGP dynamic neighbors listen range\n" NEIGHBOR_ADDR_STR @@ -3924,7 +3924,7 @@ DEFUN (no_bgp_listen_range, no_bgp_listen_range_cmd, "no bgp listen range <A.B.C.D/M|X:X::X:X/M> peer-group PGNAME", NO_STR - "BGP specific commands\n" + BGP_STR "Unconfigure BGP dynamic neighbors listen range\n" "Unconfigure BGP dynamic neighbors listen range\n" NEIGHBOR_ADDR_STR @@ -3998,7 +3998,7 @@ void bgp_config_write_listen(struct vty *vty, struct bgp *bgp) DEFUN (bgp_disable_connected_route_check, bgp_disable_connected_route_check_cmd, "bgp disable-ebgp-connected-route-check", - "BGP specific commands\n" + BGP_STR "Disable checking if nexthop is connected on ebgp sessions\n") { VTY_DECLVAR_CONTEXT(bgp, bgp); @@ -4012,7 +4012,7 @@ DEFUN (no_bgp_disable_connected_route_check, no_bgp_disable_connected_route_check_cmd, "no bgp disable-ebgp-connected-route-check", NO_STR - "BGP specific commands\n" + BGP_STR "Disable checking if nexthop is connected on ebgp sessions\n") { VTY_DECLVAR_CONTEXT(bgp, bgp); @@ -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; diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index 739c953ebf..5ef49e5108 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -838,6 +838,12 @@ bool bgp_zebra_nexthop_set(union sockunion *local, union sockunion *remote, if (direct) v6_ll_avail = if_get_ipv6_local( ifp, &nexthop->v6_local); + /* + * It's fine to not have a v6 LL when using + * update-source loopback/vrf + */ + if (!v6_ll_avail && if_is_loopback_or_vrf(ifp)) + v6_ll_avail = true; } else /* Link-local address. */ { diff --git a/bgpd/rfapi/bgp_rfapi_cfg.c b/bgpd/rfapi/bgp_rfapi_cfg.c index cc64261388..2437bd8cfe 100644 --- a/bgpd/rfapi/bgp_rfapi_cfg.c +++ b/bgpd/rfapi/bgp_rfapi_cfg.c @@ -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 */ diff --git a/doc/user/bgp.rst b/doc/user/bgp.rst index bc4827129a..819a6ab562 100644 --- a/doc/user/bgp.rst +++ b/doc/user/bgp.rst @@ -424,8 +424,8 @@ Administrative Distance Metrics .. clicmd:: distance bgp (1-255) (1-255) (1-255) - This command change distance value of BGP. The arguments are the distance - values for for external routes, internal routes and local routes + This command changes distance value of BGP. The arguments are the distance + values for external routes, internal routes and local routes respectively. .. clicmd:: distance (1-255) A.B.C.D/M @@ -959,7 +959,7 @@ BGP GR Global Mode Commands .. clicmd:: bgp graceful-restart - This command will enable BGP graceful restart ifunctionality at the global + This command will enable BGP graceful restart functionality at the global level. .. clicmd:: bgp graceful-restart disable @@ -975,7 +975,7 @@ BGP GR Peer Mode Commands .. clicmd:: neighbor A.B.C.D graceful-restart - This command will enable BGP graceful restart ifunctionality at the peer + This command will enable BGP graceful restart functionality at the peer level. .. clicmd:: neighbor A.B.C.D graceful-restart-helper @@ -1082,7 +1082,7 @@ IPv6 Support This configuration demonstrates how the 'no bgp default ipv4-unicast' might be used in a setup with two upstreams where each of the upstreams should only - receive either IPv4 or IPv6 annocuments. + receive either IPv4 or IPv6 announcements. Using the ``bgp default ipv6-unicast`` configuration, IPv6 unicast address family is enabled by default for all new neighbors. @@ -1263,7 +1263,7 @@ Redistribute routes from other protocols into BGP. This feature is used to enable read-only mode on BGP process restart or when a BGP process is cleared using 'clear ip bgp \*'. Note that this command is - configured under the specific bgp instance/vrf that the feaure is enabled for. + configured under the specific bgp instance/vrf that the feature is enabled for. It cannot be used at the same time as the global "bgp update-delay" described above, which is entered at the global level and applies to all bgp instances. The global and per-vrf approaches to defining update-delay are mutually @@ -1368,7 +1368,7 @@ Defining Peers limit is set to 100 by default. Increasing this value will really be possible if more file descriptors are available in the BGP process. This value is defined by the underlying system (ulimit value), and can be - overriden by `--limit-fds`. More information is available in chapter + overridden by `--limit-fds`. More information is available in chapter (:ref:`common-invocation-options`). .. clicmd:: coalesce-time (0-4294967295) @@ -1555,7 +1555,7 @@ Configuring Peers can't connect them directly. This is an alternative to `neighbor WORD as-override`. - The parameter `(1-10)` configures the amount of accepted occurences of the + The parameter `(1-10)` configures the amount of accepted occurrences of the system AS number in AS path. The parameter `origin` configures BGP to only accept routes originated with @@ -2566,7 +2566,7 @@ BGP routes may be leaked (i.e. copied) between a unicast VRF RIB and the VPN SAFI RIB of the default VRF for use in MPLS-based L3VPNs. Unicast routes may also be leaked between any VRFs (including the unicast RIB of the default BGP instanced). A shortcut syntax is also available for specifying leaking from one -VRF to another VRF using the default instance's VPN RIB as the intemediary. A +VRF to another VRF using the default instance's VPN RIB as the intermediary. A common application of the VRF-VRF feature is to connect a customer's private routing domain to a provider's VPN service. Leaking is configured from the point of view of an individual VRF: ``import`` refers to routes leaked from VPN @@ -2747,7 +2747,7 @@ the same behavior of using same next-hop and RMAC values. .. clicmd:: advertise-pip [ip <addr> [mac <addr>]] -Enables or disables advertise-pip feature, specifiy system-IP and/or system-MAC +Enables or disables advertise-pip feature, specify system-IP and/or system-MAC parameters. EVPN advertise-svi-ip @@ -2803,7 +2803,7 @@ Topology requirements: 1. This feature is supported for asymmetric routing model only. While sending packets to SN1, ingress PE (PE2) performs routing and egress PE (PE1) performs only bridging. -2. This feature supports only tratitional(non vlan-aware) bridge model. Bridge +2. This feature supports only traditional(non vlan-aware) bridge model. Bridge interface associated with L2VNI is an L3 interface. i.e., this interface is configured with an address in the L2VNI subnet. Note that the gateway IP should also have an address in the same subnet. @@ -2881,7 +2881,7 @@ This group of server links is referred to as an Ethernet Segment. Ethernet Segments """"""""""""""""" An Ethernet Segment can be configured by specifying a system-MAC and a -local discriminatior against the bond interface on the PE (via zebra) - +local discriminator against the bond interface on the PE (via zebra) - .. clicmd:: evpn mh es-id (1-16777215) @@ -2912,7 +2912,7 @@ The DF preference is configurable per-ES (via zebra) - BUM traffic is rxed via the overlay by all PEs attached to a server but only the DF can forward the de-capsulated traffic to the access port. To -accomodate that non-DF filters are installed in the dataplane to drop +accommodate that non-DF filters are installed in the dataplane to drop the traffic. Similarly traffic received from ES peers via the overlay cannot be forwarded @@ -3472,12 +3472,12 @@ structure is extended with :clicmd:`show bgp [afi] [safi]`. .. clicmd:: show bgp [afi] [safi] [all] summary failed [json] - Show a bgp peer summary for peers that are not succesfully exchanging routes + Show a bgp peer summary for peers that are not successfully exchanging routes for the specified address family, and subsequent address-family. .. clicmd:: show bgp [afi] [safi] [all] summary established [json] - Show a bgp peer summary for peers that are succesfully exchanging routes + Show a bgp peer summary for peers that are successfully exchanging routes for the specified address family, and subsequent address-family. .. clicmd:: show bgp [afi] [safi] [all] summary neighbor [PEER] [json] @@ -3635,7 +3635,7 @@ attribute. If ``summary`` option is specified, output is a summary of the counts for the chunks, inuse, ledger and requests list along with the count of - outstanding chunk requests to Zebra and the nummber of zebra reconnects + outstanding chunk requests to Zebra and the number of zebra reconnects that have happened If ``json`` option is specified, output is displayed in JSON format. diff --git a/eigrpd/eigrp_cli.c b/eigrpd/eigrp_cli.c index 35536979ea..533d7de2c2 100644 --- a/eigrpd/eigrp_cli.c +++ b/eigrpd/eigrp_cli.c @@ -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"); } @@ -909,7 +910,7 @@ eigrp_cli_init(void) install_element(EIGRP_NODE, &eigrp_neighbor_cmd); install_element(EIGRP_NODE, &eigrp_redistribute_source_metric_cmd); - vrf_cmd_init(NULL, &eigrpd_privs); + vrf_cmd_init(NULL); if_cmd_init(eigrp_write_interface); diff --git a/isisd/isis_circuit.c b/isisd/isis_circuit.c index a78e4996b4..6f4a91be67 100644 --- a/isisd/isis_circuit.c +++ b/isisd/isis_circuit.c @@ -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; diff --git a/isisd/isis_cli.c b/isisd/isis_cli.c index ef86d47b22..70ec66fd7f 100644 --- a/isisd/isis_cli.c +++ b/isisd/isis_cli.c @@ -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 diff --git a/isisd/isis_nb.c b/isisd/isis_nb.c index ecad16229c..f62a8d4813 100644 --- a/isisd/isis_nb.c +++ b/isisd/isis_nb.c @@ -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, }, diff --git a/isisd/isis_nb.h b/isisd/isis_nb.h index 0c2f7b6b7e..4680dd5ded 100644 --- a/isisd/isis_nb.h +++ b/isisd/isis_nb.h @@ -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, diff --git a/isisd/isisd.c b/isisd/isisd.c index 43efa0164d..65764654ee 100644 --- a/isisd/isisd.c +++ b/isisd/isisd.c @@ -701,7 +701,7 @@ void isis_vrf_init(void) vrf_init(isis_vrf_new, isis_vrf_enable, isis_vrf_disable, isis_vrf_delete, isis_vrf_enable); - vrf_cmd_init(NULL, &isisd_privs); + vrf_cmd_init(NULL); } void isis_terminate() @@ -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"); } } diff --git a/ldpd/ldp_vty_conf.c b/ldpd/ldp_vty_conf.c index b35d3dfa00..fbd718bb09 100644 --- a/ldpd/ldp_vty_conf.c +++ b/ldpd/ldp_vty_conf.c @@ -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"); } @@ -366,6 +366,9 @@ int zclient_bfd_command(struct zclient *zc, struct bfd_session_arg *args) if (args->ifnamelen) stream_put(s, args->ifname, args->ifnamelen); } + + /* Send the C bit indicator. */ + stream_putc(s, args->cbit); #endif /* HAVE_BFDD */ /* Finish the message by writing the size. */ @@ -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, diff --git a/lib/keychain.c b/lib/keychain.c index db5c23b1ba..02f83ef0a8 100644 --- a/lib/keychain.c +++ b/lib/keychain.c @@ -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"); } diff --git a/lib/nexthop_group.c b/lib/nexthop_group.c index 4fee9bde3c..97d70189ff 100644 --- a/lib/nexthop_group.c +++ b/lib/nexthop_group.c @@ -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"); } diff --git a/lib/routemap_cli.c b/lib/routemap_cli.c index 58c62e614f..045a8cddd8 100644 --- a/lib/routemap_cli.c +++ b/lib/routemap_cli.c @@ -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"); } @@ -907,8 +907,7 @@ void vrf_install_commands(void) install_element(ENABLE_NODE, &no_vrf_debug_cmd); } -void vrf_cmd_init(int (*writefunc)(struct vty *vty), - struct zebra_privs_t *daemon_privs) +void vrf_cmd_init(int (*writefunc)(struct vty *vty)) { install_element(CONFIG_NODE, &vrf_cmd); install_element(CONFIG_NODE, &no_vrf_cmd); @@ -285,8 +285,7 @@ extern int vrf_switchback_to_initial(void); /* VRF vty command initialisation */ -extern void vrf_cmd_init(int (*writefunc)(struct vty *vty), - struct zebra_privs_t *daemon_priv); +extern void vrf_cmd_init(int (*writefunc)(struct vty *vty)); /* VRF vty debugging */ @@ -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"); diff --git a/nhrpd/nhrp_vty.c b/nhrpd/nhrp_vty.c index 60ce1e6523..50161dae2f 100644 --- a/nhrpd/nhrp_vty.c +++ b/nhrpd/nhrp_vty.c @@ -1225,7 +1225,7 @@ static int interface_config_write(struct vty *vty) } } - vty_endframe(vty, "!\n"); + vty_endframe(vty, "exit\n!\n"); } return 0; @@ -1259,7 +1259,7 @@ void nhrp_config_init(void) install_element(CONFIG_NODE, &nhrp_multicast_nflog_group_cmd); install_element(CONFIG_NODE, &no_nhrp_multicast_nflog_group_cmd); - vrf_cmd_init(NULL, &nhrpd_privs); + vrf_cmd_init(NULL); /* interface specific commands */ if_cmd_init(interface_config_write); diff --git a/ospf6d/ospf6_interface.c b/ospf6d/ospf6_interface.c index bbb474ba1a..b427a0c9bd 100644 --- a/ospf6d/ospf6_interface.c +++ b/ospf6d/ospf6_interface.c @@ -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; } diff --git a/ospf6d/ospf6_top.c b/ospf6d/ospf6_top.c index fc181a6d18..6ff3789a80 100644 --- a/ospf6d/ospf6_top.c +++ b/ospf6d/ospf6_top.c @@ -238,7 +238,7 @@ void ospf6_vrf_init(void) vrf_init(ospf6_vrf_new, ospf6_vrf_enable, ospf6_vrf_disable, ospf6_vrf_delete, ospf6_vrf_enable); - vrf_cmd_init(NULL, &ospf6d_privs); + vrf_cmd_init(NULL); } static void ospf6_top_lsdb_hook_add(struct ospf6_lsa *lsa) @@ -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; diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index 4c248c0df3..715aa896af 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -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; } @@ -12984,7 +12986,7 @@ void ospf_vty_init(void) install_element(OSPF_NODE, &ospf_max_multipath_cmd); install_element(OSPF_NODE, &no_ospf_max_multipath_cmd); - vrf_cmd_init(NULL, &ospfd_privs); + vrf_cmd_init(NULL); /* Init interface related vty commands. */ ospf_vty_if_init(); diff --git a/pathd/path_cli.c b/pathd/path_cli.c index d517d75e47..bd629a2b70 100644 --- a/pathd/path_cli.c +++ b/pathd/path_cli.c @@ -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) -{ 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; } diff --git a/pathd/path_nb.c b/pathd/path_nb.c index 9c622883bc..1ab8b7f39b 100644 --- a/pathd/path_nb.c +++ b/pathd/path_nb.c @@ -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, diff --git a/pathd/path_nb.h b/pathd/path_nb.h index caeadd9ccc..6a918b8b82 100644 --- a/pathd/path_nb.h +++ b/pathd/path_nb.h @@ -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); diff --git a/pathd/path_pcep_cli.c b/pathd/path_pcep_cli.c index db5f256a86..829df3179c 100644 --- a/pathd/path_pcep_cli.c +++ b/pathd/path_pcep_cli.c @@ -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); diff --git a/pathd/pathd.h b/pathd/pathd.h index f790a0e3c9..81d7aa9105 100644 --- a/pathd/pathd.h +++ b/pathd/pathd.h @@ -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, diff --git a/pbrd/pbr_vty.c b/pbrd/pbr_vty.c index 2936d1e346..d083b9d2b0 100644 --- a/pbrd/pbr_vty.c +++ b/pbrd/pbr_vty.c @@ -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; } @@ -1229,7 +1230,7 @@ void pbr_vty_init(void) { cmd_variable_handler_register(pbr_map_name); - vrf_cmd_init(NULL, &pbr_privs); + vrf_cmd_init(NULL); if_cmd_init(pbr_interface_config_write); diff --git a/pimd/pim_igmpv3.c b/pimd/pim_igmpv3.c index 572d3a6aba..bc67a1dd1d 100644 --- a/pimd/pim_igmpv3.c +++ b/pimd/pim_igmpv3.c @@ -509,8 +509,22 @@ static void allow(struct igmp_sock *igmp, struct in_addr from, So, deleting the group present. */ group = find_group_by_addr(igmp, group_addr); - if (group && (group->group_filtermode_isexcl == 0)) + if (!group) { + return; + } + if (group->group_filtermode_isexcl) { + if (listcount(group->group_source_list) == 1) { + struct in_addr star = {.s_addr = INADDR_ANY}; + + source = igmp_find_source_by_addr(group, star); + if (source) + igmp_source_reset_gmi(igmp, group, + source); + } + } else { igmp_group_delete(group); + } + return; } @@ -544,15 +558,6 @@ static void allow(struct igmp_sock *igmp, struct in_addr from, igmp_source_reset_gmi(igmp, group, source); } /* scan received sources */ - - if ((num_sources == 0) && (group->group_filtermode_isexcl) - && (listcount(group->group_source_list) == 1)) { - struct in_addr star = {.s_addr = INADDR_ANY}; - - source = igmp_find_source_by_addr(group, star); - if (source) - igmp_source_reset_gmi(igmp, group, source); - } } void igmpv3_report_isin(struct igmp_sock *igmp, struct in_addr from, diff --git a/pimd/pim_instance.c b/pimd/pim_instance.c index 6dda66b79a..5322c48f67 100644 --- a/pimd/pim_instance.c +++ b/pimd/pim_instance.c @@ -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; @@ -231,7 +231,7 @@ void pim_vrf_init(void) vrf_init(pim_vrf_new, pim_vrf_enable, pim_vrf_disable, pim_vrf_delete, NULL); - vrf_cmd_init(pim_vrf_config_write, &pimd_privs); + vrf_cmd_init(pim_vrf_config_write); } void pim_vrf_terminate(void) diff --git a/pimd/pim_mroute.c b/pimd/pim_mroute.c index ab6d8c17df..7743bcc510 100644 --- a/pimd/pim_mroute.c +++ b/pimd/pim_mroute.c @@ -668,19 +668,15 @@ static int pim_mroute_msg(struct pim_instance *pim, const char *buf, case IGMPMSG_WRONGVIF: return pim_mroute_msg_wrongvif(pim->mroute_socket, ifp, msg); - break; case IGMPMSG_NOCACHE: return pim_mroute_msg_nocache(pim->mroute_socket, ifp, msg); - break; case IGMPMSG_WHOLEPKT: return pim_mroute_msg_wholepkt(pim->mroute_socket, ifp, (const char *)msg); - break; case IGMPMSG_WRVIFWHOLE: return pim_mroute_msg_wrvifwhole( pim->mroute_socket, ifp, (const char *)msg); - break; default: break; } diff --git a/pimd/pim_pim.c b/pimd/pim_pim.c index e7ac0d4e5b..8c38cf6c4c 100644 --- a/pimd/pim_pim.c +++ b/pimd/pim_pim.c @@ -322,7 +322,6 @@ int pim_pim_packet(struct interface *ifp, uint8_t *buf, size_t len) } return -1; } - return -1; } static void pim_sock_read_on(struct interface *ifp); @@ -514,7 +513,7 @@ static int pim_msg_send_frame(int fd, char *buf, size_t len, { struct ip *ip = (struct ip *)buf; - while (sendto(fd, buf, len, MSG_DONTWAIT, dst, salen) < 0) { + if (sendto(fd, buf, len, MSG_DONTWAIT, dst, salen) < 0) { char dst_str[INET_ADDRSTRLEN]; switch (errno) { diff --git a/pimd/pim_rpf.c b/pimd/pim_rpf.c index 98944e8fed..66c6df65ad 100644 --- a/pimd/pim_rpf.c +++ b/pimd/pim_rpf.c @@ -419,8 +419,6 @@ int pim_rpf_addr_is_inaddr_none(struct pim_rpf *rpf) default: return 0; } - - return 0; } int pim_rpf_addr_is_inaddr_any(struct pim_rpf *rpf) @@ -434,8 +432,6 @@ int pim_rpf_addr_is_inaddr_any(struct pim_rpf *rpf) default: return 0; } - - return 0; } int pim_rpf_is_same(struct pim_rpf *rpf1, struct pim_rpf *rpf2) diff --git a/pimd/pim_vty.c b/pimd/pim_vty.c index 95882cf58f..e4dec9ee8e 100644 --- a/pimd/pim_vty.c +++ b/pimd/pim_vty.c @@ -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; } } diff --git a/ripd/ripd.c b/ripd/ripd.c index 3d1427c3b6..37f4b57431 100644 --- a/ripd/ripd.c +++ b/ripd/ripd.c @@ -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; } @@ -3696,7 +3698,7 @@ void rip_vrf_init(void) vrf_init(rip_vrf_new, rip_vrf_enable, rip_vrf_disable, rip_vrf_delete, rip_vrf_enable); - vrf_cmd_init(NULL, &ripd_privs); + vrf_cmd_init(NULL); } void rip_vrf_terminate(void) diff --git a/ripngd/ripngd.c b/ripngd/ripngd.c index cbd2c22893..4f5c8e7760 100644 --- a/ripngd/ripngd.c +++ b/ripngd/ripngd.c @@ -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; } @@ -2692,7 +2694,7 @@ void ripng_vrf_init(void) vrf_init(ripng_vrf_new, ripng_vrf_enable, ripng_vrf_disable, ripng_vrf_delete, ripng_vrf_enable); - vrf_cmd_init(NULL, &ripngd_privs); + vrf_cmd_init(NULL); } void ripng_vrf_terminate(void) diff --git a/staticd/static_vrf.c b/staticd/static_vrf.c index 96e5d37d68..740d904690 100644 --- a/staticd/static_vrf.c +++ b/staticd/static_vrf.c @@ -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; @@ -175,7 +175,7 @@ void static_vrf_init(void) vrf_init(static_vrf_new, static_vrf_enable, static_vrf_disable, static_vrf_delete, NULL); - vrf_cmd_init(static_vrf_config_write, &static_privs); + vrf_cmd_init(static_vrf_config_write); } void static_vrf_terminate(void) diff --git a/tests/lib/cli/test_cli.refout.in b/tests/lib/cli/test_cli.refout.in index 8f9959cc47..1f38e08b20 100644 --- a/tests/lib/cli/test_cli.refout.in +++ b/tests/lib/cli/test_cli.refout.in @@ -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)# diff --git a/tools/frr-reload.py b/tools/frr-reload.py index a326ecc0f9..7c6a83a51d 100755 --- a/tools/frr-reload.py +++ b/tools/frr-reload.py @@ -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. + + # 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 = [] - 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 " - ) + # 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) - - # Start a new context - main_ctx_key = [] - ctx_keys = [ - line, - ] - current_context_lines = [] - - log.debug("LINE %-50s: entering new context, %-50s", line, ctx_keys) - self.save_contexts(ctx_keys, current_context_lines) - new_ctx = True - - elif line == "end": - self.save_contexts(ctx_keys, current_context_lines) - log.debug("LINE %-50s: exiting old context, %-50s", line, ctx_keys) - - # Start a new context - new_ctx = True - main_ctx_key = [] - ctx_keys = [] - current_context_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) - - # Start a new context - new_ctx = True - main_ctx_key = [] - ctx_keys = [] - current_context_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 - ) + # save current context + self.save_contexts(ctx_keys, cur_ctx_lines) - # Start a new context - new_ctx = True - main_ctx_key = [] - ctx_keys = [] - current_context_lines = [] + # exit current context + log.debug("LINE %-50s: exit context %-50s", line, ctx_keys) - elif ( - line == "exit" - and len(ctx_keys) > 1 - and ctx_keys[0].startswith("segment-routing") - ): - self.save_contexts(ctx_keys, current_context_lines) - - # 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, - ) - - 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, - ) + ctx_keys.pop() + cur_ctx_keywords.pop() + cur_ctx_lines = [] - 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, - ) + continue - elif new_ctx is True: - if not main_ctx_key: - ctx_keys = [ - line, - ] - else: - ctx_keys = copy.deepcopy(main_ctx_key) - main_ctx_key = [] + if line.startswith("end"): + # exit all contexts + while len(ctx_keys) > 0: + # save current context + self.save_contexts(ctx_keys, cur_ctx_lines) - current_context_lines = [] - new_ctx = False - log.debug("LINE %-50s: entering new context, %-50s", line, ctx_keys) + # exit current context + log.debug("LINE %-50s: exit 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 = [] + ctx_keys.pop() + cur_ctx_keywords.pop() + cur_ctx_lines = [] - # 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) + continue - 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: + new_ctx = False + + # 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 + + # save current context + self.save_contexts(ctx_keys, cur_ctx_lines) + + # 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" - ): - - # 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") - ): + 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 = [] - 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): diff --git a/vrrpd/vrrp_vty.c b/vrrpd/vrrp_vty.c index 1904e936cc..91ff6fe28e 100644 --- a/vrrpd/vrrp_vty.c +++ b/vrrpd/vrrp_vty.c @@ -762,7 +762,7 @@ void vrrp_vty_init(void) { install_node(&debug_node); install_node(&vrrp_node); - vrf_cmd_init(NULL, &vrrp_privs); + vrf_cmd_init(NULL); if_cmd_init(vrrp_config_write_interface); install_element(VIEW_NODE, &vrrp_vrid_show_cmd); diff --git a/vtysh/vtysh_config.c b/vtysh/vtysh_config.c index d22ec3113f..2e1d7c5bad 100644 --- a/vtysh/vtysh_config.c +++ b/vtysh/vtysh_config.c @@ -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; } diff --git a/zebra/interface.c b/zebra/interface.c index 21eeb20543..18f7503f82 100644 --- a/zebra/interface.c +++ b/zebra/interface.c @@ -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; } diff --git a/zebra/zebra_pw.c b/zebra/zebra_pw.c index 6b4a815151..d5083d4cbe 100644 --- a/zebra/zebra_pw.c +++ b/zebra/zebra_pw.c @@ -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; } diff --git a/zebra/zebra_srv6_vty.c b/zebra/zebra_srv6_vty.c index 97935f126e..d2b91b6c07 100644 --- a/zebra/zebra_srv6_vty.c +++ b/zebra/zebra_srv6_vty.c @@ -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; diff --git a/zebra/zebra_vrf.c b/zebra/zebra_vrf.c index a2a671e957..4fbcc6f596 100644 --- a/zebra/zebra_vrf.c +++ b/zebra/zebra_vrf.c @@ -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"); } @@ -594,7 +594,7 @@ void zebra_vrf_init(void) vrf_init(zebra_vrf_new, zebra_vrf_enable, zebra_vrf_disable, zebra_vrf_delete, zebra_vrf_update); - vrf_cmd_init(vrf_config_write, &zserv_privs); + vrf_cmd_init(vrf_config_write); if (vrf_is_backend_netns() && ns_have_netns()) { /* Install NS commands. */ |
