aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/src/nat
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <zecke@selfish.org>2010-06-01 01:03:13 +0800
committerHolger Hans Peter Freyther <zecke@selfish.org>2010-06-15 20:24:21 +0800
commit8affef5059c3663f581bd3142de606bfc124a7ab (patch)
treea9549b1fcaa23e9c1d4518626c132413b4680552 /openbsc/src/nat
parent078321aaae03fbe859f95c05f70bcf578cec539b (diff)
[nat] Introduce the concept of access-list
One can set one access-list to one BSC and one access-list to one NAT. The matching of IMSIs remains the same for now, also applying the white/blacklist. Access lists can not be deleted for now and no perf opt is done (e.g. one could cache the result of the last lookup in the bsc struct).
Diffstat (limited to 'openbsc/src/nat')
-rw-r--r--openbsc/src/nat/bsc_nat_utils.c53
-rw-r--r--openbsc/src/nat/bsc_nat_vty.c110
2 files changed, 122 insertions, 41 deletions
diff --git a/openbsc/src/nat/bsc_nat_utils.c b/openbsc/src/nat/bsc_nat_utils.c
index a243171a7..ffb37e8bc 100644
--- a/openbsc/src/nat/bsc_nat_utils.c
+++ b/openbsc/src/nat/bsc_nat_utils.c
@@ -46,6 +46,8 @@ struct bsc_nat *bsc_nat_alloc(void)
INIT_LLIST_HEAD(&nat->sccp_connections);
INIT_LLIST_HEAD(&nat->bsc_connections);
INIT_LLIST_HEAD(&nat->bsc_configs);
+ INIT_LLIST_HEAD(&nat->access_lists);
+
nat->stats.sccp.conn = counter_alloc("nat.sccp.conn");
nat->stats.sccp.calls = counter_alloc("nat.sccp.calls");
nat->stats.bsc.reconn = counter_alloc("nat.bsc.conn");
@@ -203,10 +205,16 @@ static int auth_imsi(struct bsc_connection *bsc, const char *mi_string)
* 3.) Reject if the IMSI not allowed at the global level.
* 4.) Allow directly if the IMSI is allowed at the global level
*/
+ struct bsc_nat_access_list *nat_lst = NULL;
+ struct bsc_nat_access_list *bsc_lst = NULL;
+
+ bsc_lst = bsc_nat_accs_list_find(bsc->nat, bsc->cfg->acc_lst_name);
+ nat_lst = bsc_nat_accs_list_find(bsc->nat, bsc->nat->acc_lst_name);
+
/* 1. BSC deny */
- if (bsc->cfg->imsi_deny) {
- if (regexec(&bsc->cfg->imsi_deny_re, mi_string, 0, NULL, 0) == 0) {
+ if (bsc_lst && bsc_lst->imsi_deny) {
+ if (regexec(&bsc_lst->imsi_deny_re, mi_string, 0, NULL, 0) == 0) {
LOGP(DNAT, LOGL_ERROR,
"Filtering %s by imsi_deny on bsc nr: %d.\n", mi_string, bsc->cfg->nr);
return -2;
@@ -214,14 +222,14 @@ static int auth_imsi(struct bsc_connection *bsc, const char *mi_string)
}
/* 2. BSC allow */
- if (bsc->cfg->imsi_allow) {
- if (regexec(&bsc->cfg->imsi_allow_re, mi_string, 0, NULL, 0) == 0)
+ if (bsc_lst && bsc_lst->imsi_allow) {
+ if (regexec(&bsc_lst->imsi_allow_re, mi_string, 0, NULL, 0) == 0)
return 0;
}
/* 3. NAT deny */
- if (bsc->nat->imsi_deny) {
- if (regexec(&bsc->nat->imsi_deny_re, mi_string, 0, NULL, 0) == 0) {
+ if (nat_lst && nat_lst->imsi_deny) {
+ if (regexec(&nat_lst->imsi_deny_re, mi_string, 0, NULL, 0) == 0) {
LOGP(DNAT, LOGL_ERROR,
"Filtering %s by nat imsi_deny on bsc nr: %d.\n", mi_string, bsc->cfg->nr);
return -3;
@@ -402,4 +410,37 @@ static const char *con_types [] = {
const char *bsc_con_type_to_string(int type)
{
return con_types[type];
+}
+
+struct bsc_nat_access_list *bsc_nat_accs_list_find(struct bsc_nat *nat, const char *name)
+{
+ struct bsc_nat_access_list *lst;
+
+ if (!name)
+ return NULL;
+
+ llist_for_each_entry(lst, &nat->access_lists, list)
+ if (strcmp(lst->name, name) == 0)
+ return lst;
+
+ return NULL;
+}
+
+struct bsc_nat_access_list *bsc_nat_accs_list_get(struct bsc_nat *nat, const char *name)
+{
+ struct bsc_nat_access_list *lst;
+
+ lst = bsc_nat_accs_list_find(nat, name);
+ if (lst)
+ return lst;
+
+ lst = talloc_zero(nat, struct bsc_nat_access_list);
+ if (!lst) {
+ LOGP(DNAT, LOGL_ERROR, "Failed to allocate access list");
+ return NULL;
+ }
+
+ lst->name = talloc_strdup(lst, name);
+ llist_add(&lst->list, &nat->access_lists);
+ return lst;
} \ No newline at end of file
diff --git a/openbsc/src/nat/bsc_nat_vty.c b/openbsc/src/nat/bsc_nat_vty.c
index cef47d1b3..e77a896a2 100644
--- a/openbsc/src/nat/bsc_nat_vty.c
+++ b/openbsc/src/nat/bsc_nat_vty.c
@@ -51,9 +51,9 @@ static struct cmd_node bsc_node = {
static int config_write_nat(struct vty *vty)
{
+ struct bsc_nat_access_list *lst;
+
vty_out(vty, "nat%s", VTY_NEWLINE);
- if (_nat->imsi_deny)
- vty_out(vty, " imsi deny %s%s", _nat->imsi_deny, VTY_NEWLINE);
vty_out(vty, " msc ip %s%s", _nat->msc_ip, VTY_NEWLINE);
vty_out(vty, " msc port %d%s", _nat->msc_port, VTY_NEWLINE);
vty_out(vty, " timeout auth %d%s", _nat->auth_timeout, VTY_NEWLINE);
@@ -62,6 +62,18 @@ static int config_write_nat(struct vty *vty)
if (_nat->token)
vty_out(vty, " token %s%s", _nat->token, VTY_NEWLINE);
vty_out(vty, " ip-tos %d%s", _nat->bsc_ip_tos, VTY_NEWLINE);
+ if (_nat->acc_lst_name)
+ vty_out(vty, " access-list-name %s%s", _nat->acc_lst_name, VTY_NEWLINE);
+
+ llist_for_each_entry(lst, &_nat->access_lists, list) {
+ if (lst->imsi_allow)
+ vty_out(vty, " access-list %s imsi-allow %s%s",
+ lst->name, lst->imsi_allow, VTY_NEWLINE);
+ if (lst->imsi_deny)
+ vty_out(vty, " access-list %s imsi-deny %s%s",
+ lst->name, lst->imsi_deny, VTY_NEWLINE);
+ }
+
return CMD_SUCCESS;
}
@@ -70,13 +82,11 @@ static void config_write_bsc_single(struct vty *vty, struct bsc_config *bsc)
vty_out(vty, " bsc %u%s", bsc->nr, VTY_NEWLINE);
vty_out(vty, " token %s%s", bsc->token, VTY_NEWLINE);
vty_out(vty, " location_area_code %u%s", bsc->lac, VTY_NEWLINE);
- if (bsc->imsi_allow)
- vty_out(vty, " imsi allow %s%s", bsc->imsi_allow, VTY_NEWLINE);
- if (bsc->imsi_deny)
- vty_out(vty, " imsi deny %s%s", bsc->imsi_deny, VTY_NEWLINE);
vty_out(vty, " paging forbidden %d%s", bsc->forbid_paging, VTY_NEWLINE);
if (bsc->description)
vty_out(vty, " description %s%s", bsc->description, VTY_NEWLINE);
+ if (bsc->acc_lst_name)
+ vty_out(vty, " access-list-name %s%s", bsc->acc_lst_name, VTY_NEWLINE);
}
static int config_write_bsc(struct vty *vty)
@@ -137,10 +147,9 @@ DEFUN(show_bsc_cfg, show_bsc_cfg_cmd, "show bsc config",
llist_for_each_entry(conf, &_nat->bsc_configs, entry) {
vty_out(vty, "BSC token: '%s' lac: %u nr: %u%s",
conf->token, conf->lac, conf->nr, VTY_NEWLINE);
- vty_out(vty, " imsi_allow: '%s' imsi_deny: '%s'%s",
- conf->imsi_allow ? conf->imsi_allow: "any",
- conf->imsi_deny ? conf->imsi_deny : "none",
- VTY_NEWLINE);
+ if (conf->acc_lst_name)
+ vty_out(vty, " access-list: %s%s",
+ conf->acc_lst_name, VTY_NEWLINE);
vty_out(vty, " paging forbidden: %d%s",
conf->forbid_paging, VTY_NEWLINE);
if (conf->description)
@@ -233,16 +242,6 @@ DEFUN(cfg_nat, cfg_nat_cmd, "nat", "Configute the NAT")
return CMD_SUCCESS;
}
-DEFUN(cfg_nat_imsi_deny,
- cfg_nat_imsi_deny_cmd,
- "imsi deny [REGEXP]",
- "Deny matching IMSIs to talk to the MSC. "
- "The defualt is to not deny.")
-{
- bsc_parse_reg(_nat, &_nat->imsi_deny_re, &_nat->imsi_deny, argc, argv);
- return CMD_SUCCESS;
-}
-
DEFUN(cfg_nat_msc_ip,
cfg_nat_msc_ip_cmd,
"msc ip A.B.C.D",
@@ -306,6 +305,18 @@ DEFUN(cfg_nat_bsc_ip_tos, cfg_nat_bsc_ip_tos_cmd,
return CMD_SUCCESS;
}
+DEFUN(cfg_nat_acc_lst_name,
+ cfg_nat_acc_lst_name_cmd,
+ "access-list-name NAME",
+ "Set the name of the access list to use.\n"
+ "The name of the to be used access list.")
+{
+ if (_nat->acc_lst_name)
+ talloc_free(_nat->acc_lst_name);
+ _nat->acc_lst_name = talloc_strdup(_nat, argv[0]);
+ return CMD_SUCCESS;
+}
+
/* per BSC configuration */
DEFUN(cfg_bsc, cfg_bsc_cmd, "bsc BSC_NR", "Select a BSC to configure")
{
@@ -368,27 +379,53 @@ DEFUN(cfg_bsc_lac, cfg_bsc_lac_cmd, "location_area_code <0-65535>",
return CMD_SUCCESS;
}
-DEFUN(cfg_bsc_imsi_allow,
- cfg_bsc_imsi_allow_cmd,
- "imsi allow [REGEXP]",
- "Allow IMSIs with the following network to talk to the MSC."
- "The default is to allow everyone)")
+DEFUN(cfg_lst_imsi_allow,
+ cfg_lst_imsi_allow_cmd,
+ "access-list NAME imsi-allow [REGEXP]",
+ "Allow IMSIs matching the REGEXP\n"
+ "The name of the access-list\n"
+ "The regexp of allowed IMSIs\n")
{
+ struct bsc_nat_access_list *acc;
struct bsc_config *conf = vty->index;
- bsc_parse_reg(conf, &conf->imsi_allow_re, &conf->imsi_allow, argc, argv);
+ acc = bsc_nat_accs_list_get(conf->nat, argv[0]);
+ if (!acc)
+ return CMD_WARNING;
+
+ bsc_parse_reg(acc, &acc->imsi_allow_re, &acc->imsi_allow, argc, argv);
return CMD_SUCCESS;
}
-DEFUN(cfg_bsc_imsi_deny,
- cfg_bsc_imsi_deny_cmd,
- "imsi deny [REGEXP]",
- "Deny IMSIs with the following network to talk to the MSC."
- "The default is to not deny anyone.)")
+DEFUN(cfg_lst_imsi_deny,
+ cfg_lst_imsi_deny_cmd,
+ "access-list NAME imsi-deny [REGEXP]",
+ "Allow IMSIs matching the REGEXP\n"
+ "The name of the access-list\n"
+ "The regexp of to be denied IMSIs\n")
{
+ struct bsc_nat_access_list *acc;
struct bsc_config *conf = vty->index;
- bsc_parse_reg(conf, &conf->imsi_deny_re, &conf->imsi_deny, argc, argv);
+ acc = bsc_nat_accs_list_get(conf->nat, argv[0]);
+ if (!acc)
+ return CMD_WARNING;
+
+ bsc_parse_reg(acc, &acc->imsi_deny_re, &acc->imsi_deny, argc, argv);
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_bsc_acc_lst_name,
+ cfg_bsc_acc_lst_name_cmd,
+ "access-list-name NAME",
+ "Set the name of the access list to use.\n"
+ "The name of the to be used access list.")
+{
+ struct bsc_config *conf = vty->index;
+
+ if (conf->acc_lst_name)
+ talloc_free(conf->acc_lst_name);
+ conf->acc_lst_name = talloc_strdup(conf, argv[0]);
return CMD_SUCCESS;
}
@@ -460,7 +497,6 @@ int bsc_nat_vty_init(struct bsc_nat *nat)
install_element(CONFIG_NODE, &cfg_nat_cmd);
install_node(&nat_node, config_write_nat);
install_default(NAT_NODE);
- install_element(NAT_NODE, &cfg_nat_imsi_deny_cmd);
install_element(NAT_NODE, &cfg_nat_msc_ip_cmd);
install_element(NAT_NODE, &cfg_nat_msc_port_cmd);
install_element(NAT_NODE, &cfg_nat_auth_time_cmd);
@@ -468,6 +504,11 @@ int bsc_nat_vty_init(struct bsc_nat *nat)
install_element(NAT_NODE, &cfg_nat_pong_time_cmd);
install_element(NAT_NODE, &cfg_nat_token_cmd);
install_element(NAT_NODE, &cfg_nat_bsc_ip_tos_cmd);
+ install_element(NAT_NODE, &cfg_nat_acc_lst_name_cmd);
+
+ /* access-list */
+ install_element(NAT_NODE, &cfg_lst_imsi_allow_cmd);
+ install_element(NAT_NODE, &cfg_lst_imsi_deny_cmd);
/* BSC subgroups */
install_element(NAT_NODE, &cfg_bsc_cmd);
@@ -475,10 +516,9 @@ int bsc_nat_vty_init(struct bsc_nat *nat)
install_default(BSC_NODE);
install_element(BSC_NODE, &cfg_bsc_token_cmd);
install_element(BSC_NODE, &cfg_bsc_lac_cmd);
- install_element(BSC_NODE, &cfg_bsc_imsi_allow_cmd);
- install_element(BSC_NODE, &cfg_bsc_imsi_deny_cmd);
install_element(BSC_NODE, &cfg_bsc_paging_cmd);
install_element(BSC_NODE, &cfg_bsc_desc_cmd);
+ install_element(NAT_NODE, &cfg_bsc_acc_lst_name_cmd);
mgcp_vty_init();