diff options
author | Holger Hans Peter Freyther <holger@moiji-mobile.com> | 2014-02-04 19:12:04 +0100 |
---|---|---|
committer | Holger Hans Peter Freyther <holger@moiji-mobile.com> | 2014-03-04 20:39:27 +0100 |
commit | bc3780a73fbe00bb7a9e42cc94511a369ba4a698 (patch) | |
tree | 222bcb9a42110a5c7573a2614295e580a08a7d9d /openbsc/src/osmo-bsc_nat | |
parent | ecdf912ffb77c3971fb5c56e5a271c2583e6a593 (diff) |
nat: Implement setting the access-control-name through CTRL interface
For operation we want to switch the access-list of a BSC at runtime
in a programatic way.
Sponsored-by: On-Waves ehf
Diffstat (limited to 'openbsc/src/osmo-bsc_nat')
-rw-r--r-- | openbsc/src/osmo-bsc_nat/bsc_nat_ctrl.c | 118 |
1 files changed, 99 insertions, 19 deletions
diff --git a/openbsc/src/osmo-bsc_nat/bsc_nat_ctrl.c b/openbsc/src/osmo-bsc_nat/bsc_nat_ctrl.c index 6ff4541a0..8b675d44d 100644 --- a/openbsc/src/osmo-bsc_nat/bsc_nat_ctrl.c +++ b/openbsc/src/osmo-bsc_nat/bsc_nat_ctrl.c @@ -186,6 +186,26 @@ static void ctrl_conn_closed_cb(struct ctrl_connection *connection) } } +static int extract_bsc_nr_variable(char *variable, unsigned int *nr, char **bsc_variable) +{ + char *nr_str, *tmp, *saveptr = NULL; + + tmp = strtok_r(variable, ".", &saveptr); + tmp = strtok_r(NULL, ".", &saveptr); + tmp = strtok_r(NULL, ".", &saveptr); + nr_str = strtok_r(NULL, ".", &saveptr); + if (!nr_str) + return 0; + *nr = atoi(nr_str); + + tmp = strtok_r(NULL, "\0", &saveptr); + if (!tmp) + return 0; + + *bsc_variable = tmp; + return 1; +} + static int forward_to_bsc(struct ctrl_cmd *cmd) { int ret = CTRL_CMD_HANDLED; @@ -193,24 +213,14 @@ static int forward_to_bsc(struct ctrl_cmd *cmd) struct bsc_connection *bsc; struct bsc_cmd_list *pending; unsigned int nr; - char *nr_str, *tmp, *saveptr = NULL; + char *bsc_variable; /* Skip over the beginning (bsc.) */ - tmp = strtok_r(cmd->variable, ".", &saveptr); - tmp = strtok_r(NULL, ".", &saveptr); - tmp = strtok_r(NULL, ".", &saveptr); - nr_str = strtok_r(NULL, ".", &saveptr); - if (!nr_str) { + if (!extract_bsc_nr_variable(cmd->variable, &nr, &bsc_variable)) { cmd->reply = "command incomplete"; goto err; } - nr = atoi(nr_str); - tmp = strtok_r(NULL, "\0", &saveptr); - if (!tmp) { - cmd->reply = "command incomplete"; - goto err; - } llist_for_each_entry(bsc, &g_nat->bsc_connections, list_entry) { if (!bsc->cfg) @@ -245,7 +255,7 @@ static int forward_to_bsc(struct ctrl_cmd *cmd) } talloc_free(bsc_cmd->variable); - bsc_cmd->variable = talloc_strdup(bsc_cmd, tmp); + bsc_cmd->variable = talloc_strdup(bsc_cmd, bsc_variable); if (!bsc_cmd->variable) { cmd->reply = "OOM"; goto err; @@ -274,8 +284,7 @@ static int forward_to_bsc(struct ctrl_cmd *cmd) err: ret = CTRL_CMD_ERROR; done: - if (bsc_cmd) - talloc_free(bsc_cmd); + talloc_free(bsc_cmd); return ret; } @@ -297,6 +306,69 @@ static int verify_fwd_cmd(struct ctrl_cmd *cmd, const char *value, void *data) return 0; } +static int extract_bsc_cfg_variable(struct ctrl_cmd *cmd, struct bsc_config **cfg, + char **bsc_variable) +{ + unsigned int nr; + + if (!extract_bsc_nr_variable(cmd->variable, &nr, bsc_variable)) { + cmd->reply = "command incomplete"; + return 0; + } + + *cfg = bsc_config_num(g_nat, nr); + if (!*cfg) { + cmd->reply = "Unknown BSC"; + return 0; + } + + return 1; +} + +CTRL_CMD_DEFINE(net_cfg_cmd, "net 0 bsc_cfg *"); +static int get_net_cfg_cmd(struct ctrl_cmd *cmd, void *data) +{ + char *bsc_variable; + struct bsc_config *bsc_cfg; + + if (!extract_bsc_cfg_variable(cmd, &bsc_cfg, &bsc_variable)) + return CTRL_CMD_ERROR; + + if (strcmp(bsc_variable, "access-list-name") == 0) { + cmd->reply = talloc_asprintf(cmd, "%s", + bsc_cfg->acc_lst_name ? bsc_cfg->acc_lst_name : ""); + return CTRL_CMD_REPLY; + } + + cmd->reply = "unknown command"; + return CTRL_CMD_ERROR; +} + +static int set_net_cfg_cmd(struct ctrl_cmd *cmd, void *data) +{ + char *bsc_variable; + struct bsc_config *bsc_cfg; + + if (!extract_bsc_cfg_variable(cmd, &bsc_cfg, &bsc_variable)) + return CTRL_CMD_ERROR; + + if (strcmp(bsc_variable, "access-list-name") == 0) { + bsc_replace_string(bsc_cfg, &bsc_cfg->acc_lst_name, cmd->value); + cmd->reply = talloc_asprintf(cmd, "%s", + bsc_cfg->acc_lst_name ? bsc_cfg->acc_lst_name : ""); + return CTRL_CMD_REPLY; + } + + cmd->reply = "unknown command"; + return CTRL_CMD_ERROR; +} + +static int verify_net_cfg_cmd(struct ctrl_cmd *cmd, const char *value, void *data) +{ + return 0; +} + + struct ctrl_handle *bsc_nat_controlif_setup(struct bsc_nat *nat, int port) { struct ctrl_handle *ctrl; @@ -312,13 +384,21 @@ struct ctrl_handle *bsc_nat_controlif_setup(struct bsc_nat *nat, int port) rc = ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_fwd_cmd); if (rc) { fprintf(stderr, "Failed to install the control command. Exiting.\n"); - osmo_fd_unregister(&ctrl->listen_fd); - close(ctrl->listen_fd.fd); - talloc_free(ctrl); - return NULL; + goto error; + } + rc = ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_net_cfg_cmd); + if (rc) { + fprintf(stderr, "Failed to install the net cfg command. Exiting.\n"); + goto error; } g_nat = nat; return ctrl; + +error: + osmo_fd_unregister(&ctrl->listen_fd); + close(ctrl->listen_fd.fd); + talloc_free(ctrl); + return NULL; } |