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
This commit is contained in:
Harald Welte 2021-01-31 11:41:34 +01:00
parent b40bf8ba3b
commit c3aa8f903a
6 changed files with 67 additions and 84 deletions

View File

@ -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;
}
/*! @} */

View File

@ -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;
}

View File

@ -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 (gprs_ns2_bind_by_name(nsi, name))
return -EALREADY;
if (!bind)
return -ENOSPC;
if (local->u.sa.sa_family != AF_INET && local->u.sa.sa_family != AF_INET6) {
talloc_free(bind);
if (local->u.sa.sa_family != AF_INET && local->u.sa.sa_family != AF_INET6)
return -EINVAL;
bind = gprs_ns2_bind_by_name(nsi, name);
if (bind) {
*result = bind;
return -EALREADY;
}
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;
}

View File

@ -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);

View File

@ -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;

View File

@ -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;
}