gb_proxy: Rename gbproxy_peer to gbproxy_bvc

I cannot really read the code while it contains its historical weird
naming.  A "peer" used to be a strange amalgamation of NSE + BVC,
while in reality we can have any number of BVC on top of each NSE.

We recently started to split the peer into a gbproxy_nse_peer + gbproxy_peer.
This takes it one step further and renames gbproxy_peer to gbproxy_bvc,
as that's really what it is.

Change-Id: Iae01067282a6401f6af4cab731202872d2cdb080
This commit is contained in:
Harald Welte 2020-12-04 22:24:47 +01:00
parent 173a182d03
commit 560bdb37cc
8 changed files with 596 additions and 592 deletions

View File

@ -37,7 +37,7 @@ enum gbproxy_global_ctr {
GBPROX_GLOB_CTR_PATCH_PEER_ERR,
};
enum gbproxy_peer_ctr {
enum gbproxy_bvc_ctr {
GBPROX_PEER_CTR_BLOCKED,
GBPROX_PEER_CTR_UNBLOCKED,
GBPROX_PEER_CTR_DROPPED,
@ -102,7 +102,7 @@ struct gbproxy_config {
struct gprs_ns2_inst *nsi;
/* Linked list of all Gb peers (except SGSN) */
struct llist_head nse_peers;
struct llist_head nses;
/* Counter */
struct rate_ctr_group *ctrg;
@ -118,7 +118,7 @@ struct gbproxy_config {
unsigned int clean_stale_timer_freq;
/* If !0, Max age to consider a struct gbproxy_link_info as stale */
int tlli_max_age;
/* If !0, Max len of gbproxy_peer->list (list of struct gbproxy_link_info) */
/* If !0, Max len of gbproxy_bvc->list (list of struct gbproxy_link_info) */
int tlli_max_len;
/* If !0, Max len of gbproxy_link_info->stored_msgs (list of msgb) */
uint32_t stored_msgs_max_len;
@ -147,17 +147,17 @@ struct gbproxy_patch_state {
};
/* One BVC inside an NSE */
struct gbproxy_peer {
/* linked to gbproxy_nse.bts_peers */
struct gbproxy_bvc {
/* linked to gbproxy_nse.bvcs */
struct llist_head list;
/* The peer this BVC belongs to */
/* The NSE this BVC belongs to */
struct gbproxy_nse *nse;
/* BVCI used for Point-to-Point to this peer */
/* PTP BVCI of this BVC */
uint16_t bvci;
/* Routing Area that this peer is part of (raw 04.08 encoding) */
/* Routing Area that this BVC is part of (raw 04.08 encoding) */
uint8_t ra[6];
/* true if this BVC is blocked */
@ -173,19 +173,19 @@ struct gbproxy_peer {
struct osmo_timer_list clean_stale_timer;
};
/* one peer at NS level that we interact with (BSS/PCU) */
/* one NS Entity that we interact with (BSS/PCU) */
struct gbproxy_nse {
/* linked to gbproxy_config.nse_peers */
/* linked to gbproxy_config.nses */
struct llist_head list;
/* point back to the config */
struct gbproxy_config *cfg;
/* NSEI of the peer entity */
/* NSEI of the NSE */
uint16_t nsei;
/* List of all BVCs in this NSE */
struct llist_head bts_peers;
struct llist_head bvcs;
};
struct gbproxy_tlli_state {
@ -205,7 +205,7 @@ struct gbproxy_tlli_state {
/* One TLLI (= UE, = Subscriber) served via this proxy */
struct gbproxy_link_info {
/* link to gbproxy_peer.patch_state.logical_links */
/* link to gbproxy_bvc.patch_state.logical_links */
struct llist_head list;
/* TLLI on the BSS/PCU side */
@ -276,40 +276,40 @@ int gprs_ns2_prim_cb(struct osmo_prim_hdr *oph, void *ctx);
void gbprox_reset(struct gbproxy_config *cfg);
/* TLLI info handling */
void gbproxy_delete_link_infos(struct gbproxy_peer *peer);
void gbproxy_delete_link_infos(struct gbproxy_bvc *bvc);
struct gbproxy_link_info *gbproxy_update_link_state_ul(
struct gbproxy_peer *peer, time_t now,
struct gbproxy_bvc *bvc, time_t now,
struct gprs_gb_parse_context *parse_ctx);
struct gbproxy_link_info *gbproxy_update_link_state_dl(
struct gbproxy_peer *peer, time_t now,
struct gbproxy_bvc *bvc, time_t now,
struct gprs_gb_parse_context *parse_ctx);
int gbproxy_update_link_state_after(
struct gbproxy_peer *peer, struct gbproxy_link_info *link_info,
struct gbproxy_bvc *bvc, struct gbproxy_link_info *link_info,
time_t now, struct gprs_gb_parse_context *parse_ctx);
int gbproxy_remove_stale_link_infos(struct gbproxy_peer *peer, time_t now);
void gbproxy_delete_link_info(struct gbproxy_peer *peer,
int gbproxy_remove_stale_link_infos(struct gbproxy_bvc *bvc, time_t now);
void gbproxy_delete_link_info(struct gbproxy_bvc *bvc,
struct gbproxy_link_info *link_info);
void gbproxy_link_info_discard_messages(struct gbproxy_link_info *link_info);
void gbproxy_attach_link_info(struct gbproxy_peer *peer, time_t now,
void gbproxy_attach_link_info(struct gbproxy_bvc *bvc, time_t now,
struct gbproxy_link_info *link_info);
void gbproxy_update_link_info(struct gbproxy_link_info *link_info,
const uint8_t *imsi, size_t imsi_len);
void gbproxy_detach_link_info(struct gbproxy_peer *peer,
void gbproxy_detach_link_info(struct gbproxy_bvc *bvc,
struct gbproxy_link_info *link_info);
struct gbproxy_link_info *gbproxy_link_info_alloc( struct gbproxy_peer *peer);
struct gbproxy_link_info *gbproxy_link_info_alloc( struct gbproxy_bvc *bvc);
struct gbproxy_link_info *gbproxy_link_info_by_tlli(
struct gbproxy_peer *peer, uint32_t tlli);
struct gbproxy_bvc *bvc, uint32_t tlli);
struct gbproxy_link_info *gbproxy_link_info_by_imsi(
struct gbproxy_peer *peer, const uint8_t *imsi, size_t imsi_len);
struct gbproxy_bvc *bvc, const uint8_t *imsi, size_t imsi_len);
struct gbproxy_link_info *gbproxy_link_info_by_any_sgsn_tlli(
struct gbproxy_peer *peer, uint32_t tlli);
struct gbproxy_bvc *bvc, uint32_t tlli);
struct gbproxy_link_info *gbproxy_link_info_by_sgsn_tlli(
struct gbproxy_peer *peer,
struct gbproxy_bvc *bvc,
uint32_t tlli, uint32_t sgsn_nsei);
struct gbproxy_link_info *gbproxy_link_info_by_ptmsi(
struct gbproxy_peer *peer,
struct gbproxy_bvc *bvc,
uint32_t ptmsi);
int gbproxy_imsi_matches(
@ -320,9 +320,9 @@ uint32_t gbproxy_map_tlli(
uint32_t other_tlli, struct gbproxy_link_info *link_info, int to_bss);
/* needed by gb_proxy_tlli.h */
uint32_t gbproxy_make_bss_ptmsi(struct gbproxy_peer *peer, uint32_t sgsn_ptmsi);
uint32_t gbproxy_make_bss_ptmsi(struct gbproxy_bvc *bvc, uint32_t sgsn_ptmsi);
uint32_t gbproxy_make_sgsn_tlli(
struct gbproxy_peer *peer, struct gbproxy_link_info *link_info,
struct gbproxy_bvc *bvc, struct gbproxy_link_info *link_info,
uint32_t bss_tlli);
void gbproxy_reset_link(struct gbproxy_link_info *link_info);
int gbproxy_check_imsi(
@ -331,12 +331,12 @@ int gbproxy_check_imsi(
/* Message patching */
void gbproxy_patch_bssgp(
struct msgb *msg, uint8_t *bssgp, size_t bssgp_len,
struct gbproxy_peer *peer, struct gbproxy_link_info *link_info,
struct gbproxy_bvc *bvc, struct gbproxy_link_info *link_info,
int *len_change, struct gprs_gb_parse_context *parse_ctx);
int gbproxy_patch_llc(
struct msgb *msg, uint8_t *llc, size_t llc_len,
struct gbproxy_peer *peer, struct gbproxy_link_info *link_info,
struct gbproxy_bvc *bvc, struct gbproxy_link_info *link_info,
int *len_change, struct gprs_gb_parse_context *parse_ctx);
int gbproxy_set_patch_filter(
@ -344,22 +344,22 @@ int gbproxy_set_patch_filter(
void gbproxy_clear_patch_filter(struct gbproxy_match *match);
/* Peer handling */
struct gbproxy_peer *gbproxy_peer_by_bvci(
struct gbproxy_bvc *gbproxy_bvc_by_bvci(
struct gbproxy_config *cfg, uint16_t bvci);
struct gbproxy_peer *gbproxy_peer_by_nsei(
struct gbproxy_bvc *gbproxy_bvc_by_nsei(
struct gbproxy_config *cfg, uint16_t nsei);
struct gbproxy_peer *gbproxy_peer_by_rai(
struct gbproxy_bvc *gbproxy_bvc_by_rai(
struct gbproxy_config *cfg, const uint8_t *ra);
struct gbproxy_peer *gbproxy_peer_by_lai(
struct gbproxy_bvc *gbproxy_bvc_by_lai(
struct gbproxy_config *cfg, const uint8_t *la);
struct gbproxy_peer *gbproxy_peer_by_lac(
struct gbproxy_bvc *gbproxy_bvc_by_lac(
struct gbproxy_config *cfg, const uint8_t *la);
struct gbproxy_peer *gbproxy_peer_by_bssgp_tlv(
struct gbproxy_bvc *gbproxy_bvc_by_bssgp_tlv(
struct gbproxy_config *cfg, struct tlv_parsed *tp);
struct gbproxy_peer *gbproxy_peer_alloc(struct gbproxy_nse *nse, uint16_t bvci);
void gbproxy_peer_free(struct gbproxy_peer *peer);
void gbproxy_peer_move(struct gbproxy_peer *peer, struct gbproxy_nse *nse);
int gbproxy_cleanup_peers(struct gbproxy_config *cfg, uint16_t nsei, uint16_t bvci);
struct gbproxy_bvc *gbproxy_bvc_alloc(struct gbproxy_nse *nse, uint16_t bvci);
void gbproxy_bvc_free(struct gbproxy_bvc *bvc);
void gbproxy_bvc_move(struct gbproxy_bvc *bvc, struct gbproxy_nse *nse);
int gbproxy_cleanup_bvcs(struct gbproxy_config *cfg, uint16_t nsei, uint16_t bvci);
/* NSE handling */
struct gbproxy_nse *gbproxy_nse_alloc(struct gbproxy_config *cfg, uint16_t nsei);

File diff suppressed because it is too large Load Diff

View File

@ -69,7 +69,7 @@ static int get_nsvc_state(struct ctrl_cmd *cmd, void *data)
gprs_ns2_nse_foreach_nsvc(nse, &ctrl_nsvc_state_cb, cmd);
/* NS-VCs for BSS peers */
llist_for_each_entry(nse_peer, &cfg->nse_peers, list) {
llist_for_each_entry(nse_peer, &cfg->nses, list) {
nse = gprs_ns2_nse_by_nsei(nsi, nse_peer->nsei);
if (nse)
gprs_ns2_nse_foreach_nsvc(nse, &ctrl_nsvc_state_cb, cmd);
@ -87,17 +87,17 @@ static int get_gbproxy_state(struct ctrl_cmd *cmd, void *data)
cmd->reply = talloc_strdup(cmd, "");
llist_for_each_entry(nse_peer, &cfg->nse_peers, list) {
struct gbproxy_peer *peer;
llist_for_each_entry(peer, &nse_peer->bts_peers, list) {
llist_for_each_entry(nse_peer, &cfg->nses, list) {
struct gbproxy_bvc *bvc;
llist_for_each_entry(bvc, &nse_peer->bvcs, list) {
struct gprs_ra_id raid;
gsm48_parse_ra(&raid, peer->ra);
gsm48_parse_ra(&raid, bvc->ra);
cmd->reply = talloc_asprintf_append(cmd->reply, "%u,%u,%u,%u,%u,%u,%s\n",
nse_peer->nsei, peer->bvci,
nse_peer->nsei, bvc->bvci,
raid.mcc, raid.mnc,
raid.lac, raid.rac,
peer->blocked ? "BLOCKED" : "UNBLOCKED");
bvc->blocked ? "BLOCKED" : "UNBLOCKED");
}
}
@ -112,8 +112,8 @@ static int get_num_peers(struct ctrl_cmd *cmd, void *data)
struct gbproxy_nse *nse_peer;
uint32_t count = 0;
llist_for_each_entry(nse_peer, &cfg->nse_peers, list)
count += llist_count(&nse_peer->bts_peers);
llist_for_each_entry(nse_peer, &cfg->nses, list)
count += llist_count(&nse_peer->bvcs);
cmd->reply = talloc_strdup(cmd, "");
cmd->reply = talloc_asprintf_append(cmd->reply, "%u", count);

View File

@ -33,20 +33,20 @@
extern void *tall_sgsn_ctx;
/* patch RA identifier in place */
static void gbproxy_patch_raid(struct gsm48_ra_id *raid_enc, struct gbproxy_peer *peer,
static void gbproxy_patch_raid(struct gsm48_ra_id *raid_enc, struct gbproxy_bvc *bvc,
int to_bss, const char *log_text)
{
OSMO_ASSERT(peer);
struct gbproxy_patch_state *state = &peer->patch_state;
OSMO_ASSERT(bvc);
struct gbproxy_patch_state *state = &bvc->patch_state;
struct osmo_plmn_id old_plmn;
struct gprs_ra_id raid;
enum gbproxy_peer_ctr counter =
enum gbproxy_bvc_ctr counter =
to_bss ?
GBPROX_PEER_CTR_RAID_PATCHED_SGSN :
GBPROX_PEER_CTR_RAID_PATCHED_BSS;
OSMO_ASSERT(peer->nse);
struct gbproxy_config *cfg = peer->nse->cfg;
OSMO_ASSERT(bvc->nse);
struct gbproxy_config *cfg = bvc->nse->cfg;
OSMO_ASSERT(cfg);
if (!state->local_plmn.mcc || !state->local_plmn.mnc)
@ -80,7 +80,7 @@ static void gbproxy_patch_raid(struct gsm48_ra_id *raid_enc, struct gbproxy_peer
}
}
LOGPBVC(peer, LOGL_DEBUG,
LOGPBVC(bvc, LOGL_DEBUG,
"Patching %s to %s: "
"%s-%d-%d -> %s\n",
log_text,
@ -89,12 +89,12 @@ static void gbproxy_patch_raid(struct gsm48_ra_id *raid_enc, struct gbproxy_peer
osmo_rai_name(&raid));
gsm48_encode_ra(raid_enc, &raid);
rate_ctr_inc(&peer->ctrg->ctr[counter]);
rate_ctr_inc(&bvc->ctrg->ctr[counter]);
}
static void gbproxy_patch_apn_ie(struct msgb *msg,
uint8_t *apn_ie, size_t apn_ie_len,
struct gbproxy_peer *peer,
struct gbproxy_bvc *bvc,
size_t *new_apn_ie_len, const char *log_text)
{
struct apn_ie_hdr {
@ -105,9 +105,9 @@ static void gbproxy_patch_apn_ie(struct msgb *msg,
size_t apn_len = hdr->apn_len;
uint8_t *apn = hdr->apn;
OSMO_ASSERT(peer);
OSMO_ASSERT(peer->nse);
struct gbproxy_config *cfg = peer->nse->cfg;
OSMO_ASSERT(bvc);
OSMO_ASSERT(bvc->nse);
struct gbproxy_config *cfg = bvc->nse->cfg;
OSMO_ASSERT(cfg);
OSMO_ASSERT(apn_ie_len == apn_len + sizeof(struct apn_ie_hdr));
@ -116,7 +116,7 @@ static void gbproxy_patch_apn_ie(struct msgb *msg,
if (cfg->core_apn_size == 0) {
char str1[110];
/* Remove the IE */
LOGPBVC(peer, LOGL_DEBUG,
LOGPBVC(bvc, LOGL_DEBUG,
"Patching %s to SGSN: Removing APN '%s'\n",
log_text,
osmo_apn_to_str(str1, apn, apn_len));
@ -130,7 +130,7 @@ static void gbproxy_patch_apn_ie(struct msgb *msg,
OSMO_ASSERT(cfg->core_apn_size <= 100);
LOGPBVC(peer, LOGL_DEBUG,
LOGPBVC(bvc, LOGL_DEBUG,
"Patching %s to SGSN: "
"Replacing APN '%s' -> '%s'\n",
log_text,
@ -144,21 +144,21 @@ static void gbproxy_patch_apn_ie(struct msgb *msg,
hdr->apn_len = cfg->core_apn_size;
}
rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_APN_PATCHED]);
rate_ctr_inc(&bvc->ctrg->ctr[GBPROX_PEER_CTR_APN_PATCHED]);
}
static int gbproxy_patch_tlli(uint8_t *tlli_enc,
struct gbproxy_peer *peer,
struct gbproxy_bvc *bvc,
uint32_t new_tlli,
int to_bss, const char *log_text)
{
uint32_t tlli_be;
uint32_t tlli;
enum gbproxy_peer_ctr counter =
enum gbproxy_bvc_ctr counter =
to_bss ?
GBPROX_PEER_CTR_TLLI_PATCHED_SGSN :
GBPROX_PEER_CTR_TLLI_PATCHED_BSS;
OSMO_ASSERT(peer);
OSMO_ASSERT(bvc);
memcpy(&tlli_be, tlli_enc, sizeof(tlli_be));
tlli = ntohl(tlli_be);
@ -166,7 +166,7 @@ static int gbproxy_patch_tlli(uint8_t *tlli_enc,
if (tlli == new_tlli)
return 0;
LOGPBVC(peer, LOGL_DEBUG,
LOGPBVC(bvc, LOGL_DEBUG,
"Patching %ss: "
"Replacing %08x -> %08x\n",
log_text, tlli, new_tlli);
@ -174,23 +174,23 @@ static int gbproxy_patch_tlli(uint8_t *tlli_enc,
tlli_be = htonl(new_tlli);
memcpy(tlli_enc, &tlli_be, sizeof(tlli_be));
rate_ctr_inc(&peer->ctrg->ctr[counter]);
rate_ctr_inc(&bvc->ctrg->ctr[counter]);
return 1;
}
static int gbproxy_patch_ptmsi(uint8_t *ptmsi_enc,
struct gbproxy_peer *peer,
struct gbproxy_bvc *bvc,
uint32_t new_ptmsi,
int to_bss, const char *log_text)
{
uint32_t ptmsi_be;
uint32_t ptmsi;
enum gbproxy_peer_ctr counter =
enum gbproxy_bvc_ctr counter =
to_bss ?
GBPROX_PEER_CTR_PTMSI_PATCHED_SGSN :
GBPROX_PEER_CTR_PTMSI_PATCHED_BSS;
OSMO_ASSERT(peer);
OSMO_ASSERT(bvc);
memcpy(&ptmsi_be, ptmsi_enc, sizeof(ptmsi_be));
ptmsi = ntohl(ptmsi_be);
@ -198,7 +198,7 @@ static int gbproxy_patch_ptmsi(uint8_t *ptmsi_enc,
if (ptmsi == new_ptmsi)
return 0;
LOGPBVC(peer, LOGL_DEBUG,
LOGPBVC(bvc, LOGL_DEBUG,
"Patching %ss: "
"Replacing %08x -> %08x\n",
log_text, ptmsi, new_ptmsi);
@ -206,22 +206,22 @@ static int gbproxy_patch_ptmsi(uint8_t *ptmsi_enc,
ptmsi_be = htonl(new_ptmsi);
memcpy(ptmsi_enc, &ptmsi_be, sizeof(ptmsi_be));
rate_ctr_inc(&peer->ctrg->ctr[counter]);
rate_ctr_inc(&bvc->ctrg->ctr[counter]);
return 1;
}
int gbproxy_patch_llc(struct msgb *msg, uint8_t *llc, size_t llc_len,
struct gbproxy_peer *peer,
struct gbproxy_bvc *bvc,
struct gbproxy_link_info *link_info, int *len_change,
struct gprs_gb_parse_context *parse_ctx)
{
struct gprs_llc_hdr_parsed *ghp = &parse_ctx->llc_hdr_parsed;
int have_patched = 0;
int fcs;
OSMO_ASSERT(peer);
OSMO_ASSERT(peer->nse);
struct gbproxy_config *cfg = peer->nse->cfg;
OSMO_ASSERT(bvc);
OSMO_ASSERT(bvc->nse);
struct gbproxy_config *cfg = bvc->nse->cfg;
OSMO_ASSERT(cfg);
if (parse_ctx->ptmsi_enc && link_info &&
@ -233,7 +233,7 @@ int gbproxy_patch_llc(struct msgb *msg, uint8_t *llc, size_t llc_len,
ptmsi = link_info->sgsn_tlli.ptmsi;
if (ptmsi != GSM_RESERVED_TMSI) {
if (gbproxy_patch_ptmsi(parse_ctx->ptmsi_enc, peer,
if (gbproxy_patch_ptmsi(parse_ctx->ptmsi_enc, bvc,
ptmsi, parse_ctx->to_bss, "P-TMSI"))
have_patched = 1;
} else {
@ -249,20 +249,20 @@ int gbproxy_patch_llc(struct msgb *msg, uint8_t *llc, size_t llc_len,
ptmsi = link_info->sgsn_tlli.ptmsi;
OSMO_ASSERT(ptmsi);
if (gbproxy_patch_ptmsi(parse_ctx->new_ptmsi_enc, peer,
if (gbproxy_patch_ptmsi(parse_ctx->new_ptmsi_enc, bvc,
ptmsi, parse_ctx->to_bss, "new P-TMSI"))
have_patched = 1;
}
if (parse_ctx->raid_enc) {
gbproxy_patch_raid((struct gsm48_ra_id *)parse_ctx->raid_enc, peer, parse_ctx->to_bss,
gbproxy_patch_raid((struct gsm48_ra_id *)parse_ctx->raid_enc, bvc, parse_ctx->to_bss,
parse_ctx->llc_msg_name);
have_patched = 1;
}
if (parse_ctx->old_raid_enc && !parse_ctx->old_raid_is_foreign) {
/* TODO: Patch to invalid if P-TMSI unknown. */
gbproxy_patch_raid((struct gsm48_ra_id *)parse_ctx->old_raid_enc, peer, parse_ctx->to_bss,
gbproxy_patch_raid((struct gsm48_ra_id *)parse_ctx->old_raid_enc, bvc, parse_ctx->to_bss,
parse_ctx->llc_msg_name);
have_patched = 1;
}
@ -275,7 +275,7 @@ int gbproxy_patch_llc(struct msgb *msg, uint8_t *llc, size_t llc_len,
size_t new_len;
gbproxy_patch_apn_ie(msg,
parse_ctx->apn_ie, parse_ctx->apn_ie_len,
peer, &new_len, parse_ctx->llc_msg_name);
bvc, &new_len, parse_ctx->llc_msg_name);
*len_change += (int)new_len - (int)parse_ctx->apn_ie_len;
have_patched = 1;
@ -287,7 +287,7 @@ int gbproxy_patch_llc(struct msgb *msg, uint8_t *llc, size_t llc_len,
/* Fix FCS */
fcs = gprs_llc_fcs(llc, ghp->crc_length);
LOGPBVC_CAT(peer, DLLC, LOGL_DEBUG, "Updated LLC message, CRC: %06x -> %06x\n",
LOGPBVC_CAT(bvc, DLLC, LOGL_DEBUG, "Updated LLC message, CRC: %06x -> %06x\n",
ghp->fcs, fcs);
llc[llc_len - 3] = fcs & 0xff;
@ -300,18 +300,18 @@ int gbproxy_patch_llc(struct msgb *msg, uint8_t *llc, size_t llc_len,
/* patch BSSGP message to use core_plmn.mcc/mnc on the SGSN side */
void gbproxy_patch_bssgp(struct msgb *msg, uint8_t *bssgp, size_t bssgp_len,
struct gbproxy_peer *peer,
struct gbproxy_bvc *bvc,
struct gbproxy_link_info *link_info, int *len_change,
struct gprs_gb_parse_context *parse_ctx)
{
const char *err_info = NULL;
int err_ctr = -1;
OSMO_ASSERT(peer->nse);
struct gbproxy_config *cfg = peer->nse->cfg;
OSMO_ASSERT(bvc->nse);
struct gbproxy_config *cfg = bvc->nse->cfg;
OSMO_ASSERT(cfg);
if (parse_ctx->bssgp_raid_enc)
gbproxy_patch_raid((struct gsm48_ra_id *)parse_ctx->bssgp_raid_enc, peer,
gbproxy_patch_raid((struct gsm48_ra_id *)parse_ctx->bssgp_raid_enc, bvc,
parse_ctx->to_bss, "BSSGP");
if (parse_ctx->need_decryption &&
@ -342,7 +342,7 @@ void gbproxy_patch_bssgp(struct msgb *msg, uint8_t *bssgp, size_t bssgp_len,
link_info, parse_ctx->to_bss);
if (tlli) {
gbproxy_patch_tlli(parse_ctx->tlli_enc, peer, tlli,
gbproxy_patch_tlli(parse_ctx->tlli_enc, bvc, tlli,
parse_ctx->to_bss, "TLLI");
parse_ctx->tlli = tlli;
} else {
@ -362,7 +362,7 @@ void gbproxy_patch_bssgp(struct msgb *msg, uint8_t *bssgp, size_t bssgp_len,
if (ptmsi != GSM_RESERVED_TMSI)
gbproxy_patch_ptmsi(
parse_ctx->bssgp_ptmsi_enc, peer,
parse_ctx->bssgp_ptmsi_enc, bvc,
ptmsi, parse_ctx->to_bss, "BSSGP P-TMSI");
}
@ -371,7 +371,7 @@ void gbproxy_patch_bssgp(struct msgb *msg, uint8_t *bssgp, size_t bssgp_len,
size_t llc_len = parse_ctx->llc_len;
int llc_len_change = 0;
gbproxy_patch_llc(msg, llc, llc_len, peer, link_info,
gbproxy_patch_llc(msg, llc, llc_len, bvc, link_info,
&llc_len_change, parse_ctx);
/* Note that the APN might have been resized here, but no
* pointer int the parse_ctx will refer to an adress after the
@ -406,8 +406,8 @@ void gbproxy_patch_bssgp(struct msgb *msg, uint8_t *bssgp, size_t bssgp_len,
patch_error:
OSMO_ASSERT(err_ctr >= 0);
rate_ctr_inc(&peer->ctrg->ctr[err_ctr]);
LOGPBVC(peer, LOGL_ERROR,
rate_ctr_inc(&bvc->ctrg->ctr[err_ctr]);
LOGPBVC(bvc, LOGL_ERROR,
"NSE(%05u/%s) failed to patch BSSGP message as requested: %s.\n",
msgb_nsei(msg), parse_ctx->to_bss ? "SGSN" : "BSS",
err_info);

View File

@ -35,7 +35,7 @@
extern void *tall_sgsn_ctx;
static const struct rate_ctr_desc peer_ctr_description[] = {
static const struct rate_ctr_desc bvc_ctr_description[] = {
{ "blocked", "BVC Block " },
{ "unblocked", "BVC Unblock " },
{ "dropped", "BVC blocked, dropped packet " },
@ -71,98 +71,98 @@ static const struct rate_ctr_desc peer_ctr_description[] = {
{ "tlli-cache", "TLLI cache size " },
};
osmo_static_assert(ARRAY_SIZE(peer_ctr_description) == GBPROX_PEER_CTR_LAST, everything_described);
osmo_static_assert(ARRAY_SIZE(bvc_ctr_description) == GBPROX_PEER_CTR_LAST, everything_described);
static const struct rate_ctr_group_desc peer_ctrg_desc = {
static const struct rate_ctr_group_desc bvc_ctrg_desc = {
.group_name_prefix = "gbproxy:peer",
.group_description = "GBProxy Peer Statistics",
.num_ctr = ARRAY_SIZE(peer_ctr_description),
.ctr_desc = peer_ctr_description,
.num_ctr = ARRAY_SIZE(bvc_ctr_description),
.ctr_desc = bvc_ctr_description,
.class_id = OSMO_STATS_CLASS_PEER,
};
/* Find the gbproxy_peer by its BVCI. There can only be one match */
struct gbproxy_peer *gbproxy_peer_by_bvci(struct gbproxy_config *cfg, uint16_t bvci)
/* Find the gbproxy_bvc by its BVCI. There can only be one match */
struct gbproxy_bvc *gbproxy_bvc_by_bvci(struct gbproxy_config *cfg, uint16_t bvci)
{
struct gbproxy_nse *nse;
llist_for_each_entry(nse, &cfg->nse_peers, list) {
struct gbproxy_peer *peer;
llist_for_each_entry(peer, &nse->bts_peers, list) {
if (peer->bvci == bvci)
return peer;
llist_for_each_entry(nse, &cfg->nses, list) {
struct gbproxy_bvc *bvc;
llist_for_each_entry(bvc, &nse->bvcs, list) {
if (bvc->bvci == bvci)
return bvc;
}
}
return NULL;
}
/* Find the gbproxy_peer by its NSEI */
/* FIXME: Only returns the first peer, but we could have multiple on this nsei */
struct gbproxy_peer *gbproxy_peer_by_nsei(struct gbproxy_config *cfg,
/* Find the gbproxy_bvc by its NSEI */
/* FIXME: Only returns the first bvc, but we could have multiple on this nsei */
struct gbproxy_bvc *gbproxy_bvc_by_nsei(struct gbproxy_config *cfg,
uint16_t nsei)
{
struct gbproxy_nse *nse;
llist_for_each_entry(nse, &cfg->nse_peers, list) {
if (nse->nsei == nsei && !llist_empty(&nse->bts_peers))
return llist_first_entry(&nse->bts_peers, struct gbproxy_peer, list);
llist_for_each_entry(nse, &cfg->nses, list) {
if (nse->nsei == nsei && !llist_empty(&nse->bvcs))
return llist_first_entry(&nse->bvcs, struct gbproxy_bvc, list);
}
return NULL;
}
/* look-up a peer by its Routeing Area Identification (RAI) */
/* FIXME: this doesn't make sense, as RA can span multiple peers! */
struct gbproxy_peer *gbproxy_peer_by_rai(struct gbproxy_config *cfg,
/* look-up a bvc by its Routeing Area Identification (RAI) */
/* FIXME: this doesn't make sense, as RA can span multiple bvcs! */
struct gbproxy_bvc *gbproxy_bvc_by_rai(struct gbproxy_config *cfg,
const uint8_t *ra)
{
struct gbproxy_nse *nse;
llist_for_each_entry(nse, &cfg->nse_peers, list) {
struct gbproxy_peer *peer;
llist_for_each_entry(peer, &nse->bts_peers, list) {
if (!memcmp(peer->ra, ra, 6))
return peer;
llist_for_each_entry(nse, &cfg->nses, list) {
struct gbproxy_bvc *bvc;
llist_for_each_entry(bvc, &nse->bvcs, list) {
if (!memcmp(bvc->ra, ra, 6))
return bvc;
}
}
return NULL;
}
/* look-up a peer by its Location Area Identification (LAI) */
/* FIXME: this doesn't make sense, as LA can span multiple peers! */
struct gbproxy_peer *gbproxy_peer_by_lai(struct gbproxy_config *cfg,
/* look-up a bvc by its Location Area Identification (LAI) */
/* FIXME: this doesn't make sense, as LA can span multiple bvcs! */
struct gbproxy_bvc *gbproxy_bvc_by_lai(struct gbproxy_config *cfg,
const uint8_t *la)
{
struct gbproxy_nse *nse;
llist_for_each_entry(nse, &cfg->nse_peers, list) {
struct gbproxy_peer *peer;
llist_for_each_entry(peer, &nse->bts_peers, list) {
if (!memcmp(peer->ra, la, 5))
return peer;
llist_for_each_entry(nse, &cfg->nses, list) {
struct gbproxy_bvc *bvc;
llist_for_each_entry(bvc, &nse->bvcs, list) {
if (!memcmp(bvc->ra, la, 5))
return bvc;
}
}
return NULL;
}
/* look-up a peer by its Location Area Code (LAC) */
/* FIXME: this doesn't make sense, as LAC can span multiple peers! */
struct gbproxy_peer *gbproxy_peer_by_lac(struct gbproxy_config *cfg,
/* look-up a bvc by its Location Area Code (LAC) */
/* FIXME: this doesn't make sense, as LAC can span multiple bvcs! */
struct gbproxy_bvc *gbproxy_bvc_by_lac(struct gbproxy_config *cfg,
const uint8_t *la)
{
struct gbproxy_nse *nse;
llist_for_each_entry(nse, &cfg->nse_peers, list) {
struct gbproxy_peer *peer;
llist_for_each_entry(peer, &nse->bts_peers, list) {
if (!memcmp(peer->ra + 3, la + 3, 2))
return peer;
llist_for_each_entry(nse, &cfg->nses, list) {
struct gbproxy_bvc *bvc;
llist_for_each_entry(bvc, &nse->bvcs, list) {
if (!memcmp(bvc->ra + 3, la + 3, 2))
return bvc;
}
}
return NULL;
}
struct gbproxy_peer *gbproxy_peer_by_bssgp_tlv(struct gbproxy_config *cfg,
struct gbproxy_bvc *gbproxy_bvc_by_bssgp_tlv(struct gbproxy_config *cfg,
struct tlv_parsed *tp)
{
if (TLVP_PRES_LEN(tp, BSSGP_IE_BVCI, 2)) {
@ -170,22 +170,22 @@ struct gbproxy_peer *gbproxy_peer_by_bssgp_tlv(struct gbproxy_config *cfg,
bvci = ntohs(tlvp_val16_unal(tp, BSSGP_IE_BVCI));
if (bvci >= 2)
return gbproxy_peer_by_bvci(cfg, bvci);
return gbproxy_bvc_by_bvci(cfg, bvci);
}
/* FIXME: this doesn't make sense, as RA can span multiple peers! */
/* FIXME: this doesn't make sense, as RA can span multiple bvcs! */
if (TLVP_PRES_LEN(tp, BSSGP_IE_ROUTEING_AREA, 6)) {
uint8_t *rai = (uint8_t *)TLVP_VAL(tp, BSSGP_IE_ROUTEING_AREA);
/* Only compare LAC part, since MCC/MNC are possibly patched.
* Since the LAC of different BSS must be different when
* MCC/MNC are patched, collisions shouldn't happen. */
return gbproxy_peer_by_lac(cfg, rai);
return gbproxy_bvc_by_lac(cfg, rai);
}
/* FIXME: this doesn't make sense, as LA can span multiple peers! */
/* FIXME: this doesn't make sense, as LA can span multiple bvcs! */
if (TLVP_PRES_LEN(tp, BSSGP_IE_LOCATION_AREA, 5)) {
uint8_t *lai = (uint8_t *)TLVP_VAL(tp, BSSGP_IE_LOCATION_AREA);
return gbproxy_peer_by_lac(cfg, lai);
return gbproxy_bvc_by_lac(cfg, lai);
}
return NULL;
@ -195,88 +195,92 @@ static void clean_stale_timer_cb(void *data)
{
time_t now;
struct timespec ts = {0,};
struct gbproxy_peer *peer = (struct gbproxy_peer *) data;
OSMO_ASSERT(peer);
OSMO_ASSERT(peer->nse);
struct gbproxy_config *cfg = peer->nse->cfg;
struct gbproxy_bvc *bvc = (struct gbproxy_bvc *) data;
OSMO_ASSERT(bvc);
OSMO_ASSERT(bvc->nse);
struct gbproxy_config *cfg = bvc->nse->cfg;
OSMO_ASSERT(cfg);
osmo_clock_gettime(CLOCK_MONOTONIC, &ts);
now = ts.tv_sec;
gbproxy_remove_stale_link_infos(peer, now);
gbproxy_remove_stale_link_infos(bvc, now);
if (cfg->clean_stale_timer_freq != 0)
osmo_timer_schedule(&peer->clean_stale_timer,
osmo_timer_schedule(&bvc->clean_stale_timer,
cfg->clean_stale_timer_freq, 0);
}
struct gbproxy_peer *gbproxy_peer_alloc(struct gbproxy_nse *nse, uint16_t bvci)
struct gbproxy_bvc *gbproxy_bvc_alloc(struct gbproxy_nse *nse, uint16_t bvci)
{
struct gbproxy_peer *peer;
struct gbproxy_bvc *bvc;
OSMO_ASSERT(nse);
struct gbproxy_config *cfg = nse->cfg;
OSMO_ASSERT(cfg);
peer = talloc_zero(tall_sgsn_ctx, struct gbproxy_peer);
if (!peer)
bvc = talloc_zero(tall_sgsn_ctx, struct gbproxy_bvc);
if (!bvc)
return NULL;
peer->bvci = bvci;
peer->ctrg = rate_ctr_group_alloc(peer, &peer_ctrg_desc, bvci);
if (!peer->ctrg) {
talloc_free(peer);
bvc->bvci = bvci;
bvc->ctrg = rate_ctr_group_alloc(bvc, &bvc_ctrg_desc, bvci);
if (!bvc->ctrg) {
talloc_free(bvc);
return NULL;
}
peer->nse = nse;
bvc->nse = nse;
llist_add(&peer->list, &nse->bts_peers);
llist_add(&bvc->list, &nse->bvcs);
INIT_LLIST_HEAD(&peer->patch_state.logical_links);
INIT_LLIST_HEAD(&bvc->patch_state.logical_links);
osmo_timer_setup(&peer->clean_stale_timer, clean_stale_timer_cb, peer);
osmo_timer_setup(&bvc->clean_stale_timer, clean_stale_timer_cb, bvc);
if (cfg->clean_stale_timer_freq != 0)
osmo_timer_schedule(&peer->clean_stale_timer,
osmo_timer_schedule(&bvc->clean_stale_timer,
cfg->clean_stale_timer_freq, 0);
return peer;
return bvc;
}
void gbproxy_peer_free(struct gbproxy_peer *peer)
void gbproxy_bvc_free(struct gbproxy_bvc *bvc)
{
if (!peer)
if (!bvc)
return;
llist_del(&peer->list);
osmo_timer_del(&peer->clean_stale_timer);
gbproxy_delete_link_infos(peer);
llist_del(&bvc->list);
osmo_timer_del(&bvc->clean_stale_timer);
gbproxy_delete_link_infos(bvc);
rate_ctr_group_free(peer->ctrg);
peer->ctrg = NULL;
rate_ctr_group_free(bvc->ctrg);
bvc->ctrg = NULL;
talloc_free(peer);
talloc_free(bvc);
}
void gbproxy_peer_move(struct gbproxy_peer *peer, struct gbproxy_nse *nse)
void gbproxy_bvc_move(struct gbproxy_bvc *bvc, struct gbproxy_nse *nse)
{
llist_del(&peer->list);
llist_add(&peer->list, &nse->bts_peers);
peer->nse = nse;
llist_del(&bvc->list);
llist_add(&bvc->list, &nse->bvcs);
bvc->nse = nse;
}
int gbproxy_cleanup_peers(struct gbproxy_config *cfg, uint16_t nsei, uint16_t bvci)
/*! remove bvcs (BVCs) on NSE specified by NSEI.
* \param[in] cfg proxy in which we operate
* \param[in] nsei NS entity in which we should 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 counter = 0;
struct gbproxy_nse *nse, *ntmp;
OSMO_ASSERT(cfg);
llist_for_each_entry_safe(nse, ntmp, &cfg->nse_peers, list) {
struct gbproxy_peer *peer, *tmp;
llist_for_each_entry_safe(nse, ntmp, &cfg->nses, list) {
struct gbproxy_bvc *bvc, *tmp;
if (nse->nsei != nsei)
continue;
llist_for_each_entry_safe(peer, tmp, &nse->bts_peers, list) {
if (bvci && peer->bvci != bvci)
llist_for_each_entry_safe(bvc, tmp, &nse->bvcs, list) {
if (bvci && bvc->bvci != bvci)
continue;
gbproxy_peer_free(peer);
gbproxy_bvc_free(bvc);
counter += 1;
}
}
@ -296,23 +300,23 @@ struct gbproxy_nse *gbproxy_nse_alloc(struct gbproxy_config *cfg, uint16_t nsei)
nse->nsei = nsei;
nse->cfg = cfg;
llist_add(&nse->list, &cfg->nse_peers);
llist_add(&nse->list, &cfg->nses);
INIT_LLIST_HEAD(&nse->bts_peers);
INIT_LLIST_HEAD(&nse->bvcs);
return nse;
}
void gbproxy_nse_free(struct gbproxy_nse *nse)
{
struct gbproxy_peer *peer, *tmp;
struct gbproxy_bvc *bvc, *tmp;
if (!nse)
return;
llist_del(&nse->list);
llist_for_each_entry_safe(peer, tmp, &nse->bts_peers, list)
gbproxy_peer_free(peer);
llist_for_each_entry_safe(bvc, tmp, &nse->bvcs, list)
gbproxy_bvc_free(bvc);
talloc_free(nse);
}
@ -322,7 +326,7 @@ struct gbproxy_nse *gbproxy_nse_by_nsei(struct gbproxy_config *cfg, uint16_t nse
struct gbproxy_nse *nse;
OSMO_ASSERT(cfg);
llist_for_each_entry(nse, &cfg->nse_peers, list) {
llist_for_each_entry(nse, &cfg->nses, list) {
if (nse->nsei == nsei)
return nse;
}
@ -340,4 +344,4 @@ struct gbproxy_nse *gbproxy_nse_by_nsei_or_new(struct gbproxy_config *cfg, uint1
nse = gbproxy_nse_alloc(cfg, nsei);
return nse;
}
}

View File

@ -32,11 +32,11 @@
#include <osmocom/core/rate_ctr.h>
#include <osmocom/core/talloc.h>
struct gbproxy_link_info *gbproxy_link_info_by_tlli(struct gbproxy_peer *peer,
struct gbproxy_link_info *gbproxy_link_info_by_tlli(struct gbproxy_bvc *bvc,
uint32_t tlli)
{
struct gbproxy_link_info *link_info;
struct gbproxy_patch_state *state = &peer->patch_state;
struct gbproxy_patch_state *state = &bvc->patch_state;
if (!tlli)
return NULL;
@ -50,11 +50,11 @@ struct gbproxy_link_info *gbproxy_link_info_by_tlli(struct gbproxy_peer *peer,
}
struct gbproxy_link_info *gbproxy_link_info_by_ptmsi(
struct gbproxy_peer *peer,
struct gbproxy_bvc *bvc,
uint32_t ptmsi)
{
struct gbproxy_link_info *link_info;
struct gbproxy_patch_state *state = &peer->patch_state;
struct gbproxy_patch_state *state = &bvc->patch_state;
if (ptmsi == GSM_RESERVED_TMSI)
return NULL;
@ -67,11 +67,11 @@ struct gbproxy_link_info *gbproxy_link_info_by_ptmsi(
}
struct gbproxy_link_info *gbproxy_link_info_by_any_sgsn_tlli(
struct gbproxy_peer *peer,
struct gbproxy_bvc *bvc,
uint32_t tlli)
{
struct gbproxy_link_info *link_info;
struct gbproxy_patch_state *state = &peer->patch_state;
struct gbproxy_patch_state *state = &bvc->patch_state;
if (!tlli)
return NULL;
@ -86,11 +86,11 @@ struct gbproxy_link_info *gbproxy_link_info_by_any_sgsn_tlli(
}
struct gbproxy_link_info *gbproxy_link_info_by_sgsn_tlli(
struct gbproxy_peer *peer,
struct gbproxy_bvc *bvc,
uint32_t tlli, uint32_t sgsn_nsei)
{
struct gbproxy_link_info *link_info;
struct gbproxy_patch_state *state = &peer->patch_state;
struct gbproxy_patch_state *state = &bvc->patch_state;
if (!tlli)
return NULL;
@ -105,12 +105,12 @@ struct gbproxy_link_info *gbproxy_link_info_by_sgsn_tlli(
}
struct gbproxy_link_info *gbproxy_link_info_by_imsi(
struct gbproxy_peer *peer,
struct gbproxy_bvc *bvc,
const uint8_t *imsi,
size_t imsi_len)
{
struct gbproxy_link_info *link_info;
struct gbproxy_patch_state *state = &peer->patch_state;
struct gbproxy_patch_state *state = &bvc->patch_state;
if (!gprs_is_mi_imsi(imsi, imsi_len))
return NULL;
@ -137,10 +137,10 @@ void gbproxy_link_info_discard_messages(struct gbproxy_link_info *link_info)
}
}
void gbproxy_delete_link_info(struct gbproxy_peer *peer,
void gbproxy_delete_link_info(struct gbproxy_bvc *bvc,
struct gbproxy_link_info *link_info)
{
struct gbproxy_patch_state *state = &peer->patch_state;
struct gbproxy_patch_state *state = &bvc->patch_state;
gbproxy_link_info_discard_messages(link_info);
@ -148,44 +148,44 @@ void gbproxy_delete_link_info(struct gbproxy_peer *peer,
talloc_free(link_info);
state->logical_link_count -= 1;
peer->ctrg->ctr[GBPROX_PEER_CTR_TLLI_CACHE_SIZE].current =
bvc->ctrg->ctr[GBPROX_PEER_CTR_TLLI_CACHE_SIZE].current =
state->logical_link_count;
}
void gbproxy_delete_link_infos(struct gbproxy_peer *peer)
void gbproxy_delete_link_infos(struct gbproxy_bvc *bvc)
{
struct gbproxy_link_info *link_info, *nxt;
struct gbproxy_patch_state *state = &peer->patch_state;
struct gbproxy_patch_state *state = &bvc->patch_state;
llist_for_each_entry_safe(link_info, nxt, &state->logical_links, list)
gbproxy_delete_link_info(peer, link_info);
gbproxy_delete_link_info(bvc, link_info);
OSMO_ASSERT(state->logical_link_count == 0);
OSMO_ASSERT(llist_empty(&state->logical_links));
}
void gbproxy_attach_link_info(struct gbproxy_peer *peer, time_t now,
void gbproxy_attach_link_info(struct gbproxy_bvc *bvc, time_t now,
struct gbproxy_link_info *link_info)
{
struct gbproxy_patch_state *state = &peer->patch_state;
struct gbproxy_patch_state *state = &bvc->patch_state;
link_info->timestamp = now;
llist_add(&link_info->list, &state->logical_links);
state->logical_link_count += 1;
peer->ctrg->ctr[GBPROX_PEER_CTR_TLLI_CACHE_SIZE].current =
bvc->ctrg->ctr[GBPROX_PEER_CTR_TLLI_CACHE_SIZE].current =
state->logical_link_count;
}
int gbproxy_remove_stale_link_infos(struct gbproxy_peer *peer, time_t now)
int gbproxy_remove_stale_link_infos(struct gbproxy_bvc *bvc, time_t now)
{
OSMO_ASSERT(peer);
struct gbproxy_patch_state *state = &peer->patch_state;
OSMO_ASSERT(bvc);
struct gbproxy_patch_state *state = &bvc->patch_state;
int exceeded_max_len = 0;
int deleted_count = 0;
int check_for_age;
OSMO_ASSERT(peer->nse);
struct gbproxy_config *cfg = peer->nse->cfg;
OSMO_ASSERT(bvc->nse);
struct gbproxy_config *cfg = bvc->nse->cfg;
OSMO_ASSERT(cfg);
if (cfg->tlli_max_len > 0)
@ -200,12 +200,12 @@ int gbproxy_remove_stale_link_infos(struct gbproxy_peer *peer, time_t now)
link_info = llist_entry(state->logical_links.prev,
struct gbproxy_link_info,
list);
LOGPBVC(peer, LOGL_INFO,
LOGPBVC(bvc, LOGL_INFO,
"Removing TLLI %08x from list "
"(stale, length %d, max_len exceeded)\n",
link_info->tlli.current, state->logical_link_count);
gbproxy_delete_link_info(peer, link_info);
gbproxy_delete_link_info(bvc, link_info);
deleted_count += 1;
}
@ -222,23 +222,23 @@ int gbproxy_remove_stale_link_infos(struct gbproxy_peer *peer, time_t now)
continue;
}
LOGPBVC(peer, LOGL_INFO,
LOGPBVC(bvc, LOGL_INFO,
"Removing TLLI %08x from list "
"(stale, age %d, max_age exceeded)\n",
link_info->tlli.current, (int)age);
gbproxy_delete_link_info(peer, link_info);
gbproxy_delete_link_info(bvc, link_info);
deleted_count += 1;
}
return deleted_count;
}
struct gbproxy_link_info *gbproxy_link_info_alloc( struct gbproxy_peer *peer)
struct gbproxy_link_info *gbproxy_link_info_alloc( struct gbproxy_bvc *bvc)
{
struct gbproxy_link_info *link_info;
link_info = talloc_zero(peer, struct gbproxy_link_info);
link_info = talloc_zero(bvc, struct gbproxy_link_info);
link_info->tlli.ptmsi = GSM_RESERVED_TMSI;
link_info->sgsn_tlli.ptmsi = GSM_RESERVED_TMSI;
@ -250,16 +250,16 @@ struct gbproxy_link_info *gbproxy_link_info_alloc( struct gbproxy_peer *peer)
}
void gbproxy_detach_link_info(
struct gbproxy_peer *peer,
struct gbproxy_bvc *bvc,
struct gbproxy_link_info *link_info)
{
struct gbproxy_patch_state *state = &peer->patch_state;
struct gbproxy_patch_state *state = &bvc->patch_state;
llist_del(&link_info->list);
OSMO_ASSERT(state->logical_link_count > 0);
state->logical_link_count -= 1;
peer->ctrg->ctr[GBPROX_PEER_CTR_TLLI_CACHE_SIZE].current =
bvc->ctrg->ctr[GBPROX_PEER_CTR_TLLI_CACHE_SIZE].current =
state->logical_link_count;
}
@ -277,13 +277,13 @@ void gbproxy_update_link_info(struct gbproxy_link_info *link_info,
}
void gbproxy_reassign_tlli(struct gbproxy_tlli_state *tlli_state,
struct gbproxy_peer *peer, uint32_t new_tlli)
struct gbproxy_bvc *bvc, uint32_t new_tlli)
{
OSMO_ASSERT(peer);
OSMO_ASSERT(bvc);
if (new_tlli == tlli_state->current)
return;
LOGPBVC(peer, LOGL_INFO,
LOGPBVC(bvc, LOGL_INFO,
"The TLLI has been reassigned from %08x to %08x\n",
tlli_state->current, new_tlli);
@ -345,26 +345,26 @@ static void gbproxy_validate_tlli(struct gbproxy_tlli_state *tlli_state,
tlli_state->assigned = 0;
}
static void gbproxy_touch_link_info(struct gbproxy_peer *peer,
static void gbproxy_touch_link_info(struct gbproxy_bvc *bvc,
struct gbproxy_link_info *link_info,
time_t now)
{
gbproxy_detach_link_info(peer, link_info);
gbproxy_attach_link_info(peer, now, link_info);
gbproxy_detach_link_info(bvc, link_info);
gbproxy_attach_link_info(bvc, now, link_info);
}
static int gbproxy_unregister_link_info(struct gbproxy_peer *peer,
static int gbproxy_unregister_link_info(struct gbproxy_bvc *bvc,
struct gbproxy_link_info *link_info)
{
OSMO_ASSERT(peer);
OSMO_ASSERT(bvc);
if (!link_info)
return 1;
if (link_info->tlli.ptmsi == GSM_RESERVED_TMSI && !link_info->imsi_len) {
LOGPBVC(peer, LOGL_INFO,
LOGPBVC(bvc, LOGL_INFO,
"Removing TLLI %08x from list (P-TMSI or IMSI are not set)\n",
link_info->tlli.current);
gbproxy_delete_link_info(peer, link_info);
gbproxy_delete_link_info(bvc, link_info);
return 1;
}
@ -394,32 +394,32 @@ int gbproxy_imsi_matches(struct gbproxy_config *cfg,
return link_info != NULL && link_info->is_matching[match_id];
}
static void gbproxy_assign_imsi(struct gbproxy_peer *peer,
static void gbproxy_assign_imsi(struct gbproxy_bvc *bvc,
struct gbproxy_link_info *link_info,
struct gprs_gb_parse_context *parse_ctx)
{
int imsi_matches;
struct gbproxy_link_info *other_link_info;
enum gbproxy_match_id match_id;
OSMO_ASSERT(peer);
OSMO_ASSERT(peer->nse);
struct gbproxy_config *cfg = peer->nse->cfg;
OSMO_ASSERT(bvc);
OSMO_ASSERT(bvc->nse);
struct gbproxy_config *cfg = bvc->nse->cfg;
OSMO_ASSERT(cfg);
/* Make sure that there is a second entry with the same IMSI */
other_link_info = gbproxy_link_info_by_imsi(
peer, parse_ctx->imsi, parse_ctx->imsi_len);
bvc, parse_ctx->imsi, parse_ctx->imsi_len);
if (other_link_info && other_link_info != link_info) {
struct osmo_mobile_identity mi;
if (osmo_mobile_identity_decode(&mi, parse_ctx->imsi, parse_ctx->imsi_len, false)
|| mi.type != GSM_MI_TYPE_IMSI) {
LOGPBVC(peer, LOGL_ERROR, "Failed to decode Mobile Identity\n");
LOGPBVC(bvc, LOGL_ERROR, "Failed to decode Mobile Identity\n");
} else {
LOGPBVC(peer, LOGL_INFO,
LOGPBVC(bvc, LOGL_INFO,
"Removing TLLI %08x from list (IMSI %s re-used)\n",
other_link_info->tlli.current, mi.imsi);
gbproxy_delete_link_info(peer, other_link_info);
gbproxy_delete_link_info(bvc, other_link_info);
}
}
@ -456,11 +456,11 @@ static int gbproxy_tlli_match(const struct gbproxy_tlli_state *a,
}
static void gbproxy_remove_matching_link_infos(
struct gbproxy_peer *peer, struct gbproxy_link_info *link_info)
struct gbproxy_bvc *bvc, struct gbproxy_link_info *link_info)
{
OSMO_ASSERT(peer);
OSMO_ASSERT(bvc);
struct gbproxy_link_info *info, *nxt;
struct gbproxy_patch_state *state = &peer->patch_state;
struct gbproxy_patch_state *state = &bvc->patch_state;
/* Make sure that there is no second entry with the same P-TMSI or TLLI */
llist_for_each_entry_safe(info, nxt, &state->logical_links, list) {
@ -472,22 +472,22 @@ static void gbproxy_remove_matching_link_infos(
!gbproxy_tlli_match(&link_info->sgsn_tlli, &info->sgsn_tlli)))
continue;
LOGPBVC(peer, LOGL_INFO,
LOGPBVC(bvc, LOGL_INFO,
"Removing TLLI %08x from list (P-TMSI/TLLI re-used)\n",
info->tlli.current);
gbproxy_delete_link_info(peer, info);
gbproxy_delete_link_info(bvc, info);
}
}
static struct gbproxy_link_info *gbproxy_get_link_info_ul(
struct gbproxy_peer *peer,
struct gbproxy_bvc *bvc,
int *tlli_is_valid,
struct gprs_gb_parse_context *parse_ctx)
{
struct gbproxy_link_info *link_info = NULL;
if (parse_ctx->tlli_enc) {
link_info = gbproxy_link_info_by_tlli(peer, parse_ctx->tlli);
link_info = gbproxy_link_info_by_tlli(bvc, parse_ctx->tlli);
if (link_info) {
*tlli_is_valid = 1;
@ -499,13 +499,13 @@ static struct gbproxy_link_info *gbproxy_get_link_info_ul(
if (!link_info && parse_ctx->imsi) {
link_info = gbproxy_link_info_by_imsi(
peer, parse_ctx->imsi, parse_ctx->imsi_len);
bvc, parse_ctx->imsi, parse_ctx->imsi_len);
}
if (!link_info && parse_ctx->ptmsi_enc && !parse_ctx->old_raid_is_foreign) {
uint32_t bss_ptmsi;
gprs_parse_tmsi(parse_ctx->ptmsi_enc, &bss_ptmsi);
link_info = gbproxy_link_info_by_ptmsi(peer, bss_ptmsi);
link_info = gbproxy_link_info_by_ptmsi(bvc, bss_ptmsi);
}
if (!link_info)
@ -517,27 +517,27 @@ static struct gbproxy_link_info *gbproxy_get_link_info_ul(
}
struct gbproxy_link_info *gbproxy_update_link_state_ul(
struct gbproxy_peer *peer,
struct gbproxy_bvc *bvc,
time_t now,
struct gprs_gb_parse_context *parse_ctx)
{
struct gbproxy_link_info *link_info;
int tlli_is_valid;
OSMO_ASSERT(peer);
OSMO_ASSERT(bvc);
link_info = gbproxy_get_link_info_ul(peer, &tlli_is_valid, parse_ctx);
link_info = gbproxy_get_link_info_ul(bvc, &tlli_is_valid, parse_ctx);
if (parse_ctx->tlli_enc && parse_ctx->llc) {
uint32_t sgsn_tlli;
if (!link_info) {
LOGPBVC(peer, LOGL_INFO, "Adding TLLI %08x to list\n",
LOGPBVC(bvc, LOGL_INFO, "Adding TLLI %08x to list\n",
parse_ctx->tlli);
link_info = gbproxy_link_info_alloc(peer);
gbproxy_attach_link_info(peer, now, link_info);
link_info = gbproxy_link_info_alloc(bvc);
gbproxy_attach_link_info(bvc, now, link_info);
/* Setup TLLIs */
sgsn_tlli = gbproxy_make_sgsn_tlli(peer, link_info,
sgsn_tlli = gbproxy_make_sgsn_tlli(bvc, link_info,
parse_ctx->tlli);
link_info->sgsn_tlli.current = sgsn_tlli;
link_info->tlli.current = parse_ctx->tlli;
@ -546,34 +546,34 @@ struct gbproxy_link_info *gbproxy_update_link_state_ul(
link_info->tlli.current = parse_ctx->tlli;
link_info->tlli.assigned = 0;
link_info->sgsn_tlli.current =
gbproxy_make_sgsn_tlli(peer, link_info,
gbproxy_make_sgsn_tlli(bvc, link_info,
parse_ctx->tlli);
link_info->sgsn_tlli.assigned = 0;
gbproxy_touch_link_info(peer, link_info, now);
gbproxy_touch_link_info(bvc, link_info, now);
} else {
sgsn_tlli = gbproxy_map_tlli(parse_ctx->tlli, link_info, 0);
if (!sgsn_tlli)
sgsn_tlli = gbproxy_make_sgsn_tlli(peer, link_info,
sgsn_tlli = gbproxy_make_sgsn_tlli(bvc, link_info,
parse_ctx->tlli);
gbproxy_validate_tlli(&link_info->tlli,
parse_ctx->tlli, 0);
gbproxy_validate_tlli(&link_info->sgsn_tlli,
sgsn_tlli, 0);
gbproxy_touch_link_info(peer, link_info, now);
gbproxy_touch_link_info(bvc, link_info, now);
}
} else if (link_info) {
gbproxy_touch_link_info(peer, link_info, now);
gbproxy_touch_link_info(bvc, link_info, now);
}
if (parse_ctx->imsi && link_info && link_info->imsi_len == 0)
gbproxy_assign_imsi(peer, link_info, parse_ctx);
gbproxy_assign_imsi(bvc, link_info, parse_ctx);
return link_info;
}
static struct gbproxy_link_info *gbproxy_get_link_info_dl(
struct gbproxy_peer *peer,
struct gbproxy_bvc *bvc,
struct gprs_gb_parse_context *parse_ctx)
{
struct gbproxy_link_info *link_info = NULL;
@ -581,14 +581,14 @@ static struct gbproxy_link_info *gbproxy_get_link_info_dl(
/* Which key to use depends on its availability only, if that fails, do
* not retry it with another key (e.g. IMSI). */
if (parse_ctx->tlli_enc)
link_info = gbproxy_link_info_by_sgsn_tlli(peer, parse_ctx->tlli,
link_info = gbproxy_link_info_by_sgsn_tlli(bvc, parse_ctx->tlli,
parse_ctx->peer_nsei);
/* TODO: Get link_info by (SGSN) P-TMSI if that is available (see
* GSM 08.18, 7.2) instead of using the IMSI as key. */
else if (parse_ctx->imsi)
link_info = gbproxy_link_info_by_imsi(
peer, parse_ctx->imsi, parse_ctx->imsi_len);
bvc, parse_ctx->imsi, parse_ctx->imsi_len);
if (link_info)
link_info->is_deregistered = false;
@ -597,17 +597,17 @@ static struct gbproxy_link_info *gbproxy_get_link_info_dl(
}
struct gbproxy_link_info *gbproxy_update_link_state_dl(
struct gbproxy_peer *peer,
struct gbproxy_bvc *bvc,
time_t now,
struct gprs_gb_parse_context *parse_ctx)
{
struct gbproxy_link_info *link_info = NULL;
OSMO_ASSERT(peer);
OSMO_ASSERT(peer->nse);
struct gbproxy_config *cfg = peer->nse->cfg;
OSMO_ASSERT(bvc);
OSMO_ASSERT(bvc->nse);
struct gbproxy_config *cfg = bvc->nse->cfg;
OSMO_ASSERT(cfg);
link_info = gbproxy_get_link_info_dl(peer, parse_ctx);
link_info = gbproxy_get_link_info_dl(bvc, parse_ctx);
if (parse_ctx->tlli_enc && parse_ctx->new_ptmsi_enc && link_info) {
/* A new P-TMSI has been signalled in the message,
@ -620,9 +620,9 @@ struct gbproxy_link_info *gbproxy_update_link_state_dl(
new_bss_ptmsi = link_info->tlli.ptmsi;
if (new_bss_ptmsi == GSM_RESERVED_TMSI)
new_bss_ptmsi = gbproxy_make_bss_ptmsi(peer, new_sgsn_ptmsi);
new_bss_ptmsi = gbproxy_make_bss_ptmsi(bvc, new_sgsn_ptmsi);
LOGPBVC(peer, LOGL_INFO,
LOGPBVC(bvc, LOGL_INFO,
"Got new PTMSI %08x from SGSN, using %08x for BSS\n",
new_sgsn_ptmsi, new_bss_ptmsi);
/* Setup PTMSIs */
@ -636,25 +636,25 @@ struct gbproxy_link_info *gbproxy_update_link_state_dl(
uint32_t new_ptmsi;
gprs_parse_tmsi(parse_ctx->new_ptmsi_enc, &new_ptmsi);
LOGPBVC(peer, LOGL_INFO,
LOGPBVC(bvc, LOGL_INFO,
"Adding TLLI %08x to list (SGSN, new P-TMSI is %08x)\n",
parse_ctx->tlli, new_ptmsi);
link_info = gbproxy_link_info_alloc(peer);
link_info = gbproxy_link_info_alloc(bvc);
link_info->sgsn_tlli.current = parse_ctx->tlli;
link_info->tlli.current = parse_ctx->tlli;
link_info->sgsn_tlli.ptmsi = new_ptmsi;
link_info->tlli.ptmsi = new_ptmsi;
gbproxy_attach_link_info(peer, now, link_info);
gbproxy_attach_link_info(bvc, now, link_info);
} else if (parse_ctx->tlli_enc && parse_ctx->llc && !link_info &&
!cfg->patch_ptmsi) {
/* Unknown SGSN TLLI, create a new link_info */
uint32_t new_ptmsi;
link_info = gbproxy_link_info_alloc(peer);
LOGPBVC(peer, LOGL_INFO, "Adding TLLI %08x to list (SGSN)\n",
link_info = gbproxy_link_info_alloc(bvc);
LOGPBVC(bvc, LOGL_INFO, "Adding TLLI %08x to list (SGSN)\n",
parse_ctx->tlli);
gbproxy_attach_link_info(peer, now, link_info);
gbproxy_attach_link_info(bvc, now, link_info);
/* Setup TLLIs */
link_info->sgsn_tlli.current = parse_ctx->tlli;
@ -665,7 +665,7 @@ struct gbproxy_link_info *gbproxy_update_link_state_dl(
/* A new P-TMSI has been signalled in the message */
gprs_parse_tmsi(parse_ctx->new_ptmsi_enc, &new_ptmsi);
LOGPBVC(peer, LOGL_INFO,
LOGPBVC(bvc, LOGL_INFO,
"Assigning new P-TMSI %08x\n", new_ptmsi);
/* Setup P-TMSIs */
link_info->sgsn_tlli.ptmsi = new_ptmsi;
@ -675,27 +675,27 @@ struct gbproxy_link_info *gbproxy_update_link_state_dl(
link_info, 1);
gbproxy_validate_tlli(&link_info->sgsn_tlli, parse_ctx->tlli, 1);
gbproxy_validate_tlli(&link_info->tlli, bss_tlli, 1);
gbproxy_touch_link_info(peer, link_info, now);
gbproxy_touch_link_info(bvc, link_info, now);
} else if (link_info) {
gbproxy_touch_link_info(peer, link_info, now);
gbproxy_touch_link_info(bvc, link_info, now);
}
if (parse_ctx->imsi && link_info && link_info->imsi_len == 0)
gbproxy_assign_imsi(peer, link_info, parse_ctx);
gbproxy_assign_imsi(bvc, link_info, parse_ctx);
return link_info;
}
int gbproxy_update_link_state_after(
struct gbproxy_peer *peer,
struct gbproxy_bvc *bvc,
struct gbproxy_link_info *link_info,
time_t now,
struct gprs_gb_parse_context *parse_ctx)
{
int rc = 0;
OSMO_ASSERT(peer);
OSMO_ASSERT(peer->nse);
struct gbproxy_config *cfg = peer->nse->cfg;
OSMO_ASSERT(bvc);
OSMO_ASSERT(bvc->nse);
struct gbproxy_config *cfg = bvc->nse->cfg;
OSMO_ASSERT(cfg);
if (parse_ctx->invalidate_tlli && link_info) {
@ -706,13 +706,13 @@ int gbproxy_update_link_state_after(
(cfg->keep_link_infos == GBPROX_KEEP_IDENTIFIED &&
link_info->imsi_len > 0);
if (keep_info) {
LOGPBVC(peer, LOGL_INFO, "Unregistering TLLI %08x\n",
LOGPBVC(bvc, LOGL_INFO, "Unregistering TLLI %08x\n",
link_info->tlli.current);
rc = gbproxy_unregister_link_info(peer, link_info);
rc = gbproxy_unregister_link_info(bvc, link_info);
} else {
LOGPBVC(peer, LOGL_INFO, "Removing TLLI %08x from list\n",
LOGPBVC(bvc, LOGL_INFO, "Removing TLLI %08x from list\n",
link_info->tlli.current);
gbproxy_delete_link_info(peer, link_info);
gbproxy_delete_link_info(bvc, link_info);
rc = 1;
}
} else if (parse_ctx->to_bss && parse_ctx->tlli_enc &&
@ -727,18 +727,18 @@ int gbproxy_update_link_state_after(
new_sgsn_tlli = gprs_tmsi2tlli(new_sgsn_ptmsi, TLLI_LOCAL);
if (new_bss_ptmsi != GSM_RESERVED_TMSI)
new_bss_tlli = gprs_tmsi2tlli(new_bss_ptmsi, TLLI_LOCAL);
LOGPBVC(peer, LOGL_INFO,
LOGPBVC(bvc, LOGL_INFO,
"Assigning new TLLI %08x to SGSN, %08x to BSS\n",
new_sgsn_tlli, new_bss_tlli);
gbproxy_reassign_tlli(&link_info->sgsn_tlli,
peer, new_sgsn_tlli);
bvc, new_sgsn_tlli);
gbproxy_reassign_tlli(&link_info->tlli,
peer, new_bss_tlli);
gbproxy_remove_matching_link_infos(peer, link_info);
bvc, new_bss_tlli);
gbproxy_remove_matching_link_infos(bvc, link_info);
}
gbproxy_remove_stale_link_infos(peer, now);
gbproxy_remove_stale_link_infos(bvc, now);
return rc;
}

View File

@ -68,14 +68,14 @@ static const struct value_string match_ids[] = {
{0, NULL}
};
static void gbprox_vty_print_peer(struct vty *vty, struct gbproxy_peer *peer)
static void gbprox_vty_print_bvc(struct vty *vty, struct gbproxy_bvc *bvc)
{
struct gprs_ra_id raid;
gsm48_parse_ra(&raid, peer->ra);
gsm48_parse_ra(&raid, bvc->ra);
vty_out(vty, "NSEI %5u, PTP-BVCI %5u, "
"RAI %s", peer->nse->nsei, peer->bvci, osmo_rai_name(&raid));
if (peer->blocked)
"RAI %s", bvc->nse->nsei, bvc->bvci, osmo_rai_name(&raid));
if (bvc->blocked)
vty_out(vty, " [BVC-BLOCKED]");
vty_out(vty, "%s", VTY_NEWLINE);
@ -426,12 +426,12 @@ DEFUN(cfg_gbproxy_link_list_clean_stale_timer,
/* Re-schedule running timers soon in case prev frequency was really big
and new frequency is desired to be lower. After initial run, periodic
time is used. Use random() to avoid firing timers for all peers at
time is used. Use random() to avoid firing timers for all bvcs at
the same time */
llist_for_each_entry(nse, &g_cfg->nse_peers, list) {
struct gbproxy_peer *peer;
llist_for_each_entry(peer, &nse->bts_peers, list)
osmo_timer_schedule(&peer->clean_stale_timer,
llist_for_each_entry(nse, &g_cfg->nses, list) {
struct gbproxy_bvc *bvc;
llist_for_each_entry(bvc, &nse->bvcs, list)
osmo_timer_schedule(&bvc->clean_stale_timer,
random() % 5, random() % 1000000);
}
@ -447,10 +447,10 @@ DEFUN(cfg_gbproxy_link_list_no_clean_stale_timer,
struct gbproxy_nse *nse;
g_cfg->clean_stale_timer_freq = 0;
llist_for_each_entry(nse, &g_cfg->nse_peers, list) {
struct gbproxy_peer *peer;
llist_for_each_entry(peer, &nse->bts_peers, list)
osmo_timer_del(&peer->clean_stale_timer);
llist_for_each_entry(nse, &g_cfg->nses, list) {
struct gbproxy_bvc *bvc;
llist_for_each_entry(bvc, &nse->bvcs, list)
osmo_timer_del(&bvc->clean_stale_timer);
}
return CMD_SUCCESS;
@ -584,13 +584,13 @@ DEFUN(show_gbproxy, show_gbproxy_cmd, "show gbproxy [stats]",
if (show_stats)
vty_out_rate_ctr_group(vty, "", g_cfg->ctrg);
llist_for_each_entry(nse, &g_cfg->nse_peers, list) {
struct gbproxy_peer *peer;
llist_for_each_entry(peer, &nse->bts_peers, list) {
gbprox_vty_print_peer(vty, peer);
llist_for_each_entry(nse, &g_cfg->nses, list) {
struct gbproxy_bvc *bvc;
llist_for_each_entry(bvc, &nse->bvcs, list) {
gbprox_vty_print_bvc(vty, bvc);
if (show_stats)
vty_out_rate_ctr_group(vty, " ", peer->ctrg);
vty_out_rate_ctr_group(vty, " ", bvc->ctrg);
}
}
return CMD_SUCCESS;
@ -606,13 +606,13 @@ DEFUN(show_gbproxy_links, show_gbproxy_links_cmd, "show gbproxy links",
osmo_clock_gettime(CLOCK_MONOTONIC, &ts);
now = ts.tv_sec;
llist_for_each_entry(nse, &g_cfg->nse_peers, list) {
struct gbproxy_peer *peer;
llist_for_each_entry(peer, &nse->bts_peers, list) {
llist_for_each_entry(nse, &g_cfg->nses, list) {
struct gbproxy_bvc *bvc;
llist_for_each_entry(bvc, &nse->bvcs, list) {
struct gbproxy_link_info *link_info;
struct gbproxy_patch_state *state = &peer->patch_state;
struct gbproxy_patch_state *state = &bvc->patch_state;
gbprox_vty_print_peer(vty, peer);
gbprox_vty_print_bvc(vty, bvc);
llist_for_each_entry(link_info, &state->logical_links, list) {
time_t age = now - link_info->timestamp;
@ -652,16 +652,16 @@ DEFUN(show_gbproxy_links, show_gbproxy_links_cmd, "show gbproxy links",
DEFUN(delete_gb_bvci, delete_gb_bvci_cmd,
"delete-gbproxy-peer <0-65534> bvci <2-65534>",
"Delete a GBProxy peer by NSEI and optionally BVCI\n"
"Delete a GBProxy bvc by NSEI and optionally BVCI\n"
"NSEI number\n"
"Only delete peer with a matching BVCI\n"
"Only delete bvc with a matching BVCI\n"
"BVCI number\n")
{
const uint16_t nsei = atoi(argv[0]);
const uint16_t bvci = atoi(argv[1]);
int counter;
counter = gbproxy_cleanup_peers(g_cfg, nsei, bvci);
counter = gbproxy_cleanup_bvcs(g_cfg, nsei, bvci);
if (counter == 0) {
vty_out(vty, "BVC not found%s", VTY_NEWLINE);
@ -673,7 +673,7 @@ DEFUN(delete_gb_bvci, delete_gb_bvci_cmd,
DEFUN(delete_gb_nsei, delete_gb_nsei_cmd,
"delete-gbproxy-peer <0-65534> (only-bvc|only-nsvc|all) [dry-run]",
"Delete a GBProxy peer by NSEI and optionally BVCI\n"
"Delete a GBProxy bvc by NSEI and optionally BVCI\n"
"NSEI number\n"
"Only delete BSSGP connections (BVC)\n"
"Only delete dynamic NS connections (NS-VC)\n"
@ -698,18 +698,18 @@ DEFUN(delete_gb_nsei, delete_gb_nsei_cmd,
if (delete_bvc) {
if (!dry_run) {
struct gbproxy_nse *nse = gbproxy_nse_by_nsei(g_cfg, nsei);
counter = gbproxy_cleanup_peers(g_cfg, nsei, 0);
counter = gbproxy_cleanup_bvcs(g_cfg, nsei, 0);
gbproxy_nse_free(nse);
} else {
struct gbproxy_nse *nse;
struct gbproxy_peer *peer;
struct gbproxy_bvc *bvc;
counter = 0;
llist_for_each_entry(nse, &g_cfg->nse_peers, list) {
llist_for_each_entry(nse, &g_cfg->nses, list) {
if (nse->nsei != nsei)
continue;
llist_for_each_entry(peer, &nse->bts_peers, list) {
llist_for_each_entry(bvc, &nse->bvcs, list) {
vty_out(vty, "BVC: ");
gbprox_vty_print_peer(vty, peer);
gbprox_vty_print_bvc(vty, bvc);
counter += 1;
}
}
@ -754,7 +754,7 @@ DEFUN(delete_gb_link_by_id, delete_gb_link_by_id_cmd,
enum {MATCH_TLLI = 't', MATCH_IMSI = 'i', MATCH_SGSN = 's'} match;
uint32_t ident = 0;
const char *imsi = NULL;
struct gbproxy_peer *peer = 0;
struct gbproxy_bvc *bvc = 0;
struct gbproxy_link_info *link_info, *nxt;
struct gbproxy_patch_state *state;
int found = 0;
@ -767,14 +767,14 @@ DEFUN(delete_gb_link_by_id, delete_gb_link_by_id_cmd,
case MATCH_SGSN: ident = strtoll(argv[2], NULL, 0); break;
};
peer = gbproxy_peer_by_nsei(g_cfg, nsei);
if (!peer) {
vty_out(vty, "Didn't find peer with NSEI %d%s",
bvc = gbproxy_bvc_by_nsei(g_cfg, nsei);
if (!bvc) {
vty_out(vty, "Didn't find bvc with NSEI %d%s",
nsei, VTY_NEWLINE);
return CMD_WARNING;
}
state = &peer->patch_state;
state = &bvc->patch_state;
llist_for_each_entry_safe(link_info, nxt, &state->logical_links, list) {
struct osmo_mobile_identity mi;
@ -801,7 +801,7 @@ DEFUN(delete_gb_link_by_id, delete_gb_link_by_id_cmd,
vty_out(vty, "Deleting link with TLLI %08x%s", link_info->tlli.current,
VTY_NEWLINE);
gbproxy_delete_link_info(peer, link_info);
gbproxy_delete_link_info(bvc, link_info);
found += 1;
}
@ -821,7 +821,7 @@ DEFUN(delete_gb_link, delete_gb_link_cmd,
{
const uint16_t nsei = atoi(argv[0]);
enum {MATCH_STALE = 's', MATCH_DEREGISTERED = 'd'} match;
struct gbproxy_peer *peer = 0;
struct gbproxy_bvc *bvc = 0;
struct gbproxy_link_info *link_info, *nxt;
struct gbproxy_patch_state *state;
time_t now;
@ -831,20 +831,20 @@ DEFUN(delete_gb_link, delete_gb_link_cmd,
match = argv[1][0];
peer = gbproxy_peer_by_nsei(g_cfg, nsei);
if (!peer) {
vty_out(vty, "Didn't find peer with NSEI %d%s",
bvc = gbproxy_bvc_by_nsei(g_cfg, nsei);
if (!bvc) {
vty_out(vty, "Didn't find bvc with NSEI %d%s",
nsei, VTY_NEWLINE);
return CMD_WARNING;
}
state = &peer->patch_state;
state = &bvc->patch_state;
osmo_clock_gettime(CLOCK_MONOTONIC, &ts);
now = ts.tv_sec;
if (match == MATCH_STALE) {
found = gbproxy_remove_stale_link_infos(peer, now);
found = gbproxy_remove_stale_link_infos(bvc, now);
if (found)
vty_out(vty, "Deleted %d stale logical link%s%s",
found, found == 1 ? "" : "s", VTY_NEWLINE);
@ -854,7 +854,7 @@ DEFUN(delete_gb_link, delete_gb_link_cmd,
if (!link_info->is_deregistered)
continue;
gbproxy_delete_link_info(peer, link_info);
gbproxy_delete_link_info(bvc, link_info);
found += 1;
}
}

View File

@ -129,9 +129,9 @@ static int dump_peers(FILE *stream, int indent, time_t now,
return rc;
llist_for_each_entry(nse, &cfg->nse_peers, list) {
struct gbproxy_peer *peer;
llist_for_each_entry(peer, &nse->bts_peers, list) {
llist_for_each_entry(nse, &cfg->nses, list) {
struct gbproxy_bvc *peer;
llist_for_each_entry(peer, &nse->bvcs, list) {
struct gbproxy_link_info *link_info;
struct gbproxy_patch_state *state = &peer->patch_state;
gsm48_parse_ra(&raid, peer->ra);
@ -1285,20 +1285,20 @@ static void test_gbproxy()
send_ns_unitdata(nsi, NULL, SGSN_NSEI, 0x10ff, (uint8_t *)"", 0);
/* Find peer */
OSMO_ASSERT(gbproxy_peer_by_bvci(&gbcfg, 0xeeee) == NULL);
OSMO_ASSERT(gbproxy_peer_by_bvci(&gbcfg, 0x1000) == NULL);
OSMO_ASSERT(gbproxy_peer_by_bvci(&gbcfg, 0x1012) != NULL);
OSMO_ASSERT(gbproxy_peer_by_nsei(&gbcfg, 0xeeee) == NULL);
OSMO_ASSERT(gbproxy_peer_by_nsei(&gbcfg, 0x1012) == NULL);
OSMO_ASSERT(gbproxy_peer_by_nsei(&gbcfg, 0x1000) != NULL);
OSMO_ASSERT(gbproxy_bvc_by_bvci(&gbcfg, 0xeeee) == NULL);
OSMO_ASSERT(gbproxy_bvc_by_bvci(&gbcfg, 0x1000) == NULL);
OSMO_ASSERT(gbproxy_bvc_by_bvci(&gbcfg, 0x1012) != NULL);
OSMO_ASSERT(gbproxy_bvc_by_nsei(&gbcfg, 0xeeee) == NULL);
OSMO_ASSERT(gbproxy_bvc_by_nsei(&gbcfg, 0x1012) == NULL);
OSMO_ASSERT(gbproxy_bvc_by_nsei(&gbcfg, 0x1000) != NULL);
/* Cleanup */
OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0, 0) == 0);
OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0x1000, 0xeeee) == 0);
OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0, 0x1002) == 0);
OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0x1000, 0x1012) == 1);
OSMO_ASSERT(gbproxy_cleanup_peers(&gbcfg, 0x1000, 0x1012) == 0);
OSMO_ASSERT(gbproxy_cleanup_bvcs(&gbcfg, 0, 0) == 0);
OSMO_ASSERT(gbproxy_cleanup_bvcs(&gbcfg, 0x1000, 0xeeee) == 0);
OSMO_ASSERT(gbproxy_cleanup_bvcs(&gbcfg, 0, 0x1002) == 0);
OSMO_ASSERT(gbproxy_cleanup_bvcs(&gbcfg, 0x1000, 0x1012) == 1);
OSMO_ASSERT(gbproxy_cleanup_bvcs(&gbcfg, 0x1000, 0x1012) == 0);
dump_peers(stdout, 0, 0, &gbcfg);
@ -1411,7 +1411,7 @@ static void test_gbproxy_ra_patching()
const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0xf8};
const char *patch_re = "^9898|^121314";
struct gbproxy_link_info *link_info;
struct gbproxy_peer *peer;
struct gbproxy_bvc *peer;
LLIST_HEAD(rcv_list);
struct expect_result *expect_res;
@ -1450,7 +1450,7 @@ static void test_gbproxy_ra_patching()
setup_bssgp(nsi, bss_nsei[0], 0x1002);
dump_peers(stdout, 0, 0, &gbcfg);
peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
peer = gbproxy_bvc_by_nsei(&gbcfg, 0x1000);
OSMO_ASSERT(peer != NULL);
OSMO_ASSERT(expect_bssgp_msg(SGSN_NSEI, 0, BSSGP_PDUT_BVC_RESET));
@ -1509,17 +1509,17 @@ static void test_gbproxy_ra_patching()
OSMO_ASSERT(2 == peer->ctrg->ctr[GBPROX_PEER_CTR_RAID_PATCHED_SGSN].current);
OSMO_ASSERT(gbproxy_peer_by_rai(&gbcfg, convert_ra(&rai_bss)) != NULL);
OSMO_ASSERT(gbproxy_peer_by_rai(&gbcfg, convert_ra(&rai_sgsn)) == NULL);
OSMO_ASSERT(gbproxy_peer_by_rai(&gbcfg, convert_ra(&rai_unknown)) == NULL);
OSMO_ASSERT(gbproxy_bvc_by_rai(&gbcfg, convert_ra(&rai_bss)) != NULL);
OSMO_ASSERT(gbproxy_bvc_by_rai(&gbcfg, convert_ra(&rai_sgsn)) == NULL);
OSMO_ASSERT(gbproxy_bvc_by_rai(&gbcfg, convert_ra(&rai_unknown)) == NULL);
OSMO_ASSERT(gbproxy_peer_by_lai(&gbcfg, convert_ra(&rai_bss)) != NULL);
OSMO_ASSERT(gbproxy_peer_by_lai(&gbcfg, convert_ra(&rai_sgsn)) == NULL);
OSMO_ASSERT(gbproxy_peer_by_lai(&gbcfg, convert_ra(&rai_unknown)) == NULL);
OSMO_ASSERT(gbproxy_bvc_by_lai(&gbcfg, convert_ra(&rai_bss)) != NULL);
OSMO_ASSERT(gbproxy_bvc_by_lai(&gbcfg, convert_ra(&rai_sgsn)) == NULL);
OSMO_ASSERT(gbproxy_bvc_by_lai(&gbcfg, convert_ra(&rai_unknown)) == NULL);
OSMO_ASSERT(gbproxy_peer_by_lac(&gbcfg, convert_ra(&rai_bss)) != NULL);
OSMO_ASSERT(gbproxy_peer_by_lac(&gbcfg, convert_ra(&rai_sgsn)) != NULL);
OSMO_ASSERT(gbproxy_peer_by_lac(&gbcfg, convert_ra(&rai_unknown)) == NULL);
OSMO_ASSERT(gbproxy_bvc_by_lac(&gbcfg, convert_ra(&rai_bss)) != NULL);
OSMO_ASSERT(gbproxy_bvc_by_lac(&gbcfg, convert_ra(&rai_sgsn)) != NULL);
OSMO_ASSERT(gbproxy_bvc_by_lac(&gbcfg, convert_ra(&rai_unknown)) == NULL);
link_info = gbproxy_link_info_by_sgsn_tlli(peer, local_tlli, SGSN_NSEI);
OSMO_ASSERT(link_info);
@ -1750,7 +1750,7 @@ static void test_gbproxy_ptmsi_assignment()
const uint8_t imsi2[] = {0x11, 0x12, 0x99, 0x99, 0x99, 0x16, 0x17, 0xf8};
struct gbproxy_link_info *link_info, *link_info2;
struct gbproxy_peer *peer;
struct gbproxy_bvc *peer;
unsigned bss_nu = 0;
unsigned sgsn_nu = 0;
@ -1777,7 +1777,7 @@ static void test_gbproxy_ptmsi_assignment()
setup_ns(nsi, bss_nsei[0]);
setup_bssgp(nsi, bss_nsei[0], 0x1002);
peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
peer = gbproxy_bvc_by_nsei(&gbcfg, 0x1000);
OSMO_ASSERT(peer != NULL);
send_bssgp_reset_ack(nsi, SGSN_NSEI, 0x1002);
@ -1977,7 +1977,7 @@ static void test_gbproxy_ptmsi_patching()
const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0xf8};
struct gbproxy_link_info *link_info;
struct gbproxy_peer *peer;
struct gbproxy_bvc *peer;
unsigned bss_nu = 0;
unsigned sgsn_nu = 0;
int old_ctr;
@ -2010,7 +2010,7 @@ static void test_gbproxy_ptmsi_patching()
setup_ns(nsi, bss_nsei[0]);
setup_bssgp(nsi, bss_nsei[0], 0x1002);
peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
peer = gbproxy_bvc_by_nsei(&gbcfg, 0x1000);
OSMO_ASSERT(peer != NULL);
send_bssgp_reset_ack(nsi, SGSN_NSEI, 0x1002);
@ -2300,7 +2300,7 @@ static void test_gbproxy_ptmsi_patching_bad_cases()
const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0xf8};
struct gbproxy_link_info *link_info;
struct gbproxy_peer *peer;
struct gbproxy_bvc *peer;
unsigned bss_nu = 0;
unsigned sgsn_nu = 0;
uint16_t bss_nsei[] = { 0x1000 };
@ -2327,7 +2327,7 @@ static void test_gbproxy_ptmsi_patching_bad_cases()
setup_ns(nsi, bss_nsei[0]);
setup_bssgp(nsi, bss_nsei[0], 0x1002);
peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
peer = gbproxy_bvc_by_nsei(&gbcfg, 0x1000);
OSMO_ASSERT(peer != NULL);
send_bssgp_reset_ack(nsi, SGSN_NSEI, 0x1002);
@ -2483,7 +2483,7 @@ static void test_gbproxy_imsi_acquisition()
const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0xf8};
struct gbproxy_link_info *link_info;
struct gbproxy_peer *peer;
struct gbproxy_bvc *peer;
unsigned bss_nu = 0;
unsigned sgsn_nu = 0;
uint16_t bss_nsei[] = { 0x1000 };
@ -2510,7 +2510,7 @@ static void test_gbproxy_imsi_acquisition()
setup_ns(nsi, bss_nsei[0]);
setup_bssgp(nsi, bss_nsei[0], 0x1002);
peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
peer = gbproxy_bvc_by_nsei(&gbcfg, 0x1000);
OSMO_ASSERT(peer != NULL);
send_bssgp_reset_ack(nsi, SGSN_NSEI, 0x1002);
@ -2803,7 +2803,7 @@ static void test_gbproxy_secondary_sgsn()
const uint8_t imsi3[] = {0x11, 0x12, 0x99, 0x99, 0x99, 0x26, 0x27, 0xf8};
struct gbproxy_link_info *link_info;
struct gbproxy_link_info *other_info;
struct gbproxy_peer *peer;
struct gbproxy_bvc *peer;
unsigned bss_nu = 0;
unsigned sgsn_nu = 0;
@ -2852,7 +2852,7 @@ static void test_gbproxy_secondary_sgsn()
send_bssgp_reset_ack(nsi, SGSN_NSEI, 0x1002);
send_bssgp_reset_ack(nsi, SGSN2_NSEI, 0x1002);
peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
peer = gbproxy_bvc_by_nsei(&gbcfg, 0x1000);
OSMO_ASSERT(peer != NULL);
dump_global(stdout, 0);
@ -3279,7 +3279,7 @@ static void test_gbproxy_keep_info()
const uint8_t imsi[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0xf8};
struct gbproxy_link_info *link_info, *link_info2;
struct gbproxy_peer *peer;
struct gbproxy_bvc *peer;
unsigned bss_nu = 0;
unsigned sgsn_nu = 0;
uint16_t bss_nsei[] = { 0x1000 };
@ -3311,7 +3311,7 @@ static void test_gbproxy_keep_info()
setup_ns(nsi, bss_nsei[0]);
setup_bssgp(nsi, bss_nsei[0], 0x1002);
peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
peer = gbproxy_bvc_by_nsei(&gbcfg, 0x1000);
OSMO_ASSERT(peer != NULL);
send_bssgp_reset_ack(nsi, SGSN_NSEI, 0x1002);
@ -4208,7 +4208,7 @@ static void test_gbproxy_keep_info()
}
struct gbproxy_link_info *register_tlli(
struct gbproxy_peer *peer, uint32_t tlli,
struct gbproxy_bvc *peer, uint32_t tlli,
const uint8_t *imsi, size_t imsi_len, time_t now)
{
struct gbproxy_link_info *link_info;
@ -4264,7 +4264,7 @@ static void test_gbproxy_tlli_expire(void)
{
struct gbproxy_config cfg = {0};
struct gbproxy_nse *nse;
struct gbproxy_peer *peer;
struct gbproxy_bvc *peer;
const char *err_msg = NULL;
const uint8_t imsi1[] = { GSM_MI_TYPE_IMSI, 0x23, 0x24, 0x25, 0xf6 };
const uint8_t imsi2[] = { GSM_MI_TYPE_IMSI, 0x26, 0x27, 0x28, 0xf9 };
@ -4294,7 +4294,7 @@ static void test_gbproxy_tlli_expire(void)
cfg.tlli_max_len = 0;
cfg.tlli_max_age = 0;
peer = gbproxy_peer_alloc(nse, 20);
peer = gbproxy_bvc_alloc(nse, 20);
OSMO_ASSERT(peer->patch_state.logical_link_count == 0);
printf(" Add TLLI 1, IMSI 1\n");
@ -4323,7 +4323,7 @@ static void test_gbproxy_tlli_expire(void)
printf("\n");
gbproxy_peer_free(peer);
gbproxy_bvc_free(peer);
}
{
@ -4333,7 +4333,7 @@ static void test_gbproxy_tlli_expire(void)
cfg.tlli_max_len = 0;
cfg.tlli_max_age = 0;
peer = gbproxy_peer_alloc(nse, 20);
peer = gbproxy_bvc_alloc(nse, 20);
OSMO_ASSERT(peer->patch_state.logical_link_count == 0);
printf(" Add TLLI 1, IMSI 1\n");
@ -4362,7 +4362,7 @@ static void test_gbproxy_tlli_expire(void)
printf("\n");
gbproxy_peer_free(peer);
gbproxy_bvc_free(peer);
}
{
@ -4373,7 +4373,7 @@ static void test_gbproxy_tlli_expire(void)
cfg.tlli_max_len = 1;
cfg.tlli_max_age = 0;
peer = gbproxy_peer_alloc(nse, 20);
peer = gbproxy_bvc_alloc(nse, 20);
OSMO_ASSERT(peer->patch_state.logical_link_count == 0);
printf(" Add TLLI 1, IMSI 1\n");
@ -4400,7 +4400,7 @@ static void test_gbproxy_tlli_expire(void)
printf("\n");
gbproxy_peer_free(peer);
gbproxy_bvc_free(peer);
}
{
@ -4411,7 +4411,7 @@ static void test_gbproxy_tlli_expire(void)
cfg.tlli_max_len = 0;
cfg.tlli_max_age = 1;
peer = gbproxy_peer_alloc(nse, 20);
peer = gbproxy_bvc_alloc(nse, 20);
OSMO_ASSERT(peer->patch_state.logical_link_count == 0);
printf(" Add TLLI 1, IMSI 1 (should expire after timeout)\n");
@ -4438,7 +4438,7 @@ static void test_gbproxy_tlli_expire(void)
printf("\n");
gbproxy_peer_free(peer);
gbproxy_bvc_free(peer);
}
{
@ -4449,7 +4449,7 @@ static void test_gbproxy_tlli_expire(void)
cfg.tlli_max_len = 0;
cfg.tlli_max_age = 1;
peer = gbproxy_peer_alloc(nse, 20);
peer = gbproxy_bvc_alloc(nse, 20);
OSMO_ASSERT(peer->patch_state.logical_link_count == 0);
printf(" Add TLLI 1, IMSI 1 (should expire)\n");
@ -4486,7 +4486,7 @@ static void test_gbproxy_tlli_expire(void)
printf("\n");
gbproxy_peer_free(peer);
gbproxy_bvc_free(peer);
}
gbproxy_clear_patch_filter(&cfg.matches[GBPROX_MATCH_PATCHING]);
gbprox_reset(&cfg);
@ -4583,7 +4583,7 @@ static void test_gbproxy_stored_messages()
const uint32_t foreign_tlli1 = 0x8000dead;
struct gbproxy_peer *peer;
struct gbproxy_bvc *peer;
unsigned bss_nu = 0;
unsigned sgsn_nu = 0;
uint16_t bss_nsei[] = { 0x1000 };
@ -4611,7 +4611,7 @@ static void test_gbproxy_stored_messages()
setup_ns(nsi, bss_nsei[0]);
setup_bssgp(nsi, bss_nsei[0], 0x1002);
peer = gbproxy_peer_by_nsei(&gbcfg, 0x1000);
peer = gbproxy_bvc_by_nsei(&gbcfg, 0x1000);
OSMO_ASSERT(peer != NULL);
send_bssgp_reset_ack(nsi, SGSN_NSEI, 0x1002);