lynxis lazus has uploaded this change for review. ( 
https://gerrit.osmocom.org/c/libosmocore/+/21484 )


Change subject: gprs_ns2: introduce NS dialects
......................................................................

gprs_ns2: introduce NS dialects

A NS dialect describes how the NS Entity interacts with
different virtual circuits. E.g. ipaccess use reset/block on udp
and is a dynamic connection.
A single NS Entity can only support one dialect. This can be later
used to protect a NS Entity against dynamic NS virtual circuits of a
different type.

It further allows a bind to support multiple dialects at the same time.

Change-Id: Ia118bb6f994845d84db09de7a94856f5ca573404
---
M include/osmocom/gprs/gprs_ns2.h
M src/gb/gprs_ns2.c
M src/gb/gprs_ns2_fr.c
M src/gb/gprs_ns2_internal.h
M src/gb/gprs_ns2_udp.c
M src/gb/gprs_ns2_vty.c
M src/gb/libosmogb.map
7 files changed, 68 insertions(+), 28 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/84/21484/1

diff --git a/include/osmocom/gprs/gprs_ns2.h b/include/osmocom/gprs/gprs_ns2.h
index 4575329..ccb1a94 100644
--- a/include/osmocom/gprs/gprs_ns2.h
+++ b/include/osmocom/gprs/gprs_ns2.h
@@ -32,6 +32,13 @@
        NS2_VC_MODE_ALIVE,
 };

+enum gprs_ns2_dialect {
+       NS2_DIALECT_STATIC_ALIVE,
+       NS2_DIALECT_STATIC_RESETBLOCK,
+       NS2_DIALECT_IPACCESS,
+       NS2_DIALECT_SNS,
+};
+
 /*! Osmocom NS link layer types */
 enum gprs_ns2_ll {
        GPRS_NS2_LL_UDP,        /*!< NS/UDP/IP */
@@ -144,7 +151,8 @@
                              gprs_ns2_foreach_nsvc_cb cb, void *cb_data);
 struct gprs_ns2_nse *gprs_ns2_nse_by_nsei(struct gprs_ns2_inst *nsi, uint16_t 
nsei);
 struct gprs_ns2_nse *gprs_ns2_create_nse(struct gprs_ns2_inst *nsi, uint16_t 
nsei,
-                                        enum gprs_ns2_ll linklayer);
+                                        enum gprs_ns2_ll linklayer,
+                                        enum gprs_ns2_dialect dialect);
 uint16_t gprs_ns2_nse_nsei(struct gprs_ns2_nse *nse);
 void gprs_ns2_free_nse(struct gprs_ns2_nse *nse);
 void gprs_ns2_free_nses(struct gprs_ns2_inst *nsi);
