gbproxy: convert bss_nses from llist_head to hashtable
For the common lookup-by-nsei, this should reduce the computational complexity significantly. Depends: libosmocore.git I8ef73a62fe9846ce45058eb21cf999dd3eed5741 Change-Id: Idbb6a362332bb6e3ce22102e7409ae80d0980f44
This commit is contained in:
parent
2b7b1bbbdc
commit
d2fef95945
|
@ -1,2 +1,3 @@
|
||||||
#component what description / commit summary line
|
#component what description / commit summary line
|
||||||
manual needs common chapter cs7-config.adoc, vty_cpu_sched.adoc from osmo-gsm-manuals > 0.3.0
|
manual needs common chapter cs7-config.adoc, vty_cpu_sched.adoc from osmo-gsm-manuals > 0.3.0
|
||||||
|
configure.ac libosmocore depend on next released libosmocore after 1.4.x with hashtable support
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#include <osmocom/core/msgb.h>
|
#include <osmocom/core/msgb.h>
|
||||||
#include <osmocom/core/timer.h>
|
#include <osmocom/core/timer.h>
|
||||||
|
#include <osmocom/core/hashtable.h>
|
||||||
#include <osmocom/gsm/gsm23003.h>
|
#include <osmocom/gsm/gsm23003.h>
|
||||||
|
|
||||||
#include <osmocom/gprs/gprs_ns2.h>
|
#include <osmocom/gprs/gprs_ns2.h>
|
||||||
|
@ -102,7 +103,7 @@ struct gbproxy_config {
|
||||||
struct gprs_ns2_inst *nsi;
|
struct gprs_ns2_inst *nsi;
|
||||||
|
|
||||||
/* Linked list of all BSS side Gb peers */
|
/* Linked list of all BSS side Gb peers */
|
||||||
struct llist_head bss_nses;
|
DECLARE_HASHTABLE(bss_nses, 8);
|
||||||
|
|
||||||
/* Counter */
|
/* Counter */
|
||||||
struct rate_ctr_group *ctrg;
|
struct rate_ctr_group *ctrg;
|
||||||
|
@ -176,7 +177,7 @@ struct gbproxy_bvc {
|
||||||
/* one NS Entity that we interact with (BSS/PCU) */
|
/* one NS Entity that we interact with (BSS/PCU) */
|
||||||
struct gbproxy_nse {
|
struct gbproxy_nse {
|
||||||
/* linked to gbproxy_config.bss_nses */
|
/* linked to gbproxy_config.bss_nses */
|
||||||
struct llist_head list;
|
struct hlist_node list;
|
||||||
|
|
||||||
/* point back to the config */
|
/* point back to the config */
|
||||||
struct gbproxy_config *cfg;
|
struct gbproxy_config *cfg;
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
|
#include <osmocom/core/hashtable.h>
|
||||||
#include <osmocom/core/logging.h>
|
#include <osmocom/core/logging.h>
|
||||||
#include <osmocom/core/talloc.h>
|
#include <osmocom/core/talloc.h>
|
||||||
#include <osmocom/core/select.h>
|
#include <osmocom/core/select.h>
|
||||||
|
@ -1183,6 +1184,7 @@ static int gbprox_rx_paging(struct gbproxy_config *cfg, struct msgb *msg, struct
|
||||||
struct gbproxy_bvc *bvc;
|
struct gbproxy_bvc *bvc;
|
||||||
unsigned int n_nses = 0;
|
unsigned int n_nses = 0;
|
||||||
int errctr = GBPROX_GLOB_CTR_PROTO_ERR_SGSN;
|
int errctr = GBPROX_GLOB_CTR_PROTO_ERR_SGSN;
|
||||||
|
int i;
|
||||||
|
|
||||||
/* FIXME: Handle paging logic to only page each matching NSE */
|
/* FIXME: Handle paging logic to only page each matching NSE */
|
||||||
|
|
||||||
|
@ -1203,7 +1205,7 @@ static int gbprox_rx_paging(struct gbproxy_config *cfg, struct msgb *msg, struct
|
||||||
} else if (TLVP_PRES_LEN(tp, BSSGP_IE_ROUTEING_AREA, 6)) {
|
} else if (TLVP_PRES_LEN(tp, BSSGP_IE_ROUTEING_AREA, 6)) {
|
||||||
errctr = GBPROX_GLOB_CTR_INV_RAI;
|
errctr = GBPROX_GLOB_CTR_INV_RAI;
|
||||||
/* iterate over all bvcs and dispatch the paging to each matching one */
|
/* iterate over all bvcs and dispatch the paging to each matching one */
|
||||||
llist_for_each_entry(nse, &cfg->bss_nses, list) {
|
hash_for_each(cfg->bss_nses, i, nse, list) {
|
||||||
llist_for_each_entry(bvc, &nse->bvcs, list) {
|
llist_for_each_entry(bvc, &nse->bvcs, list) {
|
||||||
if (!memcmp(bvc->ra, TLVP_VAL(tp, BSSGP_IE_ROUTEING_AREA), 6)) {
|
if (!memcmp(bvc->ra, TLVP_VAL(tp, BSSGP_IE_ROUTEING_AREA), 6)) {
|
||||||
LOGPNSE(nse, LOGL_INFO, "routing to NSE (RAI match)\n");
|
LOGPNSE(nse, LOGL_INFO, "routing to NSE (RAI match)\n");
|
||||||
|
@ -1217,7 +1219,7 @@ static int gbprox_rx_paging(struct gbproxy_config *cfg, struct msgb *msg, struct
|
||||||
} else if (TLVP_PRES_LEN(tp, BSSGP_IE_LOCATION_AREA, 5)) {
|
} else if (TLVP_PRES_LEN(tp, BSSGP_IE_LOCATION_AREA, 5)) {
|
||||||
errctr = GBPROX_GLOB_CTR_INV_LAI;
|
errctr = GBPROX_GLOB_CTR_INV_LAI;
|
||||||
/* iterate over all bvcs and dispatch the paging to each matching one */
|
/* iterate over all bvcs and dispatch the paging to each matching one */
|
||||||
llist_for_each_entry(nse, &cfg->bss_nses, list) {
|
hash_for_each(cfg->bss_nses, i, nse, list) {
|
||||||
llist_for_each_entry(bvc, &nse->bvcs, list) {
|
llist_for_each_entry(bvc, &nse->bvcs, list) {
|
||||||
if (!memcmp(bvc->ra, TLVP_VAL(tp, BSSGP_IE_LOCATION_AREA), 5)) {
|
if (!memcmp(bvc->ra, TLVP_VAL(tp, BSSGP_IE_LOCATION_AREA), 5)) {
|
||||||
LOGPNSE(nse, LOGL_INFO, "routing to NSE (LAI match)\n");
|
LOGPNSE(nse, LOGL_INFO, "routing to NSE (LAI match)\n");
|
||||||
|
@ -1230,7 +1232,7 @@ static int gbprox_rx_paging(struct gbproxy_config *cfg, struct msgb *msg, struct
|
||||||
}
|
}
|
||||||
} else if (TLVP_PRES_LEN(tp, BSSGP_IE_BSS_AREA_ID, 1)) {
|
} else if (TLVP_PRES_LEN(tp, BSSGP_IE_BSS_AREA_ID, 1)) {
|
||||||
/* iterate over all bvcs and dispatch the paging to each matching one */
|
/* iterate over all bvcs and dispatch the paging to each matching one */
|
||||||
llist_for_each_entry(nse, &cfg->bss_nses, list) {
|
hash_for_each(cfg->bss_nses, i, nse, list) {
|
||||||
llist_for_each_entry(bvc, &nse->bvcs, list) {
|
llist_for_each_entry(bvc, &nse->bvcs, list) {
|
||||||
LOGPNSE(nse, LOGL_INFO, "routing to NSE (broadcast)\n");
|
LOGPNSE(nse, LOGL_INFO, "routing to NSE (broadcast)\n");
|
||||||
gbprox_relay2nse(msg, nse, ns_bvci);
|
gbprox_relay2nse(msg, nse, ns_bvci);
|
||||||
|
@ -1263,6 +1265,7 @@ static int rx_reset_from_sgsn(struct gbproxy_config *cfg,
|
||||||
struct gbproxy_nse *nse;
|
struct gbproxy_nse *nse;
|
||||||
struct gbproxy_bvc *bvc;
|
struct gbproxy_bvc *bvc;
|
||||||
uint16_t ptp_bvci;
|
uint16_t ptp_bvci;
|
||||||
|
int i;
|
||||||
|
|
||||||
if (!TLVP_PRES_LEN(tp, BSSGP_IE_BVCI, 2)) {
|
if (!TLVP_PRES_LEN(tp, BSSGP_IE_BVCI, 2)) {
|
||||||
rate_ctr_inc(&cfg->ctrg->
|
rate_ctr_inc(&cfg->ctrg->
|
||||||
|
@ -1291,7 +1294,7 @@ static int rx_reset_from_sgsn(struct gbproxy_config *cfg,
|
||||||
* from the SGSN. As the signalling BVCI is shared
|
* from the SGSN. As the signalling BVCI is shared
|
||||||
* among all the BSS's that we multiplex, it needs to
|
* among all the BSS's that we multiplex, it needs to
|
||||||
* be relayed */
|
* be relayed */
|
||||||
llist_for_each_entry(nse, &cfg->bss_nses, list) {
|
hash_for_each(cfg->bss_nses, i, nse, list) {
|
||||||
llist_for_each_entry(bvc, &nse->bvcs, list)
|
llist_for_each_entry(bvc, &nse->bvcs, list)
|
||||||
gbprox_relay2peer(msg, bvc, ns_bvci);
|
gbprox_relay2peer(msg, bvc, ns_bvci);
|
||||||
}
|
}
|
||||||
|
@ -1315,6 +1318,7 @@ static int gbprox_rx_sig_from_sgsn(struct gbproxy_config *cfg,
|
||||||
struct msgb *msg;
|
struct msgb *msg;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
int cause;
|
int cause;
|
||||||
|
int i;
|
||||||
|
|
||||||
if (ns_bvci != 0 && ns_bvci != 1) {
|
if (ns_bvci != 0 && ns_bvci != 1) {
|
||||||
LOGP(DGPRS, LOGL_NOTICE, "NSE(%05u/SGSN) BVCI=%05u is not "
|
LOGP(DGPRS, LOGL_NOTICE, "NSE(%05u/SGSN) BVCI=%05u is not "
|
||||||
|
@ -1425,7 +1429,7 @@ static int gbprox_rx_sig_from_sgsn(struct gbproxy_config *cfg,
|
||||||
LOGP(DGPRS, LOGL_DEBUG,
|
LOGP(DGPRS, LOGL_DEBUG,
|
||||||
"NSE(%05u/SGSN) BSSGP %s: broadcasting\n", nsei, bssgp_pdu_str(pdu_type));
|
"NSE(%05u/SGSN) BSSGP %s: broadcasting\n", nsei, bssgp_pdu_str(pdu_type));
|
||||||
/* broadcast to all BSS-side bvcs */
|
/* broadcast to all BSS-side bvcs */
|
||||||
llist_for_each_entry(nse, &cfg->bss_nses, list) {
|
hash_for_each(cfg->bss_nses, i, nse, list) {
|
||||||
gbprox_relay2nse(msg, nse, 0);
|
gbprox_relay2nse(msg, nse, 0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1618,9 +1622,11 @@ int gprs_ns2_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
|
||||||
|
|
||||||
void gbprox_reset(struct gbproxy_config *cfg)
|
void gbprox_reset(struct gbproxy_config *cfg)
|
||||||
{
|
{
|
||||||
struct gbproxy_nse *nse, *ntmp;
|
struct gbproxy_nse *nse;
|
||||||
|
struct hlist_node *ntmp;
|
||||||
|
int i;
|
||||||
|
|
||||||
llist_for_each_entry_safe(nse, ntmp, &cfg->bss_nses, list) {
|
hash_for_each_safe(cfg->bss_nses, i, ntmp, nse, list) {
|
||||||
struct gbproxy_bvc *bvc, *tmp;
|
struct gbproxy_bvc *bvc, *tmp;
|
||||||
llist_for_each_entry_safe(bvc, tmp, &nse->bvcs, list)
|
llist_for_each_entry_safe(bvc, tmp, &nse->bvcs, list)
|
||||||
gbproxy_bvc_free(bvc);
|
gbproxy_bvc_free(bvc);
|
||||||
|
@ -1636,7 +1642,7 @@ int gbproxy_init_config(struct gbproxy_config *cfg)
|
||||||
{
|
{
|
||||||
struct timespec tp;
|
struct timespec tp;
|
||||||
|
|
||||||
INIT_LLIST_HEAD(&cfg->bss_nses);
|
hash_init(cfg->bss_nses);
|
||||||
cfg->ctrg = rate_ctr_group_alloc(tall_sgsn_ctx, &global_ctrg_desc, 0);
|
cfg->ctrg = rate_ctr_group_alloc(tall_sgsn_ctx, &global_ctrg_desc, 0);
|
||||||
if (!cfg->ctrg) {
|
if (!cfg->ctrg) {
|
||||||
LOGP(DGPRS, LOGL_ERROR, "Cannot allocate global counter group!\n");
|
LOGP(DGPRS, LOGL_ERROR, "Cannot allocate global counter group!\n");
|
||||||
|
|
|
@ -56,6 +56,7 @@ static int get_nsvc_state(struct ctrl_cmd *cmd, void *data)
|
||||||
struct gprs_ns2_inst *nsi = cfg->nsi;
|
struct gprs_ns2_inst *nsi = cfg->nsi;
|
||||||
struct gprs_ns2_nse *nse;
|
struct gprs_ns2_nse *nse;
|
||||||
struct gbproxy_nse *nse_peer;
|
struct gbproxy_nse *nse_peer;
|
||||||
|
int i;
|
||||||
|
|
||||||
cmd->reply = talloc_strdup(cmd, "");
|
cmd->reply = talloc_strdup(cmd, "");
|
||||||
|
|
||||||
|
@ -69,7 +70,7 @@ static int get_nsvc_state(struct ctrl_cmd *cmd, void *data)
|
||||||
gprs_ns2_nse_foreach_nsvc(nse, &ctrl_nsvc_state_cb, cmd);
|
gprs_ns2_nse_foreach_nsvc(nse, &ctrl_nsvc_state_cb, cmd);
|
||||||
|
|
||||||
/* NS-VCs for BSS peers */
|
/* NS-VCs for BSS peers */
|
||||||
llist_for_each_entry(nse_peer, &cfg->bss_nses, list) {
|
hash_for_each(cfg->bss_nses, i, nse_peer, list) {
|
||||||
nse = gprs_ns2_nse_by_nsei(nsi, nse_peer->nsei);
|
nse = gprs_ns2_nse_by_nsei(nsi, nse_peer->nsei);
|
||||||
if (nse)
|
if (nse)
|
||||||
gprs_ns2_nse_foreach_nsvc(nse, &ctrl_nsvc_state_cb, cmd);
|
gprs_ns2_nse_foreach_nsvc(nse, &ctrl_nsvc_state_cb, cmd);
|
||||||
|
@ -84,10 +85,11 @@ static int get_gbproxy_state(struct ctrl_cmd *cmd, void *data)
|
||||||
{
|
{
|
||||||
struct gbproxy_config *cfg = data;
|
struct gbproxy_config *cfg = data;
|
||||||
struct gbproxy_nse *nse_peer;
|
struct gbproxy_nse *nse_peer;
|
||||||
|
int i;
|
||||||
|
|
||||||
cmd->reply = talloc_strdup(cmd, "");
|
cmd->reply = talloc_strdup(cmd, "");
|
||||||
|
|
||||||
llist_for_each_entry(nse_peer, &cfg->bss_nses, list) {
|
hash_for_each(cfg->bss_nses, i, nse_peer, list) {
|
||||||
struct gbproxy_bvc *bvc;
|
struct gbproxy_bvc *bvc;
|
||||||
llist_for_each_entry(bvc, &nse_peer->bvcs, list) {
|
llist_for_each_entry(bvc, &nse_peer->bvcs, list) {
|
||||||
struct gprs_ra_id raid;
|
struct gprs_ra_id raid;
|
||||||
|
@ -111,8 +113,9 @@ static int get_num_peers(struct ctrl_cmd *cmd, void *data)
|
||||||
struct gbproxy_config *cfg = data;
|
struct gbproxy_config *cfg = data;
|
||||||
struct gbproxy_nse *nse_peer;
|
struct gbproxy_nse *nse_peer;
|
||||||
uint32_t count = 0;
|
uint32_t count = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
llist_for_each_entry(nse_peer, &cfg->bss_nses, list)
|
hash_for_each(cfg->bss_nses, i, nse_peer, list)
|
||||||
count += llist_count(&nse_peer->bvcs);
|
count += llist_count(&nse_peer->bvcs);
|
||||||
|
|
||||||
cmd->reply = talloc_strdup(cmd, "");
|
cmd->reply = talloc_strdup(cmd, "");
|
||||||
|
|
|
@ -86,8 +86,9 @@ static const struct rate_ctr_group_desc bvc_ctrg_desc = {
|
||||||
struct gbproxy_bvc *gbproxy_bvc_by_bvci(struct gbproxy_config *cfg, uint16_t bvci)
|
struct gbproxy_bvc *gbproxy_bvc_by_bvci(struct gbproxy_config *cfg, uint16_t bvci)
|
||||||
{
|
{
|
||||||
struct gbproxy_nse *nse;
|
struct gbproxy_nse *nse;
|
||||||
|
int i;
|
||||||
|
|
||||||
llist_for_each_entry(nse, &cfg->bss_nses, list) {
|
hash_for_each(cfg->bss_nses, i, nse, list) {
|
||||||
struct gbproxy_bvc *bvc;
|
struct gbproxy_bvc *bvc;
|
||||||
llist_for_each_entry(bvc, &nse->bvcs, list) {
|
llist_for_each_entry(bvc, &nse->bvcs, list) {
|
||||||
if (bvc->bvci == bvci)
|
if (bvc->bvci == bvci)
|
||||||
|
@ -102,11 +103,11 @@ struct gbproxy_bvc *gbproxy_bvc_by_bvci(struct gbproxy_config *cfg, uint16_t bvc
|
||||||
struct gbproxy_bvc *gbproxy_bvc_by_nsei(struct gbproxy_config *cfg,
|
struct gbproxy_bvc *gbproxy_bvc_by_nsei(struct gbproxy_config *cfg,
|
||||||
uint16_t nsei)
|
uint16_t nsei)
|
||||||
{
|
{
|
||||||
struct gbproxy_nse *nse;
|
struct gbproxy_nse *nse = gbproxy_nse_by_nsei(cfg, nsei);
|
||||||
llist_for_each_entry(nse, &cfg->bss_nses, list) {
|
|
||||||
if (nse->nsei == nsei && !llist_empty(&nse->bvcs))
|
if (nse && !llist_empty(&nse->bvcs))
|
||||||
return llist_first_entry(&nse->bvcs, struct gbproxy_bvc, list);
|
return llist_first_entry(&nse->bvcs, struct gbproxy_bvc, list);
|
||||||
}
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,8 +117,9 @@ struct gbproxy_bvc *gbproxy_bvc_by_rai(struct gbproxy_config *cfg,
|
||||||
const uint8_t *ra)
|
const uint8_t *ra)
|
||||||
{
|
{
|
||||||
struct gbproxy_nse *nse;
|
struct gbproxy_nse *nse;
|
||||||
|
int i;
|
||||||
|
|
||||||
llist_for_each_entry(nse, &cfg->bss_nses, list) {
|
hash_for_each(cfg->bss_nses, i, nse, list) {
|
||||||
struct gbproxy_bvc *bvc;
|
struct gbproxy_bvc *bvc;
|
||||||
llist_for_each_entry(bvc, &nse->bvcs, list) {
|
llist_for_each_entry(bvc, &nse->bvcs, list) {
|
||||||
if (!memcmp(bvc->ra, ra, 6))
|
if (!memcmp(bvc->ra, ra, 6))
|
||||||
|
@ -134,8 +136,9 @@ struct gbproxy_bvc *gbproxy_bvc_by_lai(struct gbproxy_config *cfg,
|
||||||
const uint8_t *la)
|
const uint8_t *la)
|
||||||
{
|
{
|
||||||
struct gbproxy_nse *nse;
|
struct gbproxy_nse *nse;
|
||||||
|
int i;
|
||||||
|
|
||||||
llist_for_each_entry(nse, &cfg->bss_nses, list) {
|
hash_for_each(cfg->bss_nses, i, nse, list) {
|
||||||
struct gbproxy_bvc *bvc;
|
struct gbproxy_bvc *bvc;
|
||||||
llist_for_each_entry(bvc, &nse->bvcs, list) {
|
llist_for_each_entry(bvc, &nse->bvcs, list) {
|
||||||
if (!memcmp(bvc->ra, la, 5))
|
if (!memcmp(bvc->ra, la, 5))
|
||||||
|
@ -151,8 +154,9 @@ struct gbproxy_bvc *gbproxy_bvc_by_lac(struct gbproxy_config *cfg,
|
||||||
const uint8_t *la)
|
const uint8_t *la)
|
||||||
{
|
{
|
||||||
struct gbproxy_nse *nse;
|
struct gbproxy_nse *nse;
|
||||||
|
int i;
|
||||||
|
|
||||||
llist_for_each_entry(nse, &cfg->bss_nses, list) {
|
hash_for_each(cfg->bss_nses, i, nse, list) {
|
||||||
struct gbproxy_bvc *bvc;
|
struct gbproxy_bvc *bvc;
|
||||||
llist_for_each_entry(bvc, &nse->bvcs, list) {
|
llist_for_each_entry(bvc, &nse->bvcs, list) {
|
||||||
if (!memcmp(bvc->ra + 3, la + 3, 2))
|
if (!memcmp(bvc->ra + 3, la + 3, 2))
|
||||||
|
@ -268,11 +272,12 @@ void gbproxy_bvc_move(struct gbproxy_bvc *bvc, struct gbproxy_nse *nse)
|
||||||
* \param[in] bvci if 0: remove all BVCs; if != 0: BVCI of the single BVC to clean up */
|
* \param[in] bvci if 0: remove all BVCs; if != 0: BVCI of the single BVC to clean up */
|
||||||
int gbproxy_cleanup_bvcs(struct gbproxy_config *cfg, uint16_t nsei, uint16_t bvci)
|
int gbproxy_cleanup_bvcs(struct gbproxy_config *cfg, uint16_t nsei, uint16_t bvci)
|
||||||
{
|
{
|
||||||
int counter = 0;
|
int i, counter = 0;
|
||||||
struct gbproxy_nse *nse, *ntmp;
|
struct gbproxy_nse *nse;
|
||||||
|
struct hlist_node *ntmp;
|
||||||
OSMO_ASSERT(cfg);
|
OSMO_ASSERT(cfg);
|
||||||
|
|
||||||
llist_for_each_entry_safe(nse, ntmp, &cfg->bss_nses, list) {
|
hash_for_each_safe(cfg->bss_nses, i, ntmp, nse, list) {
|
||||||
struct gbproxy_bvc *bvc, *tmp;
|
struct gbproxy_bvc *bvc, *tmp;
|
||||||
if (nse->nsei != nsei)
|
if (nse->nsei != nsei)
|
||||||
continue;
|
continue;
|
||||||
|
@ -300,7 +305,7 @@ struct gbproxy_nse *gbproxy_nse_alloc(struct gbproxy_config *cfg, uint16_t nsei)
|
||||||
nse->nsei = nsei;
|
nse->nsei = nsei;
|
||||||
nse->cfg = cfg;
|
nse->cfg = cfg;
|
||||||
|
|
||||||
llist_add(&nse->list, &cfg->bss_nses);
|
hash_add(cfg->bss_nses, &nse->list, nsei);
|
||||||
|
|
||||||
INIT_LLIST_HEAD(&nse->bvcs);
|
INIT_LLIST_HEAD(&nse->bvcs);
|
||||||
|
|
||||||
|
@ -313,7 +318,7 @@ void gbproxy_nse_free(struct gbproxy_nse *nse)
|
||||||
if (!nse)
|
if (!nse)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
llist_del(&nse->list);
|
hash_del(&nse->list);
|
||||||
|
|
||||||
llist_for_each_entry_safe(bvc, tmp, &nse->bvcs, list)
|
llist_for_each_entry_safe(bvc, tmp, &nse->bvcs, list)
|
||||||
gbproxy_bvc_free(bvc);
|
gbproxy_bvc_free(bvc);
|
||||||
|
@ -326,7 +331,7 @@ struct gbproxy_nse *gbproxy_nse_by_nsei(struct gbproxy_config *cfg, uint16_t nse
|
||||||
struct gbproxy_nse *nse;
|
struct gbproxy_nse *nse;
|
||||||
OSMO_ASSERT(cfg);
|
OSMO_ASSERT(cfg);
|
||||||
|
|
||||||
llist_for_each_entry(nse, &cfg->bss_nses, list) {
|
hash_for_each_possible(cfg->bss_nses, nse, list, nsei) {
|
||||||
if (nse->nsei == nsei)
|
if (nse->nsei == nsei)
|
||||||
return nse;
|
return nse;
|
||||||
}
|
}
|
||||||
|
|
|
@ -422,13 +422,14 @@ DEFUN(cfg_gbproxy_link_list_clean_stale_timer,
|
||||||
"Frequency at which the periodic timer is fired (in seconds)\n")
|
"Frequency at which the periodic timer is fired (in seconds)\n")
|
||||||
{
|
{
|
||||||
struct gbproxy_nse *nse;
|
struct gbproxy_nse *nse;
|
||||||
|
int i;
|
||||||
g_cfg->clean_stale_timer_freq = (unsigned int) atoi(argv[0]);
|
g_cfg->clean_stale_timer_freq = (unsigned int) atoi(argv[0]);
|
||||||
|
|
||||||
/* Re-schedule running timers soon in case prev frequency was really big
|
/* Re-schedule running timers soon in case prev frequency was really big
|
||||||
and new frequency is desired to be lower. After initial run, periodic
|
and new frequency is desired to be lower. After initial run, periodic
|
||||||
time is used. Use random() to avoid firing timers for all bvcs at
|
time is used. Use random() to avoid firing timers for all bvcs at
|
||||||
the same time */
|
the same time */
|
||||||
llist_for_each_entry(nse, &g_cfg->bss_nses, list) {
|
hash_for_each(g_cfg->bss_nses, i, nse, list) {
|
||||||
struct gbproxy_bvc *bvc;
|
struct gbproxy_bvc *bvc;
|
||||||
llist_for_each_entry(bvc, &nse->bvcs, list)
|
llist_for_each_entry(bvc, &nse->bvcs, list)
|
||||||
osmo_timer_schedule(&bvc->clean_stale_timer,
|
osmo_timer_schedule(&bvc->clean_stale_timer,
|
||||||
|
@ -445,9 +446,10 @@ DEFUN(cfg_gbproxy_link_list_no_clean_stale_timer,
|
||||||
|
|
||||||
{
|
{
|
||||||
struct gbproxy_nse *nse;
|
struct gbproxy_nse *nse;
|
||||||
|
int i;
|
||||||
g_cfg->clean_stale_timer_freq = 0;
|
g_cfg->clean_stale_timer_freq = 0;
|
||||||
|
|
||||||
llist_for_each_entry(nse, &g_cfg->bss_nses, list) {
|
hash_for_each(g_cfg->bss_nses, i, nse, list) {
|
||||||
struct gbproxy_bvc *bvc;
|
struct gbproxy_bvc *bvc;
|
||||||
llist_for_each_entry(bvc, &nse->bvcs, list)
|
llist_for_each_entry(bvc, &nse->bvcs, list)
|
||||||
osmo_timer_del(&bvc->clean_stale_timer);
|
osmo_timer_del(&bvc->clean_stale_timer);
|
||||||
|
@ -580,11 +582,12 @@ DEFUN(show_gbproxy, show_gbproxy_cmd, "show gbproxy [stats]",
|
||||||
{
|
{
|
||||||
struct gbproxy_nse *nse;
|
struct gbproxy_nse *nse;
|
||||||
int show_stats = argc >= 1;
|
int show_stats = argc >= 1;
|
||||||
|
int i;
|
||||||
|
|
||||||
if (show_stats)
|
if (show_stats)
|
||||||
vty_out_rate_ctr_group(vty, "", g_cfg->ctrg);
|
vty_out_rate_ctr_group(vty, "", g_cfg->ctrg);
|
||||||
|
|
||||||
llist_for_each_entry(nse, &g_cfg->bss_nses, list) {
|
hash_for_each(g_cfg->bss_nses, i, nse, list) {
|
||||||
struct gbproxy_bvc *bvc;
|
struct gbproxy_bvc *bvc;
|
||||||
llist_for_each_entry(bvc, &nse->bvcs, list) {
|
llist_for_each_entry(bvc, &nse->bvcs, list) {
|
||||||
gbprox_vty_print_bvc(vty, bvc);
|
gbprox_vty_print_bvc(vty, bvc);
|
||||||
|
@ -602,11 +605,12 @@ DEFUN(show_gbproxy_links, show_gbproxy_links_cmd, "show gbproxy links",
|
||||||
struct gbproxy_nse *nse;
|
struct gbproxy_nse *nse;
|
||||||
time_t now;
|
time_t now;
|
||||||
struct timespec ts = {0,};
|
struct timespec ts = {0,};
|
||||||
|
int i;
|
||||||
|
|
||||||
osmo_clock_gettime(CLOCK_MONOTONIC, &ts);
|
osmo_clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||||
now = ts.tv_sec;
|
now = ts.tv_sec;
|
||||||
|
|
||||||
llist_for_each_entry(nse, &g_cfg->bss_nses, list) {
|
hash_for_each(g_cfg->bss_nses, i, nse, list) {
|
||||||
struct gbproxy_bvc *bvc;
|
struct gbproxy_bvc *bvc;
|
||||||
llist_for_each_entry(bvc, &nse->bvcs, list) {
|
llist_for_each_entry(bvc, &nse->bvcs, list) {
|
||||||
struct gbproxy_link_info *link_info;
|
struct gbproxy_link_info *link_info;
|
||||||
|
@ -703,8 +707,9 @@ DEFUN(delete_gb_nsei, delete_gb_nsei_cmd,
|
||||||
} else {
|
} else {
|
||||||
struct gbproxy_nse *nse;
|
struct gbproxy_nse *nse;
|
||||||
struct gbproxy_bvc *bvc;
|
struct gbproxy_bvc *bvc;
|
||||||
|
int i;
|
||||||
counter = 0;
|
counter = 0;
|
||||||
llist_for_each_entry(nse, &g_cfg->bss_nses, list) {
|
hash_for_each(g_cfg->bss_nses, i, nse, list) {
|
||||||
if (nse->nsei != nsei)
|
if (nse->nsei != nsei)
|
||||||
continue;
|
continue;
|
||||||
llist_for_each_entry(bvc, &nse->bvcs, list) {
|
llist_for_each_entry(bvc, &nse->bvcs, list) {
|
||||||
|
|
|
@ -120,7 +120,7 @@ static int dump_peers(FILE *stream, int indent, time_t now,
|
||||||
{
|
{
|
||||||
struct gbproxy_nse *nse;
|
struct gbproxy_nse *nse;
|
||||||
struct gprs_ra_id raid;
|
struct gprs_ra_id raid;
|
||||||
unsigned int i;
|
unsigned int i, _nse;
|
||||||
const struct rate_ctr_group_desc *desc;
|
const struct rate_ctr_group_desc *desc;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
@ -129,7 +129,7 @@ static int dump_peers(FILE *stream, int indent, time_t now,
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
|
|
||||||
llist_for_each_entry(nse, &cfg->bss_nses, list) {
|
hash_for_each(cfg->bss_nses, _nse, nse, list) {
|
||||||
struct gbproxy_bvc *peer;
|
struct gbproxy_bvc *peer;
|
||||||
llist_for_each_entry(peer, &nse->bvcs, list) {
|
llist_for_each_entry(peer, &nse->bvcs, list) {
|
||||||
struct gbproxy_link_info *link_info;
|
struct gbproxy_link_info *link_info;
|
||||||
|
|
Loading…
Reference in New Issue