blob: 8e613fae5c0e74be8dd08ab8216cf545e9425c45 [file] [log] [blame]
Harald Welte8857f3b2022-11-18 13:54:44 +01001/*! \file osmo_io.h
2 * io(_uring) abstraction osmo fd compatibility
3 */
4
5#pragma once
6
Harald Welte1047ed72023-11-18 18:51:58 +01007#include <sys/socket.h>
8
Harald Welte8857f3b2022-11-18 13:54:44 +01009#include <osmocom/core/linuxlist.h>
10#include <osmocom/core/logging.h>
11#include <osmocom/core/msgb.h>
12#include <osmocom/core/socket.h>
13#include <osmocom/core/utils.h>
14
15
16#define LOGPIO(iofd, level, fmt, args...) \
17 LOGP(DLIO, level, "iofd(%s)" fmt, iofd->name, ## args)
18
19struct osmo_io_fd;
20
21enum osmo_io_fd_mode {
22 /*! use read() / write() calls */
23 OSMO_IO_FD_MODE_READ_WRITE,
24 /*! use recvfrom() / sendto() calls */
25 OSMO_IO_FD_MODE_RECVFROM_SENDTO,
Harald Welte1047ed72023-11-18 18:51:58 +010026 /*! emulate recvmsg() / sendmsg() */
27 OSMO_IO_FD_MODE_RECVMSG_SENDMSG,
Harald Welte8857f3b2022-11-18 13:54:44 +010028};
29
30enum osmo_io_backend {
31 OSMO_IO_BACKEND_POLL,
Daniel Willmannf91d2aa2023-01-04 18:20:55 +010032 OSMO_IO_BACKEND_IO_URING,
Harald Welte8857f3b2022-11-18 13:54:44 +010033};
34
35extern const struct value_string osmo_io_backend_names[];
36static inline const char *osmo_io_backend_name(enum osmo_io_backend val)
37{ return get_value_string(osmo_io_backend_names, val); }
38
Harald Welte09ab0412024-03-07 10:11:52 +010039extern const struct value_string osmo_iofd_mode_names[];
40static inline const char *osmo_iofd_mode_name(enum osmo_io_fd_mode val)
41{ return get_value_string(osmo_iofd_mode_names, val); }
42
Harald Welte8857f3b2022-11-18 13:54:44 +010043struct osmo_io_ops {
Harald Welteb365b1d2024-02-23 16:08:49 +010044 /* mode OSMO_IO_FD_MODE_READ_WRITE: */
45 struct {
46 /*! call-back function when something was read from fd */
47 void (*read_cb)(struct osmo_io_fd *iofd, int res, struct msgb *msg);
48 /*! call-back function when write has completed on fd */
49 void (*write_cb)(struct osmo_io_fd *iofd, int res,
50 struct msgb *msg);
51 /*! call-back function to segment the data at message boundaries.
52 * Needs to return the size of the next message. If it returns
53 * -EAGAIN or a value larger than msgb_length() (message is incomplete)
54 * osmo_io will wait for more data to be read. Other negative values
55 * cause the msg to be discarded.
56 * If a full message was received (segmentation_cb() returns a value <= msgb_length())
57 * the msgb will be trimmed to size by osmo_io and forwarded to the read call-back. Any
58 * parsing done to the msgb by segmentation_cb() will be preserved for the read_cb()
59 * (e.g. setting lxh or msgb->cb). */
60 int (*segmentation_cb)(struct msgb *msg);
61 };
Harald Welte8857f3b2022-11-18 13:54:44 +010062
Harald Welteb365b1d2024-02-23 16:08:49 +010063 /* mode OSMO_IO_FD_MODE_RECVFROM_SENDTO: */
64 struct {
65 /*! call-back function emulating recvfrom */
66 void (*recvfrom_cb)(struct osmo_io_fd *iofd, int res,
67 struct msgb *msg,
68 const struct osmo_sockaddr *saddr);
69 /*! call-back function emulating sendto */
70 void (*sendto_cb)(struct osmo_io_fd *iofd, int res,
71 struct msgb *msg,
72 const struct osmo_sockaddr *daddr);
Harald Welte8857f3b2022-11-18 13:54:44 +010073 };
Harald Welte1047ed72023-11-18 18:51:58 +010074
75 /* mode OSMO_IO_FD_MODE_RECVMSG_SENDMSG: */
76 struct {
77 void (*recvmsg_cb)(struct osmo_io_fd *iofd, int res,
78 struct msgb *msg, const struct msghdr *msgh);
79 void (*sendmsg_cb)(struct osmo_io_fd *iofd, int res, struct msgb *msg);
80 };
Harald Welte8857f3b2022-11-18 13:54:44 +010081};
82
arehbein2a405d42023-09-25 22:03:41 +020083void osmo_iofd_init(void);
Harald Welte8857f3b2022-11-18 13:54:44 +010084
85struct osmo_io_fd *osmo_iofd_setup(const void *ctx, int fd, const char *name,
86 enum osmo_io_fd_mode mode, const struct osmo_io_ops *ioops, void *data);
Harald Welte1047ed72023-11-18 18:51:58 +010087int osmo_iofd_set_cmsg_size(struct osmo_io_fd *iofd, size_t cmsg_size);
Harald Welte8857f3b2022-11-18 13:54:44 +010088int osmo_iofd_register(struct osmo_io_fd *iofd, int fd);
89int osmo_iofd_unregister(struct osmo_io_fd *iofd);
90unsigned int osmo_iofd_txqueue_len(struct osmo_io_fd *iofd);
91void osmo_iofd_txqueue_clear(struct osmo_io_fd *iofd);
92int osmo_iofd_close(struct osmo_io_fd *iofd);
93void osmo_iofd_free(struct osmo_io_fd *iofd);
Harald Welte8857f3b2022-11-18 13:54:44 +010094
Daniel Willmanne2a8dc42023-06-30 10:51:53 +020095void osmo_iofd_notify_connected(struct osmo_io_fd *iofd);
96
Harald Welte8857f3b2022-11-18 13:54:44 +010097int osmo_iofd_write_msgb(struct osmo_io_fd *iofd, struct msgb *msg);
98int osmo_iofd_sendto_msgb(struct osmo_io_fd *iofd, struct msgb *msg, int sendto_flags,
99 const struct osmo_sockaddr *dest);
Harald Welte1047ed72023-11-18 18:51:58 +0100100int osmo_iofd_sendmsg_msgb(struct osmo_io_fd *iofd, struct msgb *msg, int sendmsg_flags,
101 const struct msghdr *msgh);
Harald Welte8857f3b2022-11-18 13:54:44 +0100102
103void osmo_iofd_set_alloc_info(struct osmo_io_fd *iofd, unsigned int size, unsigned int headroom);
Daniel Willmanna9303f32023-07-07 11:20:48 +0200104void osmo_iofd_set_txqueue_max_length(struct osmo_io_fd *iofd, unsigned int size);
Harald Welte8857f3b2022-11-18 13:54:44 +0100105void *osmo_iofd_get_data(const struct osmo_io_fd *iofd);
106void osmo_iofd_set_data(struct osmo_io_fd *iofd, void *data);
107
108unsigned int osmo_iofd_get_priv_nr(const struct osmo_io_fd *iofd);
109void osmo_iofd_set_priv_nr(struct osmo_io_fd *iofd, unsigned int priv_nr);
110
111int osmo_iofd_get_fd(const struct osmo_io_fd *iofd);
112const char *osmo_iofd_get_name(const struct osmo_io_fd *iofd);
Pau Espin Pedrol63e45e62023-06-16 16:19:45 +0200113void osmo_iofd_set_name(struct osmo_io_fd *iofd, const char *name);
arehbein0c374c62023-05-14 21:43:11 +0200114
Harald Welteb365b1d2024-02-23 16:08:49 +0100115int osmo_iofd_set_ioops(struct osmo_io_fd *iofd, const struct osmo_io_ops *ioops);
Harald Weltef574aea2024-02-23 12:07:03 +0100116void osmo_iofd_get_ioops(struct osmo_io_fd *iofd, struct osmo_io_ops *ioops);