aboutsummaryrefslogtreecommitdiffstats
path: root/src/vty_interface.c
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <zecke@selfish.org>2011-02-22 20:57:08 +0100
committerHolger Hans Peter Freyther <zecke@selfish.org>2011-02-23 15:25:35 +0100
commit7176030e02ca59d5b4ee015f24ee2bf733eeed8e (patch)
treeeed6a2bb6bd74d365a09e77cbdc875bfcac689ed /src/vty_interface.c
parent2917644d503b706f0df5cf7228fc284a79436e31 (diff)
vty: Add all mighty new vty interface for osmo-stp
This new interface allows to have multiple linksets, msc connections and ways to connect those in one instance of the osmo-stp. Forbid to reset linksets without an app.
Diffstat (limited to 'src/vty_interface.c')
-rw-r--r--src/vty_interface.c887
1 files changed, 719 insertions, 168 deletions
diff --git a/src/vty_interface.c b/src/vty_interface.c
index 6528417..36cdfbb 100644
--- a/src/vty_interface.c
+++ b/src/vty_interface.c
@@ -1,4 +1,4 @@
-/* VTY code for the Cellmgr */
+/* VTY code for the osmo-stp */
/*
* (C) 2010-2011 by Holger Hans Peter Freyther <zecke@selfish.org>
* (C) 2010-2011 by On-Waves
@@ -22,7 +22,11 @@
#include <bsc_data.h>
#include <mtp_pcap.h>
#include <msc_connection.h>
+#include <sctp_m2ua.h>
#include <ss7_application.h>
+#include <ss7_vty.h>
+#include <cellmgr_debug.h>
+#include <snmp_mtp.h>
#include <osmocore/talloc.h>
#include <osmocore/gsm48.h>
@@ -43,288 +47,812 @@
extern struct bsc_data *bsc;
+static enum node_type ss7_go_parent(struct vty *vty)
+{
+ switch (vty->node) {
+ case LINK_NODE:
+ vty->node = LINKSETS_NODE;
+ {
+ struct mtp_link *lnk = vty->index;
+ vty->index = lnk->set;
+ vty->index_sub = &lnk->set->name;
+ }
+ break;
+ case MSC_NODE:
+ case APP_NODE:
+ case LINKSETS_NODE:
+ vty->node = SS7_NODE;
+ vty->index = NULL;
+ vty->index_sub = NULL;
+ break;
+ case SS7_NODE:
+ default:
+ vty->node = CONFIG_NODE;
+ vty->index = NULL;
+ vty->index_sub = NULL;
+ break;
+ }
+
+ return vty->node;
+}
+
+
+DEFUN(node_exit, node_exit_cmd,
+ "exit", "Exit the current node\n")
+{
+ ss7_go_parent(vty);
+ return CMD_SUCCESS;
+}
+
+DEFUN(node_end, node_end_cmd,
+ "end", "End the current mode and change to the enable node\n")
+{
+ switch (vty->node) {
+ case VIEW_NODE:
+ case ENABLE_NODE:
+ break;
+ default:
+ vty_config_unlock(vty);
+ vty->node = ENABLE_NODE;
+ vty->index = NULL;
+ vty->index_sub = NULL;
+ break;
+ }
+ return CMD_SUCCESS;
+}
+
static struct vty_app_info vty_info = {
.name = "Cellmgr-ng",
.version = VERSION,
- .go_parent_cb = NULL,
+ .go_parent_cb = ss7_go_parent,
};
/* vty code */
-enum cellmgr_node {
- CELLMGR_NODE = _LAST_OSMOVTY_NODE,
+
+static struct cmd_node ss7_node = {
+ SS7_NODE,
+ "%s(ss7)#",
+ 1,
+};
+
+static struct cmd_node linkset_node = {
+ LINKSETS_NODE,
+ "%s(linkset)#",
+ 1,
+};
+
+static struct cmd_node link_node = {
+ LINK_NODE,
+ "%s(link)#",
+ 1,
};
-static struct cmd_node cell_node = {
- CELLMGR_NODE,
- "%s(cellmgr)#",
+static struct cmd_node msc_node = {
+ MSC_NODE,
+ "%s(msc)#",
1,
};
-static int config_write_cell(struct vty *vty)
-{
- struct mtp_link_set *set = mtp_link_set_num(bsc, 0);
- struct msc_connection *msc = msc_connection_num(bsc, 0);
- struct ss7_application *app = ss7_application_num(bsc, 0);
-
- vty_out(vty, "cellmgr%s", VTY_NEWLINE);
- vty_out(vty, " mtp dpc %d%s", set->dpc, VTY_NEWLINE);
- vty_out(vty, " mtp opc %d%s", set->opc, VTY_NEWLINE);
- vty_out(vty, " mtp sccp-opc %d%s", set->sccp_opc, VTY_NEWLINE);
- vty_out(vty, " mtp ni %d%s", set->ni, VTY_NEWLINE);
- vty_out(vty, " mtp spare %d%s", set->spare, VTY_NEWLINE);
- vty_out(vty, " mtp sltm once %d%s", set->sltm_once, VTY_NEWLINE);
- if (bsc->udp_ip)
- vty_out(vty, " udp dest ip %s%s", bsc->udp_ip, VTY_NEWLINE);
- vty_out(vty, " udp dest port %d%s", bsc->udp_port, VTY_NEWLINE);
- vty_out(vty, " udp src port %d%s", bsc->src_port, VTY_NEWLINE);
- vty_out(vty, " udp reset %d%s", bsc->udp_reset_timeout, VTY_NEWLINE);
- vty_out(vty, " udp number-links %d%s", bsc->udp_nr_links, VTY_NEWLINE);
- vty_out(vty, " isup pass-through %d%s", app->isup_pass, VTY_NEWLINE);
-
- if (msc) {
- vty_out(vty, " msc ip %s%s", msc->ip, VTY_NEWLINE);
- vty_out(vty, " msc ip-dscp %d%s", msc->dscp, VTY_NEWLINE);
- vty_out(vty, " msc token %s%s", msc->token, VTY_NEWLINE);
+static struct cmd_node app_node = {
+ APP_NODE,
+ "%s(application)#",
+ 1,
+};
+
+static int dummy_write(struct vty *vty)
+{
+ return CMD_SUCCESS;
+}
+
+static int config_write_ss7(struct vty *vty)
+{
+ vty_out(vty, "ss7%s", VTY_NEWLINE);
+ vty_out(vty, " udp src-port %d%s", bsc->udp_src_port, VTY_NEWLINE);
+ vty_out(vty, " m2ua src-port %d%s", bsc->m2ua_src_port, VTY_NEWLINE);
+ return CMD_SUCCESS;
+}
+
+static void write_link(struct vty *vty, struct mtp_link *link)
+{
+ const char *name = link->name ? link->name : "";
+ struct mtp_udp_link *ulnk;
+ struct mtp_m2ua_link *m2ua;
+
+ vty_out(vty, " link %d%s", link->nr, VTY_NEWLINE);
+ vty_out(vty, " description %s%s", name, VTY_NEWLINE);
+
+ switch (link->type) {
+ case SS7_LTYPE_UDP:
+ ulnk = (struct mtp_udp_link *) link->data;
+ vty_out(vty, " ss7-transport udp%s", VTY_NEWLINE);
+ vty_out(vty, " udp dest ip %s%s",
+ inet_ntoa(ulnk->remote.sin_addr), VTY_NEWLINE);
+ vty_out(vty, " udp dest port %d%s",
+ ntohs(ulnk->remote.sin_port), VTY_NEWLINE);
+ vty_out(vty, " udp reset-timeout %d%s",
+ ulnk->reset_timeout, VTY_NEWLINE);
+ vty_out(vty, " udp link-index %d%s",
+ ulnk->link_index, VTY_NEWLINE);
+ break;
+ case SS7_LTYPE_M2UA:
+ m2ua = (struct mtp_m2ua_link *) link->data;
+ vty_out(vty, " ss7-transport m2ua%s", VTY_NEWLINE);
+
+ if (m2ua->as)
+ vty_out(vty, " m2ua application-server %s%s",
+ m2ua->as, VTY_NEWLINE);
+ vty_out(vty, " m2ua link-index %d%s",
+ m2ua->link_index, VTY_NEWLINE);
+ break;
+ case SS7_LTYPE_NONE:
+ break;
+ }
+}
+
+static void write_linkset(struct vty *vty, struct mtp_link_set *set)
+{
+ const char *name = set->name ? set->name : "";
+ struct mtp_link *link;
+ int i;
+
+ vty_out(vty, " linkset %d%s", set->nr, VTY_NEWLINE);
+ vty_out(vty, " description %s%s", name, VTY_NEWLINE);
+ vty_out(vty, " mtp3 dpc %d%s", set->dpc, VTY_NEWLINE);
+ vty_out(vty, " mtp3 opc %d%s", set->opc, VTY_NEWLINE);
+ vty_out(vty, " mtp3 ni %d%s", set->ni, VTY_NEWLINE);
+ vty_out(vty, " mtp3 spare %d%s", set->spare, VTY_NEWLINE);
+ vty_out(vty, " mtp3 sltm-once %d%s", set->sltm_once, VTY_NEWLINE);
+
+ for (i = 0; i < ARRAY_SIZE(set->supported_ssn); ++i) {
+ if (!set->supported_ssn[i])
+ continue;
+ vty_out(vty, " mtp3 ssn %d%s", i, VTY_NEWLINE);
}
+ llist_for_each_entry(link, &set->links, entry)
+ write_link(vty, link);
+}
+
+static int config_write_linkset(struct vty *vty)
+{
+ struct mtp_link_set *set;
+
+ llist_for_each_entry(set, &bsc->linksets, entry)
+ write_linkset(vty, set);
return CMD_SUCCESS;
}
-DEFUN(cfg_cell, cfg_cell_cmd,
- "cellmgr", "Configure the Cellmgr")
+static void write_msc(struct vty *vty, struct msc_connection *msc)
+{
+ const char *name = msc->name ? msc->name : "";
+
+ vty_out(vty, " msc %d%s", msc->nr, VTY_NEWLINE);
+ vty_out(vty, " description %s%s", name, VTY_NEWLINE);
+ vty_out(vty, " ip %s%s", msc->ip, VTY_NEWLINE);
+ vty_out(vty, " token %s%s", msc->token, VTY_NEWLINE);
+ vty_out(vty, " dscp %d%s", msc->dscp, VTY_NEWLINE);
+ vty_out(vty, " timeout ping %d%s", msc->ping_time, VTY_NEWLINE);
+ vty_out(vty, " timeout pong %d%s", msc->pong_time, VTY_NEWLINE);
+ vty_out(vty, " timeout restart %d%s", msc->msc_time, VTY_NEWLINE);
+}
+
+static int config_write_msc(struct vty *vty)
+{
+ struct msc_connection *msc;
+
+ llist_for_each_entry(msc, &bsc->mscs, entry)
+ write_msc(vty, msc);
+ return 0;
+}
+
+static const char *app_type(enum ss7_app_type type)
{
- vty->node = CELLMGR_NODE;
+ switch (type) {
+ case APP_NONE:
+ return "none";
+ case APP_CELLMGR:
+ return "msc";
+ case APP_RELAY:
+ return "relay";
+ case APP_STP:
+ return "stp";
+ default:
+ LOGP(DINP, LOGL_ERROR, "Should no be reached.\n");
+ return "";
+ }
+}
+
+static const char *link_type(enum ss7_set_type type)
+{
+ switch (type) {
+ case SS7_SET_LINKSET:
+ return "linkset";
+ case SS7_SET_MSC:
+ return "msc";
+ default:
+ LOGP(DINP, LOGL_ERROR, "Should no be reached.\n");
+ return "";
+ }
+}
+
+static void write_application(struct vty *vty, struct ss7_application *app)
+{
+ const char *name = app->name ? app->name : "";
+
+ vty_out(vty, " application %d%s", app->nr, VTY_NEWLINE);
+ vty_out(vty, " description %s%s", name, VTY_NEWLINE);
+ vty_out(vty, " type %s%s", app_type(app->type), VTY_NEWLINE);
+
+ if (app->type == APP_STP)
+ vty_out(vty, " isup-pass-through %d%s", app->isup_pass, VTY_NEWLINE);
+
+ if (app->route_is_set) {
+ vty_out(vty, " route %s %d %s %d%s",
+ link_type(app->route_src.type), app->route_src.nr,
+ link_type(app->route_dst.type), app->route_dst.nr,
+ VTY_NEWLINE);
+ }
+}
+
+static int config_write_app(struct vty *vty)
+{
+ struct ss7_application *app;
+
+ llist_for_each_entry(app, &bsc->apps, entry)
+ write_application(vty, app);
+
return CMD_SUCCESS;
}
-DEFUN(cfg_net_dpc, cfg_net_dpc_cmd,
- "mtp dpc DPC_NR",
- "Set the DPC to be used.")
+DEFUN(cfg_ss7, cfg_ss7_cmd,
+ "ss7", "Configure the application\n")
{
- struct mtp_link_set *set = mtp_link_set_num(bsc, 0);
- set->dpc = atoi(argv[0]);
+ vty->node = SS7_NODE;
return CMD_SUCCESS;
}
-DEFUN(cfg_net_opc, cfg_net_opc_cmd,
- "mtp opc OPC_NR",
- "Set the OPC to be used.")
+DEFUN(cfg_ss7_udp_src_port, cfg_ss7_udp_src_port_cmd,
+ "udp src-port <1-65535>",
+ "UDP related commands\n"
+ "Source port for SS7 via UDP transport\n"
+ "Port to bind to\n")
{
- struct mtp_link_set *set = mtp_link_set_num(bsc, 0);
- set->opc = atoi(argv[0]);
+ bsc->udp_src_port = atoi(argv[0]);
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_ss7_m2ua_src_port, cfg_ss7_m2ua_src_port_cmd,
+ "m2ua src-port <1-65535>",
+ "M2UA related commands\n"
+ "Source port for SS7 via M2UA\n"
+ "Port to bind to\n")
+{
+ bsc->m2ua_src_port = atoi(argv[0]);
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_ss7_linkset, cfg_ss7_linkset_cmd,
+ "linkset <0-100>",
+ "Linkset commands\n" "Linkset number\n")
+{
+ struct mtp_link_set *set;
+ int nr;
+
+ nr = atoi(argv[0]);
+ if (nr > bsc->num_linksets) {
+ vty_out(vty, "%% The next unused Linkset number is %u%s",
+ bsc->num_linksets, VTY_NEWLINE);
+ return CMD_WARNING;
+ } else if (nr == bsc->num_linksets) {
+ set = mtp_link_set_alloc(bsc);
+ } else
+ set = mtp_link_set_num(bsc, nr);
+
+ if (!set) {
+ vty_out(vty, "%% Unable to allocate Linkset %u%s",
+ nr, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ vty->node = LINKSETS_NODE;
+ vty->index = set;
+ vty->index_sub = &set->name;
return CMD_SUCCESS;
}
-DEFUN(cfg_net_sccp_opc, cfg_net_sccp_opc_cmd,
- "mtp sccp-opc OPC_NR",
- "Set the SCCP OPC to be used.")
+DEFUN(cfg_linkset_mtp3_dpc, cfg_linkset_mtp3_dpc_cmd,
+ "mtp3 dpc <0-255>",
+ "MTP Level3\n" "Destination Point Code\n" "Point Code\n")
{
- struct mtp_link_set *set = mtp_link_set_num(bsc, 0);
- set->sccp_opc = atoi(argv[0]);
+ struct mtp_link_set *set = vty->index;
+ set->dpc = atoi(argv[0]);
return CMD_SUCCESS;
}
-DEFUN(cfg_net_mtp_ni, cfg_net_mtp_ni_cmd,
- "mtp ni NR",
- "Set the MTP NI to be used.\n" "NR")
+DEFUN(cfg_linkset_mtp3_opc, cfg_linkset_mtp3_opc_cmd,
+ "mtp3 opc <0-255>",
+ "MTP Level3\n" "Originating Point Code\n" "Point Code\n")
{
- struct mtp_link_set *set = mtp_link_set_num(bsc, 0);
+ struct mtp_link_set *set = vty->index;
+ set->opc = atoi(argv[0]);
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_linkset_mtp3_ni, cfg_linkset_mtp3_ni_cmd,
+ "mtp3 ni <0-3>",
+ "MTP Level3\n" "NI for the address\n" "NI\n")
+{
+ struct mtp_link_set *set = vty->index;
set->ni = atoi(argv[0]);
return CMD_SUCCESS;
}
-DEFUN(cfg_net_mtp_spare, cfg_net_mtp_spare_cmd,
- "mtp spare NR",
- "Set the MTP Spare to be used.\n" "NR")
+DEFUN(cfg_linkset_mtp3_spare, cfg_linkset_mtp3_spare_cmd,
+ "mtp3 spare <0-3>",
+ "MTP Level3\n" "Spare for the address\n" "Spare\n")
{
- struct mtp_link_set *set = mtp_link_set_num(bsc, 0);
+ struct mtp_link_set *set = vty->index;
set->spare = atoi(argv[0]);
return CMD_SUCCESS;
}
+DEFUN(cfg_linkset_mtp3_ssn, cfg_linkset_mtp3_ssn_cmd,
+ "mtp3 ssn <0-255>",
+ "MTP Level3\n" "SSN supported\n" "SSN\n")
+{
+ struct mtp_link_set *set = vty->index;
+ set->supported_ssn[atoi(argv[0])] = 1;
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_linkset_no_mtp3_ssn, cfg_linkset_no_mtp3_ssn_cmd,
+ "no mtp3 ssn <0-255>",
+ "MTP Level3\n" "SSN supported\n" "SSN\n")
+{
+ struct mtp_link_set *set = vty->index;
+ set->supported_ssn[atoi(argv[0])] = 0;
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_linkset_sltm_once, cfg_linkset_sltm_once_cmd,
+ "mtp3 sltm-once (0|1)",
+ "MTP Level3\n" "Test the link once\n" "Continous testing\n" "Test once\n")
+{
+ struct mtp_link_set *set = vty->index;
+ set->sltm_once = !!atoi(argv[0]);
+
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_linkset_link, cfg_linkset_link_cmd,
+ "link <0-100>",
+ "Link\n" "Link number\n")
+{
+ struct mtp_link_set *set = vty->index;
+
+ struct mtp_link *lnk;
+ int nr;
+
+ nr = atoi(argv[0]);
+ if (nr > set->nr_links) {
+ vty_out(vty, "%% The next unused Link number is %u%s",
+ set->nr_links, VTY_NEWLINE);
+ return CMD_WARNING;
+ } else if (nr == set->nr_links) {
+ lnk = mtp_link_alloc(set);
+ } else
+ lnk = mtp_link_num(set, nr);
+
+ if (!set) {
+ vty_out(vty, "%% Unable to allocate Link %u%s",
+ nr, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ vty->node = LINK_NODE;
+ vty->index = lnk;
+ vty->index_sub = &lnk->name;
+ return CMD_SUCCESS;
+}
-DEFUN(cfg_udp_dst_ip, cfg_udp_dst_ip_cmd,
- "udp dest ip IP",
- "Set the IP when UDP mode is supposed to be used.")
+DEFUN(cfg_link_ss7_transport, cfg_link_ss7_transport_cmd,
+ "ss7-transport (none|udp|m2ua)",
+ "SS7 transport for the link\n"
+ "No transport\n" "MTP over UDP\n" "SCTP M2UA\n")
+{
+ int wanted = SS7_LTYPE_NONE;
+ struct mtp_link *link;
+
+ link = vty->index;
+
+ if (strcmp("udp", argv[0]) == 0)
+ wanted = SS7_LTYPE_UDP;
+ else if (strcmp("m2ua", argv[0]) == 0)
+ wanted = SS7_LTYPE_M2UA;
+
+ if (link->type != wanted && link->type != SS7_LTYPE_NONE) {
+ vty_out(vty, "%%Can not change the type of a link.\n");
+ return CMD_WARNING;
+ }
+
+ switch (wanted) {
+ case SS7_LTYPE_UDP:
+ link->data = mtp_udp_link_init(link);
+ break;
+ case SS7_LTYPE_M2UA:
+ link->data = mtp_m2ua_link_init(link);
+ break;
+ case SS7_LTYPE_NONE:
+ /* nothing */
+ break;
+ }
+
+ if (!link->data) {
+ vty_out(vty, "Failed to allocate the link type.%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_link_udp_dest_ip, cfg_link_udp_dest_ip_cmd,
+ "udp dest ip HOST_NAME",
+ "UDP Transport\n" "IP\n" "Hostname\n")
{
struct hostent *hosts;
- struct in_addr *addr;
- hosts = gethostbyname(argv[0]);
+ struct mtp_link *link = vty->index;
+ struct mtp_udp_link *ulnk;
+
+ if (link->type != SS7_LTYPE_UDP) {
+ vty_out(vty, "%%This only applies to UDP links.%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ ulnk = link->data;
+
+ if (ulnk->dest)
+ talloc_free(ulnk->dest);
+ ulnk->dest = talloc_strdup(ulnk, argv[0]);
+
+ hosts = gethostbyname(ulnk->dest);
if (!hosts || hosts->h_length < 1 || hosts->h_addrtype != AF_INET) {
vty_out(vty, "Failed to resolve '%s'%s", argv[0], VTY_NEWLINE);
return CMD_WARNING;
}
+ ulnk->remote.sin_addr = * (struct in_addr *) hosts->h_addr_list[0];
+
+ if (snmp_mtp_peer_name(ulnk->session, ulnk->dest) != 0) {
+ vty_out(vty, "%%Failed to open SNMP port on link %d.%s",
+ link->nr, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
- addr = (struct in_addr *) hosts->h_addr_list[0];
- bsc->udp_ip = talloc_strdup(NULL, inet_ntoa(*addr));
return CMD_SUCCESS;
}
-DEFUN(cfg_udp_dst_port, cfg_udp_dst_port_cmd,
- "udp dest port PORT_NR",
- "If UDP mode is used specify the UDP dest port")
+DEFUN(cfg_link_udp_dest_port, cfg_link_udp_dest_port_cmd,
+ "udp dest port <1-65535>",
+ "UDP Transport\n" "Set the port number\n" "Port\n")
{
- bsc->udp_port = atoi(argv[0]);
+ struct mtp_link *link = vty->index;
+ struct mtp_udp_link *ulnk;
+
+ if (link->type != SS7_LTYPE_UDP) {
+ vty_out(vty, "%%This only applies to UDP links.%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ ulnk = link->data;
+ ulnk->remote.sin_port = htons(atoi(argv[0]));
return CMD_SUCCESS;
}
-DEFUN(cfg_udp_src_port, cfg_udp_src_port_cmd,
- "udp src port PORT_NR",
- "Set the UDP source port to be used.")
+DEFUN(cfg_link_udp_reset, cfg_link_udp_reset_cmd,
+ "udp reset-timeout <1-65535>",
+ "UDP Transport\n" "Reset timeout after a failure\n" "Seconds\n")
{
- bsc->src_port = atoi(argv[0]);
+ struct mtp_link *link = vty->index;
+ struct mtp_udp_link *ulnk;
+
+ if (link->type != SS7_LTYPE_UDP) {
+ vty_out(vty, "%%This only applies to UDP links.%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ ulnk = link->data;
+ ulnk->reset_timeout = atoi(argv[0]);
return CMD_SUCCESS;
}
-DEFUN(cfg_udp_reset, cfg_udp_reset_cmd,
- "udp reset TIMEOUT",
- "Set the timeout to take the link down")
+DEFUN(cfg_link_udp_link_index, cfg_link_udp_link_index_cmd,
+ "udp link-index <0-65535>",
+ "UDP Transport\n" "Link index\n" "Index\n")
{
- bsc->udp_reset_timeout = atoi(argv[0]);
+ struct mtp_link *link = vty->index;
+ struct mtp_udp_link *ulnk;
+
+ if (link->type != SS7_LTYPE_UDP) {
+ vty_out(vty, "%%This only applies to UDP links.%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ ulnk = link->data;
+ ulnk->link_index = atoi(argv[0]);
return CMD_SUCCESS;
}
-DEFUN(cfg_udp_nr_links, cfg_udp_nr_links_cmd,
- "udp number-links <1-32>",
- "Set the number of links to use\n")
+DEFUN(cfg_link_m2ua_as, cfg_link_m2ua_as_cmd,
+ "m2ua application-server NAME",
+ "M2UA Transport\n" "Application Server Name\n" "Name\n")
{
- bsc->udp_nr_links = atoi(argv[0]);
+ struct mtp_link *link = vty->index;
+ struct mtp_m2ua_link *m2ua;
+
+ if (link->type != SS7_LTYPE_M2UA) {
+ vty_out(vty, "%%This only applies to M2UA links.%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ m2ua = link->data;
+ if (m2ua->as)
+ talloc_free(m2ua->as);
+ m2ua->as = talloc_strdup(m2ua, argv[0]);
return CMD_SUCCESS;
}
-DEFUN(cfg_sltm_once, cfg_sltm_once_cmd,
- "mtp sltm once (0|1)",
- "Send SLTMs until the link is established.")
+DEFUN(cfg_link_m2ua_link_index, cfg_link_m2ua_link_index_cmd,
+ "m2ua link-index <0-65535>",
+ "M2UA Transport\n" "Link index\n" "Index\n")
{
- struct mtp_link_set *set = mtp_link_set_num(bsc, 0);
- set->sltm_once = !!atoi(argv[0]);
+ struct mtp_link *link = vty->index;
+ struct mtp_m2ua_link *m2ua;
+
+ if (link->type != SS7_LTYPE_M2UA) {
+ vty_out(vty, "%%This only applies to M2UA links.%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ m2ua = link->data;
+ m2ua->link_index = atoi(argv[0]);
return CMD_SUCCESS;
}
-DEFUN(cfg_msc_ip, cfg_msc_ip_cmd,
- "msc ip IP",
- "Set the MSC IP")
+DEFUN(cfg_ss7_msc, cfg_ss7_msc_cmd,
+ "msc <0-100>",
+ "MSC Connection\n" "MSC Number\n")
{
- struct hostent *hosts;
- struct in_addr *addr;
- struct msc_connection *msc = msc_connection_num(bsc, 0);
+ struct msc_connection *msc;
+ int nr;
+
+ nr = atoi(argv[0]);
+ if (nr > bsc->num_mscs) {
+ vty_out(vty, "%% The next unused MSC number is %u%s",
+ bsc->num_mscs, VTY_NEWLINE);
+ return CMD_WARNING;
+ } else if (nr == bsc->num_mscs) {
+ msc = msc_connection_create(bsc, 1);
+ } else
+ msc = msc_connection_num(bsc, nr);
if (!msc) {
- vty_out(vty, "%%No MSC Connection defined in this app.%s", VTY_NEWLINE);
+ vty_out(vty, "%% Unable to allocate MSC %u%s",
+ nr, VTY_NEWLINE);
return CMD_WARNING;
}
+ vty->node = MSC_NODE;
+ vty->index = msc;
+ vty->index_sub = &msc->name;
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_msc_ip, cfg_msc_ip_cmd,
+ "ip ADDR",
+ "IP Address of the MSC\n" "Address\n")
+{
+ struct hostent *hosts;
+ struct msc_connection *msc;
+
+ msc = vty->index;
hosts = gethostbyname(argv[0]);
if (!hosts || hosts->h_length < 1 || hosts->h_addrtype != AF_INET) {
vty_out(vty, "Failed to resolve '%s'%s", argv[0], VTY_NEWLINE);
return CMD_WARNING;
}
- addr = (struct in_addr *) hosts->h_addr_list[0];
-
if (msc->ip)
talloc_free(msc->ip);
- msc->ip = talloc_strdup(msc, inet_ntoa(*addr));
+
+ msc->ip = talloc_strdup(msc,
+ inet_ntoa(*((struct in_addr *) hosts->h_addr_list[0])));
return CMD_SUCCESS;
}
-DEFUN(cfg_msc_ip_dscp, cfg_msc_ip_dscp_cmd,
- "msc ip-dscp <0-255>",
- "Set the IP DSCP on the A-link\n"
- "Set the DSCP in IP packets to the MSC")
+DEFUN(cfg_msc_token, cfg_msc_token_cmd,
+ "token TOKEN",
+ "Token for the MSC\n" "The token\n")
{
- struct msc_connection *msc = msc_connection_num(bsc, 0);
+ struct msc_connection *msc = vty->index;
- if (!msc) {
- vty_out(vty, "%%No MSC Connection defined in this app.%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
+ if (msc->token)
+ talloc_free(msc->token);
+ msc->token = talloc_strdup(msc, argv[0]);
+ return CMD_SUCCESS;
+}
+DEFUN(cfg_msc_dscp, cfg_msc_dscp_cmd,
+ "dscp <0-255>",
+ "DSCP for the IP Connection\n" "Nr\n")
+{
+ struct msc_connection *msc = vty->index;
msc->dscp = atoi(argv[0]);
return CMD_SUCCESS;
}
-ALIAS_DEPRECATED(cfg_msc_ip_dscp, cfg_msc_ip_tos_cmd,
- "msc ip-tos <0-255>",
- "Set the IP DSCP on the A-link\n"
- "Set the DSCP in IP packets to the MSC")
+DEFUN(cfg_msc_timeout_ping, cfg_msc_timeout_ping_cmd,
+ "timeout ping <1-65535>",
+ "Timeout commands\n" "Time between pings\n" "Seconds\n")
+{
+ struct msc_connection *msc = vty->index;
+ msc->ping_time = atoi(argv[0]);
+ return CMD_SUCCESS;
+}
-DEFUN(cfg_msc_token, cfg_msc_token_cmd,
- "msc token TOKEN",
- "Set the Token to be used for the MSC")
+DEFUN(cfg_msc_timeout_pong, cfg_msc_timeout_pong_cmd,
+ "timeout pong <1-65535>",
+ "Timeout commands\n" "Time between pongs\n" "Seconds\n")
+{
+ struct msc_connection *msc = vty->index;
+ msc->pong_time = atoi(argv[0]);
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_msc_timeout_restart, cfg_msc_timeout_restart_cmd,
+ "timeout restart <1-65535>",
+ "Timeout commands\n" "Time between restarts\n" "Seconds\n")
{
- struct msc_connection *msc = msc_connection_num(bsc, 0);
+ struct msc_connection *msc = vty->index;
+ msc->msc_time = atoi(argv[0]);
+ return CMD_SUCCESS;
+}
- if (!msc) {
- vty_out(vty, "%%No MSC Connection defined in this app.%s", VTY_NEWLINE);
+DEFUN(cfg_ss7_app, cfg_ss7_app_cmd,
+ "application <0-100>",
+ "Application Commands\n" "Number\n")
+{
+ struct ss7_application *app;
+ int nr;
+
+ nr = atoi(argv[0]);
+ if (nr > bsc->num_apps) {
+ vty_out(vty, "%% The next unused Application number is %u%s",
+ bsc->num_apps, VTY_NEWLINE);
+ return CMD_WARNING;
+ } else if (nr == bsc->num_apps) {
+ app = ss7_application_alloc(bsc);
+ } else
+ app = ss7_application_num(bsc, nr);
+
+ if (!app) {
+ vty_out(vty, "%% Unable to allocate Application %u%s",
+ nr, VTY_NEWLINE);
return CMD_WARNING;
}
- if (msc->token)
- talloc_free(msc->token);
- msc->token = talloc_strdup(msc, argv[0]);
+ vty->node = APP_NODE;
+ vty->index = app;
+ vty->index_sub = &app->name;
return CMD_SUCCESS;
}
-DEFUN(cfg_ping_time, cfg_ping_time_cmd,
- "timeout ping NR",
- "Set the PING interval. Negative to disable it")
+DEFUN(cfg_app_type, cfg_app_type_cmd,
+ "type (none|stp|relay|msc)",
+ "Type of Application\n"
+ "No type\n" "Signalling Transfer Point\n"
+ "Relay SCCP/ISUP messages\n" "MSC connector with state\n")
{
- struct msc_connection *msc = msc_connection_num(bsc, 0);
+ enum ss7_app_type type;
+ struct ss7_application *app = vty->index;
+
+ switch (argv[0][0]) {
+ case 'm':
+ type = APP_CELLMGR;
+ break;
+ case 'r':
+ type = APP_RELAY;
+ break;
+ case 's':
+ type = APP_STP;
+ break;
+ default:
+ case 'n':
+ type = APP_NONE;
+ break;
+ }
- if (!msc) {
- vty_out(vty, "%%No MSC Connection defined in this app.%s", VTY_NEWLINE);
+ if (app->type != APP_NONE && app->type != type) {
+ vty_out(vty, "The type can not be changed at runtime on app %d.%s",
+ app->nr, VTY_NEWLINE);
return CMD_WARNING;
}
- msc->ping_time = atoi(argv[0]);
+ app->type = type;
return CMD_SUCCESS;
}
-DEFUN(cfg_pong_time, cfg_pong_time_cmd,
- "timeout pong NR",
- "Set the PING interval. Negative to disable it")
+DEFUN(cfg_app_isup_pass, cfg_app_isup_pass_cmd,
+ "isup-pass-through (0|1)",
+ "Pass all ISUP messages\n" "Handle some ISUP locally\n" "Pass all messages\n")
{
- struct msc_connection *msc = msc_connection_num(bsc, 0);
+ struct ss7_application *app = vty->index;
- if (!msc) {
- vty_out(vty, "%%No MSC Connection defined in this app.%s", VTY_NEWLINE);
+ if (app->type != APP_STP) {
+ vty_out(vty, "%%Need to use the 'stp' app for this option on app %d.%s",
+ app->nr, VTY_NEWLINE);
return CMD_WARNING;
}
- msc->pong_time = atoi(argv[0]);
+ ss7_application_pass_isup(app, atoi(argv[0]));
return CMD_SUCCESS;
}
-DEFUN(cfg_msc_time, cfg_msc_time_cmd,
- "timeout msc NR",
- "Set the MSC connect timeout")
+DEFUN(cfg_app_route, cfg_app_route_cmd,
+ "route linkset <0-100> msc <0-100>",
+ "Routing commands\n" "Source Linkset\n" "Linkset Nr\n"
+ "Dest MSC\n" "MSC Nr\n")
{
- struct msc_connection *msc = msc_connection_num(bsc, 0);
+ struct ss7_application *app = vty->index;
- if (!msc) {
- vty_out(vty, "%%No MSC Connection defined in this app.%s", VTY_NEWLINE);
+ if (app->type != APP_CELLMGR && app->type != APP_RELAY) {
+ vty_out(vty, "The app type needs to be 'relay' or 'msc'.%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ if (ss7_application_setup(app, app->type,
+ SS7_SET_LINKSET, atoi(argv[0]),
+ SS7_SET_MSC, atoi(argv[1])) != 0) {
+ vty_out(vty, "Failed to route linkset %d to msc %d.%s",
+ atoi(argv[0]), atoi(argv[1]), VTY_NEWLINE);
return CMD_WARNING;
}
- msc->msc_time = atoi(argv[0]);
return CMD_SUCCESS;
}
-DEFUN(cfg_isup_pass, cfg_isup_pass_cmd,
- "isup pass-through (0|1)",
- "ISUP related functionality\n"
- "Pass through all ISUP messages directly\n"
- "Handle some messages locally\n" "Pass through everything\n")
+DEFUN(cfg_app_route_ls, cfg_app_route_ls_cmd,
+ "route linkset <0-100> linkset <0-100>",
+ "Routing commands\n" "Source Linkset\n" "Linkset Nr\n"
+ "Dest Linkset\n" "Linkset Nr\n" )
{
- struct ss7_application *app = ss7_application_num(bsc, 0);
- ss7_application_pass_isup(app, atoi(argv[0]));
+ struct ss7_application *app = vty->index;
+
+ if (app->type != APP_STP) {
+ vty_out(vty, "The app type needs to be 'stp'.%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ if (ss7_application_setup(app, app->type,
+ SS7_SET_LINKSET, atoi(argv[0]),
+ SS7_SET_LINKSET, atoi(argv[1])) != 0) {
+ vty_out(vty, "Failed to route linkset %d to linkset %d.%s",
+ atoi(argv[0]), atoi(argv[1]), VTY_NEWLINE);
+ return CMD_WARNING;
+ }
return CMD_SUCCESS;
}
+static void install_defaults(int node)
+{
+ install_default(node);
+ install_element(node, &node_exit_cmd);
+ install_element(node, &node_end_cmd);
+ install_element(node, &cfg_description_cmd);
+ install_element(node, &cfg_no_description_cmd);
+}
+
extern void cell_vty_init_cmds(void);
void cell_vty_init(void)
{
@@ -332,28 +860,51 @@ void cell_vty_init(void)
vty_init(&vty_info);
logging_vty_add_cmds();
- install_element(CONFIG_NODE, &cfg_cell_cmd);
- install_node(&cell_node, config_write_cell);
-
- install_element(CELLMGR_NODE, &cfg_net_dpc_cmd);
- install_element(CELLMGR_NODE, &cfg_net_opc_cmd);
- install_element(CELLMGR_NODE, &cfg_net_sccp_opc_cmd);
- install_element(CELLMGR_NODE, &cfg_net_mtp_ni_cmd);
- install_element(CELLMGR_NODE, &cfg_net_mtp_spare_cmd);
- install_element(CELLMGR_NODE, &cfg_udp_dst_ip_cmd);
- install_element(CELLMGR_NODE, &cfg_udp_dst_port_cmd);
- install_element(CELLMGR_NODE, &cfg_udp_src_port_cmd);
- install_element(CELLMGR_NODE, &cfg_udp_reset_cmd);
- install_element(CELLMGR_NODE, &cfg_udp_nr_links_cmd);
- install_element(CELLMGR_NODE, &cfg_sltm_once_cmd);
- install_element(CELLMGR_NODE, &cfg_msc_ip_cmd);
- install_element(CELLMGR_NODE, &cfg_msc_token_cmd);
- install_element(CELLMGR_NODE, &cfg_msc_ip_dscp_cmd);
- install_element(CELLMGR_NODE, &cfg_msc_ip_tos_cmd);
- install_element(CELLMGR_NODE, &cfg_ping_time_cmd);
- install_element(CELLMGR_NODE, &cfg_pong_time_cmd);
- install_element(CELLMGR_NODE, &cfg_msc_time_cmd);
- install_element(CELLMGR_NODE, &cfg_isup_pass_cmd);
+ install_element(CONFIG_NODE, &cfg_ss7_cmd);
+ install_node(&ss7_node, config_write_ss7);
+ install_defaults(SS7_NODE);
+ install_element(SS7_NODE, &cfg_ss7_udp_src_port_cmd);
+ install_element(SS7_NODE, &cfg_ss7_m2ua_src_port_cmd);
+
+ install_element(SS7_NODE, &cfg_ss7_linkset_cmd);
+ install_node(&linkset_node, config_write_linkset);
+ install_defaults(LINKSETS_NODE);
+ install_element(LINKSETS_NODE, &cfg_linkset_mtp3_dpc_cmd);
+ install_element(LINKSETS_NODE, &cfg_linkset_mtp3_opc_cmd);
+ install_element(LINKSETS_NODE, &cfg_linkset_mtp3_ni_cmd);
+ install_element(LINKSETS_NODE, &cfg_linkset_mtp3_spare_cmd);
+ install_element(LINKSETS_NODE, &cfg_linkset_mtp3_ssn_cmd);
+ install_element(LINKSETS_NODE, &cfg_linkset_no_mtp3_ssn_cmd);
+ install_element(LINKSETS_NODE, &cfg_linkset_sltm_once_cmd);
+
+ install_element(LINKSETS_NODE, &cfg_linkset_link_cmd);
+ install_node(&link_node, dummy_write);
+ install_defaults(LINK_NODE);
+ install_element(LINK_NODE, &cfg_link_ss7_transport_cmd);
+ install_element(LINK_NODE, &cfg_link_udp_dest_ip_cmd);
+ install_element(LINK_NODE, &cfg_link_udp_dest_port_cmd);
+ install_element(LINK_NODE, &cfg_link_udp_reset_cmd);
+ install_element(LINK_NODE, &cfg_link_udp_link_index_cmd);
+ install_element(LINK_NODE, &cfg_link_m2ua_as_cmd);
+ install_element(LINK_NODE, &cfg_link_m2ua_link_index_cmd);
+
+ install_element(SS7_NODE, &cfg_ss7_msc_cmd);
+ install_node(&msc_node, config_write_msc);
+ install_defaults(MSC_NODE);
+ install_element(MSC_NODE, &cfg_msc_ip_cmd);
+ install_element(MSC_NODE, &cfg_msc_token_cmd);
+ install_element(MSC_NODE, &cfg_msc_dscp_cmd);
+ install_element(MSC_NODE, &cfg_msc_timeout_ping_cmd);
+ install_element(MSC_NODE, &cfg_msc_timeout_pong_cmd);
+ install_element(MSC_NODE, &cfg_msc_timeout_restart_cmd);
+
+ install_element(SS7_NODE, &cfg_ss7_app_cmd);
+ install_node(&app_node, config_write_app);
+ install_defaults(APP_NODE);
+ install_element(APP_NODE, &cfg_app_type_cmd);
+ install_element(APP_NODE, &cfg_app_isup_pass_cmd);
+ install_element(APP_NODE, &cfg_app_route_cmd);
+ install_element(APP_NODE, &cfg_app_route_ls_cmd);
cell_vty_init_cmds();
}