9
0
Fork 0

linkset: Make it possible to create multiple links for a linkset

We now create multiple links and will start all of them. This
still requires good balancing between these links.
This commit is contained in:
Holger Hans Peter Freyther 2010-12-23 13:06:57 +01:00
parent d40fb5133f
commit 26b8233050
6 changed files with 162 additions and 64 deletions

View File

@ -103,7 +103,6 @@ struct bsc_data {
int pcap_fd;
int udp_reset_timeout;
struct llist_head links;
struct link_data first_link;
const char *token;
@ -180,4 +179,7 @@ int linkset_send_bsc_data(struct bsc_data *link, int sls, const uint8_t *data, i
/* another callback for SCCP data from the linkset */
void linkset_forward_sccp(struct bsc_data *bsc, struct msgb *msg, int sls);
/* find the link */
struct link_data *linkset_find_link(struct bsc_data *bsc, int link_index);
#endif

View File

@ -38,17 +38,6 @@
#define OSMO_CB_LI(msg) msg->cb[0]
static struct link_data *find_link(struct bsc_data *bsc, int link_index)
{
struct link_data *link;
llist_for_each_entry(link, &bsc->links, entry)
if (link->link_index == link_index)
return link;
return NULL;
}
static int udp_write_cb(struct bsc_fd *fd, struct msgb *msg)
{
struct bsc_data *bsc;
@ -57,7 +46,7 @@ static int udp_write_cb(struct bsc_fd *fd, struct msgb *msg)
bsc = (struct bsc_data *) fd->data;
link = find_link(bsc, OSMO_CB_LI(msg));
link = linkset_find_link(bsc, OSMO_CB_LI(msg));
if (!link) {
LOGP(DINP, LOGL_ERROR, "No link_data for %lu\n", OSMO_CB_LI(msg));
return -1;
@ -104,7 +93,7 @@ static int udp_read_cb(struct bsc_fd *fd)
hdr = (struct udp_data_hdr *) msgb_put(msg, sizeof(*hdr));
link = find_link(bsc, ntohs(hdr->data_link_index));
link = linkset_find_link(bsc, ntohs(hdr->data_link_index));
if (!link) {
LOGP(DINP, LOGL_ERROR, "Failed to find a link.\n");
rc = -1;

View File

@ -24,6 +24,17 @@
#include <cellmgr_debug.h>
#include <snmp_mtp.h>
struct link_data *linkset_find_link(struct bsc_data *bsc, int link_index)
{
struct link_data *link;
llist_for_each_entry(link, &bsc->links, entry)
if (link->link_index == link_index)
return link;
return NULL;
}
void link_stop_all(struct bsc_data *bsc)
{
struct link_data *link;
@ -87,49 +98,70 @@ static void start_rest(void *start)
int link_setup_start(struct bsc_data *bsc)
{
bsc->first_link.the_link = mtp_link_alloc();
bsc->first_link.the_link->data = &bsc->first_link;
bsc->first_link.the_link->dpc = bsc->dpc;
bsc->first_link.the_link->opc = bsc->opc;
bsc->first_link.the_link->sccp_opc = bsc->sccp_opc > -1 ? bsc->sccp_opc : bsc->opc;
bsc->first_link.the_link->link = 0;
bsc->first_link.the_link->sltm_once = bsc->once;
bsc->first_link.the_link->ni = bsc->ni_ni;
bsc->first_link.the_link->spare = bsc->ni_spare;
bsc->first_link.bsc = bsc;
bsc->first_link.pcap_fd = bsc->pcap_fd;
bsc->first_link.udp.reset_timeout = bsc->udp_reset_timeout;
bsc->first_link.link_index = 1;
struct link_data *link;
llist_add(&bsc->first_link.entry, &bsc->links);
if (!bsc->first_link.udp.udp_ip) {
LOGP(DINP, LOGL_ERROR, "Need to set a UDP IP.\n");
if (llist_empty(&bsc->links)) {
LOGP(DINP, LOGL_ERROR, "No links defined.\n");
return -1;
}
LOGP(DINP, LOGL_NOTICE, "Using UDP MTP mode.\n");
/* setup SNMP first, it is blocking */
bsc->first_link.udp.session = snmp_mtp_session_create(bsc->first_link.udp.udp_ip);
if (!bsc->first_link.udp.session)
return -1;
if (link_udp_network_init(bsc) != 0)
return -1;
/* now connect to the transport */
if (link_udp_init(&bsc->first_link, bsc->first_link.udp.udp_ip, bsc->first_link.udp.udp_port) != 0)
return -1;
llist_for_each_entry(link, &bsc->links, entry) {
link->the_link = mtp_link_alloc();
link->the_link->data = link;
link->the_link->dpc = bsc->dpc;
link->the_link->opc = bsc->opc;
link->the_link->sccp_opc = bsc->sccp_opc > -1 ? bsc->sccp_opc : bsc->opc;
link->the_link->link = 0;
link->the_link->sltm_once = bsc->once;
link->the_link->ni = bsc->ni_ni;
link->the_link->spare = bsc->ni_spare;
link->bsc = bsc;
link->pcap_fd = bsc->pcap_fd;
link->udp.reset_timeout = bsc->udp_reset_timeout;
if (!link->udp.udp_ip) {
LOGP(DINP, LOGL_ERROR, "Need to set a UDP IP on %d.\n",
link->link_index);
return -1;
}
if (!link->udp.udp_port) {
LOGP(DINP, LOGL_ERROR, "Need to set a UDP Port on %d.\n",
link->link_index);
return -1;
}
}
LOGP(DINP, LOGL_NOTICE, "Using UDP MTP mode.\n");
llist_for_each_entry(link, &bsc->links, entry) {
/* setup SNMP first, it is blocking */
link->udp.session = snmp_mtp_session_create(link->udp.udp_ip);
if (!link->udp.session) {
LOGP(DINP, LOGL_ERROR,
"Failed to initialize SNMP on %d\n", link->link_index);
return -1;
}
/* now connect to the transport */
if (link_udp_init(link, link->udp.udp_ip, link->udp.udp_port) != 0) {
LOGP(DINP, LOGL_ERROR,
"Failed to init the link on %d\n", link->link_index);
return -1;
}
/*
* We will ask the MTP link to be taken down for two
* timeouts of the BSC to make sure we are missing the
* SLTM and it begins a reset. Then we will take it up
* again and do the usual business.
*/
snmp_mtp_deactivate(link->udp.session, link->link_index);
}
/*
* We will ask the MTP link to be taken down for two
* timeouts of the BSC to make sure we are missing the
* SLTM and it begins a reset. Then we will take it up
* again and do the usual business.
*/
snmp_mtp_deactivate(bsc->first_link.udp.session,
bsc->first_link.link_index);
bsc->start_timer.cb = start_rest;
bsc->start_timer.data = bsc;
bsc_schedule_timer(&bsc->start_timer, bsc->udp_reset_timeout, 0);

View File

@ -636,8 +636,6 @@ int main(int argc, char **argv)
bsc.dpc = 1;
bsc.opc = 0;
bsc.sccp_opc = -1;
bsc.first_link.udp.udp_port = 3456;
bsc.first_link.udp.udp_ip = NULL;
bsc.src_port = 1313;
bsc.ni_ni = MTP_NI_NATION_NET;
bsc.ni_spare = 0;

View File

@ -187,8 +187,6 @@ int main(int argc, char **argv)
bsc.dpc = 1;
bsc.opc = 0;
bsc.sccp_opc = -1;
bsc.first_link.udp.udp_port = 3456;
bsc.first_link.udp.udp_ip = NULL;
bsc.src_port = 1313;
bsc.ni_ni = MTP_NI_NATION_NET;
bsc.ni_spare = 0;

View File

@ -21,6 +21,7 @@
*/
#include <bsc_data.h>
#include <cellmgr_debug.h>
#include <osmocore/talloc.h>
#include <osmocore/gsm48.h>
@ -59,6 +60,8 @@ static struct cmd_node cell_node = {
static int config_write_cell(struct vty *vty)
{
struct link_data *link;
vty_out(vty, "cellmgr%s", VTY_NEWLINE);
vty_out(vty, " mtp dpc %d%s", bsc.dpc, VTY_NEWLINE);
vty_out(vty, " mtp opc %d%s", bsc.opc, VTY_NEWLINE);
@ -69,9 +72,14 @@ static int config_write_cell(struct vty *vty)
vty_out(vty, " country-code %d%s", bsc.mcc, VTY_NEWLINE);
vty_out(vty, " network-code %d%s", bsc.mnc, VTY_NEWLINE);
vty_out(vty, " location-area-code %d%s", bsc.lac, VTY_NEWLINE);
if (bsc.first_link.udp.udp_ip)
vty_out(vty, " udp dest ip %s%s", bsc.first_link.udp.udp_ip, VTY_NEWLINE);
vty_out(vty, " udp dest port %d%s", bsc.first_link.udp.udp_port, VTY_NEWLINE);
llist_for_each_entry(link, &bsc.links, entry) {
vty_out(vty, " udp dest-ip %d %s%s",
link->link_index, link->udp.udp_ip, VTY_NEWLINE);
vty_out(vty, " udp dest-port %d %d%s",
link->link_index, link->udp.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, " msc ip %s%s", bsc.msc_address, VTY_NEWLINE);
@ -128,30 +136,98 @@ DEFUN(cfg_net_mtp_spare, cfg_net_mtp_spare_cmd,
return CMD_SUCCESS;
}
static struct link_data *find_or_create(struct bsc_data *bsc, int index)
{
struct link_data *link = linkset_find_link(bsc, index);
if (link)
return link;
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.")
link = talloc_zero(NULL, struct link_data);
if (!link) {
LOGP(DINP, LOGL_ERROR, "Failed to allocate link.\n");
return NULL;
}
link->link_index = index;
llist_add(&link->entry, &bsc->links);
return link;
}
static int set_dest_ip(struct vty *vty, struct link_data *link, const char *name)
{
struct hostent *hosts;
struct in_addr *addr;
hosts = gethostbyname(argv[0]);
hosts = gethostbyname(name);
if (!hosts || hosts->h_length < 1 || hosts->h_addrtype != AF_INET) {
vty_out(vty, "Failed to resolve '%s'%s", argv[0], VTY_NEWLINE);
vty_out(vty, "Failed to resolve '%s'%s", name, VTY_NEWLINE);
return CMD_WARNING;
}
addr = (struct in_addr *) hosts->h_addr_list[0];
bsc.first_link.udp.udp_ip = talloc_strdup(NULL, inet_ntoa(*addr));
link->udp.udp_ip = talloc_strdup(NULL, inet_ntoa(*addr));
return CMD_SUCCESS;
}
DEFUN(cfg_udp_dst_port, cfg_udp_dst_port_cmd,
DEFUN_DEPRECATED(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 link_data *link;
link = find_or_create(&bsc, 1);
if (!link) {
vty_out(vty, "Failed to create a link.\n");
return CMD_WARNING;
}
return set_dest_ip(vty, link, argv[0]);
}
DEFUN_DEPRECATED(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.first_link.udp.udp_port = atoi(argv[0]);
struct link_data *link;
link = find_or_create(&bsc, 1);
if (!link) {
vty_out(vty, "Failed to create a link.\n");
return CMD_WARNING;
}
link->udp.udp_port = atoi(argv[0]);
return CMD_SUCCESS;
}
DEFUN(cfg_link_dest_ip, cfg_link_dest_ip_cmd,
"udp dest-ip <0-64> IP",
"Set the dest-ip for a link.\n" "The link index\n" "IP or hostname\n")
{
struct link_data *link;
link = find_or_create(&bsc, atoi(argv[0]));
if (!link) {
vty_out(vty, "Failed to create a link.\n");
return CMD_WARNING;
}
return set_dest_ip(vty, link, argv[1]);
}
DEFUN(cfg_link_port_ip, cfg_link_port_ip_cmd,
"udp dest-port <0-64> PORT_NR",
"Set the dest-port for a link.\n" "The link index\n" "port number\n")
{
struct link_data *link;
link = find_or_create(&bsc, atoi(argv[0]));
if (!link) {
vty_out(vty, "Failed to create a link.\n");
return CMD_WARNING;
}
link->udp.udp_port = atoi(argv[1]);
return CMD_SUCCESS;
}
@ -305,6 +381,9 @@ void cell_vty_init(void)
install_element(CELLMGR_NODE, &cfg_mcc_cmd);
install_element(CELLMGR_NODE, &cfg_mnc_cmd);
install_element(CELLMGR_NODE, &cfg_lac_cmd);
install_element(CELLMGR_NODE, &cfg_link_dest_ip_cmd);
install_element(CELLMGR_NODE, &cfg_link_port_ip_cmd);
}
const char *openbsc_copyright = "";