@@ -160,7 +168,6 @@
                     struct gprs_ns2_vc_bind **result);
 struct gprs_ns2_vc_bind *gprs_ns2_ip_bind_by_sockaddr(struct gprs_ns2_inst 
*nsi,
                                                      const struct 
osmo_sockaddr *sockaddr);
-void gprs_ns2_bind_set_mode(struct gprs_ns2_vc_bind *bind, enum 
gprs_ns2_vc_mode mode);

 /* FR VL driver */
 struct gprs_ns2_vc_bind *gprs_ns2_fr_bind_by_netif(
@@ -188,7 +195,8 @@
 struct gprs_ns2_vc *gprs_ns2_ip_connect2(struct gprs_ns2_vc_bind *bind,
                                         const struct osmo_sockaddr *remote,
                                         uint16_t nsei,
-                                        uint16_t nsvci);
+                                        uint16_t nsvci,
+                                        enum gprs_ns2_dialect dialect);
 struct gprs_ns2_vc *gprs_ns2_ip_connect_inactive(struct gprs_ns2_vc_bind *bind,
                                        const struct osmo_sockaddr *remote,
                                        struct gprs_ns2_nse *nse,
diff --git a/src/gb/gprs_ns2.c b/src/gb/gprs_ns2.c
index 69c1174..a2443ea 100644
--- a/src/gb/gprs_ns2.c
+++ b/src/gb/gprs_ns2.c
@@ -491,7 +491,8 @@
  * \param[in] nse The NS Entity on which we operate
  * \param[in] initiater - if this is an incoming remote (!initiater) or a 
local outgoing connection (initater)
  * \return newly allocated NS-VC on success; NULL on error */
-struct gprs_ns2_vc *ns2_vc_alloc(struct gprs_ns2_vc_bind *bind, struct 
gprs_ns2_nse *nse, bool initiater)
+struct gprs_ns2_vc *ns2_vc_alloc(struct gprs_ns2_vc_bind *bind, struct 
gprs_ns2_nse *nse, bool initiater,
+                                enum gprs_ns2_vc_mode vc_mode)
 {
        struct gprs_ns2_vc *nsvc = talloc_zero(bind, struct gprs_ns2_vc);

@@ -500,7 +501,7 @@

        nsvc->bind = bind;
        nsvc->nse = nse;
-       nsvc->mode = bind->vc_mode;
+       nsvc->mode = vc_mode;
        nsvc->sig_weight = 1;
        nsvc->data_weight = 1;

@@ -671,7 +672,8 @@
  *  \param[in] nsi NS instance in which to create NS Entity
  *  \param[in] nsei NS Entity Identifier of to-be-created NSE
  *  \returns newly-allocated NS-E in successful case; NULL on error */
-struct gprs_ns2_nse *gprs_ns2_create_nse(struct gprs_ns2_inst *nsi, uint16_t 
nsei, enum gprs_ns2_ll linklayer)
+struct gprs_ns2_nse *gprs_ns2_create_nse(struct gprs_ns2_inst *nsi, uint16_t 
nsei,
+                                        enum gprs_ns2_ll linklayer, enum 
gprs_ns2_dialect dialect)
 {
        struct gprs_ns2_nse *nse;

@@ -685,6 +687,7 @@
        if (!nse)
                return NULL;

+       nse->dialect = dialect;
        nse->ll = linklayer;
        nse->nsei = nsei;
        nse->nsi = nsi;
@@ -764,6 +767,8 @@
        struct tlv_parsed tp;
        struct gprs_ns2_vc *nsvc;
        struct gprs_ns2_nse *nse;
+       enum gprs_ns2_dialect dialect;
+       enum gprs_ns2_vc_mode vc_mode;
        uint16_t nsvci;
        uint16_t nsei;

@@ -793,8 +798,10 @@
                return GPRS_NS2_CS_SKIPPED;
        case NS_PDUT_RESET:
                /* accept PDU RESET when vc_mode matches */
-               if (bind->vc_mode == NS2_VC_MODE_BLOCKRESET)
+               if (bind->accept_ipaccess) {
+                       dialect = NS2_DIALECT_IPACCESS;
                        break;
+               }

                rc = reject_status_msg(msg, &tp, reject, 
NS_CAUSE_PDU_INCOMP_PSTATE);
                if (rc < 0) {
@@ -836,13 +843,14 @@
                        return GPRS_NS2_CS_SKIPPED;
                }

-               nse = gprs_ns2_create_nse(bind->nsi, nsei, bind->ll);
+               nse = gprs_ns2_create_nse(bind->nsi, nsei, bind->ll, dialect);
                if (!nse) {
                        return GPRS_NS2_CS_ERROR;
                }
        }

-       nsvc = ns2_vc_alloc(bind, nse, false);
+       vc_mode = gprs_ns2_dialect_to_vc_mode(dialect);
+       nsvc = ns2_vc_alloc(bind, nse, false, vc_mode);
        if (!nsvc)
                return GPRS_NS2_CS_SKIPPED;

@@ -910,12 +918,13 @@
 struct gprs_ns2_vc *gprs_ns2_ip_connect2(struct gprs_ns2_vc_bind *bind,
                                         const struct osmo_sockaddr *remote,
                                         uint16_t nsei,
-                                        uint16_t nsvci)
+                                        uint16_t nsvci,
+                                        enum gprs_ns2_dialect dialect)
 {
        struct gprs_ns2_nse *nse = gprs_ns2_nse_by_nsei(bind->nsi, nsei);

        if (!nse) {
-               nse = gprs_ns2_create_nse(bind->nsi, nsei, GPRS_NS2_LL_UDP);
+               nse = gprs_ns2_create_nse(bind->nsi, nsei, GPRS_NS2_LL_UDP, 
dialect);
                if (!nse)
                        return NULL;
        }
@@ -936,7 +945,7 @@
        struct gprs_ns2_vc *nsvc;

        if (!nse) {
-               nse = gprs_ns2_create_nse(bind->nsi, nsei, GPRS_NS2_LL_UDP);
+               nse = gprs_ns2_create_nse(bind->nsi, nsei, GPRS_NS2_LL_UDP, 
NS2_DIALECT_SNS);
                if (!nse)
                        return -1;
        }
@@ -1195,14 +1204,6 @@
        }
 }

