From 2dee00b10dc8f9fbe60282cef9469d602d854ce1 Mon Sep 17 00:00:00 2001 From: Alexander Couzens Date: Thu, 3 Dec 2020 06:02:03 +0100 Subject: gprs_ns2: add member name to bind Every bind will have a unique name. Add a name argument to all bind creating functions and require them to be unique. This is an API break but there wasn't yet a release with NS2. Change-Id: I8f1d66b7b3b12da12db8b5e6bd08c1beff085b3e --- include/osmocom/gprs/gprs_ns2.h | 7 +++++++ src/gb/gprs_ns2.c | 19 +++++++++++++++++++ src/gb/gprs_ns2_fr.c | 20 ++++++++++++++++++-- src/gb/gprs_ns2_frgre.c | 13 +++++++++++++ src/gb/gprs_ns2_internal.h | 2 ++ src/gb/gprs_ns2_udp.c | 13 +++++++++++++ src/gb/gprs_ns2_vty.c | 4 ++-- src/gb/libosmogb.map | 1 + 8 files changed, 75 insertions(+), 4 deletions(-) diff --git a/include/osmocom/gprs/gprs_ns2.h b/include/osmocom/gprs/gprs_ns2.h index 6140da24..86bf1ae2 100644 --- a/include/osmocom/gprs/gprs_ns2.h +++ b/include/osmocom/gprs/gprs_ns2.h @@ -162,8 +162,13 @@ void gprs_ns2_free_nses(struct gprs_ns2_inst *nsi); void gprs_ns2_free_nsvc(struct gprs_ns2_vc *nsvc); struct gprs_ns2_vc *gprs_ns2_nsvc_by_nsvci(struct gprs_ns2_inst *nsi, uint16_t nsvci); +/* generic VL driver */ +struct gprs_ns2_vc_bind *gprs_ns2_bind_by_name(struct gprs_ns2_inst *nsi, + const char *name); + /* IP VL driver */ int gprs_ns2_ip_bind(struct gprs_ns2_inst *nsi, + const char *name, const struct osmo_sockaddr *local, int dscp, struct gprs_ns2_vc_bind **result); @@ -176,6 +181,7 @@ struct gprs_ns2_vc_bind *gprs_ns2_fr_bind_by_netif( const char *netif); const char *gprs_ns2_fr_bind_netif(struct gprs_ns2_vc_bind *bind); int gprs_ns2_fr_bind(struct gprs_ns2_inst *nsi, + const char *name, const char *netif, struct osmo_fr_network *fr_network, enum osmo_fr_role fr_role, @@ -226,6 +232,7 @@ struct gprs_ns2_vc *gprs_ns2_nsvc_by_sockaddr_bind( const struct osmo_sockaddr *saddr); int gprs_ns2_frgre_bind(struct gprs_ns2_inst *nsi, + const char *name, const struct osmo_sockaddr *local, int dscp, struct gprs_ns2_vc_bind **result); diff --git a/src/gb/gprs_ns2.c b/src/gb/gprs_ns2.c index 57590a5c..ed8737e6 100644 --- a/src/gb/gprs_ns2.c +++ b/src/gb/gprs_ns2.c @@ -1239,6 +1239,7 @@ void gprs_ns2_free_bind(struct gprs_ns2_vc_bind *bind) bind->driver->free_bind(bind); llist_del(&bind->list); + talloc_free((char *)bind->name); talloc_free(bind); } @@ -1251,6 +1252,24 @@ void gprs_ns2_free_binds(struct gprs_ns2_inst *nsi) } } +/*! Search for a bind with a unique name + * \param[in] nsi NS instance on which we operate + * \param[in] name The unique bind name to search for + * \return the bind or NULL if not found + */ +struct gprs_ns2_vc_bind *gprs_ns2_bind_by_name( + struct gprs_ns2_inst *nsi, const char *name) +{ + struct gprs_ns2_vc_bind *bind; + + llist_for_each_entry(bind, &nsi->binding, list) { + if (!strcmp(bind->name, name)) + return bind; + } + + return NULL; +} + enum gprs_ns2_vc_mode gprs_ns2_dialect_to_vc_mode( enum gprs_ns2_dialect dialect) { diff --git a/src/gb/gprs_ns2_fr.c b/src/gb/gprs_ns2_fr.c index 5b998198..b6900327 100644 --- a/src/gb/gprs_ns2_fr.c +++ b/src/gb/gprs_ns2_fr.c @@ -457,19 +457,33 @@ static void linkmon_initial_dump(struct osmo_mnl *omnl) * \param[out] result pointer to created bind * \return 0 on success; negative on error */ int gprs_ns2_fr_bind(struct gprs_ns2_inst *nsi, + const char *name, const char *netif, struct osmo_fr_network *fr_network, enum osmo_fr_role fr_role, struct gprs_ns2_vc_bind **result) { - struct gprs_ns2_vc_bind *bind = talloc_zero(nsi, struct gprs_ns2_vc_bind); + struct gprs_ns2_vc_bind *bind; struct priv_bind *priv; struct osmo_fr_link *fr_link; int rc = 0; + if (!name) + return -EINVAL; + + if (gprs_ns2_bind_by_name(nsi, name)) + return -EALREADY; + + bind = talloc_zero(nsi, struct gprs_ns2_vc_bind); if (!bind) return -ENOSPC; + bind->name = talloc_strdup(bind, name); + if (!bind->name) { + rc = -ENOSPC; + goto err_bind; + } + bind->driver = &vc_driver_fr; bind->ll = GPRS_NS2_LL_FR; bind->send_vc = fr_vc_sendmsg; @@ -479,7 +493,7 @@ int gprs_ns2_fr_bind(struct gprs_ns2_inst *nsi, priv = bind->priv = talloc_zero(bind, struct priv_bind); if (!priv) { rc = -ENOSPC; - goto err_bind; + goto err_name; } priv->fd.cb = fr_fd_cb; @@ -533,6 +547,8 @@ err_fr: osmo_fr_link_free(fr_link); err_priv: talloc_free(priv); +err_name: + talloc_free((char *)bind->name); err_bind: talloc_free(bind); diff --git a/src/gb/gprs_ns2_frgre.c b/src/gb/gprs_ns2_frgre.c index 423ea4b7..014517aa 100644 --- a/src/gb/gprs_ns2_frgre.c +++ b/src/gb/gprs_ns2_frgre.c @@ -538,6 +538,7 @@ int gprs_ns2_is_frgre_bind(struct gprs_ns2_vc_bind *bind) * \param[out] result pointer to created bind * \return 0 on success; negative on error */ int gprs_ns2_frgre_bind(struct gprs_ns2_inst *nsi, + const char *name, const struct osmo_sockaddr *local, int dscp, struct gprs_ns2_vc_bind **result) @@ -546,6 +547,12 @@ int gprs_ns2_frgre_bind(struct gprs_ns2_inst *nsi, struct priv_bind *priv; int rc; + if (!name) + return -ENOSPC; + + if (gprs_ns2_bind_by_name(nsi, name)) + return -EALREADY; + if (!bind) return -ENOSPC; @@ -554,6 +561,12 @@ int gprs_ns2_frgre_bind(struct gprs_ns2_inst *nsi, return -EINVAL; } + bind->name = talloc_strdup(bind, name); + if (!bind->name) { + talloc_free(bind); + return -ENOSPC; + } + bind->driver = &vc_driver_frgre; bind->ll = GPRS_NS2_LL_FR_GRE; bind->send_vc = frgre_vc_sendmsg; diff --git a/src/gb/gprs_ns2_internal.h b/src/gb/gprs_ns2_internal.h index 8c0c1354..9bfe0b05 100644 --- a/src/gb/gprs_ns2_internal.h +++ b/src/gb/gprs_ns2_internal.h @@ -181,6 +181,8 @@ struct gprs_ns2_vc { /*! Structure repesenting a bind instance. E.g. IPv4 listen port. */ struct gprs_ns2_vc_bind { + /*! unique name */ + const char *name; /*! list entry in nsi */ struct llist_head list; /*! list of all VC */ diff --git a/src/gb/gprs_ns2_udp.c b/src/gb/gprs_ns2_udp.c index c078badf..c0ab5f5e 100644 --- a/src/gb/gprs_ns2_udp.c +++ b/src/gb/gprs_ns2_udp.c @@ -298,6 +298,7 @@ struct gprs_ns2_vc_bind *gprs_ns2_ip_bind_by_sockaddr(struct gprs_ns2_inst *nsi, * \param[out] result if set, returns the bind object * \return 0 on success; negative in case of error */ int gprs_ns2_ip_bind(struct gprs_ns2_inst *nsi, + const char *name, const struct osmo_sockaddr *local, int dscp, struct gprs_ns2_vc_bind **result) @@ -306,6 +307,12 @@ int gprs_ns2_ip_bind(struct gprs_ns2_inst *nsi, struct priv_bind *priv; int rc; + if (!name) + return -EINVAL; + + if (gprs_ns2_bind_by_name(nsi, name)) + return -EALREADY; + bind = gprs_ns2_ip_bind_by_sockaddr(nsi, local); if (bind) { *result = bind; @@ -316,6 +323,12 @@ int gprs_ns2_ip_bind(struct gprs_ns2_inst *nsi, if (!bind) return -ENOSPC; + bind->name = talloc_strdup(bind, name); + if (!bind->name) { + talloc_free(bind); + return -ENOSPC; + } + if (local->u.sa.sa_family != AF_INET && local->u.sa.sa_family != AF_INET6) { talloc_free(bind); return -EINVAL; diff --git a/src/gb/gprs_ns2_vty.c b/src/gb/gprs_ns2_vty.c index 84886c24..60daa920 100644 --- a/src/gb/gprs_ns2_vty.c +++ b/src/gb/gprs_ns2_vty.c @@ -895,7 +895,7 @@ int gprs_ns2_vty_create() { } else { /* UDP */ osmo_sockaddr_str_to_sockaddr(&priv.udp, &sockaddr.u.sas); - if (gprs_ns2_ip_bind(vty_nsi, &sockaddr, priv.dscp, &bind)) { + if (gprs_ns2_ip_bind(vty_nsi, "vtybind", &sockaddr, priv.dscp, &bind)) { /* TODO: could not bind on the specific address */ return -1; } @@ -961,7 +961,7 @@ int gprs_ns2_vty_create() { vty_nsi, vtyvc->netif); if (!fr) { - rc = gprs_ns2_fr_bind(vty_nsi, vtyvc->netif, vty_fr_network, vtyvc->fr.role, &fr); + rc = gprs_ns2_fr_bind(vty_nsi, vtyvc->netif, vtyvc->netif, vty_fr_network, vtyvc->fr.role, &fr); if (rc < 0) { LOGP(DLNS, LOGL_ERROR, "Can not create fr bind on device %s err: %d\n", vtyvc->netif, rc); return rc; diff --git a/src/gb/libosmogb.map b/src/gb/libosmogb.map index fab1deba..e828523e 100644 --- a/src/gb/libosmogb.map +++ b/src/gb/libosmogb.map @@ -82,6 +82,7 @@ gprs_ns_ll_clear; gprs_ns_msgb_alloc; gprs_ns2_aff_cause_prim_strs; +gprs_ns2_bind_by_name; gprs_ns2_cause_strs; gprs_ns2_create_nse; gprs_ns2_dynamic_create_nse; -- cgit v1.2.3