aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <zecke@selfish.org>2011-05-02 19:16:13 +0200
committerHolger Hans Peter Freyther <zecke@selfish.org>2011-05-02 19:19:15 +0200
commit6860c440719f0a2cde89ea18a43e495bfe9177e6 (patch)
treef153ee571da4d20a0b756a62fdbbcf79950cf97d
parent474698abefae966fa8712cb47c2761ad1ef48238 (diff)
nat: Create a Paging Group that BSCs can refer to
Introduce a paging group that a BSC can refer to and is used during the LAC lookup. This way paging can be flooded through the network and just filtered at the last element in the core.
-rw-r--r--openbsc/include/openbsc/bsc_nat.h7
-rw-r--r--openbsc/include/openbsc/vty.h1
-rw-r--r--openbsc/src/libcommon/common_vty.c7
-rw-r--r--openbsc/src/osmo-bsc_nat/bsc_nat_utils.c57
-rw-r--r--openbsc/src/osmo-bsc_nat/bsc_nat_vty.c139
5 files changed, 191 insertions, 20 deletions
diff --git a/openbsc/include/openbsc/bsc_nat.h b/openbsc/include/openbsc/bsc_nat.h
index 85c9eaa48..19f8efa32 100644
--- a/openbsc/include/openbsc/bsc_nat.h
+++ b/openbsc/include/openbsc/bsc_nat.h
@@ -387,4 +387,11 @@ int bsc_close_ussd_connections(struct bsc_nat *nat);
struct msgb *bsc_nat_rewrite_setup(struct bsc_nat *nat, struct msgb *msg, struct bsc_nat_parsed *, const char *imsi);
+/** paging group handling */
+struct bsc_nat_paging_group *bsc_nat_paging_group_num(struct bsc_nat *nat, int group);
+struct bsc_nat_paging_group *bsc_nat_paging_group_create(struct bsc_nat *nat, int group);
+void bsc_nat_paging_group_delete(struct bsc_nat_paging_group *);
+void bsc_nat_paging_group_add_lac(struct bsc_nat_paging_group *grp, int lac);
+void bsc_nat_paging_group_del_lac(struct bsc_nat_paging_group *grp, int lac);
+
#endif
diff --git a/openbsc/include/openbsc/vty.h b/openbsc/include/openbsc/vty.h
index ded2e150e..663589671 100644
--- a/openbsc/include/openbsc/vty.h
+++ b/openbsc/include/openbsc/vty.h
@@ -35,6 +35,7 @@ enum bsc_vty_node {
MSC_NODE,
OM2K_NODE,
TRUNK_NODE,
+ PGROUP_NODE,
};
extern int bsc_vty_is_config_node(struct vty *vty, int node);
diff --git a/openbsc/src/libcommon/common_vty.c b/openbsc/src/libcommon/common_vty.c
index f14dbca2d..5b4b296cb 100644
--- a/openbsc/src/libcommon/common_vty.c
+++ b/openbsc/src/libcommon/common_vty.c
@@ -83,6 +83,9 @@ enum node_type bsc_vty_go_parent(struct vty *vty)
vty->index = bsc_config->nat;
}
break;
+ case PGROUP_NODE:
+ vty->node = NAT_NODE;
+ break;
case MSC_NODE:
vty->node = CONFIG_NODE;
break;
@@ -139,6 +142,9 @@ gDEFUN(ournode_exit,
vty->index = bsc_config->nat;
}
break;
+ case PGROUP_NODE:
+ vty->node = NAT_NODE;
+ break;
case MGCP_NODE:
case GBPROXY_NODE:
case SGSN_NODE:
@@ -189,6 +195,7 @@ gDEFUN(ournode_end,
case VTY_NODE:
case NAT_NODE:
case NAT_BSC_NODE:
+ case PGROUP_NODE:
case MSC_NODE:
vty_config_unlock(vty);
vty->node = ENABLE_NODE;
diff --git a/openbsc/src/osmo-bsc_nat/bsc_nat_utils.c b/openbsc/src/osmo-bsc_nat/bsc_nat_utils.c
index 512656a6b..9ddc948cd 100644
--- a/openbsc/src/osmo-bsc_nat/bsc_nat_utils.c
+++ b/openbsc/src/osmo-bsc_nat/bsc_nat_utils.c
@@ -159,29 +159,29 @@ void bsc_config_free(struct bsc_config *cfg)
rate_ctr_group_free(cfg->stats.ctrg);
}
-void bsc_config_add_lac(struct bsc_config *cfg, int _lac)
+static void _add_lac(void *ctx, struct llist_head *list, int _lac)
{
struct bsc_lac_entry *lac;
- llist_for_each_entry(lac, &cfg->lac_list, entry)
+ llist_for_each_entry(lac, list, entry)
if (lac->lac == _lac)
return;
- lac = talloc_zero(cfg, struct bsc_lac_entry);
+ lac = talloc_zero(ctx, struct bsc_lac_entry);
if (!lac) {
LOGP(DNAT, LOGL_ERROR, "Failed to allocate.\n");
return;
}
lac->lac = _lac;
- llist_add_tail(&lac->entry, &cfg->lac_list);
+ llist_add_tail(&lac->entry, list);
}
-void bsc_config_del_lac(struct bsc_config *cfg, int _lac)
+static void _del_lac(struct llist_head *list, int _lac)
{
struct bsc_lac_entry *lac;
- llist_for_each_entry(lac, &cfg->lac_list, entry)
+ llist_for_each_entry(lac, list, entry)
if (lac->lac == _lac) {
llist_del(&lac->entry);
talloc_free(lac);
@@ -189,8 +189,39 @@ void bsc_config_del_lac(struct bsc_config *cfg, int _lac)
}
}
-static struct bsc_nat_paging_group *bsc_nat_paging_group_num(
- struct bsc_nat *nat, int group)
+void bsc_config_add_lac(struct bsc_config *cfg, int _lac)
+{
+ _add_lac(cfg, &cfg->lac_list, _lac);
+}
+
+void bsc_config_del_lac(struct bsc_config *cfg, int _lac)
+{
+ _del_lac(&cfg->lac_list, _lac);
+}
+
+struct bsc_nat_paging_group *bsc_nat_paging_group_create(struct bsc_nat *nat, int group)
+{
+ struct bsc_nat_paging_group *pgroup;
+
+ pgroup = talloc_zero(nat, struct bsc_nat_paging_group);
+ if (!pgroup) {
+ LOGP(DNAT, LOGL_ERROR, "Failed to allocate a paging group.\n");
+ return NULL;
+ }
+
+ pgroup->nr = group;
+ INIT_LLIST_HEAD(&pgroup->lists);
+ llist_add_tail(&pgroup->entry, &nat->paging_groups);
+ return pgroup;
+}
+
+void bsc_nat_paging_group_delete(struct bsc_nat_paging_group *pgroup)
+{
+ llist_del(&pgroup->entry);
+ talloc_free(pgroup);
+}
+
+struct bsc_nat_paging_group *bsc_nat_paging_group_num(struct bsc_nat *nat, int group)
{
struct bsc_nat_paging_group *pgroup;
@@ -201,6 +232,16 @@ static struct bsc_nat_paging_group *bsc_nat_paging_group_num(
return NULL;
}
+void bsc_nat_paging_group_add_lac(struct bsc_nat_paging_group *pgroup, int lac)
+{
+ _add_lac(pgroup, &pgroup->lists, lac);
+}
+
+void bsc_nat_paging_group_del_lac(struct bsc_nat_paging_group *pgroup, int lac)
+{
+ _del_lac(&pgroup->lists, lac);
+}
+
int bsc_config_handles_lac(struct bsc_config *cfg, int lac_nr)
{
struct bsc_nat_paging_group *pgroup;
diff --git a/openbsc/src/osmo-bsc_nat/bsc_nat_vty.c b/openbsc/src/osmo-bsc_nat/bsc_nat_vty.c
index ffbfe9b3a..b892d7a50 100644
--- a/openbsc/src/osmo-bsc_nat/bsc_nat_vty.c
+++ b/openbsc/src/osmo-bsc_nat/bsc_nat_vty.c
@@ -50,6 +50,17 @@ static struct cmd_node bsc_node = {
1,
};
+static struct cmd_node pgroup_node = {
+ PGROUP_NODE,
+ "%s(paging-group)#",
+ 1,
+};
+
+static int config_write_pgroup(struct vty *vty)
+{
+ return CMD_SUCCESS;
+}
+
static void write_acc_lst(struct vty *vty, struct bsc_nat_acc_lst *lst)
{
struct bsc_nat_acc_lst_entry *entry;
@@ -64,9 +75,24 @@ static void write_acc_lst(struct vty *vty, struct bsc_nat_acc_lst *lst)
}
}
+static void dump_lac(struct vty *vty, struct llist_head *head)
+{
+ struct bsc_lac_entry *lac;
+ llist_for_each_entry(lac, head, entry)
+ vty_out(vty, " location_area_code %u%s", lac->lac, VTY_NEWLINE);
+}
+
+
+static void write_pgroup_lst(struct vty *vty, struct bsc_nat_paging_group *pgroup)
+{
+ vty_out(vty, " paging-group %d%s", pgroup->nr, VTY_NEWLINE);
+ dump_lac(vty, &pgroup->lists);
+}
+
static int config_write_nat(struct vty *vty)
{
struct bsc_nat_acc_lst *lst;
+ struct bsc_nat_paging_group *pgroup;
vty_out(vty, "nat%s", VTY_NEWLINE);
vty_out(vty, " msc ip %s%s", _nat->main_dest->ip, VTY_NEWLINE);
@@ -91,31 +117,27 @@ static int config_write_nat(struct vty *vty)
if (_nat->num_rewr_name)
vty_out(vty, " number-rewrite %s%s", _nat->num_rewr_name, VTY_NEWLINE);
- llist_for_each_entry(lst, &_nat->access_lists, list) {
+ llist_for_each_entry(lst, &_nat->access_lists, list)
write_acc_lst(vty, lst);
- }
+ llist_for_each_entry(pgroup, &_nat->paging_groups, entry)
+ write_pgroup_lst(vty, pgroup);
return CMD_SUCCESS;
}
-static void dump_lac(struct vty *vty, struct bsc_config *cfg)
-{
- struct bsc_lac_entry *lac;
- llist_for_each_entry(lac, &cfg->lac_list, entry)
- vty_out(vty, " location_area_code %u%s", lac->lac, VTY_NEWLINE);
-}
-
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);
- dump_lac(vty, bsc);
+ dump_lac(vty, &bsc->lac_list);
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);
vty_out(vty, " max-endpoints %d%s", bsc->max_endpoints, VTY_NEWLINE);
+ if (bsc->paging_group != -1)
+ vty_out(vty, " paging-group %d%s", bsc->paging_group, VTY_NEWLINE);
}
static int config_write_bsc(struct vty *vty)
@@ -523,7 +545,7 @@ DEFUN(cfg_bsc_token, cfg_bsc_token_cmd, "token TOKEN", "Set the token")
}
DEFUN(cfg_bsc_lac, cfg_bsc_lac_cmd, "location_area_code <0-65535>",
- "Set the Location Area Code (LAC) of this BSC")
+ "Add the Location Area Code (LAC) of this BSC\n" "LAC\n")
{
struct bsc_config *tmp;
struct bsc_config *conf = vty->index;
@@ -551,7 +573,7 @@ DEFUN(cfg_bsc_lac, cfg_bsc_lac_cmd, "location_area_code <0-65535>",
DEFUN(cfg_bsc_no_lac, cfg_bsc_no_lac_cmd,
"no location_area_code <0-65535>",
- NO_STR "Set the Location Area Code (LAC) of this BSC")
+ NO_STR "Remove the Location Area Code (LAC) of this BSC\n" "LAC\n")
{
int lac = atoi(argv[0]);
struct bsc_config *conf = vty->index;
@@ -704,6 +726,26 @@ DEFUN(cfg_bsc_desc,
return CMD_SUCCESS;
}
+DEFUN(cfg_bsc_paging_grp,
+ cfg_bsc_paging_grp_cmd,
+ "paging-group <0-1000>",
+ "Use a paging group\n" "Paging Group to use\n")
+{
+ struct bsc_config *conf = vty->index;
+ conf->paging_group = atoi(argv[0]);
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_bsc_no_paging_grp,
+ cfg_bsc_no_paging_grp_cmd,
+ "no paging-group",
+ NO_STR "Disable the usage of a paging group.\n")
+{
+ struct bsc_config *conf = vty->index;
+ conf->paging_group = PAGIN_GROUP_UNASSIGNED;
+ return CMD_SUCCESS;
+}
+
DEFUN(test_regex, test_regex_cmd,
"test regex PATTERN STRING",
"Check if the string is matching the current pattern.")
@@ -759,6 +801,70 @@ DEFUN(block_new_conn, block_new_conn_cmd,
return CMD_SUCCESS;
}
+/* paging group */
+DEFUN(cfg_nat_pgroup, cfg_nat_pgroup_cmd,
+ "paging-group <0-1000>",
+ "Create a Paging Group\n" "Number of the Group\n")
+{
+ int group = atoi(argv[0]);
+ struct bsc_nat_paging_group *pgroup;
+ pgroup = bsc_nat_paging_group_num(_nat, group);
+ if (!pgroup)
+ pgroup = bsc_nat_paging_group_create(_nat, group);
+ if (!pgroup) {
+ vty_out(vty, "Failed to create the group.%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ vty->index = pgroup;
+ vty->node = PGROUP_NODE;
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_nat_no_pgroup, cfg_nat_no_pgroup_cmd,
+ "no paging-group <0-1000>",
+ NO_STR "Delete paging-group\n")
+{
+ int group = atoi(argv[0]);
+ struct bsc_nat_paging_group *pgroup;
+ pgroup = bsc_nat_paging_group_num(_nat, group);
+ if (!pgroup) {
+ vty_out(vty, "No such paging group %d.%s", group, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ bsc_nat_paging_group_delete(pgroup);
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_pgroup_lac, cfg_pgroup_lac_cmd,
+ "location_area_code <0-65535>",
+ "Add the Location Area Code (LAC)\n" "LAC\n")
+{
+ struct bsc_nat_paging_group *pgroup = vty->index;
+
+ int lac = atoi(argv[0]);
+ if (lac == GSM_LAC_RESERVED_DETACHED || lac == GSM_LAC_RESERVED_ALL_BTS) {
+ vty_out(vty, "%% LAC %d is reserved by GSM 04.08%s",
+ lac, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ bsc_nat_paging_group_add_lac(pgroup, lac);
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_pgroup_no_lac, cfg_pgroup_no_lac_cmd,
+ "no location_area_code <0-65535>",
+ NO_STR "Remove the Location Area Code (LAC)\n" "LAC\n")
+{
+ int lac = atoi(argv[0]);
+ struct bsc_nat_paging_group *pgroup = vty->index;
+
+ bsc_nat_paging_group_del_lac(pgroup, lac);
+ return CMD_SUCCESS;
+}
+
int bsc_nat_vty_init(struct bsc_nat *nat)
{
_nat = nat;
@@ -807,6 +913,13 @@ int bsc_nat_vty_init(struct bsc_nat *nat)
/* number rewriting */
install_element(NAT_NODE, &cfg_nat_number_rewrite_cmd);
+ install_element(NAT_NODE, &cfg_nat_pgroup_cmd);
+ install_element(NAT_NODE, &cfg_nat_no_pgroup_cmd);
+ install_node(&pgroup_node, config_write_pgroup);
+ install_default(PGROUP_NODE);
+ install_element(PGROUP_NODE, &cfg_pgroup_lac_cmd);
+ install_element(PGROUP_NODE, &cfg_pgroup_no_lac_cmd);
+
/* BSC subgroups */
install_element(NAT_NODE, &cfg_bsc_cmd);
install_node(&bsc_node, config_write_bsc);
@@ -821,6 +934,8 @@ int bsc_nat_vty_init(struct bsc_nat *nat)
install_element(NAT_BSC_NODE, &cfg_bsc_acc_lst_name_cmd);
install_element(NAT_BSC_NODE, &cfg_bsc_no_acc_lst_name_cmd);
install_element(NAT_BSC_NODE, &cfg_bsc_max_endps_cmd);
+ install_element(NAT_BSC_NODE, &cfg_bsc_paging_grp_cmd);
+ install_element(NAT_BSC_NODE, &cfg_bsc_no_paging_grp_cmd);
mgcp_vty_init();