-/*! Set the mode of given bind.
- *  \param[in] bind the bind we want to set the mode of
- *  \param[in] mode mode to set bind to */
-void gprs_ns2_bind_set_mode(struct gprs_ns2_vc_bind *bind, enum 
gprs_ns2_vc_mode mode)
-{
-       bind->vc_mode = mode;
-}
-
 /*! Destroy a given bind.
  *  \param[in] bind the bind we want to destroy */
 void gprs_ns2_free_bind(struct gprs_ns2_vc_bind *bind)
@@ -1230,4 +1231,20 @@
                gprs_ns2_free_bind(bind);
        }
 }
+
+enum gprs_ns2_vc_mode gprs_ns2_dialect_to_vc_mode(
+               enum gprs_ns2_dialect dialect)
+{
+       switch (dialect) {
+       case NS2_DIALECT_SNS:
+       case NS2_DIALECT_STATIC_ALIVE:
+               return NS2_VC_MODE_ALIVE;
+       case NS2_DIALECT_STATIC_RESETBLOCK:
+       case NS2_DIALECT_IPACCESS:
+               return NS2_VC_MODE_BLOCKRESET;
+       default:
+               return -1;
+       }
+}
+
 /*! @} */
diff --git a/src/gb/gprs_ns2_fr.c b/src/gb/gprs_ns2_fr.c
index 3cf44ef..9327d54 100644
--- a/src/gb/gprs_ns2_fr.c
+++ b/src/gb/gprs_ns2_fr.c
@@ -595,7 +595,7 @@
        struct priv_vc *priv = NULL;
        struct gprs_ns2_nse *nse = gprs_ns2_nse_by_nsei(bind->nsi, nsei);
        if (!nse) {
-               nse = gprs_ns2_create_nse(bind->nsi, nsei, GPRS_NS2_LL_FR);
+               nse = gprs_ns2_create_nse(bind->nsi, nsei, GPRS_NS2_LL_FR, 
NS2_DIALECT_STATIC_RESETBLOCK);
                if (!nse)
                        return NULL;
                created_nse = true;
@@ -606,7 +606,7 @@
                goto err_nse;
        }

-       nsvc = ns2_vc_alloc(bind, nse, true);
+       nsvc = ns2_vc_alloc(bind, nse, true, NS2_VC_MODE_BLOCKRESET);
        if (!nsvc)
                goto err_nse;

diff --git a/src/gb/gprs_ns2_internal.h b/src/gb/gprs_ns2_internal.h
index e72deff..a8a4321 100644
--- a/src/gb/gprs_ns2_internal.h
+++ b/src/gb/gprs_ns2_internal.h
@@ -130,6 +130,9 @@
        /*! which link-layer are we based on? */
        enum gprs_ns2_ll ll;

+       /*! which dialect does this NSE speaks? */
+       enum gprs_ns2_dialect dialect;
+
        struct osmo_fsm_inst *bss_sns_fi;
 };

@@ -188,8 +191,8 @@
        struct gprs_ns2_inst *nsi;
        struct gprs_ns2_vc_driver *driver;

-       /*! if VCs use reset/block/unblock method. IP shall not use this */
-       enum gprs_ns2_vc_mode vc_mode;
+       bool accept_ipaccess;
+       bool accept_sns;

        /*! which link-layer are we based on? */
        enum gprs_ns2_ll ll;
