/* (C) 2022-2023 by Andreas Eversberg * * All Rights Reserved * * SPDX-License-Identifier: GPL-2.0+ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * */ #include #include "v5x_internal.h" #include "v5x_protocol.h" #include "v5le_vty.h" #include "v52_le_lcp_fsm.h" #include "v52_le_pp_fsm.h" #include "v5x_le_port_fsm.h" #include "v5x_le_pstn_fsm.h" #include "v5x_le_management.h" #include "layer1.h" #include "lapv5.h" #include "../config.h" extern struct v5x_instance *v5i; enum v5_vty_node { INTERFACE_NODE = _LAST_OSMOVTY_NODE + 1, CONFIG_INTERFACE_NODE_V51, CONFIG_INTERFACE_NODE_V52, CONFIG_LINK_NODE, CONFIG_PORT_NODE, }; char if_prompt[64]; char conf_if_prompt[64]; char conf_link_prompt[64]; char conf_port_prompt[64]; static struct cmd_node interface_node = { .node = INTERFACE_NODE, .prompt = if_prompt, .vtysh = 1, }; static struct cmd_node config_interface_node_v51 = { .node = CONFIG_INTERFACE_NODE_V51, .prompt = conf_if_prompt, .vtysh = 1, }; static struct cmd_node config_interface_node_v52 = { .node = CONFIG_INTERFACE_NODE_V52, .prompt = conf_if_prompt, .vtysh = 1, }; static struct cmd_node config_link_node = { .node = CONFIG_LINK_NODE, .prompt = conf_link_prompt, .vtysh = 1, }; static struct cmd_node config_port_node = { .node = CONFIG_PORT_NODE, .prompt = conf_port_prompt, .vtysh = 1, }; static int v5le_vty_is_config_node(struct vty __attribute__((unused)) *vty, int node) { switch (node) { case INTERFACE_NODE: case CONFIG_NODE: return 0; default: return 1; } } static int v5le_vty_go_parent(struct vty *vty) { struct v5x_interface *v5if; struct v5x_link *v5l; struct v5x_user_port *v5up; switch (vty->node) { case CONFIG_PORT_NODE: v5up = vty->index; v5if = v5up->interface; vty->node = (v5if->dialect == V5X_DIALECT_V51) ? CONFIG_INTERFACE_NODE_V51 : CONFIG_INTERFACE_NODE_V52; vty->index = v5if; break; case CONFIG_LINK_NODE: v5l = vty->index; v5if = v5l->interface; vty->node = (v5if->dialect == V5X_DIALECT_V51) ? CONFIG_INTERFACE_NODE_V51 : CONFIG_INTERFACE_NODE_V52; vty->index = v5if; break; case CONFIG_INTERFACE_NODE_V51: case CONFIG_INTERFACE_NODE_V52: vty->node = CONFIG_NODE; vty->index = NULL; break; default: vty->node = ENABLE_NODE; vty->index = NULL; } return vty->node; } struct vty_app_info vty_info = { .name = "OsmoV5LE", .version = PACKAGE_VERSION, .go_parent_cb = v5le_vty_go_parent, .is_config_node = v5le_vty_is_config_node, }; /* * show */ static const char *link_status(bool established, struct lapv5_instance *li) { if (!li->enabled) return "disabled"; if (!established) return "down"; return "up"; } DEFUN(show_interfaces, show_interfaces_cmd, "show interfaces", SHOW_STR "Show all interfaces") { struct v5x_interface *v5if; if (llist_empty(&v5i->interfaces)) { vty_out(vty, "%%No interface created!%s", VTY_NEWLINE); return CMD_SUCCESS; } llist_for_each_entry(v5if, &v5i->interfaces, list) { vty_out(vty, "Interface %d: %s %s%s", v5if->id, v5if->name ? v5if->name : "(unnamed)", (v5if->dialect == V5X_DIALECT_V51) ? "V5.1" : "V5.2", VTY_NEWLINE); } return CMD_SUCCESS; } DEFUN(interface, interface_cmd, "interface <0-16777215>", "Select given interface\n" "Interface ID") { struct v5x_interface *v5if, *found = NULL; uint32_t id = atoi(argv[0]); if (llist_empty(&v5i->interfaces)) { vty_out(vty, "%%No interface created!%s", VTY_NEWLINE); return CMD_WARNING; } llist_for_each_entry(v5if, &v5i->interfaces, list) { if (v5if->id == id) found = v5if; } v5if = found; if (!v5if) { vty_out(vty, "Interface does not exist.%s", VTY_NEWLINE); return CMD_WARNING; } sprintf(if_prompt, "%%s(interface-%d)# ", v5if->id); vty->node = INTERFACE_NODE; vty->index = v5if; return CMD_SUCCESS; } DEFUN(info_interface, show_interface_cmd, "show interface", SHOW_STR "Show interface information and states") { struct v5x_interface *v5if = vty->index; struct v5x_link *v5l; struct v5x_user_port *v5up; int calls; if (!v5if) { vty_out(vty, "No interface exists.%s", VTY_NEWLINE); return CMD_WARNING; } vty_out(vty, "Interface %d %s %s:%s", v5if->id, v5if->name ? v5if->name : "(unnamed)", (v5if->dialect == V5X_DIALECT_V51) ? "V5.1" : "V5.2", VTY_NEWLINE); vty_out(vty, " Trigger system restart: %s%s", (v5if->mgmt->auto_restart) ? "automatic" : "manual", VTY_NEWLINE); vty_out(vty, " Trigger data links: %s%s", (v5if->mgmt->do_est) ? "yes" : "no", VTY_NEWLINE); vty_out(vty, " Enable PSTN datalink: %s statup)%s", (v5if->mgmt->pstn_enable_early) ? "early (before" : "late (after", VTY_NEWLINE); vty_out(vty, " Trigger user port alignment: %s%s", (v5if->mgmt->do_align) ? "yes" : "no", VTY_NEWLINE); if (v5if->dialect == V5X_DIALECT_V52) vty_out(vty, " Accelerated alignment: %s%s", (v5if->mgmt->acc_align) ? "yes" : "no", VTY_NEWLINE); if (v5if->control.li) vty_out(vty, " Control data link: %s%s", link_status(v5if->control.established, v5if->control.li), VTY_NEWLINE); if (v5if->pstn.li) vty_out(vty, " PSTN data link: %s%s", link_status(v5if->pstn.established, v5if->pstn.li), VTY_NEWLINE); if (v5if->lcp.li) vty_out(vty, " LCP data link: %s%s", link_status(v5if->lcp.established, v5if->lcp.li), VTY_NEWLINE); if (v5if->bcc.li) vty_out(vty, " BCC data link: %s%s", link_status(v5if->bcc.established, v5if->bcc.li), VTY_NEWLINE); if (v5if->protection.li[0]) vty_out(vty, " Protection data link (primary): %s%s", link_status(v5if->protection.established[0], v5if->protection.li[0]), VTY_NEWLINE); if (v5if->protection.li[1]) vty_out(vty, " Protection data link (secondary): %s%s", link_status(v5if->protection.established[1], v5if->protection.li[1]), VTY_NEWLINE); vty_out(vty, " System startup state: %s%s", v5x_le_system_fsm_state_name(v5if->mgmt->system_fi), VTY_NEWLINE); vty_out(vty, " PSTN data link startup state: %s%s", v5x_le_pstn_dl_fsm_state_name(v5if->mgmt->pstn_dl_fi), VTY_NEWLINE); vty_out(vty, " PSTN restart state: %s%s", v5x_le_pstn_rs_fsm_state_name(v5if->mgmt->pstn_rs_fi), VTY_NEWLINE); if (v5if->dialect == V5X_DIALECT_V52) { vty_out(vty, " Unblock all PSTN/ISDN state: %s%s", v5x_le_unblk_all_fsm_state_name(v5if->mgmt->unblk_all_fi[UNBLK_ALL_PSTN_ISDN]), VTY_NEWLINE); vty_out(vty, " Unblock all PSTN state: %s%s", v5x_le_unblk_all_fsm_state_name(v5if->mgmt->unblk_all_fi[UNBLK_ALL_PSTN]), VTY_NEWLINE); vty_out(vty, " Unblock all ISDN state: %s%s", v5x_le_unblk_all_fsm_state_name(v5if->mgmt->unblk_all_fi[UNBLK_ALL_ISDN]), VTY_NEWLINE); vty_out(vty, " Block all PSTN state: %s%s", v5x_le_unblk_all_fsm_state_name(v5if->mgmt->unblk_all_fi[BLK_ALL_PSTN]), VTY_NEWLINE); vty_out(vty, " Block all ISDN state: %s%s", v5x_le_unblk_all_fsm_state_name(v5if->mgmt->unblk_all_fi[BLK_ALL_ISDN]), VTY_NEWLINE); } if (!v5if->id_remote_valid) vty_out(vty, " ID: local: %d remote: unknown%s", v5if->id, VTY_NEWLINE); else vty_out(vty, " ID: local: %d remote: %d%s%s", v5if->id, v5if->id_remote, (v5if->id != v5if->id_remote) ? " (mismatching)" : "", VTY_NEWLINE); if (!v5if->variant_remote_valid) vty_out(vty, " Variant: local: %d remote: unknown%s", v5if->variant, VTY_NEWLINE); else vty_out(vty, " Variant: local: %d remote: %d%s%s", v5if->variant, v5if->variant_remote, (v5if->variant != v5if->variant_remote) ? " (mismatching)" : "", VTY_NEWLINE); if (v5if->dialect == V5X_DIALECT_V52) { vty_out(vty, " Link IDs:"); llist_for_each_entry(v5l, &v5if->links, list) vty_out(vty, " %d", v5l->id); vty_out(vty, VTY_NEWLINE); if (v5if->primary_link) vty_out(vty, " Primary link ID: %d%s", v5if->primary_link->id, VTY_NEWLINE); if (v5if->secondary_link) vty_out(vty, " Secondary link ID: %d%s", v5if->secondary_link->id, VTY_NEWLINE); if (v5if->cc_link) vty_out(vty, " Current C-Channel data link ID: %d%s", v5if->cc_link->id, VTY_NEWLINE); vty_out(vty, " C-Channel ID: %d (only relevant for protection)%s", v5if->protection.cc_id, VTY_NEWLINE); } calls = 0; llist_for_each_entry(v5up, &v5if->user_ports, list) { if (v5up->ts[0] && v5up->ts[0]->b_activated) calls++; if (v5up->ts[1] && v5up->ts[1]->b_activated) calls++; } vty_out(vty, " Active calls (B-channels): %d%s", calls, VTY_NEWLINE); return CMD_SUCCESS; } DEFUN(show_link, show_link_cmd, "show link", SHOW_STR "Show links and states") { struct v5x_interface *v5if = vty->index; struct v5x_link *v5l; struct v5x_user_port *v5up; int t; if (!v5if) return CMD_WARNING; if (llist_empty(&v5if->links)) { vty_out(vty, "%%No link created!%s", VTY_NEWLINE); return CMD_WARNING; } llist_for_each_entry(v5l, &v5if->links, list) { if (v5if->dialect == V5X_DIALECT_V51) vty_out(vty, "Link:%s", VTY_NEWLINE); else vty_out(vty, "Link ID %d:", v5l->id); if (v5if->dialect == V5X_DIALECT_V52) { vty_out(vty, " State=%s", v52_le_lcp_state_name(v5l->fi)); vty_out(vty, " L1=%s%s", v5x_l1_fsm_state_name(v5l->l1), VTY_NEWLINE); } for (t = 0; t < 32; t++) { if (v5l->c_channel[0].ts && v5l->c_channel[0].ts->nr == t) { vty_out(vty, " TS %2d: signaling channel 1%s", t, VTY_NEWLINE); continue; } if (v5l->c_channel[1].ts && v5l->c_channel[1].ts->nr == t) { vty_out(vty, " TS %2d: signaling channel 2%s", t, VTY_NEWLINE); continue; } if (v5l->c_channel[2].ts && v5l->c_channel[2].ts->nr == t) { vty_out(vty, " TS %2d: signaling channel 3%s", t, VTY_NEWLINE); continue; } if (v5l->ts[t].b_channel) { if ((v5up = v5l->ts[t].v5up)) vty_out(vty, " TS %2d: %s-%d %s%s", t, (v5up->type == V5X_USER_TYPE_PSTN) ? "PSTN" : "ISDN", v5up->nr, (v5l->ts[t].b_activated) ? "(active)": "", VTY_NEWLINE); } } } return CMD_SUCCESS; } static void print_port_channel(struct vty *vty, enum v5x_dialect dialect, const char *bchan, struct v5x_timeslot *ts) { if (dialect == V5X_DIALECT_V51) vty_out(vty, " Channel%s: TS %d %s%s", bchan, ts->nr, (ts->b_activated) ? "(active)": "", VTY_NEWLINE); else vty_out(vty, " Channel%s: link %d TS %d %s%s", bchan, ts->link->id, ts->nr, (ts->b_activated) ? "(active)": "", VTY_NEWLINE); } static void print_port(struct vty *vty, struct v5x_user_port *v5up) { if (v5up->type == V5X_USER_TYPE_PSTN) { vty_out(vty, "PSTN port nr %d", v5up->nr); if (v5up->name) vty_out(vty, " (%s)", v5up->name); vty_out(vty, ": Port state=%s;", v5x_le_port_pstn_state_name(v5up->port_fi)); vty_out(vty, " PSTN state=%s%s", v5x_le_pstn_state_name(v5up->pstn.proto), VTY_NEWLINE); if (v5up->ts[0]) print_port_channel(vty, v5up->interface->dialect, "", v5up->ts[0]); } else { vty_out(vty, "ISDN port nr %d", v5up->nr); if (v5up->name) vty_out(vty, " (%s)", v5up->name); vty_out(vty, ": Port state=%s%s", v5x_le_port_isdn_state_name(v5up->port_fi), VTY_NEWLINE); if (v5up->ts[0]) print_port_channel(vty, v5up->interface->dialect, " B1", v5up->ts[0]); if (v5up->ts[1]) print_port_channel(vty, v5up->interface->dialect, " B2", v5up->ts[1]); } } #define SHOW_PORT "Show given user port and states\n" DEFUN(show_port_pstn, show_port_pstn_cmd, "show port pstn <0-32767>", SHOW_STR SHOW_PORT "Show given PSTN user port and states\n" "L3 address") { struct v5x_interface *v5if = vty->index; struct v5x_user_port *v5up; if (!v5if) return CMD_WARNING; v5up = v5x_user_port_find(v5if, atoi(argv[0]), false); if (!v5up) { vty_out(vty, "%%Given PSTN user port does not exist.%s", VTY_NEWLINE); return CMD_WARNING; } print_port(vty, v5up); return CMD_SUCCESS; } DEFUN(show_port_isdn, show_port_isdn_cmd, "show port isdn <0-8175>", SHOW_STR SHOW_PORT "Show given ISDN user port and states\n" "L3 address") { struct v5x_interface *v5if = vty->index; struct v5x_user_port *v5up; if (!v5if) return CMD_WARNING; v5up = v5x_user_port_find(v5if, atoi(argv[0]), true); if (!v5up) { vty_out(vty, "%%Given ISDN user port does not exist.%s", VTY_NEWLINE); return CMD_WARNING; } print_port(vty, v5up); return CMD_SUCCESS; } DEFUN(show_port, show_port_cmd, "show port", SHOW_STR "Show all user ports and states") { struct v5x_interface *v5if = vty->index; struct v5x_user_port *v5up; if (!v5if) return CMD_WARNING; if (llist_empty(&v5if->user_ports)) { vty_out(vty, "%%No user port created!%s", VTY_NEWLINE); return CMD_WARNING; } llist_for_each_entry(v5up, &v5if->user_ports, list) print_port(vty, v5up); return CMD_SUCCESS; } /* * operate */ DEFUN(system_restart, system_restart_cmd, "system-restart", "Perform system startup/restart") { struct v5x_interface *v5if = vty->index; int rc; if (!v5if) return CMD_WARNING; rc = v5x_le_mgmt_start(v5if); if (rc < 0) { vty_out(vty, "%%System is not in right state.%s", VTY_NEWLINE); return CMD_WARNING; } return CMD_SUCCESS; } DEFUN(pstn_restart, pstn_restart_cmd, "pstn-restart", "Perform PSTN protocol restart") { struct v5x_interface *v5if = vty->index; int rc; if (!v5if) return CMD_WARNING; rc = v5x_le_pstn_restart(v5if); if (rc < 0) { vty_out(vty, "%%System is not in right state.%s", VTY_NEWLINE); return CMD_WARNING; } return CMD_SUCCESS; } DEFUN(align_ports, align_ports_cmd, "align-ports [accelerated]", "Perform alignment of all ports (sync (un)blocked state)") { struct v5x_interface *v5if = vty->index; int accelerated = 0; int rc; if (!v5if) return CMD_WARNING; if (argc >= 1) accelerated = 1; rc = v5x_le_align_ports(v5if, accelerated); if (rc < 0) { vty_out(vty, "%%System is not in right state.%s", VTY_NEWLINE); return CMD_WARNING; } return CMD_SUCCESS; } DEFUN(switchover, switchover_cmd, "switch-over <0-255>", "Perform switch-over to given link\n" "Link ID") { struct v5x_interface *v5if = vty->index; struct v5x_link *v5l; if (!v5if) return CMD_WARNING; if (v5if->dialect != V5X_DIALECT_V52) { vty_out(vty, "%%This command is only applicable to V5.2 interface.%s", VTY_NEWLINE); return CMD_WARNING; } v5l = v5x_link_find_id(v5if, atoi(argv[0])); if (!v5l) { vty_out(vty, "%%Given link does not exist.%s", VTY_NEWLINE); return CMD_WARNING; } if (v5l != v5if->primary_link && v5l != v5if->secondary_link) { vty_out(vty, "%%Given link is not primary, nor secondary.%s", VTY_NEWLINE); return CMD_WARNING; } v52_le_pp_mdu_snd(v5if, MDU_Protection_switch_over_com, atoi(argv[0]), v5l->c_channel[0].ts->nr, 0); return CMD_SUCCESS; } #define PERF_UBLK "Perform unblocking\n" #define PERF_BLK "Perform blocking\n" DEFUN(unblock_link, unblock_link_cmd, "unblock link <0-255>", PERF_UBLK "Perform unblocking of link\n" "Link ID") { struct v5x_interface *v5if = vty->index; struct v5x_link *v5l; if (!v5if) return CMD_WARNING; if (v5if->dialect != V5X_DIALECT_V52) { vty_out(vty, "%%This command is only applicable to V5.2 interface.%s", VTY_NEWLINE); return CMD_WARNING; } v5l = v5x_link_find_id(v5if, atoi(argv[0])); if (!v5l) { vty_out(vty, "%%Given link does not exist.%s", VTY_NEWLINE); return CMD_WARNING; } v52_le_lcp_mdu_snd(v5l, MDU_LUBR); return CMD_SUCCESS; } DEFUN(block_link, block_link_cmd, "block link <0-255>", PERF_BLK "Perform blocking of link\n" "Link ID") { struct v5x_interface *v5if = vty->index; struct v5x_link *v5l; if (!v5if) return CMD_WARNING; if (v5if->dialect != V5X_DIALECT_V52) { vty_out(vty, "%%This command is only applicable to V5.2 interface.%s", VTY_NEWLINE); return CMD_WARNING; } v5l = v5x_link_find_id(v5if, atoi(argv[0])); if (!v5l) { vty_out(vty, "%%Given link does not exist.%s", VTY_NEWLINE); return CMD_WARNING; } v52_le_lcp_mdu_snd(v5l, MDU_LBI); return CMD_SUCCESS; } DEFUN(unblock_pstn_port, unblock_pstn_port_cmd, "unblock pstn <0-32767>", PERF_UBLK "Perform unblocking of PSTN port\n" "L3 address") { struct v5x_interface *v5if = vty->index; struct v5x_user_port *v5up; if (!v5if) return CMD_WARNING; v5up = v5x_user_port_find(v5if, atoi(argv[0]), false); if (!v5up) { vty_out(vty, "%%Given PSTN user port does not exist.%s", VTY_NEWLINE); return CMD_WARNING; } v5x_le_mgmt_port_unblock(v5up); return CMD_SUCCESS; } DEFUN(block_pstn_port, block_pstn_port_cmd, "block pstn <0-32767>", PERF_BLK "Perform blocking of PSTN port\n" "L3 address") { struct v5x_interface *v5if = vty->index; struct v5x_user_port *v5up; if (!v5if) return CMD_WARNING; v5up = v5x_user_port_find(v5if, atoi(argv[0]), false); if (!v5up) { vty_out(vty, "%%Given PSTN user port does not exist.%s", VTY_NEWLINE); return CMD_WARNING; } v5x_le_mgmt_port_block(v5up); return CMD_SUCCESS; } DEFUN(unblock_isdn_port, unblock_isdn_port_cmd, "unblock isdn <0-8175>", PERF_UBLK "Perform unblocking of ISDN port\n" "L3 address") { struct v5x_interface *v5if = vty->index; struct v5x_user_port *v5up; if (!v5if) return CMD_WARNING; v5up = v5x_user_port_find(v5if, atoi(argv[0]), true); if (!v5up) { vty_out(vty, "%%Given ISDN user port does not exist.%s", VTY_NEWLINE); return CMD_WARNING; } v5x_le_mgmt_port_unblock(v5up); return CMD_SUCCESS; } DEFUN(block_isdn_port, block_isdn_port_cmd, "block isdn <0-8175>", PERF_BLK "Perform blocking of ISDN port\n" "L3 address") { struct v5x_interface *v5if = vty->index; struct v5x_user_port *v5up; if (!v5if) return CMD_WARNING; v5up = v5x_user_port_find(v5if, atoi(argv[0]), true); if (!v5up) { vty_out(vty, "%%Given ISDN user port does not exist.%s", VTY_NEWLINE); return CMD_WARNING; } v5x_le_mgmt_port_block(v5up); return CMD_SUCCESS; } /* * configure */ DEFUN(cfg_interface, cfg_interface_cmd, "interface <0-16777215> [(v5.1|v5.2)]", "Configure V5 interface\n" "Interface ID\n" "Configure as V5.1 interface\n" "Configure as V5.2 interface") { struct v5x_interface *v5if, *found = NULL; enum v5x_dialect dialect = V5X_DIALECT_V51; uint32_t id = atoi(argv[0]); llist_for_each_entry(v5if, &v5i->interfaces, list) { if (v5if->id == id) found = v5if; } v5if = found; if (argc < 2) { if (!v5if) { vty_out(vty, "%%Interface not created, Add v5.1 or v5.2 after this command.%s", VTY_NEWLINE); return CMD_WARNING; } dialect = v5if->dialect; } else { if (!strcasecmp(argv[1], "v5.2")) dialect = V5X_DIALECT_V52; } if (!v5if) { v5if = v5x_interface_alloc(v5i, id, dialect); if (!v5if) { vty_out(vty, "%%Failed to create interface. See logging output.%s", VTY_NEWLINE); return CMD_WARNING; } } else if (dialect != v5if->dialect) { vty_out(vty, "%%Different interface type already created. To change, remove first.%s", VTY_NEWLINE); } sprintf(conf_if_prompt, "%%s(config-interface-%d)# ", v5if->id); vty->node = (v5if->dialect == V5X_DIALECT_V51) ? CONFIG_INTERFACE_NODE_V51 : CONFIG_INTERFACE_NODE_V52; vty->index = v5if; return CMD_SUCCESS; } DEFUN(cfg_no_interface, cfg_no_interface_cmd, "no interface <0-16777215>", NO_STR "Remove V5 interface\n" "Interface ID") { struct v5x_interface *v5if, *found = NULL; uint32_t id = atoi(argv[0]); llist_for_each_entry(v5if, &v5i->interfaces, list) { if (v5if->id == id) found = v5if; } v5if = found; if (!v5if) { vty_out(vty, "%%Interface does not exist.%s", VTY_NEWLINE); return CMD_WARNING; } v5x_interface_free(v5if); return CMD_SUCCESS; } DEFUN(cfg_name, cfg_name_cmd, "name NAME", "Set a descriptive name for this interface") { struct v5x_interface *v5if = vty->index; if (!osmo_identifier_valid(argv[0])) { vty_out(vty, "%% Name is not a valid identifier.%s", VTY_NEWLINE); return CMD_WARNING; } osmo_talloc_replace_string(v5if, &v5if->name, argv[0]); return CMD_SUCCESS; } DEFUN(cfg_no_name, cfg_no_name_cmd, "no name", NO_STR "Remove the descriptive name for this interface") { struct v5x_interface *v5if = vty->index; talloc_free(v5if->name); v5if->name = NULL; return CMD_SUCCESS; } DEFUN(cfg_auto_restart, cfg_auto_restart_cmd, "auto-restart", "Automatically restart interface in case of failure") { struct v5x_interface *v5if = vty->index; v5if->mgmt->auto_restart = true; return CMD_SUCCESS; } DEFUN(cfg_no_auto_restart, cfg_no_auto_restart_cmd, "no auto-restart", NO_STR "Automatically restart interface in case of failure") { struct v5x_interface *v5if = vty->index; v5if->mgmt->auto_restart = false; return CMD_SUCCESS; } DEFUN(cfg_establish, cfg_establish_cmd, "establish", "Actively establish and re-establish data link layer") { struct v5x_interface *v5if = vty->index; v5if->mgmt->do_est = true; return CMD_SUCCESS; } DEFUN(cfg_no_establish, cfg_no_establish_cmd, "no establish", NO_STR "Let the remote side establish and re-establish data link layer") { struct v5x_interface *v5if = vty->index; v5if->mgmt->do_est = false; return CMD_SUCCESS; } DEFUN(cfg_pstn_enable, cfg_pstn_enable_cmd, "pstn-enable (early|late)", "Enable PSTN datalink before or after startup.\nEnable datalink before startup\nEnable datalink after startup") { struct v5x_interface *v5if = vty->index; v5if->mgmt->pstn_enable_early = (argv[0][0] == 'e'); return CMD_SUCCESS; } DEFUN(cfg_alignment, cfg_alignment_cmd, "alignment", "Actively trigger alignment of user ports on startup") { struct v5x_interface *v5if = vty->index; v5if->mgmt->do_align = true; return CMD_SUCCESS; } DEFUN(cfg_no_alignment, cfg_no_alignment_cmd, "no alignment", NO_STR "Let the remote side do the alignment of user ports on startup") { struct v5x_interface *v5if = vty->index; v5if->mgmt->do_align = false; return CMD_SUCCESS; } DEFUN(cfg_accelerated, cfg_accelerated_cmd, "accelerated-alignment", "Use accelerated alignment to block/unblock user ports") { struct v5x_interface *v5if = vty->index; v5if->mgmt->acc_align = true; return CMD_SUCCESS; } DEFUN(cfg_no_accelerated, cfg_no_accelerated_cmd, "no accelerated-alignment", NO_STR "Use individual alignment to block/unblock user ports") { struct v5x_interface *v5if = vty->index; v5if->mgmt->acc_align = false; return CMD_SUCCESS; } DEFUN(cfg_interface_variant, cfg_interface_variant_cmd, "variant <0-127>", "Set interface provisioning variant\n" "Variant value") { struct v5x_interface *v5if = vty->index; v5if->variant = atoi(argv[0]); return CMD_SUCCESS; } DEFUN(cfg_interface_cc_id, cfg_interface_cc_id_cmd, "cc-id <0-65535>", "Set protection CC-ID\n" "CC-ID value") { struct v5x_interface *v5if = vty->index; v5if->protection.cc_id = atoi(argv[0]); return CMD_SUCCESS; } DEFUN(cfg_interface_capability, cfg_interface_capability_cmd, "information-transfer-capability <0-31>", "Enable information transfer capability with ISDN port allocation\n" "Information transfer capability") { struct v5x_interface *v5if = vty->index; v5if->use_capability = true; v5if->capability = atoi(argv[0]); return CMD_SUCCESS; } DEFUN(cfg_interface_no_capability, cfg_interface_no_capability_cmd, "no information-transfer-capability", NO_STR "Disable information transfer capability with ISDN port allocation") { struct v5x_interface *v5if = vty->index; v5if->use_capability = false; return CMD_SUCCESS; } DEFUN(cfg_link_v51, cfg_link_cmd_v51, "link", "Modify link") { struct v5x_interface *v5if = vty->index; struct v5x_link *v5l; v5l = llist_first_entry(&v5if->links, struct v5x_link, list); sprintf(conf_link_prompt, "%%s(config-link-%d)# ", v5l->id); vty->node = CONFIG_LINK_NODE; vty->index = v5l; return CMD_SUCCESS; } DEFUN(cfg_link_v52, cfg_link_cmd_v52, "link <0-255>", "Add or modify link\n" "Link ID to create or modify") { struct v5x_interface *v5if = vty->index; struct v5x_link *v5l; v5l = v5x_link_find_id(v5if, atoi(argv[0])); if (!v5l) { v5l = v5x_link_create(v5if, atoi(argv[0])); if (!v5l) { vty_out(vty, "%%Failed to create link. See logging output.%s", VTY_NEWLINE); return CMD_WARNING; } } sprintf(conf_link_prompt, "%%s(config-link-%d)# ", v5l->id); vty->node = CONFIG_LINK_NODE; vty->index = v5l; return CMD_SUCCESS; } DEFUN(cfg_no_link_v52, cfg_no_link_cmd_v52, "no link <0-255>", NO_STR "Remove link from interface\n" "Link ID to remove") { struct v5x_interface *v5if = vty->index; struct v5x_link *v5l; int rc; v5l = v5x_link_find_id(v5if, atoi(argv[0])); if (!v5l) { vty_out(vty, "%%Given link with ID %d is not created.%s", atoi(argv[0]), VTY_NEWLINE); return CMD_WARNING; } rc = v5x_link_destroy(v5l); if (rc < 0) { vty_out(vty, "%%Given link with ID %d cannot be deleted, see debug output.%s", atoi(argv[0]), VTY_NEWLINE); return CMD_WARNING; } return CMD_SUCCESS; } DEFUN(cfg_e1_line, cfg_e1_line_cmd, "e1 line <0-255>", "E1 configuration\n" "E1 line configuration\n" "E1 line number to use for link") { struct v5x_interface *search_v5if; struct v5x_link *v5l = vty->index, *search_v5l; struct e1inp_line *e1_line; unsigned int num = atoi(argv[0]); /* nothing has changed, same line number */ if (v5l->e1_line && v5l->e1_line->num == num) return CMD_SUCCESS; /* is there someone using this line already? */ llist_for_each_entry(search_v5if, &v5i->interfaces, list) { llist_for_each_entry(search_v5l, &search_v5if->links, list) { if (!search_v5l->e1_line) continue; if (search_v5l->e1_line->num == num) { vty_out(vty, "%%E1 line %d already used by interface %d / link ID %d.%s", num, search_v5if->id, search_v5l->id, VTY_NEWLINE); return CMD_WARNING; } } } /* remove line, if attached */ if (v5l->e1_line) e1_line_exit(v5l); /* add line, if created */ e1_line = e1_line_init(v5l, num); if (!e1_line) { vty_out(vty, "%%E1 line %d is not created. Please create it first.%s", num, VTY_NEWLINE); return CMD_WARNING; } return CMD_SUCCESS; } DEFUN(cfg_no_e1_line, cfg_no_e1_line_cmd, "no e1 line", NO_STR "E1 configuration\n" "Remove E1 line from link") { struct v5x_link *v5l = vty->index; /* remove line, if attached */ if (v5l->e1_line) e1_line_exit(v5l); return CMD_SUCCESS; } DEFUN(cfg_port_pstn_v51, cfg_port_pstn_cmd_v51, "port pstn <0-32767> <1-31>", "Create/modify V5 user port\n" "PSTN user port\n" "L3 address\n" "Time slot") { struct v5x_interface *v5if = vty->index; struct v5x_user_port *v5up; v5up = v5x_user_port_find(v5if, atoi(argv[0]), false); if (v5up) { vty_out(vty, "%%Given PSTN user port already exists.%s", VTY_NEWLINE); return CMD_WARNING; } v5up = v5x_user_port_create(v5if, atoi(argv[0]), V5X_USER_TYPE_PSTN, atoi(argv[1]), 0); if (!v5up) { vty_out(vty, "%%Failed to create PSTN user port. See logging output.%s", VTY_NEWLINE); return CMD_WARNING; } sprintf(conf_port_prompt, "%%s(config-port-pstn-%d)# ", v5up->nr); vty->node = CONFIG_PORT_NODE; vty->index = v5up; return CMD_SUCCESS; } DEFUN(cfg_port_pstn, cfg_port_pstn_cmd, "port pstn <0-32767>", "Create/modify V5 user port\n" "PSTN user port\n" "L3 address") { struct v5x_interface *v5if = vty->index; struct v5x_user_port *v5up; v5up = v5x_user_port_find(v5if, atoi(argv[0]), false); if (!v5up) { if (v5if->dialect == V5X_DIALECT_V51) { vty_out(vty, "%%Given PSTN user port does not exist, give time slot.%s", VTY_NEWLINE); return CMD_WARNING; } v5up = v5x_user_port_create(v5if, atoi(argv[0]), V5X_USER_TYPE_PSTN, 0, 0); } if (!v5up) { vty_out(vty, "%%Failed to create PSTN user port. See logging output.%s", VTY_NEWLINE); return CMD_WARNING; } sprintf(conf_port_prompt, "%%s(config-port-pstn-%d)# ", v5up->nr); vty->node = CONFIG_PORT_NODE; vty->index = v5up; return CMD_SUCCESS; } DEFUN(cfg_no_port_pstn, cfg_no_port_pstn_cmd, "no port pstn <0-32767>", NO_STR "Delete V5 user port\n" "PSTN user port\n" "L3 address") { struct v5x_interface *v5if = vty->index; struct v5x_user_port *v5up; v5up = v5x_user_port_find(v5if, atoi(argv[0]), false); if (!v5up) { vty_out(vty, "%%Given PSTN user port does not exist.%s", VTY_NEWLINE); return CMD_WARNING; } v5x_user_port_destroy(v5up); return CMD_SUCCESS; } DEFUN(cfg_port_isdn_v51, cfg_port_isdn_cmd_v51, "port isdn <0-8175> <1-31> <1-31>", "Create/modify V5 user port\n" "ISDN user port\n" "L3 address\n" "Time slot 1\n" "Time slot 2") { struct v5x_interface *v5if = vty->index; struct v5x_user_port *v5up; v5up = v5x_user_port_find(v5if, atoi(argv[0]), true); if (v5up) { vty_out(vty, "%%Given ISDN user port already exists.%s", VTY_NEWLINE); return CMD_WARNING; } v5up = v5x_user_port_create(v5if, atoi(argv[0]), V5X_USER_TYPE_ISDN, atoi(argv[1]), atoi(argv[2])); if (!v5up) { vty_out(vty, "%%Failed to create ISDN user port. See logging output.%s", VTY_NEWLINE); return CMD_WARNING; } sprintf(conf_port_prompt, "%%s(config-port-isdn-%d)# ", v5up->nr); vty->node = CONFIG_PORT_NODE; vty->index = v5up; return CMD_SUCCESS; } DEFUN(cfg_port_isdn, cfg_port_isdn_cmd, "port isdn <0-8175>", "Create/modify V5 user port\n" "ISDN user port\n" "L3 address") { struct v5x_interface *v5if = vty->index; struct v5x_user_port *v5up; v5up = v5x_user_port_find(v5if, atoi(argv[0]), true); if (!v5up) { if (v5if->dialect == V5X_DIALECT_V51) { vty_out(vty, "%%Given ISDN user port does not exist, give time slots.%s", VTY_NEWLINE); return CMD_WARNING; } v5up = v5x_user_port_create(v5if, atoi(argv[0]), V5X_USER_TYPE_ISDN, 0, 0); } if (!v5up) { vty_out(vty, "%%Failed to create ISDN user port. See logging output.%s", VTY_NEWLINE); return CMD_WARNING; } sprintf(conf_port_prompt, "%%s(config-port-isdn-%d)# ", v5up->nr); vty->node = CONFIG_PORT_NODE; vty->index = v5up; return CMD_SUCCESS; } DEFUN(cfg_no_port_isdn, cfg_no_port_isdn_cmd, "no port isdn <0-8175>", NO_STR "Delete V5 user port\n" "ISDN user port\n" "L3 address") { struct v5x_interface *v5if = vty->index; struct v5x_user_port *v5up; v5up = v5x_user_port_find(v5if, atoi(argv[0]), true); if (!v5up) { vty_out(vty, "%%Given ISDN user port does not exist.%s", VTY_NEWLINE); return CMD_WARNING; } v5x_user_port_destroy(v5up); return CMD_SUCCESS; } DEFUN(cfg_port_name, cfg_port_name_cmd, "name NAME", "Set a descriptive name for this port") { struct v5x_user_port *v5up = vty->index; if (!osmo_identifier_valid(argv[0])) { vty_out(vty, "%% Name is not a valid identifier.%s", VTY_NEWLINE); return CMD_WARNING; } osmo_talloc_replace_string(v5up, &v5up->name, argv[0]); return CMD_SUCCESS; } DEFUN(cfg_port_no_name, cfg_port_no_name_cmd, "no name", NO_STR "Remove the descriptive name for this port") { struct v5x_user_port *v5up = vty->index; talloc_free(v5up->name); v5up->name = NULL; return CMD_SUCCESS; } DEFUN(cfg_echo_can, cfg_echo_can_cmd, "line-echo-canceler", "Enable line echo canceler for all calls") { struct v5x_user_port *v5up = vty->index; v5up->use_line_echo = USE_ECHO_CANCELER; if (v5up->ts[0] && v5up->ts[0]->b_activated) v5x_echo_reset(&v5up->ep[0], v5up->use_line_echo); if (v5up->ts[1] && v5up->ts[1]->b_activated) v5x_echo_reset(&v5up->ep[1], v5up->use_line_echo); return CMD_SUCCESS; } DEFUN(cfg_no_echo_can, cfg_no_echo_can_cmd, "no line-echo-canceler", NO_STR "Disable line echo canceler for all calls") { struct v5x_user_port *v5up = vty->index; v5up->use_line_echo = 0; if (v5up->ts[0] && v5up->ts[0]->b_activated) v5x_echo_reset(&v5up->ep[0], v5up->use_line_echo); if (v5up->ts[1] && v5up->ts[1]->b_activated) v5x_echo_reset(&v5up->ep[1], v5up->use_line_echo); return CMD_SUCCESS; } DEFUN(cfg_echo_sup, cfg_echo_sup_cmd, "line-echo-suppressor", "Enable line echo suppressor for all calls") { struct v5x_user_port *v5up = vty->index; v5up->use_line_echo = USE_ECHO_SUPPRESSOR; if (v5up->ts[0] && v5up->ts[0]->b_activated) v5x_echo_reset(&v5up->ep[0], v5up->use_line_echo); if (v5up->ts[1] && v5up->ts[1]->b_activated) v5x_echo_reset(&v5up->ep[1], v5up->use_line_echo); return CMD_SUCCESS; } DEFUN(cfg_no_echo_sup, cfg_no_echo_sup_cmd, "no line-echo-suppressor", NO_STR "Disable line echo suppressor for all calls") { struct v5x_user_port *v5up = vty->index; v5up->use_line_echo = 0; if (v5up->ts[0] && v5up->ts[0]->b_activated) v5x_echo_reset(&v5up->ep[0], v5up->use_line_echo); if (v5up->ts[1] && v5up->ts[1]->b_activated) v5x_echo_reset(&v5up->ep[1], v5up->use_line_echo); return CMD_SUCCESS; } DEFUN(cfg_v51_profile, cfg_v51_profile_cmd, "profile (fastlink)", "Set predefined profiles\n" "Set profile for Siemens Fastlink") { struct v5x_interface *v5if = vty->index; if (argv[0][0] == 'f') { v5if->mgmt->do_est = true; v5if->mgmt->pstn_enable_early = false; v5if->mgmt->do_align = true; } return CMD_SUCCESS; } DEFUN(cfg_v52_profile, cfg_v52_profile_cmd, "profile (fastlink|eksos)", "Set predefined profiles\n" "Set profile for Siemens Fastlink\n" "Set profile for Nokia Eksos") { struct v5x_interface *v5if = vty->index; if (argv[0][0] == 'f') { v5if->mgmt->do_est = true; v5if->mgmt->pstn_enable_early = false; v5if->mgmt->do_align = true; v5if->mgmt->acc_align = true; } if (argv[0][0] == 'e') { v5if->mgmt->do_est = false; v5if->mgmt->pstn_enable_early = true; v5if->mgmt->do_align = false; v5if->mgmt->acc_align = false; } return CMD_SUCCESS; } /* * write */ static void config_write_user_port(struct vty *vty, struct v5x_interface *v5if) { struct v5x_user_port *v5up; llist_for_each_entry(v5up, &v5if->user_ports, list) { switch (v5up->type) { case V5X_USER_TYPE_PSTN: if (v5if->dialect == V5X_DIALECT_V51) vty_out(vty, " port pstn %d %d%s", v5up->nr, v5up->ts[0]->nr, VTY_NEWLINE); else vty_out(vty, " port pstn %d%s", v5up->nr, VTY_NEWLINE); break; case V5X_USER_TYPE_ISDN: if (v5if->dialect == V5X_DIALECT_V51) vty_out(vty, " port isdn %d %d %d%s", v5up->nr, v5up->ts[0]->nr, v5up->ts[1]->nr, VTY_NEWLINE); else vty_out(vty, " port isdn %d%s", v5up->nr, VTY_NEWLINE); break; } if (v5up->name) vty_out(vty, " name %s%s", v5up->name, VTY_NEWLINE); if (v5up->use_line_echo == USE_ECHO_CANCELER) vty_out(vty, " line-echo-canceler%s", VTY_NEWLINE); if (v5up->use_line_echo == USE_ECHO_SUPPRESSOR) vty_out(vty, " line-echo-suppressor%s", VTY_NEWLINE); } } static void config_write_interface_v51(struct vty *vty, struct v5x_interface *v5if) { struct v5x_link *v5l; vty_out(vty, "!%s", VTY_NEWLINE); v5l = llist_first_entry(&v5if->links, struct v5x_link, list); vty_out(vty, "interface %d v5.1%s", v5if->id, VTY_NEWLINE); if (v5if->name) vty_out(vty, " name %s%s", v5if->name, VTY_NEWLINE); vty_out(vty, " %sauto-restart%s", (v5if->mgmt->auto_restart) ? "" : "no ", VTY_NEWLINE); vty_out(vty, " %sestablish%s", (v5if->mgmt->do_est) ? "" : "no ", VTY_NEWLINE); vty_out(vty, " pstn-enable %s %s", (v5if->mgmt->pstn_enable_early) ? "early" : "late", VTY_NEWLINE); vty_out(vty, " %salignment%s", (v5if->mgmt->do_align) ? "" : "no ", VTY_NEWLINE); vty_out(vty, " variant %d%s", v5if->variant, VTY_NEWLINE); vty_out(vty, " link%s", VTY_NEWLINE); if (!v5l->e1_line) vty_out(vty, " no e1 line%s", VTY_NEWLINE); else vty_out(vty, " e1 line %d%s", v5l->e1_line->num, VTY_NEWLINE); config_write_user_port(vty, v5if); } static void config_write_interface_v52(struct vty *vty, struct v5x_interface *v5if) { struct v5x_link *v5l; vty_out(vty, "!%s", VTY_NEWLINE); vty_out(vty, "interface %d v5.2%s", v5if->id, VTY_NEWLINE); if (v5if->name) vty_out(vty, " name %s%s", v5if->name, VTY_NEWLINE); vty_out(vty, " %sauto-restart%s", (v5if->mgmt->auto_restart) ? "" : "no ", VTY_NEWLINE); vty_out(vty, " %sestablish%s", (v5if->mgmt->do_est) ? "" : "no ", VTY_NEWLINE); vty_out(vty, " pstn-enable %s %s", (v5if->mgmt->pstn_enable_early) ? "early" : "late", VTY_NEWLINE); vty_out(vty, " %salignment%s", (v5if->mgmt->do_align) ? "" : "no ", VTY_NEWLINE); vty_out(vty, " %saccelerated-alignment%s", (v5if->mgmt->acc_align) ? "" : "no ", VTY_NEWLINE); vty_out(vty, " variant %d%s", v5if->variant, VTY_NEWLINE); vty_out(vty, " cc-id %d%s", v5if->protection.cc_id, VTY_NEWLINE); if (v5if->use_capability) vty_out(vty, " information-transfer-capability %d%s", v5if->capability, VTY_NEWLINE); else vty_out(vty, " no information-transfer-capability%s", VTY_NEWLINE); llist_for_each_entry(v5l, &v5if->links, list) { vty_out(vty, " link %d%s", v5l->id, VTY_NEWLINE); if (v5l == v5if->primary_link) vty_out(vty, " # primary%s", VTY_NEWLINE); if (v5l == v5if->secondary_link) vty_out(vty, " # secondary%s", VTY_NEWLINE); if (!v5l->e1_line) vty_out(vty, " no e1 line%s", VTY_NEWLINE); else vty_out(vty, " e1 line %d%s", v5l->e1_line->num, VTY_NEWLINE); } config_write_user_port(vty, v5if); } static int config_write_interfaces(struct vty *vty) { struct v5x_interface *v5if = NULL; llist_for_each_entry(v5if, &v5i->interfaces, list) { if (v5if->dialect == V5X_DIALECT_V51) config_write_interface_v51(vty, v5if); else config_write_interface_v52(vty, v5if); } return CMD_SUCCESS; } /* * init */ int v5le_vty_init(void) { install_element_ve(&show_interfaces_cmd); install_element(ENABLE_NODE, &interface_cmd); install_node(&interface_node, NULL); install_element(INTERFACE_NODE, &show_interface_cmd); install_element(INTERFACE_NODE, &show_link_cmd); install_element(INTERFACE_NODE, &show_port_cmd); install_element(INTERFACE_NODE, &show_port_pstn_cmd); install_element(INTERFACE_NODE, &show_port_isdn_cmd); install_element(INTERFACE_NODE, &system_restart_cmd); install_element(INTERFACE_NODE, &pstn_restart_cmd); install_element(INTERFACE_NODE, &align_ports_cmd); install_element(INTERFACE_NODE, &switchover_cmd); install_element(INTERFACE_NODE, &unblock_link_cmd); install_element(INTERFACE_NODE, &block_link_cmd); install_element(INTERFACE_NODE, &unblock_pstn_port_cmd); install_element(INTERFACE_NODE, &block_pstn_port_cmd); install_element(INTERFACE_NODE, &unblock_isdn_port_cmd); install_element(INTERFACE_NODE, &block_isdn_port_cmd); install_element(CONFIG_NODE, &cfg_interface_cmd); install_element(CONFIG_NODE, &cfg_no_interface_cmd); install_node(&config_interface_node_v51, config_write_interfaces); install_node(&config_interface_node_v52, NULL); install_element(CONFIG_INTERFACE_NODE_V51, &cfg_name_cmd); install_element(CONFIG_INTERFACE_NODE_V51, &cfg_no_name_cmd); install_element(CONFIG_INTERFACE_NODE_V51, &cfg_auto_restart_cmd); install_element(CONFIG_INTERFACE_NODE_V51, &cfg_no_auto_restart_cmd); install_element(CONFIG_INTERFACE_NODE_V51, &cfg_establish_cmd); install_element(CONFIG_INTERFACE_NODE_V51, &cfg_no_establish_cmd); install_element(CONFIG_INTERFACE_NODE_V51, &cfg_pstn_enable_cmd); install_element(CONFIG_INTERFACE_NODE_V51, &cfg_alignment_cmd); install_element(CONFIG_INTERFACE_NODE_V51, &cfg_no_alignment_cmd); install_element(CONFIG_INTERFACE_NODE_V51, &cfg_interface_variant_cmd); install_element(CONFIG_INTERFACE_NODE_V51, &cfg_link_cmd_v51); install_element(CONFIG_INTERFACE_NODE_V51, &cfg_port_pstn_cmd_v51); install_element(CONFIG_INTERFACE_NODE_V51, &cfg_port_pstn_cmd); install_element(CONFIG_INTERFACE_NODE_V51, &cfg_no_port_pstn_cmd); install_element(CONFIG_INTERFACE_NODE_V51, &cfg_port_isdn_cmd_v51); install_element(CONFIG_INTERFACE_NODE_V51, &cfg_port_isdn_cmd); install_element(CONFIG_INTERFACE_NODE_V51, &cfg_no_port_isdn_cmd); install_element(CONFIG_INTERFACE_NODE_V52, &cfg_name_cmd); install_element(CONFIG_INTERFACE_NODE_V52, &cfg_no_name_cmd); install_element(CONFIG_INTERFACE_NODE_V52, &cfg_auto_restart_cmd); install_element(CONFIG_INTERFACE_NODE_V52, &cfg_no_auto_restart_cmd); install_element(CONFIG_INTERFACE_NODE_V52, &cfg_establish_cmd); install_element(CONFIG_INTERFACE_NODE_V52, &cfg_no_establish_cmd); install_element(CONFIG_INTERFACE_NODE_V52, &cfg_pstn_enable_cmd); install_element(CONFIG_INTERFACE_NODE_V52, &cfg_alignment_cmd); install_element(CONFIG_INTERFACE_NODE_V52, &cfg_no_alignment_cmd); install_element(CONFIG_INTERFACE_NODE_V52, &cfg_accelerated_cmd); install_element(CONFIG_INTERFACE_NODE_V52, &cfg_no_accelerated_cmd); install_element(CONFIG_INTERFACE_NODE_V52, &cfg_interface_variant_cmd); install_element(CONFIG_INTERFACE_NODE_V52, &cfg_interface_cc_id_cmd); install_element(CONFIG_INTERFACE_NODE_V52, &cfg_interface_capability_cmd); install_element(CONFIG_INTERFACE_NODE_V52, &cfg_interface_no_capability_cmd); install_element(CONFIG_INTERFACE_NODE_V52, &cfg_link_cmd_v52); install_element(CONFIG_INTERFACE_NODE_V52, &cfg_no_link_cmd_v52); install_element(CONFIG_INTERFACE_NODE_V52, &cfg_port_pstn_cmd); install_element(CONFIG_INTERFACE_NODE_V52, &cfg_no_port_pstn_cmd); install_element(CONFIG_INTERFACE_NODE_V52, &cfg_port_isdn_cmd); install_element(CONFIG_INTERFACE_NODE_V52, &cfg_no_port_isdn_cmd); install_node(&config_link_node, NULL); install_element(CONFIG_LINK_NODE, &cfg_e1_line_cmd); install_element(CONFIG_LINK_NODE, &cfg_no_e1_line_cmd); install_node(&config_port_node, NULL); install_element(CONFIG_PORT_NODE, &cfg_port_name_cmd); install_element(CONFIG_PORT_NODE, &cfg_port_no_name_cmd); install_element(CONFIG_PORT_NODE, &cfg_echo_can_cmd); install_element(CONFIG_PORT_NODE, &cfg_no_echo_can_cmd); install_element(CONFIG_PORT_NODE, &cfg_echo_sup_cmd); install_element(CONFIG_PORT_NODE, &cfg_no_echo_sup_cmd); install_element(CONFIG_INTERFACE_NODE_V51, &cfg_v51_profile_cmd); install_element(CONFIG_INTERFACE_NODE_V52, &cfg_v52_profile_cmd); return 0; }