aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/osmocom/gprs/gprs_ns.h2
-rw-r--r--src/gb/gprs_ns.c17
-rw-r--r--src/gb/gprs_ns_vty.c62
3 files changed, 57 insertions, 24 deletions
diff --git a/include/osmocom/gprs/gprs_ns.h b/include/osmocom/gprs/gprs_ns.h
index 02faa506..94d30368 100644
--- a/include/osmocom/gprs/gprs_ns.h
+++ b/include/osmocom/gprs/gprs_ns.h
@@ -97,6 +97,8 @@ struct gprs_ns_inst {
uint32_t remote_ip;
uint16_t remote_port;
int dscp;
+ /*! IPA compatibility: NS-RESET/BLOCK/UNBLOCK even on IP-SNS */
+ bool use_reset_block_unblock;
} nsip;
/*! NS-over-FR-over-GRE-over-IP specific bits */
struct {
diff --git a/src/gb/gprs_ns.c b/src/gb/gprs_ns.c
index 4e584adc..f1b36f44 100644
--- a/src/gb/gprs_ns.c
+++ b/src/gb/gprs_ns.c
@@ -327,7 +327,7 @@ struct gprs_nsvc *gprs_nsvc_create2(struct gprs_ns_inst *nsi, uint16_t nsvci,
nsvc->nsvci = nsvci;
nsvc->nsvci_is_valid = 1;
/* before RESET procedure: BLOCKED and DEAD */
- if (nsi->bss_sns_fi)
+ if (nsi->bss_sns_fi || !nsi->nsip.use_reset_block_unblock)
ns_set_state(nsvc, 0);
else
ns_set_state(nsvc, NSE_S_BLOCKED);
@@ -793,7 +793,7 @@ static void gprs_ns_timer_cb(void *data)
nsvc->nsi->timeout[NS_TOUT_TNS_ALIVE_RETRIES]) {
/* mark as dead (and blocked unless IP-SNS) */
rate_ctr_inc(&nsvc->ctrg->ctr[NS_CTR_DEAD]);
- if (!nsvc->nsi->bss_sns_fi) {
+ if (!nsvc->nsi->bss_sns_fi && nsvc->nsi->nsip.use_reset_block_unblock) {
ns_set_state(nsvc, NSE_S_BLOCKED);
rate_ctr_inc(&nsvc->ctrg->ctr[NS_CTR_BLOCKED]);
} else
@@ -804,7 +804,7 @@ static void gprs_ns_timer_cb(void *data)
nsvc->nsi->timeout[NS_TOUT_TNS_ALIVE_RETRIES]);
ns_osmo_signal_dispatch(nsvc, S_NS_ALIVE_EXP, 0);
/* FIXME: should we send this signal in case of SNS? */
- if (!nsvc->nsi->bss_sns_fi)
+ if (!nsvc->nsi->bss_sns_fi && nsvc->nsi->nsip.use_reset_block_unblock)
ns_osmo_signal_dispatch(nsvc, S_NS_BLOCK, NS_CAUSE_NSVC_BLOCKED);
return;
}
@@ -1758,8 +1758,12 @@ int gprs_ns_process_msg(struct gprs_ns_inst *nsi, struct msgb *msg,
* fine. */
if ((*nsvc)->state == NSE_S_BLOCKED)
rc = gprs_nsvc_reset((*nsvc), NS_CAUSE_PDU_INCOMP_PSTATE);
- else if (!((*nsvc)->state & NSE_S_RESET))
+ else if (!((*nsvc)->state & NSE_S_RESET)) {
+ /* if we're not alive, we cannot transmit the ACK; set ALIVE */
+ if (!((*nsvc)->state & NSE_S_ALIVE))
+ ns_mark_alive(*nsvc);
rc = gprs_ns_tx_alive_ack(*nsvc);
+ }
break;
case NS_PDUT_ALIVE_ACK:
ns_mark_alive(*nsvc);
@@ -1915,6 +1919,11 @@ struct gprs_ns_inst *gprs_ns_instantiate(gprs_ns_cb_t *cb, void *ctx)
llist_del(&nsi->unknown_nsvc->list);
INIT_LLIST_HEAD(&nsi->unknown_nsvc->list);
+ /* By default we are in IPA compatible mode, that is we use NS-RESET, NS-BLOCK
+ * and NS-UNBLOCK procedures even for an IP/UDP based Gb interface, in violation
+ * of 3GPP TS 48.016. */
+ nsi->nsip.use_reset_block_unblock = true;
+
return nsi;
}
diff --git a/src/gb/gprs_ns_vty.c b/src/gb/gprs_ns_vty.c
index 9cffb71d..bd53f2f1 100644
--- a/src/gb/gprs_ns_vty.c
+++ b/src/gb/gprs_ns_vty.c
@@ -90,6 +90,32 @@ static int config_write_ns(struct vty *vty)
vty_out(vty, "ns%s", VTY_NEWLINE);
+ /* global configuration must be written first, as some of it may be
+ * relevant when creating the NSE/NSVC later below */
+
+ if (vty_nsi->nsip.local_ip) {
+ ia.s_addr = osmo_htonl(vty_nsi->nsip.local_ip);
+ vty_out(vty, " encapsulation udp local-ip %s%s",
+ inet_ntoa(ia), VTY_NEWLINE);
+ }
+ if (vty_nsi->nsip.local_port)
+ vty_out(vty, " encapsulation udp local-port %u%s",
+ vty_nsi->nsip.local_port, VTY_NEWLINE);
+ if (vty_nsi->nsip.dscp)
+ vty_out(vty, " encapsulation udp dscp %d%s",
+ vty_nsi->nsip.dscp, VTY_NEWLINE);
+
+ vty_out(vty, " encapsulation udp use-reset-block-unblock %s%s",
+ vty_nsi->nsip.use_reset_block_unblock ? "enabled" : "disabled", VTY_NEWLINE);
+
+ vty_out(vty, " encapsulation framerelay-gre enabled %u%s",
+ vty_nsi->frgre.enabled ? 1 : 0, VTY_NEWLINE);
+ if (vty_nsi->frgre.local_ip) {
+ ia.s_addr = osmo_htonl(vty_nsi->frgre.local_ip);
+ vty_out(vty, " encapsulation framerelay-gre local-ip %s%s",
+ inet_ntoa(ia), VTY_NEWLINE);
+ }
+
llist_for_each_entry(nsvc, &vty_nsi->gprs_nsvcs, list) {
if (!nsvc->persistent)
continue;
@@ -130,26 +156,6 @@ static int config_write_ns(struct vty *vty)
get_value_string(gprs_ns_timer_strs, i),
vty_nsi->timeout[i], VTY_NEWLINE);
- if (vty_nsi->nsip.local_ip) {
- ia.s_addr = osmo_htonl(vty_nsi->nsip.local_ip);
- vty_out(vty, " encapsulation udp local-ip %s%s",
- inet_ntoa(ia), VTY_NEWLINE);
- }
- if (vty_nsi->nsip.local_port)
- vty_out(vty, " encapsulation udp local-port %u%s",
- vty_nsi->nsip.local_port, VTY_NEWLINE);
- if (vty_nsi->nsip.dscp)
- vty_out(vty, " encapsulation udp dscp %d%s",
- vty_nsi->nsip.dscp, VTY_NEWLINE);
-
- vty_out(vty, " encapsulation framerelay-gre enabled %u%s",
- vty_nsi->frgre.enabled ? 1 : 0, VTY_NEWLINE);
- if (vty_nsi->frgre.local_ip) {
- ia.s_addr = osmo_htonl(vty_nsi->frgre.local_ip);
- vty_out(vty, " encapsulation framerelay-gre local-ip %s%s",
- inet_ntoa(ia), VTY_NEWLINE);
- }
-
return CMD_SUCCESS;
}
@@ -500,6 +506,21 @@ DEFUN(cfg_nsip_dscp, cfg_nsip_dscp_cmd,
return CMD_SUCCESS;
}
+DEFUN(cfg_nsip_res_block_unblock, cfg_nsip_res_block_unblock_cmd,
+ "encapsulation udp use-reset-block-unblock (enabled|disabled)",
+ ENCAPS_STR "NS over UDP Encapsulation\n"
+ "Use NS-{RESET,BLOCK,UNBLOCK} procedures in violation of 3GPP TS 48.016\n"
+ "Enable NS-{RESET,BLOCK,UNBLOCK}\n"
+ "Disable NS-{RESET,BLOCK,UNBLOCK}\n")
+{
+ if (!strcmp(argv[0], "enabled"))
+ vty_nsi->nsip.use_reset_block_unblock = true;
+ else
+ vty_nsi->nsip.use_reset_block_unblock = false;
+
+ return CMD_SUCCESS;
+}
+
DEFUN(cfg_frgre_local_ip, cfg_frgre_local_ip_cmd,
"encapsulation framerelay-gre local-ip A.B.C.D",
ENCAPS_STR "NS over Frame Relay over GRE Encapsulation\n"
@@ -643,6 +664,7 @@ int gprs_ns_vty_init(struct gprs_ns_inst *nsi)
install_element(L_NS_NODE, &cfg_nsip_local_ip_cmd);
install_element(L_NS_NODE, &cfg_nsip_local_port_cmd);
install_element(L_NS_NODE, &cfg_nsip_dscp_cmd);
+ install_element(L_NS_NODE, &cfg_nsip_res_block_unblock_cmd);
install_element(L_NS_NODE, &cfg_frgre_enable_cmd);
install_element(L_NS_NODE, &cfg_frgre_local_ip_cmd);