From 5f1faa3cd25663716de8cc4c2a81fac0f378ff76 Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Thu, 21 Aug 2014 10:01:30 +0200 Subject: gbproxy: Move peer definitions to gb_proxy_peer.c This patch moves the peer related definitions from gb_proxy.c to gb_proxy_peer.c and adjusts the prefix of each global symbol to gbproxy_: Peer definitions (prefix adjusted to gbproxy_): peer_ctr_description -> gprs/gb_proxy_peer.c (static) peer_ctrg_desc -> gprs/gb_proxy_peer.c (static) *peer_by_* -> gprs/gb_proxy_peer.c gbproxy_peer_alloc -> gprs/gb_proxy_peer.c gbproxy_peer_free -> gprs/gb_proxy_peer.c gbprox_cleanup_peers -> gprs/gb_proxy_peer.c Sponsored-by: On-Waves ehf --- openbsc/src/gprs/gb_proxy_peer.c | 200 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 200 insertions(+) create mode 100644 openbsc/src/gprs/gb_proxy_peer.c (limited to 'openbsc/src/gprs/gb_proxy_peer.c') diff --git a/openbsc/src/gprs/gb_proxy_peer.c b/openbsc/src/gprs/gb_proxy_peer.c new file mode 100644 index 000000000..820d8df87 --- /dev/null +++ b/openbsc/src/gprs/gb_proxy_peer.c @@ -0,0 +1,200 @@ +/* Gb proxy peer handling */ + +/* (C) 2010 by Harald Welte + * (C) 2010-2013 by On-Waves + * (C) 2013 by Holger Hans Peter Freyther + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include + +static const struct rate_ctr_desc peer_ctr_description[] = { + { "blocked", "BVC Block " }, + { "unblocked", "BVC Unblock " }, + { "dropped", "BVC blocked, dropped packet " }, + { "inv-nsei", "NSEI mismatch " }, + { "tx-err", "NS Transmission error " }, + { "raid-mod.bss", "RAID patched (BSS )" }, + { "raid-mod.sgsn", "RAID patched (SGSN)" }, + { "apn-mod.sgsn", "APN patched " }, + { "tlli-mod.bss", "TLLI patched (BSS )" }, + { "tlli-mod.sgsn", "TLLI patched (SGSN)" }, + { "ptmsi-mod.bss", "P-TMSI patched (BSS )" }, + { "ptmsi-mod.sgsn","P-TMSI patched (SGSN)" }, + { "mod-crypt-err", "Patch error: encrypted " }, + { "mod-err", "Patch error: other " }, + { "attach-reqs", "Attach Request count " }, + { "attach-rejs", "Attach Reject count " }, + { "tlli-unknown", "TLLI from SGSN unknown " }, + { "tlli-cache", "TLLI cache size " }, +}; + +static const struct rate_ctr_group_desc peer_ctrg_desc = { + .group_name_prefix = "gbproxy.peer", + .group_description = "GBProxy Peer Statistics", + .num_ctr = ARRAY_SIZE(peer_ctr_description), + .ctr_desc = peer_ctr_description, +}; + + +/* Find the gbprox_peer by its BVCI */ +struct gbproxy_peer *gbproxy_peer_by_bvci(struct gbproxy_config *cfg, uint16_t bvci) +{ + struct gbproxy_peer *peer; + llist_for_each_entry(peer, &cfg->bts_peers, list) { + if (peer->bvci == bvci) + return peer; + } + return NULL; +} + +/* Find the gbprox_peer by its NSEI */ +struct gbproxy_peer *gbproxy_peer_by_nsei(struct gbproxy_config *cfg, + uint16_t nsei) +{ + struct gbproxy_peer *peer; + llist_for_each_entry(peer, &cfg->bts_peers, list) { + if (peer->nsei == nsei) + return peer; + } + return NULL; +} + +/* look-up a peer by its Routeing Area Identification (RAI) */ +struct gbproxy_peer *gbproxy_peer_by_rai(struct gbproxy_config *cfg, + const uint8_t *ra) +{ + struct gbproxy_peer *peer; + llist_for_each_entry(peer, &cfg->bts_peers, list) { + if (!memcmp(peer->ra, ra, 6)) + return peer; + } + return NULL; +} + +/* look-up a peer by its Location Area Identification (LAI) */ +struct gbproxy_peer *gbproxy_peer_by_lai(struct gbproxy_config *cfg, + const uint8_t *la) +{ + struct gbproxy_peer *peer; + llist_for_each_entry(peer, &cfg->bts_peers, list) { + if (!memcmp(peer->ra, la, 5)) + return peer; + } + return NULL; +} + +/* look-up a peer by its Location Area Code (LAC) */ +struct gbproxy_peer *gbproxy_peer_by_lac(struct gbproxy_config *cfg, + const uint8_t *la) +{ + struct gbproxy_peer *peer; + llist_for_each_entry(peer, &cfg->bts_peers, list) { + if (!memcmp(peer->ra + 3, la + 3, 2)) + return peer; + } + return NULL; +} + +struct gbproxy_peer *gbproxy_peer_by_bssgp_tlv(struct gbproxy_config *cfg, + struct tlv_parsed *tp) +{ + if (TLVP_PRESENT(tp, BSSGP_IE_BVCI)) { + uint16_t bvci; + + bvci = ntohs(tlvp_val16_unal(tp, BSSGP_IE_BVCI)); + if (bvci >= 2) + return gbproxy_peer_by_bvci(cfg, bvci); + } + + if (TLVP_PRESENT(tp, BSSGP_IE_ROUTEING_AREA)) { + 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); + } + + if (TLVP_PRESENT(tp, BSSGP_IE_LOCATION_AREA)) { + uint8_t *lai = (uint8_t *)TLVP_VAL(tp, BSSGP_IE_LOCATION_AREA); + return gbproxy_peer_by_lac(cfg, lai); + } + + return NULL; +} + + +struct gbproxy_peer *gbproxy_peer_alloc(struct gbproxy_config *cfg, uint16_t bvci) +{ + struct gbproxy_peer *peer; + + peer = talloc_zero(tall_bsc_ctx, struct gbproxy_peer); + if (!peer) + return NULL; + + peer->bvci = bvci; + peer->ctrg = rate_ctr_group_alloc(peer, &peer_ctrg_desc, bvci); + peer->cfg = cfg; + + llist_add(&peer->list, &cfg->bts_peers); + + INIT_LLIST_HEAD(&peer->patch_state.enabled_tllis); + + return peer; +} + +void gbproxy_peer_free(struct gbproxy_peer *peer) +{ + llist_del(&peer->list); + + gbproxy_delete_tllis(peer); + + rate_ctr_group_free(peer->ctrg); + peer->ctrg = NULL; + + talloc_free(peer); +} + +int gbproxy_cleanup_peers(struct gbproxy_config *cfg, uint16_t nsei, uint16_t bvci) +{ + int counter = 0; + struct gbproxy_peer *peer, *tmp; + + llist_for_each_entry_safe(peer, tmp, &cfg->bts_peers, list) { + if (peer->nsei != nsei) + continue; + if (bvci && peer->bvci != bvci) + continue; + + gbproxy_peer_free(peer); + counter += 1; + } + + return counter; +} + -- cgit v1.2.3