diff options
author | Holger Hans Peter Freyther <zecke@selfish.org> | 2011-02-22 20:57:08 +0100 |
---|---|---|
committer | Holger Hans Peter Freyther <zecke@selfish.org> | 2011-02-23 15:25:35 +0100 |
commit | 7176030e02ca59d5b4ee015f24ee2bf733eeed8e (patch) | |
tree | eed6a2bb6bd74d365a09e77cbdc875bfcac689ed /src/vty_interface.c | |
parent | 2917644d503b706f0df5cf7228fc284a79436e31 (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.c | 887 |
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(); } |