Change in libosmocore[master]: gprs_ns2_sns: Implement checks during processing of inbound SNS-SIZE

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

laforge gerrit-no-reply at lists.osmocom.org
Tue Mar 23 23:53:31 UTC 2021


laforge has submitted this change. ( https://gerrit.osmocom.org/c/libosmocore/+/23412 )

Change subject: gprs_ns2_sns: Implement checks during processing of inbound SNS-SIZE
......................................................................

gprs_ns2_sns: Implement checks during processing of inbound SNS-SIZE

As per 3GPP TS 48.016 section 6.2.4.1, we need to perform some
consistency checks during the SNS-SIZE procedure.  Let's implement them.

Change-Id: I1638f04ba45fef3ba0b237948dff6022267141fb
Related: OS#3373
---
M src/gb/gprs_ns2_sns.c
1 file changed, 59 insertions(+), 1 deletion(-)

Approvals:
  Jenkins Builder: Verified
  daniel: Looks good to me, but someone else must approve
  lynxis lazus: Looks good to me, approved



diff --git a/src/gb/gprs_ns2_sns.c b/src/gb/gprs_ns2_sns.c
index 1af9631..11c5a8e 100644
--- a/src/gb/gprs_ns2_sns.c
+++ b/src/gb/gprs_ns2_sns.c
@@ -750,6 +750,31 @@
 	}
 }
 
+static int ns2_sns_count_num_local_ep(struct osmo_fsm_inst *fi, enum ns2_sns_type stype)
+{
+	struct ns2_sns_state *gss = (struct ns2_sns_state *) fi->priv;
+	struct ns2_sns_bind *sbind;
+	int count = 0;
+
+	llist_for_each_entry(sbind, &gss->binds, list) {
+		const struct osmo_sockaddr *sa = gprs_ns2_ip_bind_sockaddr(sbind->bind);
+		if (!sa)
+			continue;
+
+		switch (stype) {
+		case IPv4:
+			if (sa->u.sas.ss_family == AF_INET)
+				count++;
+			break;
+		case IPv6:
+			if (sa->u.sas.ss_family == AF_INET6)
+				count++;
+			break;
+		}
+	}
+	return count;
+}
+
 static void ns2_sns_compute_local_ep_from_binds(struct osmo_fsm_inst *fi)
 {
 	struct ns2_sns_state *gss = (struct ns2_sns_state *) fi->priv;
@@ -2019,7 +2044,6 @@
 	struct ns2_sns_state *gss = (struct ns2_sns_state *) fi->priv;
 	OSMO_ASSERT(gss->role == GPRS_SNS_ROLE_SGSN);
 
-	ns2_sns_compute_local_ep_from_binds(fi);
 	/* transmit SGSN-oriented SNS-CONFIG */
 	ns2_tx_sns_config(gss->sns_nsvc, true, gss->ip4_local, gss->num_ip4_local,
 			  gss->ip6_local, gss->num_ip6_local);
@@ -2123,6 +2147,7 @@
 {
 	struct ns2_sns_state *gss = (struct ns2_sns_state *) fi->priv;
 	struct tlv_parsed *tp = NULL;
+	size_t num_local_eps, num_remote_eps;
 	uint8_t flag;
 	uint8_t cause;
 
@@ -2144,6 +2169,39 @@
 			ns2_tx_sns_size_ack(gss->sns_nsvc, &cause);
 			break;
 		}
+		if (TLVP_PRES_LEN(tp, NS_IE_IPv4_EP_NR, 2))
+			gss->num_max_ip4_remote = tlvp_val16be(tp, NS_IE_IPv4_EP_NR);
+		if (TLVP_PRES_LEN(tp, NS_IE_IPv6_EP_NR, 2))
+			gss->num_max_ip6_remote = tlvp_val16be(tp, NS_IE_IPv6_EP_NR);
+		/* decide if we go for IPv4 or IPv6 */
+		if (gss->num_max_ip6_remote && ns2_sns_count_num_local_ep(fi, IPv6)) {
+			gss->ip = IPv6;
+			num_local_eps = gss->num_ip6_local;
+			num_remote_eps = gss->num_max_ip6_remote;
+		} else if (gss->num_max_ip4_remote && ns2_sns_count_num_local_ep(fi, IPv4)) {
+			gss->ip = IPv4;
+			num_local_eps = gss->num_ip4_local;
+			num_remote_eps = gss->num_max_ip4_remote;
+		} else {
+			if (gss->num_ip4_local && !gss->num_max_ip4_remote)
+				cause = NS_CAUSE_INVAL_NR_IPv4_EP;
+			else
+				cause = NS_CAUSE_INVAL_NR_IPv6_EP;
+			ns2_tx_sns_size_ack(gss->sns_nsvc, &cause);
+			break;
+		}
+		ns2_sns_compute_local_ep_from_binds(fi);
+		/* ensure number of NS-VCs is sufficient for full mesh */
+		gss->num_max_nsvcs = tlvp_val16be(tp, NS_IE_MAX_NR_NSVC);
+		if (gss->num_max_nsvcs < num_remote_eps * num_local_eps) {
+			LOGPFSML(fi, LOGL_ERROR, "%zu local and %zu remote EPs, requires %zu NS-VC, "
+				 "but BSS supports only %zu maximum NS-VCs\n", num_local_eps,
+				 num_remote_eps, num_local_eps * num_remote_eps, gss->num_max_nsvcs);
+			cause = NS_CAUSE_INVAL_NR_NS_VC;
+			ns2_tx_sns_size_ack(gss->sns_nsvc, &cause);
+			break;
+		}
+		/* perform state reset, if requested */
 		flag = *TLVP_VAL(tp, NS_IE_RESET_FLAG);
 		if (flag & 1) {
 			struct gprs_ns2_vc *nsvc, *nsvc2;

-- 
To view, visit https://gerrit.osmocom.org/c/libosmocore/+/23412
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: libosmocore
Gerrit-Branch: master
Gerrit-Change-Id: I1638f04ba45fef3ba0b237948dff6022267141fb
Gerrit-Change-Number: 23412
Gerrit-PatchSet: 6
Gerrit-Owner: laforge <laforge at osmocom.org>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: daniel <dwillmann at sysmocom.de>
Gerrit-Reviewer: laforge <laforge at osmocom.org>
Gerrit-Reviewer: lynxis lazus <lynxis at fe80.eu>
Gerrit-Reviewer: pespin <pespin at sysmocom.de>
Gerrit-MessageType: merged
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20210323/02b0f5d3/attachment.htm>


More information about the gerrit-log mailing list