gprs_ns2_vc_fsm: check NSEI match the NSE

The NSE must match the PDUs. The only exception is a RESET with
dialect ipaccess. However those will be handled later.

Change-Id: I00bc04f3f46f5ae8ddd8b4b7d5479fb8e6463e1e
diff --git a/src/gb/gprs_ns2_vc_fsm.c b/src/gb/gprs_ns2_vc_fsm.c
index fc2a86a..3ec6909 100644
--- a/src/gb/gprs_ns2_vc_fsm.c
+++ b/src/gb/gprs_ns2_vc_fsm.c
@@ -750,6 +750,7 @@
 	struct osmo_fsm_inst *fi = nsvc->fi;
 	int rc = 0;
 	uint8_t cause;
+	uint16_t nsei;
 
 	/* TODO: 7.2: on UNBLOCK/BLOCK: check if NS-VCI is correct,
 	 *  if not answer STATUS with "NS-VC unknown" */
@@ -763,6 +764,19 @@
 		}
 	}
 
+	if (TLVP_PRESENT(tp, NS_IE_NSEI)) {
+		nsei = tlvp_val16be(tp, NS_IE_NSEI);
+		if (nsei != nsvc->nse->nsei) {
+			/* 48.016 § 7.3.1 send, RESET_ACK to wrong NSVCI + ignore */
+			if (nsh->pdu_type == NS_PDUT_RESET)
+				ns2_tx_reset_ack(nsvc);
+
+			LOGNSVC(nsvc, LOGL_ERROR, "Rx %s with wrong NSEI=%05u. Ignoring PDU.\n",
+				get_value_string(gprs_ns_pdu_strings, nsh->pdu_type), nsei);
+			goto out;
+		}
+	}
+
 	switch (nsh->pdu_type) {
 	case NS_PDUT_RESET:
 		osmo_fsm_inst_dispatch(fi, GPRS_NS2_EV_RX_RESET, tp);