From 6860c440719f0a2cde89ea18a43e495bfe9177e6 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Mon, 2 May 2011 19:16:13 +0200 Subject: 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. --- openbsc/src/osmo-bsc_nat/bsc_nat_utils.c | 57 +++++++++++-- openbsc/src/osmo-bsc_nat/bsc_nat_vty.c | 139 ++++++++++++++++++++++++++++--- 2 files changed, 176 insertions(+), 20 deletions(-) (limited to 'openbsc/src/osmo-bsc_nat') 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(); -- cgit v1.2.3