Port gbproxy to NS2

Since NS2 has a different abstraction we mock up the prim send/recv
functions and don't test NS like the old tests did.

Related: SYS#4998
Change-Id: Iecfd0408a35a11638d254c1db3c1d477b1a11524
This commit is contained in:
Alexander Couzens 2020-09-22 13:21:46 +02:00 committed by Daniel Willmann
parent 5f573156e2
commit 951e133d17
10 changed files with 3325 additions and 4991 deletions

View File

@ -25,7 +25,8 @@ ns
nse 666 nsvci 666
nse 666 remote-role sgsn
! nse 666 encapsulation framerelay-gre
! nse 666 remote-ip 172.16.1.70
nse 666 remote-ip 127.0.0.1
nse 666 remote-port 23001
! nse 666 fr-dlci 666
timer tns-block 3
timer tns-block-retries 3
@ -35,6 +36,7 @@ ns
timer tns-alive 3
timer tns-alive-retries 10
encapsulation udp local-port 23000
encapsulation udp local-ip 127.0.0.1
! encapsulation framerelay-gre enabled 1
gbproxy
sgsn nsei 666

View File

@ -3,9 +3,10 @@
#include <osmocom/core/msgb.h>
#include <osmocom/core/timer.h>
#include <osmocom/gsm/gsm23003.h>
#include <osmocom/gprs/gprs_ns.h>
#include <osmocom/gprs/gprs_ns2.h>
#include <osmocom/vty/command.h>
#include <sys/types.h>
@ -95,7 +96,7 @@ struct gbproxy_config {
uint16_t nsip_sgsn_nsei;
/* NS instance of libosmogb */
struct gprs_ns_inst *nsi;
struct gprs_ns2_inst *nsi;
/* Linked list of all Gb peers (except SGSN) */
struct llist_head bts_peers;
@ -236,13 +237,13 @@ int gb_ctrl_cmds_install(void);
int gbproxy_init_config(struct gbproxy_config *cfg);
/* Main input function for Gb proxy */
int gbprox_rcvmsg(struct gbproxy_config *cfg, struct msgb *msg, uint16_t nsei, uint16_t ns_bvci, uint16_t nsvci);
int gbprox_rcvmsg(void *ctx, struct msgb *msg);
int gbprox_signal(unsigned int subsys, unsigned int signal,
void *handler_data, void *signal_data);
/* Reset all persistent NS-VC's */
int gbprox_reset_persistent_nsvcs(struct gprs_ns_inst *nsi);
int gprs_ns2_prim_cb(struct osmo_prim_hdr *oph, void *ctx);
void gbprox_reset(struct gbproxy_config *cfg);

View File

@ -36,8 +36,9 @@
#include <osmocom/core/rate_ctr.h>
#include <osmocom/core/stats.h>
#include <osmocom/gprs/gprs_ns.h>
#include <osmocom/gprs/gprs_ns2.h>
#include <osmocom/gprs/gprs_bssgp.h>
#include <osmocom/gprs/gprs_bssgp_bss.h>
#include <osmocom/gsm/gsm_utils.h>
@ -385,6 +386,8 @@ static int gbproxy_gsm48_to_peer(struct gbproxy_peer *peer,
link_info->vu_gen_tx_bss = (link_info->vu_gen_tx_bss + 1) % 512;
gprs_push_bssgp_dl_unitdata(msg, link_info->tlli.current);
msg->l3h = msg->data;
rc = gbprox_relay2peer(msg, peer, bvci);
msgb_free(msg);
return rc;
@ -779,21 +782,23 @@ static int gbprox_relay2sgsn(struct gbproxy_config *cfg, struct msgb *old_msg,
{
/* create a copy of the message so the old one can
* be free()d safely when we return from gbprox_rcvmsg() */
struct gprs_ns2_inst *nsi = cfg->nsi;
struct osmo_gprs_ns2_prim nsp = {};
struct msgb *msg = bssgp_msgb_copy(old_msg, "msgb_relay2sgsn");
int rc;
DEBUGP(DGPRS, "NSEI=%u proxying BTS->SGSN (NS_BVCI=%u, NSEI=%u)\n",
msgb_nsei(msg), ns_bvci, sgsn_nsei);
msgb_bvci(msg) = ns_bvci;
msgb_nsei(msg) = sgsn_nsei;
nsp.bvci = ns_bvci;
nsp.nsei = sgsn_nsei;
strip_ns_hdr(msg);
rc = gprs_ns_sendmsg(bssgp_nsi, msg);
osmo_prim_init(&nsp.oph, SAP_NS, PRIM_NS_UNIT_DATA,
PRIM_OP_REQUEST, msg);
rc = gprs_ns2_recv_prim(nsi, &nsp.oph);
if (rc < 0)
rate_ctr_inc(&cfg->ctrg->ctr[GBPROX_GLOB_CTR_TX_ERR_SGSN]);
return rc;
}
@ -803,19 +808,23 @@ static int gbprox_relay2peer(struct msgb *old_msg, struct gbproxy_peer *peer,
{
/* create a copy of the message so the old one can
* be free()d safely when we return from gbprox_rcvmsg() */
struct gprs_ns2_inst *nsi = peer->cfg->nsi;
struct osmo_gprs_ns2_prim nsp = {};
struct msgb *msg = bssgp_msgb_copy(old_msg, "msgb_relay2peer");
int rc;
DEBUGP(DGPRS, "NSEI=%u proxying SGSN->BSS (NS_BVCI=%u, NSEI=%u)\n",
msgb_nsei(msg), ns_bvci, peer->nsei);
msgb_bvci(msg) = ns_bvci;
msgb_nsei(msg) = peer->nsei;
nsp.bvci = ns_bvci;
nsp.nsei = peer->nsei;
/* Strip the old NS header, it will be replaced with a new one */
strip_ns_hdr(msg);
rc = gprs_ns_sendmsg(bssgp_nsi, msg);
osmo_prim_init(&nsp.oph, SAP_NS, PRIM_NS_UNIT_DATA,
PRIM_OP_REQUEST, msg);
rc = gprs_ns2_recv_prim(nsi, &nsp.oph);
if (rc < 0)
rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_TX_ERR]);
@ -875,7 +884,7 @@ int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
/* Receive an incoming PTP message from a BSS-side NS-VC */
static int gbprox_rx_ptp_from_bss(struct gbproxy_config *cfg,
struct msgb *msg, uint16_t nsei,
uint16_t nsvci, uint16_t ns_bvci)
uint16_t ns_bvci)
{
struct gbproxy_peer *peer;
struct bssgp_normal_hdr *bgph = (struct bssgp_normal_hdr *) msgb_bssgph(msg);
@ -885,9 +894,9 @@ static int gbprox_rx_ptp_from_bss(struct gbproxy_config *cfg,
peer = gbproxy_peer_by_bvci(cfg, ns_bvci);
if (!peer) {
LOGP(DGPRS, LOGL_NOTICE, "Didn't find peer for "
"BVCI=%u for PTP message from NSVC=%u/NSEI=%u (BSS), "
"BVCI=%u for PTP message from NSEI=%u (BSS), "
"discarding message\n",
ns_bvci, nsvci, nsei);
ns_bvci, nsei);
return bssgp_tx_status(BSSGP_CAUSE_UNKNOWN_BVCI,
&ns_bvci, msg);
}
@ -917,7 +926,7 @@ static int gbprox_rx_ptp_from_bss(struct gbproxy_config *cfg,
/* Receive an incoming PTP message from a SGSN-side NS-VC */
static int gbprox_rx_ptp_from_sgsn(struct gbproxy_config *cfg,
struct msgb *msg, uint16_t nsei,
uint16_t nsvci, uint16_t ns_bvci)
uint16_t ns_bvci)
{
struct gbproxy_peer *peer;
struct bssgp_normal_hdr *bgph = (struct bssgp_normal_hdr *) msgb_bssgph(msg);
@ -929,8 +938,8 @@ static int gbprox_rx_ptp_from_sgsn(struct gbproxy_config *cfg,
if (!peer) {
LOGP(DGPRS, LOGL_INFO, "Didn't find peer for "
"BVCI=%u for message from NSVC=%u/NSEI=%u (SGSN)\n",
ns_bvci, nsvci, nsei);
"BVCI=%u for message from NSEI=%u (SGSN)\n",
ns_bvci, nsei);
rate_ctr_inc(&cfg->ctrg->
ctr[GBPROX_GLOB_CTR_INV_BVCI]);
return bssgp_tx_status(BSSGP_CAUSE_UNKNOWN_BVCI,
@ -939,8 +948,8 @@ static int gbprox_rx_ptp_from_sgsn(struct gbproxy_config *cfg,
if (peer->blocked) {
LOGP(DGPRS, LOGL_NOTICE, "Dropping PDU for "
"blocked BVCI=%u via NSVC=%u/NSEI=%u\n",
ns_bvci, nsvci, nsei);
"blocked BVCI=%u via NSEI=%u\n",
ns_bvci, nsei);
rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_DROPPED]);
return bssgp_tx_status(BSSGP_CAUSE_BVCI_BLOCKED, &ns_bvci, msg);
}
@ -1313,11 +1322,30 @@ static int gbproxy_is_sgsn_nsei(struct gbproxy_config *cfg, uint16_t nsei)
(cfg->route_to_sgsn2 && nsei == cfg->nsip_sgsn2_nsei);
}
/* Main input function for Gb proxy */
int gbprox_rcvmsg(struct gbproxy_config *cfg, struct msgb *msg, uint16_t nsei,
uint16_t ns_bvci, uint16_t nsvci)
int gbprox_bssgp_send_cb(void *ctx, struct msgb *msg)
{
int rc;
struct gbproxy_config *cfg = (struct gbproxy_config *) ctx;
struct gprs_ns2_inst *nsi = cfg->nsi;
struct osmo_gprs_ns2_prim nsp = {};
nsp.bvci = msgb_bvci(msg);
nsp.nsei = msgb_nsei(msg);
osmo_prim_init(&nsp.oph, SAP_NS, PRIM_NS_UNIT_DATA, PRIM_OP_REQUEST, msg);
rc = gprs_ns2_recv_prim(nsi, &nsp.oph);
return rc;
}
/* Main input function for Gb proxy */
int gbprox_rcvmsg(void *ctx, struct msgb *msg)
{
int rc;
uint16_t nsei = msgb_nsei(msg);
uint16_t ns_bvci = msgb_bvci(msg);
struct gbproxy_config *cfg = (struct gbproxy_config *) ctx;
int remote_end_is_sgsn = gbproxy_is_sgsn_nsei(cfg, nsei);
/* Only BVCI=0 messages need special treatment */
@ -1329,102 +1357,122 @@ int gbprox_rcvmsg(struct gbproxy_config *cfg, struct msgb *msg, uint16_t nsei,
} else {
/* All other BVCI are PTP */
if (remote_end_is_sgsn)
rc = gbprox_rx_ptp_from_sgsn(cfg, msg, nsei, nsvci,
rc = gbprox_rx_ptp_from_sgsn(cfg, msg, nsei,
ns_bvci);
else
rc = gbprox_rx_ptp_from_bss(cfg, msg, nsei, nsvci,
rc = gbprox_rx_ptp_from_bss(cfg, msg, nsei,
ns_bvci);
}
return rc;
}
int gbprox_reset_persistent_nsvcs(struct gprs_ns_inst *nsi)
{
struct gprs_nsvc *nsvc;
/* TODO: What about handling:
* NS_AFF_CAUSE_VC_FAILURE,
NS_AFF_CAUSE_VC_RECOVERY,
NS_AFF_CAUSE_FAILURE,
NS_AFF_CAUSE_RECOVERY,
osmocom own causes
NS_AFF_CAUSE_SNS_CONFIGURED,
NS_AFF_CAUSE_SNS_FAILURE,
*/
llist_for_each_entry(nsvc, &nsi->gprs_nsvcs, list) {
if (!nsvc->persistent)
continue;
gprs_nsvc_reset(nsvc, NS_CAUSE_OM_INTERVENTION);
}
return 0;
}
/* Signal handler for signals from NS layer */
int gbprox_signal(unsigned int subsys, unsigned int signal,
void *handler_data, void *signal_data)
void gprs_ns_prim_status_cb(struct gbproxy_config *cfg, struct osmo_gprs_ns2_prim *nsp)
{
struct gbproxy_config *cfg = handler_data;
struct ns_signal_data *nssd = signal_data;
struct gprs_nsvc *nsvc = nssd->nsvc;
/* TODO: bss nsei available/unavailable bssgp_tx_simple_bvci(BSSGP_PDUT_BVC_BLOCK, nsvc->nsei, peer->bvci, 0);
* TODO: sgsn nsei available/unavailable
*/
struct gbproxy_peer *peer;
int remote_end_is_sgsn = gbproxy_is_sgsn_nsei(cfg, nsvc->nsei);
if (subsys != SS_L_NS)
return 0;
switch (nsp->u.status.cause) {
case NS_AFF_CAUSE_SNS_FAILURE:
case NS_AFF_CAUSE_SNS_CONFIGURED:
break;
if (signal == S_NS_RESET && remote_end_is_sgsn) {
/* We have received a NS-RESET from the NSEI and NSVC
* of the SGSN. This might happen with SGSN that start
* their own NS-RESET procedure without waiting for our
* NS-RESET */
nsvc->remote_end_is_sgsn = 1;
}
case NS_AFF_CAUSE_RECOVERY:
LOGP(DPCU, LOGL_NOTICE, "NS-NSE %d became available\n", nsp->nsei);
if (nsp->nsei == cfg->nsip_sgsn_nsei) {
/* look-up or create the BTS context for this BVC */
struct bssgp_bvc_ctx *bctx = btsctx_by_bvci_nsei(nsp->bvci, nsp->nsei);
if (!bctx)
bctx = btsctx_alloc(nsp->bvci, nsp->nsei);
if (signal == S_NS_ALIVE_EXP && nsvc->remote_end_is_sgsn) {
LOGP(DGPRS, LOGL_NOTICE, "Tns alive expired too often, "
"re-starting RESET procedure\n");
rate_ctr_inc(&cfg->ctrg->
ctr[GBPROX_GLOB_CTR_RESTART_RESET_SGSN]);
gprs_ns_nsip_connect(nsvc->nsi, &nsvc->ip.bts_addr,
nsvc->nsei, nsvc->nsvci);
}
if (!nsvc->remote_end_is_sgsn) {
/* from BSS to SGSN */
peer = gbproxy_peer_by_nsei(cfg, nsvc->nsei);
if (!peer) {
LOGP(DGPRS, LOGL_NOTICE, "signal '%s' for unknown peer NSEI=%u/NSVCI=%u\n",
get_value_string(gprs_ns_signal_ns_names, signal), nsvc->nsei, nsvc->nsvci);
return 0;
bssgp_tx_bvc_reset_nsei_bvci(cfg->nsip_sgsn_nsei, 0, BSSGP_CAUSE_OML_INTERV, NULL, 0);
}
switch (signal) {
case S_NS_RESET:
case S_NS_BLOCK:
if (!peer->blocked)
break;
LOGP(DGPRS, LOGL_NOTICE, "Converting '%s' from NSEI=%u/NSVCI=%u into BSSGP_BVC_BLOCK to SGSN\n",
get_value_string(gprs_ns_signal_ns_names, signal), nsvc->nsei, nsvc->nsvci);
bssgp_tx_simple_bvci(BSSGP_PDUT_BVC_BLOCK, nsvc->nsei,
peer->bvci, 0);
break;
}
} else {
/* Forward this message to all NS-VC to BSS */
struct gprs_ns_inst *nsi = cfg->nsi;
struct gprs_nsvc *next_nsvc;
llist_for_each_entry(next_nsvc, &nsi->gprs_nsvcs, list) {
if (next_nsvc->remote_end_is_sgsn)
continue;
/* Note that the following does not start the full
* procedures including timer based retransmissions. */
switch (signal) {
case S_NS_RESET:
gprs_ns_tx_reset(next_nsvc, nssd->cause);
break;
case S_NS_BLOCK:
gprs_ns_tx_block(next_nsvc, nssd->cause);
break;
case S_NS_UNBLOCK:
gprs_ns_tx_unblock(next_nsvc);
break;
case NS_AFF_CAUSE_FAILURE:
if (nsp->nsei == cfg->nsip_sgsn_nsei) {
/* sgsn */
/* TODO: BSVC: block all PtP towards bss */
rate_ctr_inc(&cfg->ctrg->
ctr[GBPROX_GLOB_CTR_RESTART_RESET_SGSN]);
} else {
/* bss became unavailable */
peer = gbproxy_peer_by_nsei(cfg, nsp->nsei);
if (!peer) {
/* TODO: use primitive name + status cause name */
LOGP(DGPRS, LOGL_NOTICE, "Received ns2 primitive %d for unknown peer NSEI=%u\n",
nsp->u.status.cause, nsp->nsei);
break;
}
if (!peer->blocked)
break;
bssgp_tx_simple_bvci(BSSGP_PDUT_BVC_BLOCK, cfg->nsip_sgsn_nsei,
peer->bvci, 0);
}
LOGP(DPCU, LOGL_NOTICE, "NS-NSE %d became unavailable\n", nsp->nsei);
break;
default:
LOGP(DPCU, LOGL_NOTICE,
"NS: %s Unknown prim %d from NS\n",
get_value_string(osmo_prim_op_names, nsp->oph.operation),
nsp->oph.primitive);
break;
}
return 0;
}
/* called by the ns layer */
int gprs_ns2_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
{
struct osmo_gprs_ns2_prim *nsp;
struct gbproxy_config *cfg = (struct gbproxy_config *) ctx;
int rc = 0;
if (oph->sap != SAP_NS)
return 0;
nsp = container_of(oph, struct osmo_gprs_ns2_prim, oph);
if (oph->operation != PRIM_OP_INDICATION) {
LOGP(DPCU, LOGL_NOTICE, "NS: %s Unknown prim %d from NS\n",
get_value_string(osmo_prim_op_names, oph->operation),
oph->operation);
return 0;
}
switch (oph->primitive) {
case PRIM_NS_UNIT_DATA:
/* hand the message into the BSSGP implementation */
msgb_bssgph(oph->msg) = oph->msg->l3h;
msgb_bvci(oph->msg) = nsp->bvci;
msgb_nsei(oph->msg) = nsp->nsei;
rc = gbprox_rcvmsg(cfg, oph->msg);
break;
case PRIM_NS_STATUS:
gprs_ns_prim_status_cb(cfg, nsp);
break;
default:
LOGP(DPCU, LOGL_NOTICE,
"NS: %s Unknown prim %d from NS\n",
get_value_string(osmo_prim_op_names, oph->operation),
oph->primitive);
break;
}
return rc;
}
void gbprox_reset(struct gbproxy_config *cfg)

View File

@ -33,22 +33,41 @@
extern vector ctrl_node_vec;
static int ctrl_nsvc_state_cb(struct gprs_ns2_vc *nsvc, void *ctx) {
/* FIXME: Can't get NSVC state in ns2
struct ctrl_cmd *cmd = (struct ctrl_cmd *)ctx;
cmd->reply = gprs_ns2_vc_state_append(cmd->reply, nsvc);
*/
return 0;
}
static int get_nsvc_state(struct ctrl_cmd *cmd, void *data)
{
struct gbproxy_config *cfg = data;
struct gprs_ns_inst *nsi = cfg->nsi;
struct gprs_nsvc *nsvc;
struct gprs_ns2_inst *nsi = cfg->nsi;
struct gprs_ns2_nse *nse;
struct gbproxy_peer *peer;
cmd->reply = talloc_strdup(cmd, "");
llist_for_each_entry(nsvc, &nsi->gprs_nsvcs, list) {
if (nsvc == nsi->unknown_nsvc)
continue;
/* NS-VCs for SGSN */
nse = gprs_ns2_nse_by_nsei(nsi, cfg->nsip_sgsn_nsei);
if (nse)
gprs_ns2_nse_foreach_nsvc(nse, &ctrl_nsvc_state_cb, cmd);
/* NS-VCs for SGSN2 */
nse = gprs_ns2_nse_by_nsei(nsi, cfg->nsip_sgsn2_nsei);
if (nse)
gprs_ns2_nse_foreach_nsvc(nse, &ctrl_nsvc_state_cb, cmd);
cmd->reply = gprs_nsvc_state_append(cmd->reply, nsvc);
/* NS-VCs for BSS peers */
llist_for_each_entry(peer, &cfg->bts_peers, list) {
nse = gprs_ns2_nse_by_nsei(nsi, peer->nsei);
if (nse)
gprs_ns2_nse_foreach_nsvc(nse, &ctrl_nsvc_state_cb, cmd);
}
return CTRL_CMD_REPLY;
cmd->reply = "Getting NSVC state not yet implemented for NS2";
return CTRL_CMD_ERROR;
}
CTRL_CMD_DEFINE_RO(nsvc_state, "nsvc-state");

View File

@ -38,7 +38,7 @@
#include <osmocom/core/rate_ctr.h>
#include <osmocom/core/stats.h>
#include <osmocom/gprs/gprs_ns.h>
#include <osmocom/gprs/gprs_ns2.h>
#include <osmocom/gprs/gprs_bssgp.h>
#include <osmocom/sgsn/signal.h>
@ -80,26 +80,6 @@ static int daemonize = 0;
/* Pointer to the SGSN peer */
extern struct gbprox_peer *gbprox_peer_sgsn;
/* call-back function for the NS protocol */
static int proxy_ns_cb(enum gprs_ns_evt event, struct gprs_nsvc *nsvc,
struct msgb *msg, uint16_t bvci)
{
int rc = 0;
switch (event) {
case GPRS_NS_EVT_UNIT_DATA:
rc = gbprox_rcvmsg(gbcfg, msg, nsvc->nsei, bvci, nsvc->nsvci);
break;
default:
LOGP(DGPRS, LOGL_ERROR, "SGSN: Unknown event %u from NS\n", event);
if (msg)
msgb_free(msg);
rc = -EIO;
break;
}
return rc;
}
static void signal_handler(int signal)
{
fprintf(stdout, "signal %u received\n", signal);
@ -269,6 +249,8 @@ static bool file_exists(const char *path)
return stat(path, &sb) ? false : true;
}
int gbprox_bssgp_send_cb(void *ctx, struct msgb *msg);
int main(int argc, char **argv)
{
int rc;
@ -314,23 +296,23 @@ int main(int argc, char **argv)
rate_ctr_init(tall_sgsn_ctx);
osmo_stats_init(tall_sgsn_ctx);
bssgp_nsi = gprs_ns_instantiate(&proxy_ns_cb, tall_sgsn_ctx);
if (!bssgp_nsi) {
LOGP(DGPRS, LOGL_ERROR, "Unable to instantiate NS\n");
exit(1);
}
gbcfg = talloc_zero(tall_sgsn_ctx, struct gbproxy_config);
if (!gbcfg) {
LOGP(DGPRS, LOGL_FATAL, "Unable to allocate config\n");
exit(1);
}
gbproxy_init_config(gbcfg);
gbcfg->nsi = bssgp_nsi;
gprs_ns_vty_init(bssgp_nsi);
gprs_ns_set_log_ss(DNS);
gbcfg->nsi = gprs_ns2_instantiate(tall_sgsn_ctx, gprs_ns2_prim_cb, gbcfg);
if (!gbcfg->nsi) {
LOGP(DGPRS, LOGL_ERROR, "Unable to instantiate NS\n");
exit(1);
}
gprs_ns2_vty_init(gbcfg->nsi, NULL);
bssgp_set_log_ss(DBSSGP);
osmo_signal_register_handler(SS_L_NS, &gbprox_signal, gbcfg);
gprs_ns2_dynamic_create_nse(gbcfg->nsi, true);
bssgp_set_bssgp_callback(gbprox_bssgp_send_cb, gbcfg);
rc = gbproxy_parse_config(config_file, gbcfg);
if (rc < 0) {
@ -338,6 +320,8 @@ int main(int argc, char **argv)
exit(2);
}
gprs_ns2_vty_create();
/* start telnet after reading config for vty_get_bind_addr() */
rc = telnet_init_dynif(tall_sgsn_ctx, NULL,
vty_get_bind_addr(), OSMO_VTY_PORT_GBPROXY);
@ -357,26 +341,13 @@ int main(int argc, char **argv)
exit(1);
}
if (!gprs_nsvc_by_nsei(gbcfg->nsi, gbcfg->nsip_sgsn_nsei)) {
if (!gprs_ns2_nse_by_nsei(gbcfg->nsi, gbcfg->nsip_sgsn_nsei)) {
LOGP(DGPRS, LOGL_FATAL, "You cannot proxy to NSEI %u "
"without creating that NSEI before\n",
gbcfg->nsip_sgsn_nsei);
exit(2);
}
rc = gprs_ns_nsip_listen(bssgp_nsi);
if (rc < 0) {
LOGP(DGPRS, LOGL_FATAL, "Cannot bind/listen on NSIP socket\n");
exit(2);
}
rc = gprs_ns_frgre_listen(bssgp_nsi);
if (rc < 0) {
LOGP(DGPRS, LOGL_FATAL, "Cannot bind/listen GRE "
"socket. Do you have CAP_NET_RAW?\n");
exit(2);
}
if (daemonize) {
rc = osmo_daemonize();
if (rc < 0) {
@ -385,9 +356,6 @@ int main(int argc, char **argv)
}
}
/* Reset all the persistent NS-VCs that we've read from the config */
gbprox_reset_persistent_nsvcs(bssgp_nsi);
while (1) {
rc = osmo_select_main(0);
if (rc < 0)

View File

@ -18,6 +18,7 @@
*
*/
#include <osmocom/gprs/gprs_msgb.h>
#include <osmocom/sgsn/gb_proxy.h>
#include <osmocom/sgsn/gprs_utils.h>

View File

@ -26,10 +26,11 @@
#include <inttypes.h>
#include <osmocom/core/talloc.h>
#include <osmocom/core/timer.h>
#include <osmocom/core/rate_ctr.h>
#include <osmocom/gsm/gsm48.h>
#include <osmocom/gprs/gprs_ns.h>
#include <osmocom/gprs/gprs_ns2.h>
#include <osmocom/gsm/apn.h>
#include <osmocom/sgsn/debug.h>
@ -666,27 +667,21 @@ DEFUN(delete_gb_nsei, delete_gb_nsei_cmd,
}
if (delete_nsvc) {
struct gprs_ns_inst *nsi = g_cfg->nsi;
struct gprs_nsvc *nsvc, *nsvc2;
struct gprs_ns2_inst *nsi = g_cfg->nsi;
struct gprs_ns2_nse *nse;
counter = 0;
llist_for_each_entry_safe(nsvc, nsvc2, &nsi->gprs_nsvcs, list) {
if (nsvc->nsei != nsei)
continue;
if (nsvc->persistent)
continue;
if (!dry_run)
gprs_nsvc_delete(nsvc);
else
vty_out(vty, "NS-VC: NSEI %5u, NS-VCI %5u, "
"remote %s%s",
nsvc->nsei, nsvc->nsvci,
gprs_ns_ll_str(nsvc), VTY_NEWLINE);
counter += 1;
nse = gprs_ns2_nse_by_nsei(nsi, nsei);
if (!nse) {
vty_out(vty, "NSEI not found%s", VTY_NEWLINE);
return CMD_WARNING;
}
vty_out(vty, "%sDeleted %d NS-VC%s",
dry_run ? "Not " : "", counter, VTY_NEWLINE);
/* TODO: We should NOT delete a persistent NSEI/NSVC as soon as we can check for these */
if (!dry_run)
gprs_ns2_free_nse(nse);
vty_out(vty, "%sDeleted NS-VCs for NSEI %d%s",
dry_run ? "Not " : "", nsei, VTY_NEWLINE);
}
return CMD_SUCCESS;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -95,7 +95,7 @@ class TestVTYGbproxy(TestVTYBase):
def testVtyShow(self):
res = self.vty.command("show ns")
self.assertTrue(res.find('Encapsulation NS-UDP-IP') >= 0)
self.assertTrue(res.find('UDP bind') >= 0)
res = self.vty.command("show gbproxy stats")
self.assertTrue(res.find('GBProxy Global Statistics') >= 0)
@ -105,16 +105,14 @@ class TestVTYGbproxy(TestVTYBase):
self.assertTrue(self.vty.verify('delete-gbproxy-peer 9999 bvci 7777', ['BVC not found']))
res = self.vty.command("delete-gbproxy-peer 9999 all dry-run")
self.assertTrue(res.find('Not Deleted 0 BVC') >= 0)
self.assertTrue(res.find('Not Deleted 0 NS-VC') >= 0)
self.assertTrue(res.find('NSEI not found') >= 0)
res = self.vty.command("delete-gbproxy-peer 9999 only-bvc dry-run")
self.assertTrue(res.find('Not Deleted 0 BVC') >= 0)
self.assertTrue(res.find('Not Deleted 0 NS-VC') < 0)
res = self.vty.command("delete-gbproxy-peer 9999 only-nsvc dry-run")
self.assertTrue(res.find('Not Deleted 0 BVC') < 0)
self.assertTrue(res.find('Not Deleted 0 NS-VC') >= 0)
self.assertTrue(res.find('NSEI not found') >= 0)
res = self.vty.command("delete-gbproxy-peer 9999 all")
self.assertTrue(res.find('Deleted 0 BVC') >= 0)
self.assertTrue(res.find('Deleted 0 NS-VC') >= 0)
self.assertTrue(res.find('NSEI not found') >= 0)
class TestVTYSGSN(TestVTYBase):