diff options
author | Neels Hofmeyr <nhofmeyr@sysmocom.de> | 2015-09-24 17:32:30 +0200 |
---|---|---|
committer | Neels Hofmeyr <nhofmeyr@sysmocom.de> | 2015-11-16 15:16:26 +0100 |
commit | c8a614d2e9c56fe13c22f239be82f2a2c958e039 (patch) | |
tree | ce820c172725b3072ed106ea2c233df108b8ef1d /openbsc/src/gprs/gtphub_vty.c | |
parent | 65482c919f82b28aa53cd519c4f7799b104051c0 (diff) |
Add GTP hub initial code base.
First steps towards a new GTP hub. The aim is to mux GTP connections, so that
multiple SGSN <--> GGSN links can pass through a single point. Background:
allow having more than one SGSN, possibly in various remote locations.
The recent addition of OAP to GSUP is related to the same background idea.
(This is a collapsed patch of various changes that do not make sense to review
in chronological order anymore, since a lot of it has thorougly transmorphed
after it was first committed.)
Sponsored-by: On-Waves ehf
Diffstat (limited to 'openbsc/src/gprs/gtphub_vty.c')
-rw-r--r-- | openbsc/src/gprs/gtphub_vty.c | 258 |
1 files changed, 258 insertions, 0 deletions
diff --git a/openbsc/src/gprs/gtphub_vty.c b/openbsc/src/gprs/gtphub_vty.c new file mode 100644 index 000000000..aead17878 --- /dev/null +++ b/openbsc/src/gprs/gtphub_vty.c @@ -0,0 +1,258 @@ +/* (C) 2015 by sysmocom s.f.m.c. GmbH + * All Rights Reserved + * + * Author: Neels Hofmeyr + * + * 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 <http://www.gnu.org/licenses/>. + * + */ + +#include <string.h> + +#include <osmocom/core/talloc.h> +#include <osmocom/vty/command.h> + +#include <openbsc/vty.h> +#include <openbsc/gtphub.h> + +static struct gtphub_cfg *g_cfg = 0; + +static struct cmd_node gtphub_node = { + GTPHUB_NODE, + "%s(config-gtphub)# ", + 1, +}; + +#define GTPH_DEFAULT_CONTROL_PORT 2123 +#define GTPH_DEFAULT_USER_PORT 2152 + +static void write_addrs(struct vty *vty, const char *name, + struct gtphub_cfg_addr *c, struct gtphub_cfg_addr *u) +{ + if ((c->port == GTPH_DEFAULT_CONTROL_PORT) + && (u->port == GTPH_DEFAULT_USER_PORT) + && (strcmp(c->addr_str, u->addr_str) == 0)) { + /* Default port numbers and same IP address: write "short" + * variant. */ + vty_out(vty, " %s %s%s", + name, + c->addr_str, + VTY_NEWLINE); + return; + } + + vty_out(vty, " %s ctrl %s %d user %s %d%s", + name, + c->addr_str, (int)c->port, + u->addr_str, (int)u->port, + VTY_NEWLINE); +} + +static int config_write_gtphub(struct vty *vty) +{ + vty_out(vty, "gtphub%s", VTY_NEWLINE); + + write_addrs(vty, "bind-to-sgsns", + &g_cfg->to_sgsns[GTPH_PLANE_CTRL].bind, + &g_cfg->to_sgsns[GTPH_PLANE_USER].bind); + + write_addrs(vty, "bind-to-ggsns", + &g_cfg->to_ggsns[GTPH_PLANE_CTRL].bind, + &g_cfg->to_ggsns[GTPH_PLANE_USER].bind); + + if (g_cfg->ggsn_proxy[GTPH_PLANE_CTRL].addr_str) { + write_addrs(vty, "ggsn-proxy", + &g_cfg->ggsn_proxy[GTPH_PLANE_CTRL], + &g_cfg->ggsn_proxy[GTPH_PLANE_USER]); + } + + return CMD_SUCCESS; +} + +DEFUN(cfg_gtphub, cfg_gtphub_cmd, + "gtphub", + "Configure the GTP hub") +{ + vty->node = GTPHUB_NODE; + return CMD_SUCCESS; +} + +#define BIND_ARGS "ctrl ADDR <0-65535> user ADDR <0-65535>" +#define BIND_DOCS \ + "Set GTP-C bind\n" \ + "GTP-C local IP address (v4 or v6)\n" \ + "GTP-C local port\n" \ + "Set GTP-U bind\n" \ + "GTP-U local IP address (v4 or v6)\n" \ + "GTP-U local port\n" + + +DEFUN(cfg_gtphub_bind_to_sgsns_short, cfg_gtphub_bind_to_sgsns_short_cmd, + "bind-to-sgsns ADDR", + "GTP Hub Parameters\n" + "Set the local bind address to listen for SGSNs, for both GTP-C and GTP-U\n" + "Local IP address (v4 or v6)\n" + ) +{ + int i; + for (i = 0; i < GTPH_PLANE_N; i++) + g_cfg->to_sgsns[i].bind.addr_str = talloc_strdup(tall_vty_ctx, argv[0]); + g_cfg->to_sgsns[GTPH_PLANE_CTRL].bind.port = GTPH_DEFAULT_CONTROL_PORT; + g_cfg->to_sgsns[GTPH_PLANE_USER].bind.port = GTPH_DEFAULT_USER_PORT; + return CMD_SUCCESS; +} + +DEFUN(cfg_gtphub_bind_to_ggsns_short, cfg_gtphub_bind_to_ggsns_short_cmd, + "bind-to-ggsns ADDR", + "GTP Hub Parameters\n" + "Set the local bind address to listen for GGSNs, for both GTP-C and GTP-U\n" + "Local IP address (v4 or v6)\n" + ) +{ + int i; + for (i = 0; i < GTPH_PLANE_N; i++) + g_cfg->to_ggsns[i].bind.addr_str = talloc_strdup(tall_vty_ctx, argv[0]); + g_cfg->to_ggsns[GTPH_PLANE_CTRL].bind.port = GTPH_DEFAULT_CONTROL_PORT; + g_cfg->to_ggsns[GTPH_PLANE_USER].bind.port = GTPH_DEFAULT_USER_PORT; + return CMD_SUCCESS; +} + + +static int handle_binds(struct gtphub_cfg_bind *b, const char **argv) +{ + b[GTPH_PLANE_CTRL].bind.addr_str = talloc_strdup(tall_vty_ctx, argv[0]); + b[GTPH_PLANE_CTRL].bind.port = atoi(argv[1]); + b[GTPH_PLANE_USER].bind.addr_str = talloc_strdup(tall_vty_ctx, argv[2]); + b[GTPH_PLANE_USER].bind.port = atoi(argv[3]); + return CMD_SUCCESS; +} + +DEFUN(cfg_gtphub_bind_to_sgsns, cfg_gtphub_bind_to_sgsns_cmd, + "bind-to-sgsns " BIND_ARGS, + "GTP Hub Parameters\n" + "Set the local bind addresses and ports to listen for SGSNs\n" + BIND_DOCS + ) +{ + return handle_binds(g_cfg->to_sgsns, argv); +} + +DEFUN(cfg_gtphub_bind_to_ggsns, cfg_gtphub_bind_to_ggsns_cmd, + "bind-to-ggsns " BIND_ARGS, + "GTP Hub Parameters\n" + "Set the local bind addresses and ports to listen for GGSNs\n" + BIND_DOCS + ) +{ + return handle_binds(g_cfg->to_ggsns, argv); +} + +DEFUN(cfg_gtphub_ggsn_proxy_short, cfg_gtphub_ggsn_proxy_short_cmd, + "ggsn-proxy ADDR", + "GTP Hub Parameters\n" + "Redirect all GGSN bound traffic to default ports on this address (another gtphub)\n" + "Remote IP address (v4 or v6)\n" + ) +{ + g_cfg->ggsn_proxy[GTPH_PLANE_CTRL].addr_str = talloc_strdup(tall_vty_ctx, argv[0]); + g_cfg->ggsn_proxy[GTPH_PLANE_CTRL].port = GTPH_DEFAULT_CONTROL_PORT; + g_cfg->ggsn_proxy[GTPH_PLANE_USER].addr_str = talloc_strdup(tall_vty_ctx, argv[0]); + g_cfg->ggsn_proxy[GTPH_PLANE_USER].port = GTPH_DEFAULT_USER_PORT; + return CMD_SUCCESS; +} + +DEFUN(cfg_gtphub_ggsn_proxy, cfg_gtphub_ggsn_proxy_cmd, + "ggsn-proxy " BIND_ARGS, + "GTP Hub Parameters\n" + "Redirect all GGSN bound traffic to these addresses and ports (another gtphub)\n" + BIND_DOCS + ) +{ + g_cfg->ggsn_proxy[GTPH_PLANE_CTRL].addr_str = talloc_strdup(tall_vty_ctx, argv[0]); + g_cfg->ggsn_proxy[GTPH_PLANE_CTRL].port = atoi(argv[1]); + g_cfg->ggsn_proxy[GTPH_PLANE_USER].addr_str = talloc_strdup(tall_vty_ctx, argv[2]); + g_cfg->ggsn_proxy[GTPH_PLANE_USER].port = atoi(argv[3]); + return CMD_SUCCESS; +} + +DEFUN(cfg_gtphub_sgsn_proxy_short, cfg_gtphub_sgsn_proxy_short_cmd, + "sgsn-proxy ADDR", + "GTP Hub Parameters\n" + "Redirect all SGSN bound traffic to default ports on this address (another gtphub)\n" + "Remote IP address (v4 or v6)\n" + ) +{ + g_cfg->sgsn_proxy[GTPH_PLANE_CTRL].addr_str = talloc_strdup(tall_vty_ctx, argv[0]); + g_cfg->sgsn_proxy[GTPH_PLANE_CTRL].port = GTPH_DEFAULT_CONTROL_PORT; + g_cfg->sgsn_proxy[GTPH_PLANE_USER].addr_str = talloc_strdup(tall_vty_ctx, argv[0]); + g_cfg->sgsn_proxy[GTPH_PLANE_USER].port = GTPH_DEFAULT_USER_PORT; + return CMD_SUCCESS; +} + +DEFUN(cfg_gtphub_sgsn_proxy, cfg_gtphub_sgsn_proxy_cmd, + "sgsn-proxy " BIND_ARGS, + "GTP Hub Parameters\n" + "Redirect all SGSN bound traffic to these addresses and ports (another gtphub)\n" + BIND_DOCS + ) +{ + g_cfg->sgsn_proxy[GTPH_PLANE_CTRL].addr_str = talloc_strdup(tall_vty_ctx, argv[0]); + g_cfg->sgsn_proxy[GTPH_PLANE_CTRL].port = atoi(argv[1]); + g_cfg->sgsn_proxy[GTPH_PLANE_USER].addr_str = talloc_strdup(tall_vty_ctx, argv[2]); + g_cfg->sgsn_proxy[GTPH_PLANE_USER].port = atoi(argv[3]); + return CMD_SUCCESS; +} + +DEFUN(show_gtphub, show_gtphub_cmd, "show gtphub", + SHOW_STR "Display information about the GTP hub") +{ + vty_out(vty, "gtphub has nothing to say yet%s", VTY_NEWLINE); + return CMD_SUCCESS; +} + + +int gtphub_vty_init(void) +{ + install_element_ve(&show_gtphub_cmd); + + install_element(CONFIG_NODE, &cfg_gtphub_cmd); + install_node(>phub_node, config_write_gtphub); + vty_install_default(GTPHUB_NODE); + + install_element(GTPHUB_NODE, &cfg_gtphub_bind_to_sgsns_short_cmd); + install_element(GTPHUB_NODE, &cfg_gtphub_bind_to_sgsns_cmd); + install_element(GTPHUB_NODE, &cfg_gtphub_bind_to_ggsns_short_cmd); + install_element(GTPHUB_NODE, &cfg_gtphub_bind_to_ggsns_cmd); + install_element(GTPHUB_NODE, &cfg_gtphub_ggsn_proxy_short_cmd); + install_element(GTPHUB_NODE, &cfg_gtphub_ggsn_proxy_cmd); + install_element(GTPHUB_NODE, &cfg_gtphub_sgsn_proxy_short_cmd); + install_element(GTPHUB_NODE, &cfg_gtphub_sgsn_proxy_cmd); + + return 0; +} + +int gtphub_cfg_read(struct gtphub_cfg *cfg, const char *config_file) +{ + int rc; + + g_cfg = cfg; + + rc = vty_read_config_file(config_file, NULL); + if (rc < 0) { + fprintf(stderr, "Failed to parse the config file: '%s'\n", config_file); + return rc; + } + + return 0; +} |