aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Chagin <dchagin@FreeBSD.org>2023-08-14 12:46:12 +0000
committerDmitry Chagin <dchagin@FreeBSD.org>2023-08-14 12:46:12 +0000
commitde20eb26d014f7d9ba81fd1f84636609c8efa8e1 (patch)
treee83a361729d1a6b8a78a5d4c07c1887cd14fe5bb
parentbbaa5523c01a11e1e322928639522b9ccfd19978 (diff)
downloadsrc-de20eb26d014f7d9ba81fd1f84636609c8efa8e1.tar.gz
src-de20eb26d014f7d9ba81fd1f84636609c8efa8e1.zip
linux(4): Refactor recvmsg
As the amount of handled anxiliary messages grows move they handlers into a separate functions. MFC after: 1 week
-rw-r--r--sys/compat/linux/linux_socket.c101
1 files changed, 64 insertions, 37 deletions
diff --git a/sys/compat/linux/linux_socket.c b/sys/compat/linux/linux_socket.c
index 90dc25f2e653..90a1cf879517 100644
--- a/sys/compat/linux/linux_socket.c
+++ b/sys/compat/linux/linux_socket.c
@@ -1700,6 +1700,39 @@ _Static_assert(sizeof(struct bintime) >= sizeof(struct timespec),
#endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */
static int
+recvmsg_scm_sol_socket(struct thread *td, l_int msg_type, l_int lmsg_type,
+ l_uint flags, socklen_t *datalen, void **data, void **udata)
+{
+ int error;
+
+ error = 0;
+ switch (msg_type) {
+ case SCM_RIGHTS:
+ error = recvmsg_scm_rights(td, flags, datalen,
+ data, udata);
+ break;
+ case SCM_CREDS:
+ error = recvmsg_scm_creds(datalen, data, udata);
+ break;
+ case SCM_CREDS2:
+ error = recvmsg_scm_creds2(datalen, data, udata);
+ break;
+ case SCM_TIMESTAMP:
+#if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32))
+ error = recvmsg_scm_timestamp(lmsg_type, datalen,
+ data, udata);
+#endif
+ break;
+ case SCM_BINTIME:
+ error = recvmsg_scm_timestampns(lmsg_type, datalen,
+ data, udata);
+ break;
+ }
+
+ return (error);
+}
+
+static int
recvmsg_scm_ip_origdstaddr(socklen_t *datalen, void **data, void **udata)
{
struct l_sockaddr *lsa;
@@ -1714,6 +1747,23 @@ recvmsg_scm_ip_origdstaddr(socklen_t *datalen, void **data, void **udata)
}
static int
+recvmsg_scm_ipproto_ip(l_int msg_type, l_int lmsg_type, socklen_t *datalen,
+ void **data, void **udata)
+{
+ int error;
+
+ error = 0;
+ switch (msg_type) {
+ case IP_ORIGDSTADDR:
+ error = recvmsg_scm_ip_origdstaddr(datalen, data,
+ udata);
+ break;
+ }
+
+ return (error);
+}
+
+static int
linux_recvmsg_common(struct thread *td, l_int s, struct l_msghdr *msghdr,
l_uint flags, struct msghdr *msg)
{
@@ -1801,18 +1851,6 @@ linux_recvmsg_common(struct thread *td, l_int s, struct l_msghdr *msghdr,
cm->cmsg_level);
lcm->cmsg_level = bsd_to_linux_sockopt_level(cm->cmsg_level);
- data = CMSG_DATA(cm);
- datalen = (caddr_t)cm + cm->cmsg_len - (caddr_t)data;
- udata = NULL;
- error = 0;
-
- /* Process non SOL_SOCKET types. */
- if (cm->cmsg_level == IPPROTO_IP &&
- lcm->cmsg_type == LINUX_IP_ORIGDSTADDR) {
- error = recvmsg_scm_ip_origdstaddr(&datalen, &data, &udata);
- goto cont;
- }
-
if (lcm->cmsg_type == -1 ||
cm->cmsg_level == -1) {
LINUX_RATELIMIT_MSG_OPT2(
@@ -1822,33 +1860,22 @@ linux_recvmsg_common(struct thread *td, l_int s, struct l_msghdr *msghdr,
skiped++;
continue;
}
+ data = CMSG_DATA(cm);
+ datalen = (caddr_t)cm + cm->cmsg_len - (caddr_t)data;
+ udata = NULL;
+ error = 0;
- switch (cm->cmsg_type) {
- case SCM_RIGHTS:
- error = recvmsg_scm_rights(td, flags,
- &datalen, &data, &udata);
- break;
- case SCM_CREDS:
- error = recvmsg_scm_creds(&datalen,
- &data, &udata);
- break;
- case SCM_CREDS2:
- error = recvmsg_scm_creds2(&datalen,
- &data, &udata);
- break;
- case SCM_TIMESTAMP:
-#if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32))
- error = recvmsg_scm_timestamp(lcm->cmsg_type,
- &datalen, &data, &udata);
-#endif
- break;
- case SCM_BINTIME:
- error = recvmsg_scm_timestampns(lcm->cmsg_type,
- &datalen, &data, &udata);
- break;
- }
+ switch (cm->cmsg_level) {
+ case IPPROTO_IP:
+ error = recvmsg_scm_ipproto_ip(cm->cmsg_type,
+ lcm->cmsg_type, &datalen, &data, &udata);
+ break;
+ case SOL_SOCKET:
+ error = recvmsg_scm_sol_socket(td, cm->cmsg_type,
+ lcm->cmsg_type, flags, &datalen, &data, &udata);
+ break;
+ }
-cont:
if (error != 0)
goto bad;