aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Welte <laforge@osmocom.org>2021-01-31 11:41:34 +0100
committerHarald Welte <laforge@osmocom.org>2021-02-01 09:39:29 +0100
commitc3aa8f903a58db8af5c2687a3c040fe9f49474fb (patch)
tree2566076c74bd220591bba69a240c0b1b390964ee
parentb40bf8ba3b60ed0f2b97b5a13a85712c4a09fe45 (diff)
ns2: Move to one common/shared ns2_bind_alloc()
Avoid code duplication between three different drivers by sharing the "core" of the bind initialization in a new, shared ns2_bind_alloc(). Change-Id: I535fc68e94fcd695de827dd922706adc1c5a2cb7
-rw-r--r--src/gb/gprs_ns2.c32
-rw-r--r--src/gb/gprs_ns2_fr.c38
-rw-r--r--src/gb/gprs_ns2_frgre.c32
-rw-r--r--src/gb/gprs_ns2_internal.h3
-rw-r--r--src/gb/gprs_ns2_udp.c30
-rw-r--r--tests/gb/gprs_ns2_test.c14
6 files changed, 66 insertions, 83 deletions
diff --git a/src/gb/gprs_ns2.c b/src/gb/gprs_ns2.c
index d4d215ce..4f3bc5e5 100644
--- a/src/gb/gprs_ns2.c
+++ b/src/gb/gprs_ns2.c
@@ -1353,4 +1353,36 @@ int ns2_count_transfer_cap(struct gprs_ns2_nse *nse,
return transfer_cap;
}
+/*! common allocation + low-level initialization of a bind. Called by vc-drivers */
+int ns2_bind_alloc(struct gprs_ns2_inst *nsi, const char *name,
+ struct gprs_ns2_vc_bind **result)
+{
+ struct gprs_ns2_vc_bind *bind;
+
+ 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) {
+ talloc_free(bind);
+ return -ENOSPC;
+ }
+
+ bind->nsi = nsi;
+ INIT_LLIST_HEAD(&bind->nsvc);
+ llist_add(&bind->list, &nsi->binding);
+
+ if (result)
+ *result = bind;
+
+ return 0;
+}
+
/*! @} */
diff --git a/src/gb/gprs_ns2_fr.c b/src/gb/gprs_ns2_fr.c
index 9de2b060..953f4cad 100644
--- a/src/gb/gprs_ns2_fr.c
+++ b/src/gb/gprs_ns2_fr.c
@@ -719,21 +719,15 @@ int gprs_ns2_fr_bind(struct gprs_ns2_inst *nsi,
struct osmo_fr_link *fr_link;
int rc = 0;
- if (!name)
+ if (strlen(netif) > IFNAMSIZ)
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;
- }
+ rc = ns2_bind_alloc(nsi, name, &bind);
+ if (rc < 0)
+ return rc;
bind->driver = &vc_driver_fr;
bind->ll = GPRS_NS2_LL_FR;
@@ -742,27 +736,19 @@ int gprs_ns2_fr_bind(struct gprs_ns2_inst *nsi,
bind->send_vc = fr_vc_sendmsg;
bind->free_vc = free_vc;
bind->dump_vty = dump_vty;
- bind->nsi = nsi;
priv = bind->priv = talloc_zero(bind, struct priv_bind);
if (!priv) {
rc = -ENOSPC;
- goto err_name;
+ goto err_bind;
}
- if (strlen(netif) > IFNAMSIZ) {
- rc = -EINVAL;
- goto err_priv;
- }
OSMO_STRLCPY_ARRAY(priv->netif, netif);
- if (result)
- *result = bind;
-
/* FIXME: move fd handling into socket.c */
fr_link = osmo_fr_link_alloc(fr_network, fr_role, netif);
if (!fr_link) {
rc = -EINVAL;
- goto err_priv;
+ goto err_bind;
}
fr_link->tx_cb = fr_tx_cb;
@@ -793,9 +779,6 @@ int gprs_ns2_fr_bind(struct gprs_ns2_inst *nsi,
if (rc < 0)
goto err_fd;
- INIT_LLIST_HEAD(&bind->nsvc);
- llist_add(&bind->list, &nsi->binding);
-
#ifdef ENABLE_LIBMNL
if (!nsi->linkmon_mnl)
nsi->linkmon_mnl = osmo_mnl_init(nsi, NETLINK_ROUTE, RTMGRP_LINK, linkmon_mnl_cb, nsi);
@@ -806,18 +789,17 @@ int gprs_ns2_fr_bind(struct gprs_ns2_inst *nsi,
linkmon_initial_dump(nsi->linkmon_mnl);
#endif
+ if (result)
+ *result = bind;
+
return rc;
err_fd:
close(priv->backlog.ofd.fd);
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);
+ gprs_ns2_free_bind(bind);
return rc;
}
diff --git a/src/gb/gprs_ns2_frgre.c b/src/gb/gprs_ns2_frgre.c
index 5047af06..863f8f21 100644
--- a/src/gb/gprs_ns2_frgre.c
+++ b/src/gb/gprs_ns2_frgre.c
@@ -537,29 +537,22 @@ int gprs_ns2_frgre_bind(struct gprs_ns2_inst *nsi,
int dscp,
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;
int rc;
- if (!name)
- return -ENOSPC;
+ if (local->u.sa.sa_family != AF_INET && local->u.sa.sa_family != AF_INET6)
+ return -EINVAL;
- if (gprs_ns2_bind_by_name(nsi, name))
+ bind = gprs_ns2_bind_by_name(nsi, name);
+ if (bind) {
+ *result = bind;
return -EALREADY;
-
- if (!bind)
- return -ENOSPC;
-
- if (local->u.sa.sa_family != AF_INET && local->u.sa.sa_family != AF_INET6) {
- talloc_free(bind);
- return -EINVAL;
}
- bind->name = talloc_strdup(bind, name);
- if (!bind->name) {
- talloc_free(bind);
- return -ENOSPC;
- }
+ rc = ns2_bind_alloc(nsi, name, &bind);
+ if (rc < 0)
+ return rc;
bind->driver = &vc_driver_frgre;
bind->ll = GPRS_NS2_LL_FR_GRE;
@@ -571,7 +564,7 @@ int gprs_ns2_frgre_bind(struct gprs_ns2_inst *nsi,
priv = bind->priv = talloc_zero(bind, struct priv_bind);
if (!priv) {
- talloc_free(bind);
+ gprs_ns2_free_bind(bind);
return -ENOSPC;
}
priv->fd.cb = frgre_fd_cb;
@@ -579,14 +572,11 @@ int gprs_ns2_frgre_bind(struct gprs_ns2_inst *nsi,
priv->addr = *local;
INIT_LLIST_HEAD(&bind->nsvc);
- llist_add(&bind->list, &nsi->binding);
-
rc = osmo_sock_init_osa_ofd(&priv->fd, SOCK_RAW, IPPROTO_GRE,
local, NULL,
OSMO_SOCK_F_BIND);
if (rc < 0) {
- talloc_free(priv);
- talloc_free(bind);
+ gprs_ns2_free_bind(bind);
return rc;
}
diff --git a/src/gb/gprs_ns2_internal.h b/src/gb/gprs_ns2_internal.h
index e1497679..4a899ed5 100644
--- a/src/gb/gprs_ns2_internal.h
+++ b/src/gb/gprs_ns2_internal.h
@@ -274,6 +274,9 @@ struct gprs_ns2_vc *ns2_vc_alloc(struct gprs_ns2_vc_bind *bind,
enum gprs_ns2_vc_mode vc_mode,
const char *id);
+int ns2_bind_alloc(struct gprs_ns2_inst *nsi, const char *name,
+ struct gprs_ns2_vc_bind **result);
+
struct msgb *ns2_msgb_alloc(void);
void ns2_sns_write_vty(struct vty *vty, const struct gprs_ns2_nse *nse);
diff --git a/src/gb/gprs_ns2_udp.c b/src/gb/gprs_ns2_udp.c
index 43ece136..b4bcd018 100644
--- a/src/gb/gprs_ns2_udp.c
+++ b/src/gb/gprs_ns2_udp.c
@@ -315,32 +315,18 @@ int gprs_ns2_ip_bind(struct gprs_ns2_inst *nsi,
struct priv_bind *priv;
int rc;
- if (!name)
+ if (local->u.sa.sa_family != AF_INET && local->u.sa.sa_family != AF_INET6)
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;
return -EBUSY;
}
- bind = talloc_zero(nsi, struct gprs_ns2_vc_bind);
- 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;
- }
+ rc = ns2_bind_alloc(nsi, name, &bind);
+ if (rc < 0)
+ return rc;
bind->driver = &vc_driver_ip;
bind->ll = GPRS_NS2_LL_UDP;
@@ -351,24 +337,21 @@ int gprs_ns2_ip_bind(struct gprs_ns2_inst *nsi,
bind->send_vc = nsip_vc_sendmsg;
bind->free_vc = free_vc;
bind->dump_vty = dump_vty;
- bind->nsi = nsi;
priv = bind->priv = talloc_zero(bind, struct priv_bind);
if (!priv) {
- talloc_free(bind);
+ gprs_ns2_free_bind(bind);
return -ENOSPC;
}
priv->fd.cb = nsip_fd_cb;
priv->fd.data = bind;
priv->addr = *local;
- INIT_LLIST_HEAD(&bind->nsvc);
rc = osmo_sock_init_osa_ofd(&priv->fd, SOCK_DGRAM, IPPROTO_UDP,
local, NULL,
OSMO_SOCK_F_BIND);
if (rc < 0) {
- talloc_free(priv);
- talloc_free(bind);
+ gprs_ns2_free_bind(bind);
return rc;
}
@@ -382,7 +365,6 @@ int gprs_ns2_ip_bind(struct gprs_ns2_inst *nsi,
dscp, rc, errno);
}
- llist_add(&bind->list, &nsi->binding);
if (result)
*result = bind;
diff --git a/tests/gb/gprs_ns2_test.c b/tests/gb/gprs_ns2_test.c
index 9e4e02f6..2027e638 100644
--- a/tests/gb/gprs_ns2_test.c
+++ b/tests/gb/gprs_ns2_test.c
@@ -104,20 +104,17 @@ static int vc_sendmsg(struct gprs_ns2_vc *nsvc, struct msgb *msg)
static struct gprs_ns2_vc_bind *dummy_bind(struct gprs_ns2_inst *nsi, const char *name)
{
- struct gprs_ns2_vc_bind *bind = talloc_zero(nsi, struct gprs_ns2_vc_bind);
+ struct gprs_ns2_vc_bind *bind = NULL;
+ OSMO_ASSERT(ns2_bind_alloc(nsi, name, &bind) == 0);
OSMO_ASSERT(bind);
- bind->name = talloc_strdup(bind, name);
bind->driver = &vc_driver_dummy;
bind->ll = GPRS_NS2_LL_UDP;
bind->transfer_capability = 42;
- bind->nsi = nsi;
bind->send_vc = vc_sendmsg;
bind->priv = talloc_zero(bind, struct osmo_wqueue);
struct osmo_wqueue *queue = bind->priv;
- INIT_LLIST_HEAD(&bind->nsvc);
- llist_add(&bind->list, &nsi->binding);
osmo_wqueue_init(queue, 100);
return bind;
@@ -150,16 +147,13 @@ static struct gprs_ns2_vc *loopback_nsvc(struct gprs_ns2_vc_bind *bind, struct g
/* a loop back bind to use the tx_ functions from gprs_ns2_message.c */
static struct gprs_ns2_vc_bind *loopback_bind(struct gprs_ns2_inst *nsi, const char *name)
{
- struct gprs_ns2_vc_bind *bind = talloc_zero(nsi, struct gprs_ns2_vc_bind);
+ struct gprs_ns2_vc_bind *bind = NULL;
+ OSMO_ASSERT(ns2_bind_alloc(nsi, name, &bind) == 0)
OSMO_ASSERT(bind);
- bind->name = talloc_strdup(bind, name);
bind->driver = &vc_driver_loopback;
bind->ll = GPRS_NS2_LL_UDP;
bind->transfer_capability = 99;
- bind->nsi = nsi;
bind->send_vc = loopback_sendmsg;
- INIT_LLIST_HEAD(&bind->nsvc);
- llist_add(&bind->list, &nsi->binding);
return bind;
}