daniel has submitted this change. ( https://gerrit.osmocom.org/c/libosmocore/+/30936 )
(
17 is the latest approved patch-set. No files were changed between the latest approved patch-set and the submitted one. )Change subject: gpsr_ns2_udp: Use osmo_io_fd instead of osmo_fd ......................................................................
gpsr_ns2_udp: Use osmo_io_fd instead of osmo_fd
Change-Id: Id776d2d9f35c304620f3d5b94492148dd987f5a0 --- M src/gb/gprs_ns2_internal.h M src/gb/gprs_ns2_udp.c 2 files changed, 59 insertions(+), 75 deletions(-)
Approvals: laforge: Looks good to me, but someone else must approve pespin: Looks good to me, approved Jenkins Builder: Verified
diff --git a/src/gb/gprs_ns2_internal.h b/src/gb/gprs_ns2_internal.h index 4f33221..37b142e 100644 --- a/src/gb/gprs_ns2_internal.h +++ b/src/gb/gprs_ns2_internal.h @@ -6,6 +6,7 @@ #include <stdint.h>
#include <osmocom/core/logging.h> +#include <osmocom/core/rate_ctr.h> #include <osmocom/gprs/protocol/gsm_08_16.h> #include <osmocom/gprs/gprs_ns2.h>
diff --git a/src/gb/gprs_ns2_udp.c b/src/gb/gprs_ns2_udp.c index 7ecf276..e9e9e38 100644 --- a/src/gb/gprs_ns2_udp.c +++ b/src/gb/gprs_ns2_udp.c @@ -28,6 +28,7 @@
#include <errno.h>
+#include <osmocom/core/osmo_io.h> #include <osmocom/core/select.h> #include <osmocom/core/sockaddr_str.h> #include <osmocom/core/socket.h> @@ -46,7 +47,7 @@ };
struct priv_bind { - struct osmo_fd fd; + struct osmo_io_fd *iofd; struct osmo_sockaddr addr; int dscp; uint8_t priority; @@ -68,7 +69,8 @@
priv = bind->priv;
- osmo_fd_close(&priv->fd); + osmo_iofd_free(priv->iofd); + priv->iofd = NULL; talloc_free(priv); }
@@ -143,17 +145,11 @@
static inline int nsip_sendmsg(struct gprs_ns2_vc_bind *bind, struct msgb *msg, - struct osmo_sockaddr *dest) + const struct osmo_sockaddr *dest) { - int rc; struct priv_bind *priv = bind->priv;
- rc = sendto(priv->fd.fd, msg->data, msg->len, 0, - &dest->u.sa, sizeof(*dest)); - - msgb_free(msg); - - return rc; + return osmo_iofd_sendto_msgb(priv->iofd, msg, 0, dest); }
/*! send the msg and free it afterwards. @@ -171,40 +167,7 @@ return rc; }
-/* Read a single NS-over-IP message */ -static struct msgb *read_nsip_msg(struct osmo_fd *bfd, int *error, struct osmo_sockaddr *saddr, - const struct gprs_ns2_vc_bind *bind) -{ - struct msgb *msg = ns2_msgb_alloc(); - int ret = 0; - socklen_t saddr_len = sizeof(*saddr); - - if (!msg) { - *error = -ENOMEM; - return NULL; - } - - ret = recvfrom(bfd->fd, msg->data, NS_ALLOC_SIZE - NS_ALLOC_HEADROOM, 0, - &saddr->u.sa, &saddr_len); - if (ret < 0) { - LOGBIND(bind, LOGL_ERROR, "recv error %s during NSIP recvfrom %s\n", - strerror(errno), osmo_sock_get_name2(bfd->fd)); - msgb_free(msg); - *error = ret; - return NULL; - } else if (ret == 0) { - msgb_free(msg); - *error = ret; - return NULL; - } - - msg->l2h = msg->data; - msgb_put(msg, ret); - - return msg; -} - -static struct priv_vc *ns2_driver_alloc_vc(struct gprs_ns2_vc_bind *bind, struct gprs_ns2_vc *nsvc, struct osmo_sockaddr *remote) +static struct priv_vc *ns2_driver_alloc_vc(struct gprs_ns2_vc_bind *bind, struct gprs_ns2_vc *nsvc, const struct osmo_sockaddr *remote) { struct priv_vc *priv = talloc_zero(bind, struct priv_vc); if (!priv) @@ -216,24 +179,22 @@ return priv; }
-static int handle_nsip_read(struct osmo_fd *bfd) +static void handle_nsip_recvfrom(struct osmo_io_fd *iofd, int error, struct msgb *msg, + const struct osmo_sockaddr *saddr) { int rc = 0; - int error = 0; - struct gprs_ns2_vc_bind *bind = bfd->data; - struct osmo_sockaddr saddr; + struct gprs_ns2_vc_bind *bind = osmo_iofd_get_data(iofd); struct gprs_ns2_vc *nsvc; - struct msgb *msg = read_nsip_msg(bfd, &error, &saddr, bind); + struct msgb *reject;
- if (!msg) - return -EINVAL; + msg->l2h = msgb_data(msg);
/* check if a vc is available */ - nsvc = gprs_ns2_nsvc_by_sockaddr_bind(bind, &saddr); + nsvc = gprs_ns2_nsvc_by_sockaddr_bind(bind, saddr); if (!nsvc) { /* VC not found */ - rc = ns2_create_vc(bind, msg, &saddr, "newconnection", &reject, &nsvc); + rc = ns2_create_vc(bind, msg, saddr, "newconnection", &reject, &nsvc); switch (rc) { case NS2_CS_FOUND: break; @@ -243,10 +204,10 @@ goto out; case NS2_CS_REJECTED: /* nsip_sendmsg will free reject */ - rc = nsip_sendmsg(bind, reject, &saddr); + rc = nsip_sendmsg(bind, reject, saddr); goto out; case NS2_CS_CREATED: - ns2_driver_alloc_vc(bind, nsvc, &saddr); + ns2_driver_alloc_vc(bind, nsvc, saddr); /* only start the fsm for non SNS. SNS will take care of its own */ if (nsvc->nse->dialect != GPRS_NS2_DIALECT_SNS) ns2_vc_fsm_start(nsvc); @@ -254,29 +215,31 @@ } }
- return ns2_recv_vc(nsvc, msg); + ns2_recv_vc(nsvc, msg); + return;
out: msgb_free(msg); - return rc; }
-static int handle_nsip_write(struct osmo_fd *bfd) +static void handle_nsip_sendto(struct osmo_io_fd *iofd, int res, + const struct msgb *msg, + const struct osmo_sockaddr *daddr) { - /* FIXME: actually send the data here instead of nsip_sendmsg() */ - return -EIO; -} + struct gprs_ns2_vc_bind *bind = osmo_iofd_get_data(iofd); + struct gprs_ns2_vc *nsvc;
-static int nsip_fd_cb(struct osmo_fd *bfd, unsigned int what) -{ - int rc = 0; + nsvc = gprs_ns2_nsvc_by_sockaddr_bind(bind, daddr); + if (!nsvc) + return;
- if (what & OSMO_FD_READ) - rc = handle_nsip_read(bfd); - if (what & OSMO_FD_WRITE) - rc = handle_nsip_write(bfd); - - return rc; + if (OSMO_LIKELY(res >= 0)) { + RATE_CTR_INC_NS(nsvc, NS_CTR_PKTS_OUT); + RATE_CTR_ADD_NS(nsvc, NS_CTR_BYTES_OUT, res); + } else { + RATE_CTR_INC_NS(nsvc, NS_CTR_PKTS_OUT_DROP); + RATE_CTR_ADD_NS(nsvc, NS_CTR_BYTES_OUT_DROP, msgb_length(msg)); + } }
/*! Find NS bind for a given socket address @@ -321,6 +284,11 @@ struct priv_bind *priv; int rc;
+ struct osmo_io_ops ioops = { + .sendto_cb = &handle_nsip_sendto, + .recvfrom_cb = &handle_nsip_recvfrom, + }; + if (local->u.sa.sa_family != AF_INET && local->u.sa.sa_family != AF_INET6) return -EINVAL;
@@ -353,12 +321,11 @@ gprs_ns2_free_bind(bind); return -ENOMEM; } - priv->fd.cb = nsip_fd_cb; - priv->fd.data = bind; + priv->addr = *local; priv->dscp = dscp;
- rc = osmo_sock_init_osa_ofd(&priv->fd, SOCK_DGRAM, IPPROTO_UDP, + rc = osmo_sock_init_osa(SOCK_DGRAM, IPPROTO_UDP, local, NULL, OSMO_SOCK_F_BIND | OSMO_SOCK_F_DSCP(priv->dscp)); if (rc < 0) { @@ -366,6 +333,13 @@ return rc; }
+ priv->iofd = osmo_iofd_setup(bind, rc, "NS bind", OSMO_IO_FD_MODE_RECVFROM_SENDTO, &ioops, bind); + osmo_iofd_register(priv->iofd, rc); + osmo_iofd_set_alloc_info(priv->iofd, 4096, 128); + + osmo_iofd_read_enable(priv->iofd); + osmo_iofd_write_enable(priv->iofd); + /* IPv4: max fragmented payload can be (13 bit) * 8 byte => 65535. * IPv6: max payload can be 65535 (RFC 2460). * UDP header = 8 byte */ @@ -521,7 +495,7 @@ if (dscp != priv->dscp) { priv->dscp = dscp;
- rc = osmo_sock_set_dscp(priv->fd.fd, dscp); + rc = osmo_sock_set_dscp(osmo_iofd_get_fd(priv->iofd), dscp); if (rc < 0) { LOGBIND(bind, LOGL_ERROR, "Failed to set the DSCP to %u with ret(%d) errno(%d)\n", dscp, rc, errno); @@ -543,7 +517,7 @@ if (priority != priv->priority) { priv->priority = priority;
- rc = osmo_sock_set_priority(priv->fd.fd, priority); + rc = osmo_sock_set_priority(osmo_iofd_get_fd(priv->iofd), priority); if (rc < 0) { LOGBIND(bind, LOGL_ERROR, "Failed to set the priority to %u with ret(%d) errno(%d)\n", priority, rc, errno);