Change in libosmocore[master]: gprs_ns2_sns: Unify handling of SNS-CONFIG for IPv4 + IPv6

laforge gerrit-no-reply at lists.osmocom.org
Fri Mar 5 09:41:12 UTC 2021


laforge has uploaded this change for review. ( https://gerrit.osmocom.org/c/libosmocore/+/23245 )


Change subject: gprs_ns2_sns: Unify handling of SNS-CONFIG for IPv4 + IPv6
......................................................................

gprs_ns2_sns: Unify handling of SNS-CONFIG for IPv4 + IPv6

Related: OS#3373
Change-Id: I49e5ca4a09bc772ef5a0cd5c2a76c8b200e56d1b
---
M src/gb/gprs_ns2_sns.c
1 file changed, 70 insertions(+), 108 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/45/23245/1

diff --git a/src/gb/gprs_ns2_sns.c b/src/gb/gprs_ns2_sns.c
index 1d4d069..e008d0f 100644
--- a/src/gb/gprs_ns2_sns.c
+++ b/src/gb/gprs_ns2_sns.c
@@ -3,7 +3,7 @@
  * 3GPP TS 08.16 version 8.0.1 Release 1999 / ETSI TS 101 299 V8.0.1 (2002-05)
  * as well as its successor 3GPP TS 48.016 */
 
-/* (C) 2018 by Harald Welte <laforge at gnumonks.org>
+/* (C) 2018-2021 by Harald Welte <laforge at gnumonks.org>
  * (C) 2020 by sysmocom - s.f.m.c. GmbH <info at sysmocom.de>
  * Author: Alexander Couzens <lynxis at fe80.eu>
  *
@@ -205,6 +205,14 @@
 #define ip6_weight_sum_data(x,y)	ip6_weight_sum(x, y, true)
 #define ip6_weight_sum_sig(x,y)		ip6_weight_sum(x, y, false)
 
+static int nss_weight_sum(const struct ns2_sns_state *nss, bool data_weight)
+{
+	return ip4_weight_sum(nss->ip4_remote, nss->num_ip4_remote, data_weight) +
+	       ip6_weight_sum(nss->ip6_remote, nss->num_ip6_remote, data_weight);
+}
+#define nss_weight_sum_data(nss)	nss_weight_sum(nss, true)
+#define nss_weight_sum_sig(nss)		nss_weight_sum(nss, false)
+
 static struct gprs_ns2_vc *nsvc_by_ip4_elem(struct gprs_ns2_nse *nse,
 					    const struct gprs_ns_ie_ip4_elem *ip4)
 {
@@ -926,105 +934,51 @@
 	return secs;
 }
 
-static void ns_sns_st_config_sgsn_ip4(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+/* append the remote endpoints from the parsed TLV array to the ns2_sns_state */
+static int ns_sns_append_remote_eps(struct osmo_fsm_inst *fi, const struct tlv_parsed *tp)
 {
 	struct ns2_sns_state *gss = (struct ns2_sns_state *) fi->priv;
-	struct gprs_ns2_nse *nse = nse_inst_from_fi(fi);
-	const struct gprs_ns_ie_ip4_elem *v4_list;
-	unsigned int num_v4;
-	struct tlv_parsed *tp = NULL;
 
-	uint8_t cause;
+	if (TLVP_PRESENT(tp, NS_IE_IPv4_LIST)) {
+		const struct gprs_ns_ie_ip4_elem *v4_list;
+		unsigned int num_v4;
+		v4_list = (const struct gprs_ns_ie_ip4_elem *) TLVP_VAL(tp, NS_IE_IPv4_LIST);
+		num_v4 = TLVP_LEN(tp, NS_IE_IPv4_LIST) / sizeof(*v4_list);
 
-	tp = (struct tlv_parsed *) data;
+		if (num_v4 && gss->ip6_remote)
+			return -NS_CAUSE_INVAL_NR_IPv4_EP;
 
-	if (!TLVP_PRESENT(tp, NS_IE_IPv4_LIST)) {
-		cause = NS_CAUSE_INVAL_NR_IPv4_EP;
-		ns2_tx_sns_config_ack(gss->sns_nsvc, &cause);
-		osmo_fsm_inst_state_chg(fi, GPRS_SNS_ST_UNCONFIGURED, 0, 0);
-		return;
+		/* realloc to the new size */
+		gss->ip4_remote = talloc_realloc(gss, gss->ip4_remote,
+						 struct gprs_ns_ie_ip4_elem,
+						 gss->num_ip4_remote+num_v4);
+		/* append the new entries to the end of the list */
+		memcpy(&gss->ip4_remote[gss->num_ip4_remote], v4_list, num_v4*sizeof(*v4_list));
+		gss->num_ip4_remote += num_v4;
+
+		LOGPFSML(fi, LOGL_INFO, "Rx SNS-CONFIG: Remote IPv4 list now %u entries\n",
+			 gss->num_ip4_remote);
 	}
-	v4_list = (const struct gprs_ns_ie_ip4_elem *) TLVP_VAL(tp, NS_IE_IPv4_LIST);
-	num_v4 = TLVP_LEN(tp, NS_IE_IPv4_LIST) / sizeof(*v4_list);
-	/* realloc to the new size */
-	gss->ip4_remote = talloc_realloc(gss, gss->ip4_remote,
-					 struct gprs_ns_ie_ip4_elem,
-					 gss->num_ip4_remote+num_v4);
-	/* append the new entries to the end of the list */
-	memcpy(&gss->ip4_remote[gss->num_ip4_remote], v4_list, num_v4*sizeof(*v4_list));
-	gss->num_ip4_remote += num_v4;
 
-	LOGPFSML(fi, LOGL_INFO, "Rx SNS-CONFIG: Remote IPv4 list now %u entries\n",
-					 gss->num_ip4_remote);
-	if (event == GPRS_SNS_EV_RX_CONFIG_END) {
-		/* check if sum of data / sig weights == 0 */
-		if (ip4_weight_sum_data(gss->ip4_remote, gss->num_ip4_remote) == 0 ||
-				ip4_weight_sum_sig(gss->ip4_remote, gss->num_ip4_remote) == 0) {
-			cause = NS_CAUSE_INVAL_WEIGH;
-			ns2_tx_sns_config_ack(gss->sns_nsvc, &cause);
-			osmo_fsm_inst_state_chg(fi, GPRS_SNS_ST_UNCONFIGURED, 0, 0);
-			return;
-		}
-		create_missing_nsvcs(fi);
-		ns2_tx_sns_config_ack(gss->sns_nsvc, NULL);
-		/* start the test procedure on ALL NSVCs! */
-		gprs_ns2_start_alive_all_nsvcs(nse);
-		osmo_fsm_inst_state_chg(fi, GPRS_SNS_ST_CONFIGURED, ns_sns_configured_timeout(fi), 4);
-	} else {
-		/* just send CONFIG-ACK */
-		ns2_tx_sns_config_ack(gss->sns_nsvc, NULL);
-		osmo_timer_schedule(&fi->timer, nse->nsi->timeout[NS_TOUT_TSNS_PROV], 0);
-	}
-}
+	if (TLVP_PRESENT(tp, NS_IE_IPv6_LIST)) {
+		const struct gprs_ns_ie_ip6_elem *v6_list;
+		unsigned int num_v6;
+		v6_list = (const struct gprs_ns_ie_ip6_elem *) TLVP_VAL(tp, NS_IE_IPv6_LIST);
+		num_v6 = TLVP_LEN(tp, NS_IE_IPv6_LIST) / sizeof(*v6_list);
 
-static void ns_sns_st_config_sgsn_ip6(struct osmo_fsm_inst *fi, uint32_t event, void *data)
-{
-	struct ns2_sns_state *gss = (struct ns2_sns_state *) fi->priv;
-	struct gprs_ns2_nse *nse = nse_inst_from_fi(fi);
-	const struct gprs_ns_ie_ip6_elem *v6_list;
-	unsigned int num_v6;
-	struct tlv_parsed *tp = NULL;
+		if (num_v6 && gss->ip4_remote)
+			return -NS_CAUSE_INVAL_NR_IPv6_EP;
 
-	uint8_t cause;
+		/* realloc to the new size */
+		gss->ip6_remote = talloc_realloc(gss, gss->ip6_remote,
+						 struct gprs_ns_ie_ip6_elem,
+						 gss->num_ip6_remote+num_v6);
+		/* append the new entries to the end of the list */
+		memcpy(&gss->ip6_remote[gss->num_ip6_remote], v6_list, num_v6*sizeof(*v6_list));
+		gss->num_ip6_remote += num_v6;
 
-	tp = (struct tlv_parsed *) data;
-
-	if (!TLVP_PRESENT(tp, NS_IE_IPv6_LIST)) {
-		cause = NS_CAUSE_INVAL_NR_IPv6_EP;
-		ns2_tx_sns_config_ack(gss->sns_nsvc, &cause);
-		osmo_fsm_inst_state_chg(fi, GPRS_SNS_ST_UNCONFIGURED, 0, 0);
-		return;
-	}
-	v6_list = (const struct gprs_ns_ie_ip6_elem *) TLVP_VAL(tp, NS_IE_IPv6_LIST);
-	num_v6 = TLVP_LEN(tp, NS_IE_IPv6_LIST) / sizeof(*v6_list);
-	/* realloc to the new size */
-	gss->ip6_remote = talloc_realloc(gss, gss->ip6_remote,
-					 struct gprs_ns_ie_ip6_elem,
-					 gss->num_ip6_remote+num_v6);
-	/* append the new entries to the end of the list */
-	memcpy(&gss->ip6_remote[gss->num_ip6_remote], v6_list, num_v6*sizeof(*v6_list));
-	gss->num_ip6_remote += num_v6;
-
-	LOGPFSML(fi, LOGL_INFO, "Rx SNS-CONFIG: Remote IPv6 list now %u entries\n",
-					 gss->num_ip6_remote);
-	if (event == GPRS_SNS_EV_RX_CONFIG_END) {
-		/* check if sum of data / sig weights == 0 */
-		if (ip6_weight_sum_data(gss->ip6_remote, gss->num_ip6_remote) == 0 ||
-				ip6_weight_sum_sig(gss->ip6_remote, gss->num_ip6_remote) == 0) {
-			cause = NS_CAUSE_INVAL_WEIGH;
-			ns2_tx_sns_config_ack(gss->sns_nsvc, &cause);
-			osmo_fsm_inst_state_chg(fi, GPRS_SNS_ST_UNCONFIGURED, 0, 0);
-			return;
-		}
-		create_missing_nsvcs(fi);
-		ns2_tx_sns_config_ack(gss->sns_nsvc, NULL);
-		/* start the test procedure on ALL NSVCs! */
-		gprs_ns2_start_alive_all_nsvcs(nse);
-		osmo_fsm_inst_state_chg(fi, GPRS_SNS_ST_CONFIGURED, 0, 0);
-	} else {
-		/* just send CONFIG-ACK */
-		ns2_tx_sns_config_ack(gss->sns_nsvc, NULL);
-		osmo_timer_schedule(&fi->timer, nse->nsi->timeout[NS_TOUT_TSNS_PROV], 0);
+		LOGPFSML(fi, LOGL_INFO, "Rx SNS-CONFIG: Remote IPv6 list now %u entries\n",
+			 gss->num_ip6_remote);
 	}
 }
 
@@ -1039,29 +993,37 @@
 static void ns2_sns_st_config_sgsn(struct osmo_fsm_inst *fi, uint32_t event, void *data)
 {
 	struct ns2_sns_state *gss = (struct ns2_sns_state *) fi->priv;
+	struct gprs_ns2_nse *nse = nse_inst_from_fi(fi);
+	uint8_t cause;
+	int rc;
 
 	switch (event) {
 	case GPRS_SNS_EV_RX_CONFIG_END:
 	case GPRS_SNS_EV_RX_CONFIG:
-
-#if 0		/* part of incoming SNS-SIZE (doesn't happen on BSS side */
-		if (TLVP_PRESENT(tp, NS_IE_RESET_FLAG)) {
-			/* reset all existing config */
-			if (gss->ip4_remote)
-				talloc_free(gss->ip4_remote);
-			gss->num_ip4_remote = 0;
+		rc = ns_sns_append_remote_eps(fi, data);
+		if (rc < 0) {
+			cause = -rc;
+			ns2_tx_sns_config_ack(gss->sns_nsvc, &cause);
+			osmo_fsm_inst_state_chg(fi, GPRS_SNS_ST_UNCONFIGURED, 0, 0);
+			return;
 		}
-#endif
-		/* TODO: reject IPv6 elements on IPv4 mode and vice versa */
-		switch (gss->ip) {
-		case IPv4:
-			ns_sns_st_config_sgsn_ip4(fi, event, data);
-			break;
-		case IPv6:
-			ns_sns_st_config_sgsn_ip6(fi, event, data);
-			break;
-		default:
-			OSMO_ASSERT(0);
+		if (event == GPRS_SNS_EV_RX_CONFIG_END) {
+			/* check if sum of data / sig weights == 0 */
+			if (nss_weight_sum_data(gss) == 0 || nss_weight_sum_sig(gss) == 0) {
+				cause = NS_CAUSE_INVAL_WEIGH;
+				ns2_tx_sns_config_ack(gss->sns_nsvc, &cause);
+				osmo_fsm_inst_state_chg(fi, GPRS_SNS_ST_UNCONFIGURED, 0, 0);
+				return;
+			}
+			create_missing_nsvcs(fi);
+			ns2_tx_sns_config_ack(gss->sns_nsvc, NULL);
+			/* start the test procedure on ALL NSVCs! */
+			gprs_ns2_start_alive_all_nsvcs(nse);
+			osmo_fsm_inst_state_chg(fi, GPRS_SNS_ST_CONFIGURED, 0, 0);
+		} else {
+			/* just send CONFIG-ACK */
+			ns2_tx_sns_config_ack(gss->sns_nsvc, NULL);
+			osmo_timer_schedule(&fi->timer, nse->nsi->timeout[NS_TOUT_TSNS_PROV], 0);
 		}
 		break;
 	default:

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

Gerrit-Project: libosmocore
Gerrit-Branch: master
Gerrit-Change-Id: I49e5ca4a09bc772ef5a0cd5c2a76c8b200e56d1b
Gerrit-Change-Number: 23245
Gerrit-PatchSet: 1
Gerrit-Owner: laforge <laforge at osmocom.org>
Gerrit-MessageType: newchange
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20210305/fef099ca/attachment-0001.htm>


More information about the gerrit-log mailing list