pespin has submitted this change. ( https://gerrit.osmocom.org/c/osmo-hnbgw/+/41435?usp=email )
Change subject: iuh: Use osmo_stream_srv_create2 API ......................................................................
iuh: Use osmo_stream_srv_create2 API
Thw newer libosmo-netif API uses osmo_io under the hood and allows using iu_uring as backend as well.
Related: SYS#7693 Change-Id: If981eec0e73d696a8f68ae42ceb0db5a7a549ac3 --- M src/osmo-hnbgw/context_map.c M src/osmo-hnbgw/hnb.c M src/osmo-hnbgw/hnbgw_hnbap.c M src/osmo-hnbgw/hnbgw_vty.c M src/osmo-hnbgw/osmo_hnbgw_main.c 5 files changed, 53 insertions(+), 65 deletions(-)
Approvals: osmith: Looks good to me, but someone else must approve fixeria: Looks good to me, approved Jenkins Builder: Verified
diff --git a/src/osmo-hnbgw/context_map.c b/src/osmo-hnbgw/context_map.c index a70905c..35a0fef 100644 --- a/src/osmo-hnbgw/context_map.c +++ b/src/osmo-hnbgw/context_map.c @@ -127,7 +127,7 @@ hash_add(hsu->hnbgw_context_map_by_conn_id, &map->hnbgw_sccp_user_entry, new_scu_conn_id);
LOGP(DRUA, LOGL_INFO, "New conn: %s '%s' RUA-%u <-> SCCP-%u %s%s%s %s l=%s<->r=%s\n", - osmo_sock_get_name2_c(OTC_SELECT, osmo_stream_srv_get_ofd(map->hnb_ctx->conn)->fd), + osmo_sock_get_name2_c(OTC_SELECT, osmo_stream_srv_get_fd(map->hnb_ctx->conn)), hnb_context_name(map->hnb_ctx), map->rua_ctx_id, new_scu_conn_id, cnlink_selected->name, diff --git a/src/osmo-hnbgw/hnb.c b/src/osmo-hnbgw/hnb.c index 9938092..bd6b02c 100644 --- a/src/osmo-hnbgw/hnb.c +++ b/src/osmo-hnbgw/hnb.c @@ -95,7 +95,7 @@ return NULL; }
-static int hnb_read_cb(struct osmo_stream_srv *conn); +static int hnb_read_cb(struct osmo_stream_srv *conn, int res, struct msgb *msg); static int hnb_closed_cb(struct osmo_stream_srv *conn);
static struct hnb_context *hnb_context_alloc(struct osmo_stream_srv_link *link, int new_fd) @@ -107,12 +107,14 @@ return NULL; INIT_LLIST_HEAD(&ctx->map_list);
- ctx->conn = osmo_stream_srv_create(g_hnbgw, link, new_fd, hnb_read_cb, hnb_closed_cb, ctx); + ctx->conn = osmo_stream_srv_create2(g_hnbgw, link, new_fd, ctx); if (!ctx->conn) { LOGP(DMAIN, LOGL_INFO, "error while creating connection\n"); talloc_free(ctx); return NULL; } + osmo_stream_srv_set_read_cb(ctx->conn, hnb_read_cb); + osmo_stream_srv_set_closed_cb(ctx->conn, hnb_closed_cb);
llist_add_tail(&ctx->list, &g_hnbgw->hnb_list); return ctx; @@ -127,7 +129,7 @@ if (ctx->conn) { char hostbuf_r[INET6_ADDRSTRLEN]; char portbuf_r[6]; - int fd = osmo_stream_srv_get_ofd(ctx->conn)->fd; + int fd = osmo_stream_srv_get_fd(ctx->conn);
/* get remote addr */ if (osmo_sock_get_ip_and_port(fd, hostbuf_r, sizeof(hostbuf_r), portbuf_r, sizeof(portbuf_r), false) == 0) @@ -176,7 +178,7 @@
if (ctx->conn) { /* we own a conn, we must free it: */ LOGHNB(ctx, DMAIN, LOGL_INFO, "Closing HNB SCTP connection %s\n", - osmo_sock_get_name2(osmo_stream_srv_get_ofd(ctx->conn)->fd)); + osmo_stream_srv_get_sockname(ctx->conn)); /* Avoid our closed_cb calling hnb_context_release() again: */ osmo_stream_srv_set_data(ctx->conn, NULL); osmo_stream_srv_destroy(ctx->conn); @@ -208,36 +210,30 @@ * SCTP Socket / stream handling ***********************************************************************/
-static int hnb_read_cb(struct osmo_stream_srv *conn) +static int hnb_read_cb(struct osmo_stream_srv *conn, int res, struct msgb *msg) { struct hnb_context *hnb = osmo_stream_srv_get_data(conn); - struct osmo_fd *ofd = osmo_stream_srv_get_ofd(conn); - struct msgb *msg = msgb_alloc(IUH_MSGB_SIZE, "Iuh rx"); + int flags = msgb_sctp_msg_flags(msg); int rc;
- if (!msg) - return -ENOMEM; - OSMO_ASSERT(hnb); - /* we store a reference to the HomeNodeB in the msg->dest for the - * benefit of various downstream processing functions */ - msg->dst = hnb;
- rc = osmo_stream_srv_recv(conn, msg); + LOGHNB(hnb, DMAIN, LOGL_DEBUG, "%s(): sctp_recvmsg() returned %d (flags=0x%x)\n", + __func__, res, flags); + /* Notification received */ - if (msgb_sctp_msg_flags(msg) & OSMO_STREAM_SCTP_MSG_FLAGS_NOTIFICATION) { + if (flags & OSMO_STREAM_SCTP_MSG_FLAGS_NOTIFICATION) { union sctp_notification *notif = (union sctp_notification *)msgb_data(msg); - rc = 0; switch (notif->sn_header.sn_type) { case SCTP_ASSOC_CHANGE: switch (notif->sn_assoc_change.sac_state) { case SCTP_COMM_LOST: LOGHNB(hnb, DMAIN, LOGL_NOTICE, "sctp_recvmsg(%s) = SCTP_COMM_LOST, closing conn\n", - osmo_sock_get_name2(ofd->fd)); + osmo_stream_srv_get_sockname(conn)); + msgb_free(msg); osmo_stream_srv_destroy(conn); - rc = -EBADF; - break; + return -EBADF; case SCTP_RESTART: LOGHNB(hnb, DMAIN, LOGL_NOTICE, "HNB SCTP conn RESTARTed, marking as HNBAP-unregistered\n"); hnb->hnb_registered = false; @@ -248,40 +244,41 @@ * queue may contain plenty of oldish messages to be sent. Since the HNB will re-register after * this, we simply drop all those old messages: */ osmo_stream_srv_clear_tx_queue(conn); - break; + msgb_free(msg); + return 0; } break; case SCTP_SHUTDOWN_EVENT: LOGHNB(hnb, DMAIN, LOGL_NOTICE, "sctp_recvmsg(%s) = SCTP_SHUTDOWN_EVENT, closing conn\n", - osmo_sock_get_name2(ofd->fd)); + osmo_stream_srv_get_sockname(conn)); + msgb_free(msg); osmo_stream_srv_destroy(conn); - rc = -EBADF; - break; - } - goto out; - } else if (rc == -EAGAIN) { - /* Older versions of osmo_stream_srv_recv() not supporting - * msgb_sctp_msg_flags() may still return -EAGAIN when an sctp - * notification is received. */ - rc = 0; - goto out; - } else if (rc < 0) { - LOGHNB(hnb, DMAIN, LOGL_ERROR, "Error during sctp_recvmsg(%s)\n", - osmo_sock_get_name2(ofd->fd)); - osmo_stream_srv_destroy(conn); - rc = -EBADF; - goto out; - } else if (rc == 0) { - LOGHNB(hnb, DMAIN, LOGL_NOTICE, "Connection closed sctp_recvmsg(%s) = 0\n", - osmo_sock_get_name2(ofd->fd)); - osmo_stream_srv_destroy(conn); - rc = -EBADF; - goto out; - } else { - msgb_put(msg, rc); + return -EBADF; + default: + msgb_free(msg); + return 0; + }; }
+ if (OSMO_UNLIKELY(res < 0)) { + LOGHNB(hnb, DMAIN, LOGL_ERROR, "Error during sctp_recvmsg(%s)\n", + osmo_stream_srv_get_sockname(conn)); + msgb_free(msg); + osmo_stream_srv_destroy(conn); + return -EBADF; + } else if (OSMO_UNLIKELY(res == 0)) { + LOGHNB(hnb, DMAIN, LOGL_NOTICE, "Connection closed sctp_recvmsg(%s) = 0\n", + osmo_stream_srv_get_sockname(conn)); + msgb_free(msg); + osmo_stream_srv_destroy(conn); + return -EBADF; + } + + /* we store a reference to the HomeNodeB in the msg->dest for the + * benefit of various downstream processing functions */ + msg->dst = hnb; + switch (msgb_sctp_ppid(msg)) { case IUH_PPI_HNBAP: hnb->hnbap_stream = msgb_sctp_stream(msg); @@ -290,7 +287,8 @@ case IUH_PPI_RUA: if (!hnb->hnb_registered) { LOGHNB(hnb, DMAIN, LOGL_NOTICE, "Discarding RUA as HNB is not registered\n"); - goto out; + msgb_free(msg); + return 0; } hnb->rua_stream = msgb_sctp_stream(msg); rc = hnbgw_rua_rx(hnb, msg); @@ -307,7 +305,6 @@ break; }
-out: msgb_free(msg); return rc; } @@ -318,6 +315,8 @@ if (!hnb) return 0; /* hnb_context is being freed, nothing do be done */
+ LOGHNB(hnb, DMAIN, LOGL_INFO, "connection closed\n"); + /* hnb: conn became broken, let's release the associated hnb. * conn object is being freed after closed_cb(), so unassign it from hnb * if available to avoid it freeing it again: */ diff --git a/src/osmo-hnbgw/hnbgw_hnbap.c b/src/osmo-hnbgw/hnbgw_hnbap.c index b291513..8185f72 100644 --- a/src/osmo-hnbgw/hnbgw_hnbap.c +++ b/src/osmo-hnbgw/hnbgw_hnbap.c @@ -473,7 +473,7 @@ struct hnb_context *hnb, *tmp; HNBAP_HNBRegisterRequestIEs_t ies; int rc; - struct osmo_fd *ofd = osmo_stream_srv_get_ofd(ctx->conn); + int fd = osmo_stream_srv_get_fd(ctx->conn); char identity_str[256]; const char *cell_id_str; struct timespec tp; @@ -503,7 +503,7 @@ osmo_plmn_from_bcd(ies.plmNidentity.buf, &ctx->id.plmn); cell_id_str = umts_cell_id_to_str(&ctx->id);
- if (getpeername(ofd->fd, &cur_osa.u.sa, &len) < 0) { + if (getpeername(fd, &cur_osa.u.sa, &len) < 0) { LOGHNB(ctx, DHNBAP, LOGL_ERROR, "HNB-REGISTER-REQ %s: rejecting due to getpeername() error: %s\n", cell_id_str, strerror(errno)); hnbap_free_hnbregisterrequesties(&ies); @@ -535,10 +535,10 @@ if (hnb->hnb_registered && ctx != hnb && memcmp(&ctx->id, &hnb->id, sizeof(ctx->id)) == 0) { /* If it's coming from the same remote IP addr+port, then it must be our internal * fault (bug), and we release the old context to keep going... */ - struct osmo_fd *other_fd = osmo_stream_srv_get_ofd(hnb->conn); + int other_fd = osmo_stream_srv_get_fd(hnb->conn); struct osmo_sockaddr other_osa = {}; socklen_t len = sizeof(other_osa); - if (getpeername(other_fd->fd, &other_osa.u.sa, &len) < 0) { + if (getpeername(other_fd, &other_osa.u.sa, &len) < 0) { LOGHNB(ctx, DHNBAP, LOGL_ERROR, "BUG! Found old registered HNB with invalid socket, releasing it\n"); hnb_context_release(hnb); continue; diff --git a/src/osmo-hnbgw/hnbgw_vty.c b/src/osmo-hnbgw/hnbgw_vty.c index 7d78909..f463522 100644 --- a/src/osmo-hnbgw/hnbgw_vty.c +++ b/src/osmo-hnbgw/hnbgw_vty.c @@ -176,18 +176,6 @@ return CMD_SUCCESS; }
-static void vty_out_ofd_addr(struct vty *vty, struct osmo_fd *ofd) -{ - char *name; - if (!ofd || ofd->fd < 0 - || !(name = osmo_sock_get_name(vty, ofd->fd))) { - vty_out(vty, "(no addr)"); - return; - } - vty_out(vty, "%s", name); - talloc_free(name); -} - static void vty_dump_hnb_info__map_states(struct vty *vty, const char *name, unsigned int count, unsigned int state_count[]) { @@ -211,7 +199,7 @@ unsigned long long sec;
vty_out(vty, "HNB "); - vty_out_ofd_addr(vty, hnb->conn? osmo_stream_srv_get_ofd(hnb->conn) : NULL); + vty_out(vty, "%s", hnb->conn ? osmo_stream_srv_get_sockname(hnb->conn) : "(no addr)"); vty_out(vty, " "%s"%s", hnb->identity_info, VTY_NEWLINE); vty_out(vty, " MCC %s MNC %s LAC %u RAC %u SAC %u CID %u SCTP-stream:HNBAP=%u,RUA=%u%s", osmo_mcc_name(hnb->id.plmn.mcc), osmo_mnc_name(hnb->id.plmn.mnc, hnb->id.plmn.mnc_3_digits), diff --git a/src/osmo-hnbgw/osmo_hnbgw_main.c b/src/osmo-hnbgw/osmo_hnbgw_main.c index 0f932d9..b8b1b0b 100644 --- a/src/osmo-hnbgw/osmo_hnbgw_main.c +++ b/src/osmo-hnbgw/osmo_hnbgw_main.c @@ -315,6 +315,7 @@ osmo_stream_srv_link_set_addr(srv, g_hnbgw->config.iuh_local_ip); osmo_stream_srv_link_set_port(srv, g_hnbgw->config.iuh_local_port); osmo_stream_srv_link_set_accept_cb(srv, hnbgw_rua_accept_cb); + osmo_stream_srv_link_set_msgb_alloc_info(srv, IUH_MSGB_SIZE, 0);
if (osmo_stream_srv_link_open(srv) < 0) { perror("Cannot open server");