From 7176030e02ca59d5b4ee015f24ee2bf733eeed8e Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Tue, 22 Feb 2011 20:57:08 +0100 Subject: 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. --- include/bsc_data.h | 10 +- include/mtp_data.h | 1 + include/sctp_m2ua.h | 7 +- include/snmp_mtp.h | 3 +- include/ss7_application.h | 2 + include/ss7_vty.h | 42 +++ src/Makefile.am | 5 +- src/bsc.c | 5 +- src/link_udp.c | 78 ++-- src/links.c | 22 +- src/main_stp.c | 97 ++--- src/mtp_layer3.c | 3 + src/sctp_m2ua.c | 55 ++- src/snmp_mtp.c | 22 +- src/ss7_application.c | 8 + src/vty_interface.c | 887 ++++++++++++++++++++++++++++++++++++--------- src/vty_interface_cmds.c | 13 +- src/vty_interface_legacy.c | 358 ++++++++++++++++++ 18 files changed, 1301 insertions(+), 317 deletions(-) create mode 100644 include/ss7_vty.h create mode 100644 src/vty_interface_legacy.c diff --git a/include/bsc_data.h b/include/bsc_data.h index 12e8e93..3588ac8 100644 --- a/include/bsc_data.h +++ b/include/bsc_data.h @@ -53,6 +53,7 @@ struct mtp_udp_link { int link_index; int reset_timeout; + char *dest; struct sockaddr_in remote; struct mtp_udp_data *data; @@ -69,11 +70,13 @@ struct bsc_data { /* udp code */ struct mtp_udp_data udp_data; - int src_port; + int udp_src_port; int udp_port; char *udp_ip; int udp_nr_links; + int m2ua_src_port; + /* MTP Links */ struct llist_head linksets; int num_linksets; @@ -104,7 +107,8 @@ void mtp_linkset_up(struct mtp_link_set *); /* udp init */ struct mtp_link_set *link_set_create(struct bsc_data *bsc); -int link_global_init(struct mtp_udp_data *data, int src_port); +int link_global_init(struct mtp_udp_data *data); +int link_global_bind(struct mtp_udp_data *data, int src_port); int link_udp_init(struct mtp_udp_link *data, char *dest_ip, int port); int link_init(struct bsc_data *bsc, struct mtp_link_set *set); int link_shutdown_all(struct mtp_link_set *); @@ -120,4 +124,6 @@ int mtp_handle_pcap(struct mtp_link *, int dir, const uint8_t *data, int length) struct bsc_data *bsc_data_create(); +struct mtp_udp_link *mtp_udp_link_init(struct mtp_link *link); + #endif diff --git a/include/mtp_data.h b/include/mtp_data.h index 969a4de..bbd013e 100644 --- a/include/mtp_data.h +++ b/include/mtp_data.h @@ -84,6 +84,7 @@ struct mtp_link_set { struct rate_ctr_group *ctrg; /* custom data */ + struct bsc_data *bsc; struct ss7_application *app; }; diff --git a/include/sctp_m2ua.h b/include/sctp_m2ua.h index 34c8666..2ae1472 100644 --- a/include/sctp_m2ua.h +++ b/include/sctp_m2ua.h @@ -57,6 +57,8 @@ struct mtp_m2ua_link { int link_index; struct llist_head entry; struct sctp_m2ua_transport *transport; + + char *as; }; /* @@ -71,8 +73,11 @@ struct sctp_m2ua_conn { struct sctp_m2ua_transport *trans; }; -struct sctp_m2ua_transport *sctp_m2ua_transp_create(const char *ip, int port); +struct sctp_m2ua_transport *sctp_m2ua_transp_create(struct bsc_data *bsc); +int sctp_m2ua_transport_bind(struct sctp_m2ua_transport *, const char *ip, int port); struct mtp_m2ua_link *mtp_m2ua_link_create(struct sctp_m2ua_transport *transport, struct mtp_link_set *); +struct mtp_m2ua_link *mtp_m2ua_link_init(struct mtp_link *link); + #endif diff --git a/include/snmp_mtp.h b/include/snmp_mtp.h index 8c15df7..0c3075f 100644 --- a/include/snmp_mtp.h +++ b/include/snmp_mtp.h @@ -49,7 +49,8 @@ enum { SNMP_STATUS_TIMEOUT, }; -struct snmp_mtp_session *snmp_mtp_session_create(char *host); +struct snmp_mtp_session *snmp_mtp_session_create(void); +int snmp_mtp_peer_name(struct snmp_mtp_session *, char *name); void snmp_mtp_deactivate(struct snmp_mtp_session *, int link_id); void snmp_mtp_activate(struct snmp_mtp_session *, int link_id); void snmp_mtp_poll(); diff --git a/include/ss7_application.h b/include/ss7_application.h index 66ddd87..084a8f7 100644 --- a/include/ss7_application.h +++ b/include/ss7_application.h @@ -35,6 +35,7 @@ enum ss7_set_type { }; enum ss7_app_type { + APP_NONE, APP_CELLMGR, APP_RELAY, APP_STP, @@ -59,6 +60,7 @@ struct ss7_application { int type; /* for the routing */ + int route_is_set; struct ss7_application_route route_src; struct ss7_application_route route_dst; diff --git a/include/ss7_vty.h b/include/ss7_vty.h new file mode 100644 index 0000000..48dbb48 --- /dev/null +++ b/include/ss7_vty.h @@ -0,0 +1,42 @@ +/* + * (C) 2011 by Holger Hans Peter Freyther + * (C) 2011 by On-Waves + * All Rights Reserved + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +#ifndef SS7_VTY_H +#define SS7_VTY_H + +#include +#include +#include + +enum ss7_vty_node { + MGCP_NODE = _LAST_OSMOVTY_NODE + 1, + CELLMGR_NODE, + SS7_NODE, + LINKSETS_NODE, + LINK_NODE, + MSC_NODE, + APP_NODE, +}; + +extern struct cmd_element cfg_description_cmd; +extern struct cmd_element cfg_no_description_cmd; + + +#endif diff --git a/src/Makefile.am b/src/Makefile.am index 3b6301a..4930e97 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -13,12 +13,13 @@ cellmgr_ng_SOURCES = main.c mtp_layer3.c thread.c input/ipaccess.c pcap.c \ bss_patch.c bssap_sccp.c bsc_sccp.c bsc_ussd.c links.c \ msc_conn.c link_udp.c snmp_mtp.c debug.c isup.c \ mtp_link.c counter.c sccp_state.c bsc.c ss7_application.c \ - vty_interface.c vty_interface_cmds.c + vty_interface_legacy.c vty_interface_cmds.c cellmgr_ng_LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOSCCP_LIBS) $(LIBOSMOVTY_LIBS) $(NEXUSWARE_C7_LIBS) \ -lpthread -lnetsnmp -lcrypto osmo_stp_SOURCES = main_stp.c mtp_layer3.c thread.c pcap.c link_udp.c snmp_mtp.c \ - debug.c links.c isup.c sctp_m2ua.c \ + debug.c links.c isup.c sctp_m2ua.c msc_conn.c sccp_state.c \ + bss_patch.c bssap_sccp.c bsc_sccp.c bsc_ussd.c input/ipaccess.c \ mtp_link.c counter.c bsc.c ss7_application.c \ vty_interface.c vty_interface_cmds.c osmo_stp_LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOSCCP_LIBS) $(LIBOSMOVTY_LIBS) $(NEXUSWARE_C7_LIBS) \ diff --git a/src/bsc.c b/src/bsc.c index c4a955a..98c2e8d 100644 --- a/src/bsc.c +++ b/src/bsc.c @@ -71,10 +71,13 @@ struct bsc_data *bsc_data_create() bsc->udp_ip = NULL; bsc->udp_nr_links = 1; - bsc->src_port = 1313; + bsc->udp_src_port = 1313; bsc->pcap_fd = -1; bsc->udp_reset_timeout = 180; + /* m2ua code */ + bsc->m2ua_src_port = 2904; + return bsc; } diff --git a/src/link_udp.c b/src/link_udp.c index bea67de..69d2ee9 100644 --- a/src/link_udp.c +++ b/src/link_udp.c @@ -231,28 +231,12 @@ static int udp_link_start(struct mtp_link *link) int link_udp_init(struct mtp_udp_link *link, char *remote, int port) { - /* setup SNMP first, it is blocking */ - link->session = snmp_mtp_session_create(remote); - if (!link->session) - return -1; - link->session->data = link; - - /* function table */ - link->base->shutdown = udp_link_shutdown; - link->base->clear_queue = udp_link_dummy; - - link->base->reset = udp_link_reset; - link->base->start = udp_link_start; - link->base->write = udp_link_write; - /* prepare the remote */ memset(&link->remote, 0, sizeof(link->remote)); link->remote.sin_family = AF_INET; link->remote.sin_port = htons(port); inet_aton(remote, &link->remote.sin_addr); - /* add it to the list of udp connections */ - llist_add_tail(&link->entry, &link->data->links); return 0; } @@ -263,12 +247,8 @@ static void snmp_poll(void *_data) bsc_schedule_timer(&data->snmp_poll, 0, 5000); } -int link_global_init(struct mtp_udp_data *data, int src_port) +int link_global_init(struct mtp_udp_data *data) { - struct sockaddr_in addr; - int fd; - int on; - INIT_LLIST_HEAD(&data->links); write_queue_init(&data->write_queue, 100); @@ -278,6 +258,15 @@ int link_global_init(struct mtp_udp_data *data, int src_port) data->write_queue.read_cb = udp_read_cb; data->write_queue.write_cb = udp_write_cb; + return 0; +} + +int link_global_bind(struct mtp_udp_data *data, int src_port) +{ + struct sockaddr_in addr; + int fd; + int on; + data->write_queue.bfd.fd = fd = socket(AF_INET, SOCK_DGRAM, 0); if (fd < 0) { LOGP(DINP, LOGL_ERROR, "Failed to create UDP socket.\n"); @@ -359,3 +348,50 @@ void snmp_mtp_callback(struct snmp_mtp_session *session, area, link->nr, link->name, link->set->nr, link->set->name); } } + +struct mtp_udp_link *mtp_udp_link_init(struct mtp_link *blnk) +{ + struct bsc_data *bsc; + struct mtp_udp_link *lnk; + + lnk = talloc_zero(blnk, struct mtp_udp_link); + if (!lnk) { + LOGP(DINP, LOGL_ERROR, "Failed to allocate.\n"); + return NULL; + } + + /* setup SNMP first, it is blocking */ + lnk->session = snmp_mtp_session_create(); + if (!lnk->session) { + LOGP(DINP, LOGL_ERROR, "Failed to allocate snmp session.\n"); + talloc_free(lnk); + return NULL; + } + lnk->session->data = lnk; + + bsc = blnk->set->bsc; + lnk->data = &bsc->udp_data; + lnk->reset_timeout = bsc->udp_reset_timeout; + + lnk->base = blnk; + lnk->base->data = lnk; + lnk->base->type = SS7_LTYPE_UDP; + lnk->bsc = bsc; + + /* function table */ + lnk->base->shutdown = udp_link_shutdown; + lnk->base->clear_queue = udp_link_dummy; + + lnk->base->reset = udp_link_reset; + lnk->base->start = udp_link_start; + lnk->base->write = udp_link_write; + + /* prepare the remote */ + memset(&lnk->remote, 0, sizeof(lnk->remote)); + lnk->remote.sin_family = AF_INET; + + /* add it to the list of udp connections */ + llist_add_tail(&lnk->entry, &lnk->data->links); + + return lnk; +} diff --git a/src/links.c b/src/links.c index a756a68..09e1c2f 100644 --- a/src/links.c +++ b/src/links.c @@ -94,8 +94,6 @@ struct mtp_link_set *link_set_create(struct bsc_data *bsc) set = mtp_link_set_alloc(bsc); set->name = talloc_strdup(set, "MTP"); - set->sccp_opc = set->isup_opc = -1; - set->pcap_fd = bsc->pcap_fd; set->ni = MTP_NI_NATION_NET; set->spare = 0; @@ -116,29 +114,29 @@ int link_init(struct bsc_data *bsc, struct mtp_link_set *set) struct mtp_link *blnk; - if (!bsc->src_port) { + if (!bsc->udp_src_port) { LOGP(DINP, LOGL_ERROR, "You need to set a UDP address.\n"); return -1; } LOGP(DINP, LOGL_NOTICE, "Using UDP MTP mode.\n"); - if (link_global_init(&bsc->udp_data, bsc->src_port) != 0) + if (link_global_init(&bsc->udp_data) != 0) return -1; + if (link_global_bind(&bsc->udp_data, bsc->udp_src_port) != 0) + return -1; for (i = 1; i <= bsc->udp_nr_links; ++i) { blnk = mtp_link_alloc(set); - lnk = talloc_zero(blnk, struct mtp_udp_link); - lnk->base = blnk; - lnk->base->data = lnk; - lnk->base->type = SS7_LTYPE_UDP; - lnk->bsc = bsc; - lnk->data = &bsc->udp_data; - lnk->link_index = i; - lnk->reset_timeout = bsc->udp_reset_timeout; + lnk = mtp_udp_link_init(blnk); + + lnk->link_index = 1; /* now connect to the transport */ + if (snmp_mtp_peer_name(lnk->session, bsc->udp_ip) != 0) + return -1; + if (link_udp_init(lnk, bsc->udp_ip, bsc->udp_port) != 0) return -1; } diff --git a/src/main_stp.c b/src/main_stp.c index 35ec2ed..b87a6cb 100644 --- a/src/main_stp.c +++ b/src/main_stp.c @@ -196,9 +196,6 @@ static int inject_init(struct bsc_data *bsc) int main(int argc, char **argv) { int rc; - struct mtp_link_set *set; - struct mtp_link_set *m2ua_set; - struct mtp_m2ua_link *lnk; struct ss7_application *app; thread_init(); @@ -227,38 +224,7 @@ int main(int argc, char **argv) srand(time(NULL)); - set = link_set_create(bsc); - if (!set) { - LOGP(DINP, LOGL_ERROR, "Failed to allocate the link.\n"); - return -1; - } - - app = ss7_application_alloc(bsc); - if (!app) { - LOGP(DINP, LOGL_ERROR, "Failed to create the SS7 application.\n"); - return -1; - } - - m2ua_set = mtp_link_set_alloc(bsc); - m2ua_set->dpc = 92; - m2ua_set->opc = 9; - m2ua_set->sccp_opc = 9; - m2ua_set->isup_opc = 9; - m2ua_set->ni = 3; - m2ua_set->pcap_fd = bsc->pcap_fd; - m2ua_set->name = talloc_strdup(m2ua_set, "M2UA"); - m2ua_set->supported_ssn[1] = 1; - m2ua_set->supported_ssn[7] = 1; - m2ua_set->supported_ssn[8] = 1; - m2ua_set->supported_ssn[146] = 1; - m2ua_set->supported_ssn[254] = 1; - cell_vty_init(); - if (vty_read_config_file(config, NULL) < 0) { - fprintf(stderr, "Failed to read the VTY config.\n"); - return -1; - } - rc = telnet_init(NULL, NULL, 4242); if (rc < 0) return rc; @@ -268,23 +234,40 @@ int main(int argc, char **argv) return -1; } - if (link_init(bsc, set) != 0) + /* now bind the the UDP and SCTP port */ + if (link_global_init(&bsc->udp_data) != 0) { + LOGP(DINP, LOGL_ERROR, "Global UDP input init failed.\n"); return -1; + } - bsc->m2ua_trans = sctp_m2ua_transp_create("0.0.0.0", 2904); + bsc->m2ua_trans = sctp_m2ua_transp_create(bsc); if (!bsc->m2ua_trans) { LOGP(DINP, LOGL_ERROR, "Failed to create SCTP transport.\n"); return -1; } - /* setup things */ - lnk = mtp_m2ua_link_create(bsc->m2ua_trans, m2ua_set); + if (vty_read_config_file(config, NULL) < 0) { + fprintf(stderr, "Failed to read the VTY config.\n"); + return -1; + } - ss7_application_setup(app, APP_STP, - SS7_SET_LINKSET, 0, - SS7_SET_LINKSET, 1); + if (link_global_bind(&bsc->udp_data, bsc->udp_src_port) != 0) { + LOGP(DINP, LOGL_ERROR, "Global UDP bind failed.\n"); + return -1; + } - ss7_application_start(app); + if (sctp_m2ua_transport_bind(bsc->m2ua_trans, "0.0.0.0", bsc->m2ua_src_port) != 0) { + LOGP(DINP, LOGL_ERROR, + "Failed to bind on port %d\n", bsc->m2ua_src_port); + return -1; + } + + /* start all apps */ + llist_for_each_entry(app, &bsc->apps, entry) { + LOGP(DINP, LOGL_NOTICE, + "Going to start app %d/%s.\n", app->nr, app->name); + ss7_application_start(app); + } while (1) { bsc_select_main(0); @@ -293,33 +276,3 @@ int main(int argc, char **argv) return 0; } -/* dummy for links */ -int msc_connection_start(struct msc_connection *conn) -{ - return 0; -} - -struct msc_connection *msc_connection_num(struct bsc_data *bsc, int num) -{ - return NULL; -} - - -void msc_mgcp_reset(struct msc_connection *msc) -{ -} -void msc_send_reset(struct msc_connection *bsc) -{ -} -void msc_close_connection(struct msc_connection *bsc) -{ -} -void app_resources_released(struct ss7_application *ss7) -{ -} -void app_clear_connections(struct ss7_application *ss7) -{ -} -void app_forward_sccp(struct ss7_application *ss7, struct msgb *_msg, int sls) -{ -} diff --git a/src/mtp_layer3.c b/src/mtp_layer3.c index 08ea323..0ceb7b0 100644 --- a/src/mtp_layer3.c +++ b/src/mtp_layer3.c @@ -609,6 +609,9 @@ struct mtp_link_set *mtp_link_set_alloc(struct bsc_data *bsc) INIT_LLIST_HEAD(&link->links); link->nr = bsc->num_linksets++; + link->sccp_opc = link->isup_opc = -1; + link->pcap_fd = bsc->pcap_fd; + link->bsc = bsc; llist_add_tail(&link->entry, &bsc->linksets); return link; diff --git a/src/sctp_m2ua.c b/src/sctp_m2ua.c index 977acad..d0609dd 100644 --- a/src/sctp_m2ua.c +++ b/src/sctp_m2ua.c @@ -711,16 +711,33 @@ static int sctp_m2ua_reset(struct mtp_link *_link) return 0; } -struct sctp_m2ua_transport *sctp_m2ua_transp_create(const char *ip, int port) +struct sctp_m2ua_transport *sctp_m2ua_transp_create(struct bsc_data *bsc) +{ + struct sctp_m2ua_transport *trans; + + trans = talloc_zero(bsc, struct sctp_m2ua_transport); + if (!trans) { + LOGP(DINP, LOGL_ERROR, "Remove the talloc.\n"); + return NULL; + } + + INIT_LLIST_HEAD(&trans->conns); + INIT_LLIST_HEAD(&trans->links); + + + return trans; +} + +int sctp_m2ua_transport_bind(struct sctp_m2ua_transport *trans, + const char *ip, int port) { int sctp; struct sockaddr_in addr; - struct sctp_m2ua_transport *trans; sctp = socket(PF_INET, SOCK_STREAM, IPPROTO_SCTP); if (!sctp) { LOGP(DINP, LOGL_ERROR, "Failed to create socket.\n"); - return NULL; + return -1; } memset(&addr, 0, sizeof(addr)); @@ -731,25 +748,18 @@ struct sctp_m2ua_transport *sctp_m2ua_transp_create(const char *ip, int port) if (bind(sctp, (struct sockaddr *) &addr, sizeof(addr)) != 0) { LOGP(DINP, LOGL_ERROR, "Failed to bind.\n"); close(sctp); - return NULL; + return -2; } if (listen(sctp, 1) != 0) { LOGP(DINP, LOGL_ERROR, "Failed to listen.\n"); close(sctp); - return NULL; + return -3; } int on = 1; setsockopt(sctp, SOL_SCTP, 112, &on, sizeof(on)); - trans = talloc_zero(NULL, struct sctp_m2ua_transport); - if (!trans) { - LOGP(DINP, LOGL_ERROR, "Remove the talloc.\n"); - close(sctp); - return NULL; - } - trans->bsc.fd = sctp; trans->bsc.data = trans; trans->bsc.cb = sctp_trans_accept; @@ -757,33 +767,21 @@ struct sctp_m2ua_transport *sctp_m2ua_transp_create(const char *ip, int port) if (bsc_register_fd(&trans->bsc) != 0) { LOGP(DINP, LOGL_ERROR, "Failed to register the fd.\n"); - talloc_free(trans); close(sctp); - return NULL; + return -4; } - INIT_LLIST_HEAD(&trans->conns); - INIT_LLIST_HEAD(&trans->links); - - return trans; + return 0; } -struct mtp_m2ua_link *mtp_m2ua_link_create(struct sctp_m2ua_transport *trans, - struct mtp_link_set *set) +struct mtp_m2ua_link *mtp_m2ua_link_init(struct mtp_link *blnk) { - struct mtp_link *blnk; + struct sctp_m2ua_transport *trans; struct mtp_m2ua_link *lnk; - blnk = mtp_link_alloc(set); - if (!blnk) { - LOGP(DINP, LOGL_ERROR, "Failed to allocate.\n"); - return NULL; - } - lnk = talloc_zero(blnk, struct mtp_m2ua_link); if (!lnk) { LOGP(DINP, LOGL_ERROR, "Failed to allocate.\n"); - talloc_free(blnk); return NULL; } @@ -793,6 +791,7 @@ struct mtp_m2ua_link *mtp_m2ua_link_create(struct sctp_m2ua_transport *trans, blnk->type = SS7_LTYPE_M2UA; /* remember we have a link here */ + trans = blnk->set->bsc->m2ua_trans; llist_add_tail(&lnk->entry, &trans->links); lnk->base->shutdown = sctp_m2ua_reset; diff --git a/src/snmp_mtp.c b/src/snmp_mtp.c index 2cdf323..308e6b8 100644 --- a/src/snmp_mtp.c +++ b/src/snmp_mtp.c @@ -18,6 +18,7 @@ * */ #include +#include #include static void add_pdu_var(netsnmp_pdu *pdu, const char *mib_name, int id, const char *value) @@ -120,7 +121,7 @@ static void snmp_mtp_stop_c7_datalink(struct snmp_mtp_session *session, int link session->last_do_req = status; } -struct snmp_mtp_session *snmp_mtp_session_create(char *host) +struct snmp_mtp_session *snmp_mtp_session_create() { struct snmp_mtp_session *session = talloc_zero(NULL, struct snmp_mtp_session); if (!session) @@ -128,21 +129,32 @@ struct snmp_mtp_session *snmp_mtp_session_create(char *host) init_snmp("cellmgr_ng"); snmp_sess_init(&session->session); - session->session.peername = host; session->session.version = SNMP_VERSION_1; session->session.community = (unsigned char *) "private"; session->session.community_len = strlen((const char *) session->session.community); session->session.myvoid = session; + return session; +} + +int snmp_mtp_peer_name(struct snmp_mtp_session *session, char *host) +{ + if (session->ss) { + snmp_close(session->ss); + session->ss = NULL; + } + + session->session.peername = host; + session->ss = snmp_open(&session->session); if (!session->ss) { snmp_perror("create failure"); snmp_log(LOG_ERR, "Could not connect to the remote.\n"); - talloc_free(session); - return NULL; + LOGP(DINP, LOGL_ERROR, "Failed to open a SNMP session.\n"); + return -1; } - return session; + return 0; } void snmp_mtp_deactivate(struct snmp_mtp_session *session, int index) diff --git a/src/ss7_application.c b/src/ss7_application.c index b3c9036..485aa2e 100644 --- a/src/ss7_application.c +++ b/src/ss7_application.c @@ -213,6 +213,7 @@ static int ss7_app_setup_stp(struct ss7_application *app, app->type = APP_STP; app->bsc->m2ua_trans->started = 1; + app->route_is_set = 1; return 0; } @@ -287,6 +288,7 @@ static int ss7_app_setup_relay(struct ss7_application *app, int type, app->route_dst.msc = msc; app->type = type; + app->route_is_set = 1; return 0; } @@ -338,6 +340,12 @@ static void start_set(struct ss7_application *app, struct mtp_link_set *set) int ss7_application_start(struct ss7_application *app) { + if (!app->route_is_set) { + LOGP(DINP, LOGL_ERROR, + "The routes are not configured on app %d.\n", app->nr); + return -1; + } + start_set(app, app->route_src.set); start_set(app, app->route_dst.set); 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 * (C) 2010-2011 by On-Waves @@ -22,7 +22,11 @@ #include #include #include +#include #include +#include +#include +#include #include #include @@ -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(); } diff --git a/src/vty_interface_cmds.c b/src/vty_interface_cmds.c index e3c82cb..988444b 100644 --- a/src/vty_interface_cmds.c +++ b/src/vty_interface_cmds.c @@ -65,13 +65,14 @@ static void dump_state(struct vty *vty, struct mtp_link_set *set) { struct mtp_link *link; - if (!set) { - vty_out(vty, "LinkSet for %s is not configured.%s", set->name, VTY_NEWLINE); + if (!set->app) { + vty_out(vty, "LinkSet %d not assigned to an application.%s", + set->nr, VTY_NEWLINE); return; } - vty_out(vty, "LinkSet for %s is %s, remote sccp is %s.%s", - set->name, + vty_out(vty, "LinkSet for %d/%s is %s, remote sccp is %s.%s", + set->nr, set->name, set->available == 0 ? "not available" : "available", set->sccp_up == 0? "not established" : "established", VTY_NEWLINE); @@ -200,6 +201,10 @@ DEFUN(pcap_set_stop, pcap_set_stop_cmd, vty_out(vty, "Unknown Linkset nr %d.%s", set_no, VTY_NEWLINE); \ return CMD_WARNING; \ } \ + if (!set->app) { \ + vty_out(vty, "Linkset nr %d has no application.%s", \ + set_no, VTY_NEWLINE); \ + } \ link = mtp_link_num(set, nr); \ if (!link) { \ vty_out(vty, "Can not find link %d.%s", nr, VTY_NEWLINE); \ diff --git a/src/vty_interface_legacy.c b/src/vty_interface_legacy.c new file mode 100644 index 0000000..59f3852 --- /dev/null +++ b/src/vty_interface_legacy.c @@ -0,0 +1,358 @@ +/* VTY code for the Cellmgr */ +/* + * (C) 2010-2011 by Holger Hans Peter Freyther + * (C) 2010-2011 by On-Waves + * All Rights Reserved + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include +#include + +#undef PACKAGE_NAME +#undef PACKAGE_VERSION +#undef PACKAGE_BUGREPORT +#undef PACKAGE_TARNAME +#undef PACKAGE_STRING +#include + +extern struct bsc_data *bsc; + +static struct vty_app_info vty_info = { + .name = "Cellmgr-ng", + .version = VERSION, + .go_parent_cb = NULL, +}; + +/* vty code */ +static struct cmd_node cell_node = { + CELLMGR_NODE, + "%s(cellmgr)#", + 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->udp_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); + } + + + return CMD_SUCCESS; +} + +DEFUN(cfg_cell, cfg_cell_cmd, + "cellmgr", "Configure the Cellmgr") +{ + vty->node = CELLMGR_NODE; + return CMD_SUCCESS; +} + +DEFUN(cfg_net_dpc, cfg_net_dpc_cmd, + "mtp dpc DPC_NR", + "Set the DPC to be used.") +{ + struct mtp_link_set *set = mtp_link_set_num(bsc, 0); + set->dpc = atoi(argv[0]); + return CMD_SUCCESS; +} + +DEFUN(cfg_net_opc, cfg_net_opc_cmd, + "mtp opc OPC_NR", + "Set the OPC to be used.") +{ + struct mtp_link_set *set = mtp_link_set_num(bsc, 0); + set->opc = atoi(argv[0]); + 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.") +{ + struct mtp_link_set *set = mtp_link_set_num(bsc, 0); + set->sccp_opc = 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") +{ + struct mtp_link_set *set = mtp_link_set_num(bsc, 0); + 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") +{ + struct mtp_link_set *set = mtp_link_set_num(bsc, 0); + set->spare = atoi(argv[0]); + 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.") +{ + struct hostent *hosts; + struct in_addr *addr; + + 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]; + 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") +{ + bsc->udp_port = 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.") +{ + bsc->udp_src_port = 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") +{ + bsc->udp_reset_timeout = 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") +{ + bsc->udp_nr_links = atoi(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.") +{ + struct mtp_link_set *set = mtp_link_set_num(bsc, 0); + set->sltm_once = !!atoi(argv[0]); + return CMD_SUCCESS; +} + +DEFUN(cfg_msc_ip, cfg_msc_ip_cmd, + "msc ip IP", + "Set the MSC IP") +{ + struct hostent *hosts; + struct in_addr *addr; + struct msc_connection *msc = msc_connection_num(bsc, 0); + + if (!msc) { + vty_out(vty, "%%No MSC Connection defined in this app.%s", VTY_NEWLINE); + return CMD_WARNING; + } + + 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)); + 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") +{ + struct msc_connection *msc = msc_connection_num(bsc, 0); + + if (!msc) { + vty_out(vty, "%%No MSC Connection defined in this app.%s", VTY_NEWLINE); + return CMD_WARNING; + } + + 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_token, cfg_msc_token_cmd, + "msc token TOKEN", + "Set the Token to be used for the MSC") +{ + struct msc_connection *msc = msc_connection_num(bsc, 0); + + 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_ping_time, cfg_ping_time_cmd, + "timeout ping NR", + "Set the PING interval. Negative to disable it") +{ + struct msc_connection *msc = msc_connection_num(bsc, 0); + + if (!msc) { + vty_out(vty, "%%No MSC Connection defined in this app.%s", VTY_NEWLINE); + return CMD_WARNING; + } + + msc->ping_time = atoi(argv[0]); + return CMD_SUCCESS; +} + +DEFUN(cfg_pong_time, cfg_pong_time_cmd, + "timeout pong NR", + "Set the PING interval. Negative to disable it") +{ + struct msc_connection *msc = msc_connection_num(bsc, 0); + + if (!msc) { + vty_out(vty, "%%No MSC Connection defined in this app.%s", VTY_NEWLINE); + return CMD_WARNING; + } + + msc->pong_time = atoi(argv[0]); + return CMD_SUCCESS; +} + +DEFUN(cfg_msc_time, cfg_msc_time_cmd, + "timeout msc NR", + "Set the MSC connect timeout") +{ + struct msc_connection *msc = msc_connection_num(bsc, 0); + + if (!msc) { + vty_out(vty, "%%No MSC Connection defined in this app.%s", 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") +{ + struct ss7_application *app = ss7_application_num(bsc, 0); + ss7_application_pass_isup(app, atoi(argv[0])); + + return CMD_SUCCESS; +} + +extern void cell_vty_init_cmds(void); +void cell_vty_init(void) +{ + cmd_init(1); + 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); + + cell_vty_init_cmds(); +} + +const char *openbsc_copyright = ""; -- cgit v1.2.3