@@ -222,7 +225,8 @@

 struct gprs_ns2_vc *ns2_vc_alloc(struct gprs_ns2_vc_bind *bind,
                                 struct gprs_ns2_nse *nse,
-                                bool initiater);
+                                bool initiater,
+                                enum gprs_ns2_vc_mode vc_mode);

 struct msgb *gprs_ns2_msgb_alloc(void);

@@ -303,3 +307,4 @@

 /* nse */
 void ns2_nse_notify_unblocked(struct gprs_ns2_vc *nsvc, bool unblocked);
+enum gprs_ns2_vc_mode gprs_ns2_dialect_to_vc_mode(enum gprs_ns2_dialect 
dialect);
diff --git a/src/gb/gprs_ns2_udp.c b/src/gb/gprs_ns2_udp.c
index 928116d..a8cca47 100644
--- a/src/gb/gprs_ns2_udp.c
+++ b/src/gb/gprs_ns2_udp.c
@@ -378,8 +378,15 @@
 {
        struct gprs_ns2_vc *nsvc;
        struct priv_vc *priv;
+       enum gprs_ns2_vc_mode vc_mode;

-       nsvc = ns2_vc_alloc(bind, nse, true);
+       vc_mode = gprs_ns2_dialect_to_vc_mode(nse->dialect);
+       if (vc_mode == -1) {
+               LOGP(DLNS, LOGL_ERROR, "Can not derive vc mode from dialect. 
Maybe libosmocore is too old.\n");
+               return NULL;
+       }
+
+       nsvc = ns2_vc_alloc(bind, nse, true, vc_mode);
        if (!nsvc)
                return NULL;

diff --git a/src/gb/gprs_ns2_vty.c b/src/gb/gprs_ns2_vty.c
index 8b8a999..1650ba9 100644
--- a/src/gb/gprs_ns2_vty.c
+++ b/src/gb/gprs_ns2_vty.c
@@ -858,6 +858,7 @@
        struct gprs_ns2_nse *nse;
        struct gprs_ns2_vc *nsvc;
        struct osmo_sockaddr sockaddr;
+       enum gprs_ns2_dialect dialect;
        int rc = 0;

        if (!vty_nsi)
@@ -882,6 +883,7 @@
                /* validate settings */
                switch (vtyvc->ll) {
                case GPRS_NS2_LL_UDP:
+                       dialect = NS2_DIALECT_STATIC_ALIVE;
                        if (strlen(vtyvc->remote.ip) == 0) {
                                /* Invalid IP for VC */
                                continue;
@@ -898,14 +900,16 @@
                        }
                        break;
                case GPRS_NS2_LL_FR:
+                       dialect = NS2_DIALECT_STATIC_RESETBLOCK;
                        break;
                case GPRS_NS2_LL_FR_GRE:
+                       dialect = NS2_DIALECT_STATIC_RESETBLOCK;
                        continue;
                }

                nse = gprs_ns2_nse_by_nsei(vty_nsi, vtyvc->nsei);
                if (!nse) {
-                       nse = gprs_ns2_create_nse(vty_nsi, vtyvc->nsei, 
vtyvc->ll);
+                       nse = gprs_ns2_create_nse(vty_nsi, vtyvc->nsei, 
vtyvc->ll, dialect);
                        if (!nse) {
                                /* Could not create NSE for VTY */
                                continue;
diff --git a/src/gb/libosmogb.map b/src/gb/libosmogb.map
index 2c4e897..d390035 100644
--- a/src/gb/libosmogb.map
+++ b/src/gb/libosmogb.map
@@ -82,7 +82,6 @@
 gprs_ns_msgb_alloc;

 gprs_ns2_aff_cause_prim_strs;
-gprs_ns2_bind_set_mode;
 gprs_ns2_cause_strs;
 gprs_ns2_create_nse;
 gprs_ns2_dynamic_create_nse;

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

Gerrit-Project: libosmocore
Gerrit-Branch: master
Gerrit-Change-Id: Ia118bb6f994845d84db09de7a94856f5ca573404
Gerrit-Change-Number: 21484
Gerrit-PatchSet: 1
Gerrit-Owner: lynxis lazus <lyn...@fe80.eu>
Gerrit-MessageType: newchange

Reply via email to