summaryrefslogtreecommitdiff
path: root/lib/vty.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/vty.c')
-rw-r--r--lib/vty.c162
1 files changed, 43 insertions, 119 deletions
diff --git a/lib/vty.c b/lib/vty.c
index 90ca5f502a..d6fda8cbb4 100644
--- a/lib/vty.c
+++ b/lib/vty.c
@@ -86,10 +86,6 @@ static vector Vvty_serv_thread;
/* Current directory. */
char *vty_cwd = NULL;
-/* Configure lock. */
-static int vty_config;
-static int vty_config_is_lockless = 0;
-
/* Exclusive configuration lock. */
struct vty *vty_exclusive_lock;
@@ -779,61 +775,11 @@ static void vty_end_config(struct vty *vty)
{
vty_out(vty, "\n");
- switch (vty->node) {
- case VIEW_NODE:
- case ENABLE_NODE:
- /* Nothing to do. */
- break;
- case CONFIG_NODE:
- case INTERFACE_NODE:
- case PW_NODE:
- case ZEBRA_NODE:
- case RIP_NODE:
- case RIPNG_NODE:
- case EIGRP_NODE:
- case BGP_NODE:
- case BGP_VPNV4_NODE:
- case BGP_VPNV6_NODE:
- case BGP_VRF_POLICY_NODE:
- case BGP_VNC_DEFAULTS_NODE:
- case BGP_VNC_NVE_GROUP_NODE:
- case BGP_VNC_L2_GROUP_NODE:
- case BGP_IPV4_NODE:
- case BGP_IPV4M_NODE:
- case BGP_IPV4L_NODE:
- case BGP_IPV6_NODE:
- case BGP_IPV6M_NODE:
- case BGP_EVPN_NODE:
- case BGP_IPV6L_NODE:
- case RMAP_NODE:
- case PBRMAP_NODE:
- case OSPF_NODE:
- case OSPF6_NODE:
- case LDP_NODE:
- case LDP_IPV4_NODE:
- case LDP_IPV6_NODE:
- case LDP_IPV4_IFACE_NODE:
- case LDP_IPV6_IFACE_NODE:
- case LDP_L2VPN_NODE:
- case LDP_PSEUDOWIRE_NODE:
- case ISIS_NODE:
- case OPENFABRIC_NODE:
- case KEYCHAIN_NODE:
- case KEYCHAIN_KEY_NODE:
- case VTY_NODE:
- case BGP_EVPN_VNI_NODE:
- case BFD_NODE:
- case BFD_PEER_NODE:
- vty_config_unlock(vty);
+ if (vty->config) {
+ vty_config_exit(vty);
vty->node = ENABLE_NODE;
- break;
- default:
- /* Unknown node, we have to ignore it. */
- break;
}
- vty->xpath_index = 0;
-
vty_prompt(vty);
vty->cp = 0;
}
@@ -1194,44 +1140,11 @@ static void vty_stop_input(struct vty *vty)
vty_clear_buf(vty);
vty_out(vty, "\n");
- switch (vty->node) {
- case VIEW_NODE:
- case ENABLE_NODE:
- /* Nothing to do. */
- break;
- case CONFIG_NODE:
- case INTERFACE_NODE:
- case PW_NODE:
- case ZEBRA_NODE:
- case RIP_NODE:
- case RIPNG_NODE:
- case EIGRP_NODE:
- case BGP_NODE:
- case RMAP_NODE:
- case PBRMAP_NODE:
- case OSPF_NODE:
- case OSPF6_NODE:
- case LDP_NODE:
- case LDP_IPV4_NODE:
- case LDP_IPV6_NODE:
- case LDP_IPV4_IFACE_NODE:
- case LDP_IPV6_IFACE_NODE:
- case LDP_L2VPN_NODE:
- case LDP_PSEUDOWIRE_NODE:
- case ISIS_NODE:
- case OPENFABRIC_NODE:
- case KEYCHAIN_NODE:
- case KEYCHAIN_KEY_NODE:
- case VTY_NODE:
- case BFD_NODE:
- case BFD_PEER_NODE:
- vty_config_unlock(vty);
+ if (vty->config) {
+ vty_config_exit(vty);
vty->node = ENABLE_NODE;
- break;
- default:
- /* Unknown node, we have to ignore it. */
- break;
}
+
vty_prompt(vty);
/* Set history pointer to the latest one. */
@@ -1692,7 +1605,7 @@ static int vty_flush(struct thread *thread)
}
/* Allocate new vty struct. */
-struct vty *vty_new()
+struct vty *vty_new(void)
{
struct vty *new = XCALLOC(MTYPE_VTY, sizeof(struct vty));
@@ -2351,7 +2264,7 @@ void vty_close(struct vty *vty)
}
/* Check configure. */
- vty_config_unlock(vty);
+ vty_config_exit(vty);
/* OK free vty. */
XFREE(MTYPE_VTY, vty);
@@ -2458,8 +2371,6 @@ static void vty_read_file(struct nb_config *config, FILE *confp)
*/
if (config == NULL && vty->candidate_config
&& frr_get_cli_mode() == FRR_CLI_TRANSACTIONAL) {
- int ret;
-
ret = nb_candidate_commit(vty->candidate_config, NB_CLIENT_CLI,
true, "Read configuration file",
NULL);
@@ -2692,19 +2603,43 @@ void vty_log_fixed(char *buf, size_t len)
}
}
-int vty_config_lock(struct vty *vty)
+int vty_config_enter(struct vty *vty, bool private_config, bool exclusive)
{
- if (vty_config_is_lockless)
- return 1;
- if (vty_config == 0) {
- vty->config = 1;
- vty_config = 1;
+ if (exclusive && !vty_config_exclusive_lock(vty)) {
+ vty_out(vty, "VTY configuration is locked by other VTY\n");
+ return CMD_WARNING;
}
- return vty->config;
+
+ vty->node = CONFIG_NODE;
+ vty->config = true;
+ vty->private_config = private_config;
+ vty->xpath_index = 0;
+
+ if (private_config) {
+ vty->candidate_config = nb_config_dup(running_config);
+ vty->candidate_config_base = nb_config_dup(running_config);
+ vty_out(vty,
+ "Warning: uncommitted changes will be discarded on exit.\n\n");
+ } else {
+ vty->candidate_config = vty_shared_candidate_config;
+ if (frr_get_cli_mode() == FRR_CLI_TRANSACTIONAL)
+ vty->candidate_config_base =
+ nb_config_dup(running_config);
+ }
+
+ return CMD_SUCCESS;
}
-int vty_config_unlock(struct vty *vty)
+void vty_config_exit(struct vty *vty)
{
+ /* Check if there's a pending confirmed commit. */
+ if (vty->t_confirmed_commit_timeout) {
+ vty_out(vty,
+ "WARNING: exiting with a pending confirmed commit. Rolling back to previous configuration.\n\n");
+ nb_cli_confirmed_commit_rollback(vty);
+ nb_cli_confirmed_commit_clean(vty);
+ }
+
vty_config_exclusive_unlock(vty);
if (vty->candidate_config) {
@@ -2717,18 +2652,7 @@ int vty_config_unlock(struct vty *vty)
vty->candidate_config_base = NULL;
}
- if (vty_config_is_lockless)
- return 0;
- if (vty_config == 1 && vty->config == 1) {
- vty->config = 0;
- vty_config = 0;
- }
- return vty->config;
-}
-
-void vty_config_lockless(void)
-{
- vty_config_is_lockless = 1;
+ vty->config = false;
}
int vty_config_exclusive_lock(struct vty *vty)
@@ -3111,7 +3035,7 @@ struct cmd_node vty_node = {
};
/* Reset all VTY status. */
-void vty_reset()
+void vty_reset(void)
{
unsigned int i;
struct vty *vty;
@@ -3176,7 +3100,7 @@ static void vty_save_cwd(void)
strcpy(vty_cwd, cwd);
}
-char *vty_get_cwd()
+char *vty_get_cwd(void)
{
return vty_cwd;
}
@@ -3191,7 +3115,7 @@ int vty_shell_serv(struct vty *vty)
return vty->type == VTY_SHELL_SERV ? 1 : 0;
}
-void vty_init_vtysh()
+void vty_init_vtysh(void)
{
vtyvec = vector_init(VECTOR_MIN_SIZE);
}