mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2026-04-08 12:02:33 +02:00
commit86814d8ffdupstream. Replace setsockopt() calls with calls to functions that follow setsockopt() with getsockopt() and check that the returned value and its size are the same as have been set. (Except in vsock_perf.) Signed-off-by: Konstantin Shkolnyy <kshk@linux.ibm.com> Reviewed-by: Stefano Garzarella <sgarzare@redhat.com> Signed-off-by: Paolo Abeni <pabeni@redhat.com> [Stefano: patch needed to avoid vsock test build failure reported by Johan Korsnes after backporting commit0a98de8013("vsock/test: fix seqpacket message bounds test") in 6.12-stable tree] Signed-off-by: Stefano Garzarella <sgarzare@redhat.com> Tested-by: Johan Korsnes <johan.korsnes@remarkable.no> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
78 lines
1.8 KiB
C
78 lines
1.8 KiB
C
// SPDX-License-Identifier: GPL-2.0-only
|
|
/* Some common code for MSG_ZEROCOPY logic
|
|
*
|
|
* Copyright (C) 2023 SberDevices.
|
|
*
|
|
* Author: Arseniy Krasnov <avkrasnov@salutedevices.com>
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <sys/types.h>
|
|
#include <sys/socket.h>
|
|
#include <linux/errqueue.h>
|
|
|
|
#include "msg_zerocopy_common.h"
|
|
|
|
void vsock_recv_completion(int fd, const bool *zerocopied)
|
|
{
|
|
struct sock_extended_err *serr;
|
|
struct msghdr msg = { 0 };
|
|
char cmsg_data[128];
|
|
struct cmsghdr *cm;
|
|
ssize_t res;
|
|
|
|
msg.msg_control = cmsg_data;
|
|
msg.msg_controllen = sizeof(cmsg_data);
|
|
|
|
res = recvmsg(fd, &msg, MSG_ERRQUEUE);
|
|
if (res) {
|
|
fprintf(stderr, "failed to read error queue: %zi\n", res);
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
cm = CMSG_FIRSTHDR(&msg);
|
|
if (!cm) {
|
|
fprintf(stderr, "cmsg: no cmsg\n");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
if (cm->cmsg_level != SOL_VSOCK) {
|
|
fprintf(stderr, "cmsg: unexpected 'cmsg_level'\n");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
if (cm->cmsg_type != VSOCK_RECVERR) {
|
|
fprintf(stderr, "cmsg: unexpected 'cmsg_type'\n");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
serr = (void *)CMSG_DATA(cm);
|
|
if (serr->ee_origin != SO_EE_ORIGIN_ZEROCOPY) {
|
|
fprintf(stderr, "serr: wrong origin: %u\n", serr->ee_origin);
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
if (serr->ee_errno) {
|
|
fprintf(stderr, "serr: wrong error code: %u\n", serr->ee_errno);
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
/* This flag is used for tests, to check that transmission was
|
|
* performed as expected: zerocopy or fallback to copy. If NULL
|
|
* - don't care.
|
|
*/
|
|
if (!zerocopied)
|
|
return;
|
|
|
|
if (*zerocopied && (serr->ee_code & SO_EE_CODE_ZEROCOPY_COPIED)) {
|
|
fprintf(stderr, "serr: was copy instead of zerocopy\n");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
if (!*zerocopied && !(serr->ee_code & SO_EE_CODE_ZEROCOPY_COPIED)) {
|
|
fprintf(stderr, "serr: was zerocopy instead of copy\n");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
}
|