summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--openbsc/include/openbsc/gprs_ns.h3
-rw-r--r--openbsc/src/gprs/gprs_ns.c25
-rw-r--r--openbsc/src/gprs/gprs_ns_vty.c2
3 files changed, 22 insertions, 8 deletions
diff --git a/openbsc/include/openbsc/gprs_ns.h b/openbsc/include/openbsc/gprs_ns.h
index 34b1b62d..4ccf4c7b 100644
--- a/openbsc/include/openbsc/gprs_ns.h
+++ b/openbsc/include/openbsc/gprs_ns.h
@@ -125,6 +125,9 @@ struct gprs_ns_inst {
/* linked lists of all NSVC in this instance */
struct llist_head gprs_nsvcs;
+ /* a NSVC object that's needed to deal with packets for unknown NSVC */
+ struct gprs_nsvc *unknown_nsvc;
+
uint16_t timeout[NS_TIMERS_COUNT];
/* which link-layer are we based on? */
diff --git a/openbsc/src/gprs/gprs_ns.c b/openbsc/src/gprs/gprs_ns.c
index 2853600d..50ab8203 100644
--- a/openbsc/src/gprs/gprs_ns.c
+++ b/openbsc/src/gprs/gprs_ns.c
@@ -44,6 +44,14 @@
* Those mappings are administratively configured.
*/
+/* This implementation has the following limitations:
+ * o Only one NS-VC for each NSE: No load-sharing function
+ * o NSVCI 65535 and 65534 are reserved for internal use
+ * o Only UDP is supported as of now, no frame relay support
+ * o The IP Sub-Network-Service (SNS) as specified in 48.016 is not implemented
+ * o There are no BLOCK and UNBLOCK timers (yet?)
+ */
+
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
@@ -633,17 +641,16 @@ int gprs_ns_rcvmsg(struct gprs_ns_inst *nsi, struct msgb *msg,
uint16_t nsei;
/* Only the RESET procedure creates a new NSVC */
if (nsh->pdu_type != NS_PDUT_RESET) {
- struct gprs_nsvc fake_nsvc;
- LOGP(DNS, LOGL_INFO, "Ignoring NS PDU type 0x%0x "
+ /* Since we have no NSVC, we have to use a fake */
+ nsvc = nsi->unknown_nsvc;
+ LOGP(DNS, LOGL_INFO, "Rejecting NS PDU type 0x%0x "
"from %s:%u for non-existing NS-VC\n",
nsh->pdu_type, inet_ntoa(saddr->sin_addr),
ntohs(saddr->sin_port));
- /* Since we have no NSVC, we have to create a fake */
- fake_nsvc.nsvci = fake_nsvc.nsei = 0;
- fake_nsvc.nsi = nsi;
- fake_nsvc.ip.bts_addr = *saddr;
- fake_nsvc.state = NSE_S_ALIVE;
- return gprs_ns_tx_status(&fake_nsvc,
+ nsvc->nsvci = nsvc->nsei = 0xfffe;
+ nsvc->ip.bts_addr = *saddr;
+ nsvc->state = NSE_S_ALIVE;
+ return gprs_ns_tx_status(nsvc,
NS_CAUSE_PDU_INCOMP_PSTATE, 0,
msg);
}
@@ -766,6 +773,8 @@ struct gprs_ns_inst *gprs_ns_instantiate(gprs_ns_cb_t *cb)
nsi->timeout[NS_TOUT_TNS_ALIVE] = 3;
nsi->timeout[NS_TOUT_TNS_ALIVE_RETRIES] = 10;
+ nsi->unknown_nsvc = nsvc_create(nsi, 0xfffe);
+
return nsi;
}
diff --git a/openbsc/src/gprs/gprs_ns_vty.c b/openbsc/src/gprs/gprs_ns_vty.c
index 08b0076c..8f0628af 100644
--- a/openbsc/src/gprs/gprs_ns_vty.c
+++ b/openbsc/src/gprs/gprs_ns_vty.c
@@ -109,6 +109,8 @@ static void dump_ns(struct vty *vty, struct gprs_ns_inst *nsi, int stats)
struct gprs_nsvc *nsvc;
llist_for_each_entry(nsvc, &nsi->gprs_nsvcs, list) {
+ if (nsvc == nsi->unknown_nsvc)
+ continue;
vty_out(vty, "NSEI %5u, NS-VC %5u, Remote: %-4s, %5s %9s",
nsvc->nsei, nsvc->nsvci,
nsvc->remote_end_is_sgsn ? "SGSN" : "BSS",