sgsn: Use the new NS2 api

The new NS2 api supports NSE with multiple NS-VC and contains a NS-VC
fsm. FR/GRE support is not working.
The configuration is compatible except for FR/GRE.

Relates: OS#4629
Depends-on: Iaad7b53d44338e5dd81dc2202f23bdcb715af804 (libosmocore)
Depends-on: I6cef42749555e577d5573f2ed8b8bce4cf842a98 (libosmocore)
Change-Id: I92a3bcaf166b091a22d74c7c1586964d33d7cc9d
This commit is contained in:
Alexander Couzens 2020-07-27 22:39:58 +02:00 committed by lynxis lazus
parent 8a33528854
commit f23e2db752
9 changed files with 114 additions and 61 deletions

View File

@ -12,3 +12,9 @@ void gprs_gb_recv_pdu(struct sgsn_mm_ctx *mmctx);
/* page a MS in its routing area */
int gprs_gb_page_ps_ra(struct sgsn_mm_ctx *mmctx);
/* called by the bssgp layer to send NS PDUs */
int gprs_gb_send_cb(void *ctx, struct msgb *msg);
/* called by the ns layer */
int gprs_ns_prim_cb(struct osmo_prim_hdr *oph, void *ctx);

View File

@ -3,8 +3,9 @@
#include <osmocom/core/msgb.h>
#include <osmocom/core/select.h>
#include <osmocom/crypt/gprs_cipher.h>
#include <osmocom/gprs/gprs_ns.h>
#include <osmocom/gprs/gprs_ns2.h>
#include <osmocom/sgsn/gprs_sgsn.h>
#include <osmocom/gsm/oap_client.h>
#include <osmocom/gsupclient/gsup_client.h>
@ -69,7 +70,7 @@ struct sgsn_config {
struct sockaddr_in gtp_listenaddr;
/* misc */
struct gprs_ns_inst *nsi;
struct gprs_ns2_inst *nsi;
enum sgsn_auth_policy auth_policy;
enum gprs_ciph_algo cipher;
@ -157,7 +158,7 @@ char *sgsn_gtp_ntoa(struct ul16_t *ul);
/* sgsn.c */
/* Main input function for Gb proxy */
int sgsn_rcvmsg(struct msgb *msg, struct gprs_nsvc *nsvc, uint16_t ns_bvci);
int sgsn_rcvmsg(struct msgb *msg, struct gprs_ns2_vc *nsvc, uint16_t ns_bvci);
/* sgsn_libgtp.c */
struct sgsn_pdp_ctx *sgsn_create_pdp_ctx(struct sgsn_ggsn_ctx *ggsn,

View File

@ -22,7 +22,7 @@
#include <osmocom/sgsn/gprs_utils.h>
#include <osmocom/core/msgb.h>
#include <osmocom/gprs/gprs_ns.h>
#include <osmocom/gprs/gprs_ns2.h>
#include <osmocom/gsm/protocol/gsm_04_08_gprs.h>
#include <osmocom/gsm/protocol/gsm_04_08.h>

View File

@ -25,6 +25,9 @@
#include <osmocom/gprs/gprs_msgb.h>
#include <osmocom/gprs/gprs_bssgp.h>
#include <osmocom/gprs/gprs_ns2.h>
#include <osmocom/gprs/gprs_bssgp_bss.h>
#include <osmocom/sgsn/gprs_llc.h>
#include "bscconfig.h"
@ -103,3 +106,83 @@ int gprs_gb_page_ps_ra(struct sgsn_mm_ctx *mmctx)
return rc;
}
/* called by the bssgp layer to send NS PDUs */
int gprs_gb_send_cb(void *ctx, struct msgb *msg)
{
struct gprs_ns2_inst *nsi = (struct gprs_ns2_inst *) ctx;
struct osmo_gprs_ns2_prim nsp = {};
nsp.nsei = msgb_nsei(msg);
nsp.bvci = msgb_bvci(msg);
osmo_prim_init(&nsp.oph, SAP_NS, PRIM_NS_UNIT_DATA, PRIM_OP_REQUEST, msg);
return gprs_ns2_recv_prim(nsi, &nsp.oph);
}
void gprs_ns_prim_status_cb(struct osmo_gprs_ns2_prim *nsp)
{
switch (nsp->u.status.cause) {
case NS_AFF_CAUSE_SNS_CONFIGURED:
LOGP(DGPRS, LOGL_NOTICE, "NS-E %d SNS configured.\n", nsp->nsei);
break;
case NS_AFF_CAUSE_RECOVERY:
LOGP(DGPRS, LOGL_NOTICE, "NS-E %d became available\n", nsp->nsei);
/* workaround for broken BSS which doesn't respond correct to BSSGP status message.
* Sent a BSSGP Reset when a persistent NSVC comes up for the first time. */
if (nsp->u.status.first && nsp->u.status.persistent) {
struct bssgp_bvc_ctx bctx = {
.nsei = nsp->nsei,
};
bssgp_tx_bvc_reset2(&bctx, BVCI_SIGNALLING, BSSGP_CAUSE_EQUIP_FAIL, false);
}
break;
case NS_AFF_CAUSE_FAILURE:
LOGP(DGPRS, LOGL_NOTICE, "NS-E %d became unavailable\n", nsp->nsei);
break;
default:
LOGP(DGPRS, LOGL_NOTICE, "NS: %s Unknown prim %d from NS\n",
get_value_string(osmo_prim_op_names, nsp->oph.operation), nsp->oph.primitive);
break;
}
}
/* call-back function for the NS protocol */
int gprs_ns_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
{
struct osmo_gprs_ns2_prim *nsp;
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(DGPRS, 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 */
/* add required msg fields for Gb layer */
msgb_bssgph(oph->msg) = oph->msg->l3h;
msgb_bvci(oph->msg) = nsp->bvci;
msgb_nsei(oph->msg) = nsp->nsei;
rc = bssgp_rcvmsg(oph->msg);
break;
case PRIM_NS_STATUS:
gprs_ns_prim_status_cb(nsp);
break;
default:
LOGP(DGPRS, LOGL_NOTICE, "NS: %s Unknown prim %d from NS\n",
get_value_string(osmo_prim_op_names, oph->operation), oph->primitive);
break;
}
if (oph->msg)
msgb_free(oph->msg);
return rc;
}

View File

@ -26,6 +26,7 @@
#include <osmocom/core/rate_ctr.h>
#include <osmocom/core/tdef.h>
#include <osmocom/gprs/gprs_msgb.h>
#include <osmocom/ranap/ranap_common.h>

View File

@ -27,7 +27,7 @@
#include <osmocom/core/rate_ctr.h>
#include <osmocom/core/stats.h>
#include <osmocom/core/backtrace.h>
#include <osmocom/gprs/gprs_ns.h>
#include <osmocom/gprs/gprs_ns2.h>
#include <osmocom/gprs/gprs_bssgp.h>
#include <osmocom/gsm/protocol/gsm_04_08_gprs.h>
#include <osmocom/gsm/apn.h>

View File

@ -39,8 +39,9 @@
#include <osmocom/core/rate_ctr.h>
#include <osmocom/core/logging.h>
#include <osmocom/core/stats.h>
#include <osmocom/core/sockaddr_str.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>
@ -60,6 +61,7 @@
#include <osmocom/sgsn/gprs_llc.h>
#include <osmocom/sgsn/gprs_gmm.h>
#include <osmocom/sgsn/gprs_ranap.h>
#include <osmocom/sgsn/gprs_gb.h>
#include <osmocom/ctrl/control_if.h>
#include <osmocom/ctrl/ports.h>
@ -80,7 +82,7 @@
void *tall_sgsn_ctx;
struct ctrl_handle *g_ctrlh;
struct gprs_ns_inst *sgsn_nsi;
struct gprs_ns2_inst *sgsn_nsi;
static int daemonize = 0;
const char *openbsc_copyright =
"Copyright (C) 2010 Harald Welte and On-Waves\r\n"
@ -94,27 +96,6 @@ const char *openbsc_copyright =
struct sgsn_instance *sgsn;
/* call-back function for the NS protocol */
static int sgsn_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:
/* hand the message into the BSSGP implementation */
rc = bssgp_rcvmsg(msg);
break;
default:
LOGP(DGPRS, LOGL_ERROR, "SGSN: Unknown event %u from NS\n", event);
if (msg)
msgb_free(msg);
rc = -EIO;
break;
}
return rc;
}
/* call-back function for the BSSGP protocol */
int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
{
@ -181,23 +162,6 @@ static void signal_handler(int signum)
/* NSI that BSSGP uses when transmitting on NS */
extern struct gprs_ns_inst *bssgp_nsi;
static void bvc_reset_persistent_nsvcs(void)
{
/* Send BVC-RESET on all persistent NSVCs */
struct gprs_nsvc *nsvc;
llist_for_each_entry(nsvc, &sgsn_nsi->gprs_nsvcs, list) {
struct bssgp_bvc_ctx bctx = {
.nsei = nsvc->nsei,
};
if (!nsvc->persistent)
continue;
/* if it is not marked ALIVE, we cannot send any data over it. */
nsvc->state |= NSE_S_ALIVE;
bssgp_tx_bvc_reset2(&bctx, BVCI_SIGNALLING, BSSGP_CAUSE_EQUIP_FAIL, false);
}
}
static struct vty_app_info vty_info = {
.name = "OsmoSGSN",
.version = PACKAGE_VERSION,
@ -364,6 +328,11 @@ static bool file_exists(const char *path)
int main(int argc, char **argv)
{
int rc;
struct osmo_sockaddr_str bind_address = {
.af = AF_INET,
.ip = "0.0.0.0",
.port = 23000,
};
#if BUILD_IU
struct osmo_sccp_instance *sccp;
#endif
@ -418,27 +387,27 @@ int main(int argc, char **argv)
rate_ctr_init(tall_sgsn_ctx);
gprs_ns_set_log_ss(DNS);
logging_vty_add_deprecated_subsys(tall_sgsn_ctx, "bssgp");
sgsn_nsi = gprs_ns_instantiate(&sgsn_ns_cb, tall_sgsn_ctx);
sgsn_nsi = gprs_ns2_instantiate(tall_sgsn_ctx, &gprs_ns_prim_cb, NULL);
if (!sgsn_nsi) {
LOGP(DGPRS, LOGL_ERROR, "Unable to instantiate NS\n");
exit(1);
}
bssgp_nsi = sgsn->cfg.nsi = sgsn_nsi;
sgsn->cfg.nsi = sgsn_nsi;
bssgp_set_bssgp_callback(gprs_gb_send_cb, sgsn_nsi);
gprs_llc_init("/usr/local/lib/osmocom/crypt/");
sgsn_rate_ctr_init();
sgsn_inst_init(sgsn);
gprs_ns_vty_init(bssgp_nsi);
gprs_ns2_vty_init(sgsn_nsi, &bind_address);
bssgp_vty_init();
gprs_llc_vty_init();
gprs_sndcp_vty_init();
sgsn_auth_init(sgsn);
sgsn_cdr_init(sgsn);
/* FIXME: register signal handler for SS_L_NS */
rc = sgsn_parse_config(sgsn->config_file);
if (rc < 0) {
@ -480,18 +449,13 @@ int main(int argc, char **argv)
exit(2);
}
rc = gprs_ns_nsip_listen(sgsn_nsi);
rc = gprs_ns2_vty_create();
if (rc < 0) {
LOGP(DGPRS, LOGL_FATAL, "Cannot bind/listen on NSIP socket\n");
exit(2);
}
rc = gprs_ns_frgre_listen(sgsn_nsi);
if (rc < 0) {
LOGP(DGPRS, LOGL_FATAL, "Cannot bind/listen GRE "
"socket. Do you have CAP_NET_RAW?\n");
exit(2);
}
gprs_ns2_dynamic_create_nse(sgsn_nsi, true);
if (sgsn->cfg.dynamic_lookup) {
if (sgsn_ares_init(sgsn) != 0) {
@ -518,8 +482,6 @@ int main(int argc, char **argv)
ranap_iu_init(tall_sgsn_ctx, DRANAP, "OsmoSGSN-IuPS", sccp, gsm0408_gprs_rcvmsg_iu, sgsn_ranap_iu_event);
#endif
bvc_reset_persistent_nsvcs();
if (daemonize) {
rc = osmo_daemonize();
if (rc < 0) {

View File

@ -34,7 +34,7 @@
#include <osmocom/sgsn/debug.h>
#include <osmocom/sgsn/sgsn.h>
#include <osmocom/gprs/gprs_ns.h>
#include <osmocom/gprs/gprs_ns2.h>
#include <osmocom/sgsn/gprs_gmm.h>
#include <osmocom/sgsn/gprs_sgsn.h>
#include <osmocom/sgsn/vty.h>

View File

@ -141,7 +141,7 @@ class TestVTYSGSN(TestVTYBase):
def testVtyShow(self):
res = self.vty.command("show ns")
self.assertTrue(res.find('Encapsulation NS-UDP-IP') >= 0)
self.assertTrue(res.find('0 NS-VC:') >= 0)
self.assertTrue(self.vty.verify('show bssgp', ['']))
self.assertTrue(self.vty.verify('show bssgp stats', ['']))
self.assertTrue(self.vty.verify('show bssgp nsei 123', ['']))