From d41247d4cf12cbcb53b2097ab736ef3607cc5ad5 Mon Sep 17 00:00:00 2001 From: Neels Hofmeyr Date: Thu, 27 Aug 2020 18:44:54 +0200 Subject: [PATCH] CBSP: add local bind to client mode Add the ability to set a local bind address for the CBSP client mode. Change-Id: I56a420d204a9a487b27dd460f4cc52e0b4093d69 --- include/osmocom/bsc/smscb.h | 1 + src/osmo-bsc/bsc_init.c | 1 + src/osmo-bsc/cbsp_link.c | 58 +++++++++++++++++++++++++++++++++++-- tests/cbc.vty | 55 +++++++++++++++++++++++++++++++++++ 4 files changed, 113 insertions(+), 2 deletions(-) diff --git a/include/osmocom/bsc/smscb.h b/include/osmocom/bsc/smscb.h index c7002f694..f48c1a170 100644 --- a/include/osmocom/bsc/smscb.h +++ b/include/osmocom/bsc/smscb.h @@ -55,6 +55,7 @@ struct bsc_cbc_link { /* for handling outbound TCP connections */ struct { struct osmo_sockaddr_str remote_addr; + struct osmo_sockaddr_str local_addr; struct osmo_stream_cli *cli; char *sock_name; struct msgb *msg; diff --git a/src/osmo-bsc/bsc_init.c b/src/osmo-bsc/bsc_init.c index e7221998a..1460af44e 100644 --- a/src/osmo-bsc/bsc_init.c +++ b/src/osmo-bsc/bsc_init.c @@ -134,6 +134,7 @@ static struct gsm_network *bsc_network_init(void *ctx) /* For CBSP client mode: default remote CBSP server port is CBSP_TCP_PORT == 48049. Leave the IP address unset. * Also leave the local bind for the CBSP client disabled (unconfigured). */ net->cbc->client.remote_addr = (struct osmo_sockaddr_str){ .port = CBSP_TCP_PORT, }; + net->cbc->client.local_addr = (struct osmo_sockaddr_str){}; return net; diff --git a/src/osmo-bsc/cbsp_link.c b/src/osmo-bsc/cbsp_link.c index d58767576..e5e72ded6 100644 --- a/src/osmo-bsc/cbsp_link.c +++ b/src/osmo-bsc/cbsp_link.c @@ -250,6 +250,11 @@ int bsc_cbc_link_restart(void) /* CBC side */ osmo_stream_cli_set_addr(cbc->client.cli, cbc->client.remote_addr.ip); osmo_stream_cli_set_port(cbc->client.cli, cbc->client.remote_addr.port); + /* local side */ + if (osmo_sockaddr_str_is_set(&cbc->client.local_addr)) { + osmo_stream_cli_set_local_addr(cbc->client.cli, cbc->client.local_addr.ip); + osmo_stream_cli_set_local_port(cbc->client.cli, cbc->client.local_addr.port); + } /* Close/Reconnect? */ if (osmo_stream_cli_open(cbc->client.cli) < 0) { LOGP(DCBS, LOGL_ERROR, "Cannot open CBSP client link to " OSMO_SOCKADDR_STR_FMT "\n", @@ -400,6 +405,44 @@ DEFUN(cfg_cbc_client_remote_port, cfg_cbc_client_remote_port_cmd, return CMD_SUCCESS; } +DEFUN(cfg_cbc_client_local_ip, cfg_cbc_client_local_ip_cmd, + "local-ip " VTY_IPV46_CMD, + "Set local bind address for the outbound CBSP link to the Cell Broadcast Centre\n" + "IPv4 address\n" "IPv6 address\n") +{ + struct bsc_cbc_link *cbc = vty_cbc_data(vty); + osmo_sockaddr_str_from_str(&cbc->client.local_addr, argv[0], cbc->client.local_addr.port); + return CMD_SUCCESS; +} + +DEFUN(cfg_cbc_client_local_port, cfg_cbc_client_local_port_cmd, + "local-port <1-65535>", + "Set local bind port for the outbound CBSP link to the Cell Broadcast Centre\n" + "port number\n") +{ + struct bsc_cbc_link *cbc = vty_cbc_data(vty); + cbc->client.local_addr.port = atoi(argv[0]); + return CMD_SUCCESS; +} + +DEFUN(cfg_cbc_client_no_local_ip, cfg_cbc_client_no_local_ip_cmd, + "no local-ip", + NO_STR "Remove local IP address bind config for the CBSP client mode\n") +{ + struct bsc_cbc_link *cbc = vty_cbc_data(vty); + cbc->client.local_addr = (struct osmo_sockaddr_str){ .port = cbc->client.local_addr.port }; + return CMD_SUCCESS; +} + +DEFUN(cfg_cbc_client_no_local_port, cfg_cbc_client_no_local_port_cmd, + "no local-port", + NO_STR "Remove local TCP port bind config for the CBSP client mode\n") +{ + struct bsc_cbc_link *cbc = vty_cbc_data(vty); + cbc->client.local_addr.port = 0; + return CMD_SUCCESS; +} + static struct cmd_node cbc_node = { CBC_NODE, "%s(config-cbc)# ", @@ -424,15 +467,17 @@ static int config_write_cbc(struct vty *vty) bool default_server_local; bool default_client_remote; + bool default_client_local; default_server_local = !osmo_sockaddr_str_cmp(&cbc->server.local_addr, &bsc_cbc_default_server_local_addr); default_client_remote = !osmo_sockaddr_str_is_set(&cbc->client.remote_addr); + default_client_local = !osmo_sockaddr_str_is_set(&cbc->client.local_addr); /* If all reflects default values, skip the 'cbc' section */ if (cbc->mode == BSC_CBC_LINK_MODE_DISABLED && default_server_local - && default_client_remote) + && default_client_remote && default_client_local) return 0; vty_out(vty, "cbc%s", VTY_NEWLINE); @@ -447,7 +492,7 @@ static int config_write_cbc(struct vty *vty) vty_out(vty, " local-port %u%s", cbc->server.local_addr.port, VTY_NEWLINE); } - if (!default_client_remote) { + if (!(default_client_remote && default_client_local)) { vty_out(vty, " client%s", VTY_NEWLINE); if (osmo_sockaddr_str_is_set(&cbc->client.remote_addr)) { @@ -455,6 +500,11 @@ static int config_write_cbc(struct vty *vty) if (cbc->client.remote_addr.port != CBSP_TCP_PORT) vty_out(vty, " remote-port %u%s", cbc->client.remote_addr.port, VTY_NEWLINE); } + + if (cbc->client.local_addr.ip[0]) + vty_out(vty, " local-ip %s%s", cbc->client.local_addr.ip, VTY_NEWLINE); + if (cbc->client.local_addr.port) + vty_out(vty, " local-port %u%s", cbc->client.local_addr.port, VTY_NEWLINE); } return 0; @@ -505,4 +555,8 @@ void cbc_vty_init(void) install_node(&cbc_client_node, NULL); install_element(CBC_CLIENT_NODE, &cfg_cbc_client_remote_ip_cmd); install_element(CBC_CLIENT_NODE, &cfg_cbc_client_remote_port_cmd); + install_element(CBC_CLIENT_NODE, &cfg_cbc_client_local_ip_cmd); + install_element(CBC_CLIENT_NODE, &cfg_cbc_client_local_port_cmd); + install_element(CBC_CLIENT_NODE, &cfg_cbc_client_no_local_ip_cmd); + install_element(CBC_CLIENT_NODE, &cfg_cbc_client_no_local_port_cmd); } diff --git a/tests/cbc.vty b/tests/cbc.vty index 2cad609fa..7a4031fc7 100644 --- a/tests/cbc.vty +++ b/tests/cbc.vty @@ -94,11 +94,18 @@ OsmoBSC(config-cbc-client)# list ... remote-ip (A.B.C.D|X:X::X:X) remote-port <1-65535> + local-ip (A.B.C.D|X:X::X:X) + local-port <1-65535> + no local-ip + no local-port OsmoBSC(config-cbc-client)# ? ... remote-ip Set IP Address of the Cell Broadcast Centre, to establish CBSP link to remote-port Set TCP port of the Cell Broadcast Centre, to establish CBSP link to + local-ip Set local bind address for the outbound CBSP link to the Cell Broadcast Centre + local-port Set local bind port for the outbound CBSP link to the Cell Broadcast Centre + no Negate a command or set its defaults OsmoBSC(config-cbc-client)# remote-ip ? A.B.C.D IPv4 address @@ -106,6 +113,10 @@ OsmoBSC(config-cbc-client)# remote-ip ? OsmoBSC(config-cbc-client)# remote-port ? <1-65535> CBSP port number (Default: 48049) +OsmoBSC(config-cbc-client)# no ? + local-ip Remove local IP address bind config for the CBSP client mode + local-port Remove local TCP port bind config for the CBSP client mode + OsmoBSC(config-cbc-client)# remote-ip 1.2.3.4 OsmoBSC(config-cbc-client)# remote-port 12345 OsmoBSC(config-cbc-client)# show running-config @@ -136,6 +147,50 @@ cbc remote-ip 1:2:3:4::5 ... +OsmoBSC(config-cbc-client)# local-ip 1.2.3.4 + +OsmoBSC(config-cbc-client)# show running-config +... +cbc +... + client + remote-ip 1:2:3:4::5 + local-ip 1.2.3.4 +... !local-port + +OsmoBSC(config-cbc-client)# local-port 12345 + +OsmoBSC(config-cbc-client)# show running-config +... +cbc +... + client + remote-ip 1:2:3:4::5 + local-ip 1.2.3.4 + local-port 12345 +... + +OsmoBSC(config-cbc-client)# no local-ip + +OsmoBSC(config-cbc-client)# show running-config +... +cbc +... + client + remote-ip 1:2:3:4::5 + local-port 12345 +... !local + +OsmoBSC(config-cbc-client)# no local-port + +OsmoBSC(config-cbc-client)# show running-config +... +cbc +... + client + remote-ip 1:2:3:4::5 +... !local + OsmoBSC(config-cbc-client)# do show cbc CBSP link is disabled