cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

xdpsock_ctrl_proc.c (3873B)


      1// SPDX-License-Identifier: GPL-2.0
      2/* Copyright(c) 2017 - 2018 Intel Corporation. */
      3
      4#include <errno.h>
      5#include <getopt.h>
      6#include <libgen.h>
      7#include <net/if.h>
      8#include <stdio.h>
      9#include <stdlib.h>
     10#include <sys/socket.h>
     11#include <sys/un.h>
     12#include <unistd.h>
     13
     14#include <bpf/bpf.h>
     15#include <bpf/xsk.h>
     16#include "xdpsock.h"
     17
     18/* libbpf APIs for AF_XDP are deprecated starting from v0.7 */
     19#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
     20
     21static const char *opt_if = "";
     22
     23static struct option long_options[] = {
     24	{"interface", required_argument, 0, 'i'},
     25	{0, 0, 0, 0}
     26};
     27
     28static void usage(const char *prog)
     29{
     30	const char *str =
     31		"  Usage: %s [OPTIONS]\n"
     32		"  Options:\n"
     33		"  -i, --interface=n	Run on interface n\n"
     34		"\n";
     35	fprintf(stderr, "%s\n", str);
     36
     37	exit(0);
     38}
     39
     40static void parse_command_line(int argc, char **argv)
     41{
     42	int option_index, c;
     43
     44	opterr = 0;
     45
     46	for (;;) {
     47		c = getopt_long(argc, argv, "i:",
     48				long_options, &option_index);
     49		if (c == -1)
     50			break;
     51
     52		switch (c) {
     53		case 'i':
     54			opt_if = optarg;
     55			break;
     56		default:
     57			usage(basename(argv[0]));
     58		}
     59	}
     60}
     61
     62static int send_xsks_map_fd(int sock, int fd)
     63{
     64	char cmsgbuf[CMSG_SPACE(sizeof(int))];
     65	struct msghdr msg;
     66	struct iovec iov;
     67	int value = 0;
     68
     69	if (fd == -1) {
     70		fprintf(stderr, "Incorrect fd = %d\n", fd);
     71		return -1;
     72	}
     73	iov.iov_base = &value;
     74	iov.iov_len = sizeof(int);
     75
     76	msg.msg_name = NULL;
     77	msg.msg_namelen = 0;
     78	msg.msg_iov = &iov;
     79	msg.msg_iovlen = 1;
     80	msg.msg_flags = 0;
     81	msg.msg_control = cmsgbuf;
     82	msg.msg_controllen = CMSG_LEN(sizeof(int));
     83
     84	struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg);
     85
     86	cmsg->cmsg_level = SOL_SOCKET;
     87	cmsg->cmsg_type = SCM_RIGHTS;
     88	cmsg->cmsg_len = CMSG_LEN(sizeof(int));
     89
     90	*(int *)CMSG_DATA(cmsg) = fd;
     91	int ret = sendmsg(sock, &msg, 0);
     92
     93	if (ret == -1) {
     94		fprintf(stderr, "Sendmsg failed with %s", strerror(errno));
     95		return -errno;
     96	}
     97
     98	return ret;
     99}
    100
    101int
    102main(int argc, char **argv)
    103{
    104	struct sockaddr_un server;
    105	int listening = 1;
    106	int rval, msgsock;
    107	int ifindex = 0;
    108	int flag = 1;
    109	int cmd = 0;
    110	int sock;
    111	int err;
    112	int xsks_map_fd;
    113
    114	parse_command_line(argc, argv);
    115
    116	ifindex = if_nametoindex(opt_if);
    117	if (ifindex == 0) {
    118		fprintf(stderr, "Unable to get ifindex for Interface %s. Reason:%s",
    119			opt_if, strerror(errno));
    120		return -errno;
    121	}
    122
    123	sock = socket(AF_UNIX, SOCK_STREAM, 0);
    124	if (sock < 0) {
    125		fprintf(stderr, "Opening socket stream failed: %s", strerror(errno));
    126		return -errno;
    127	}
    128
    129	server.sun_family = AF_UNIX;
    130	strcpy(server.sun_path, SOCKET_NAME);
    131
    132	setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(int));
    133
    134	if (bind(sock, (struct sockaddr *)&server, sizeof(struct sockaddr_un))) {
    135		fprintf(stderr, "Binding to socket stream failed: %s", strerror(errno));
    136		return -errno;
    137	}
    138
    139	listen(sock, MAX_NUM_OF_CLIENTS);
    140
    141	err = xsk_setup_xdp_prog(ifindex, &xsks_map_fd);
    142	if (err) {
    143		fprintf(stderr, "Setup of xdp program failed\n");
    144		goto close_sock;
    145	}
    146
    147	while (listening) {
    148		msgsock = accept(sock, 0, 0);
    149		if (msgsock == -1) {
    150			fprintf(stderr, "Error accepting connection: %s", strerror(errno));
    151			err = -errno;
    152			goto close_sock;
    153		}
    154		err = send_xsks_map_fd(msgsock, xsks_map_fd);
    155		if (err <= 0) {
    156			fprintf(stderr, "Error %d sending xsks_map_fd\n", err);
    157			goto cleanup;
    158		}
    159		do {
    160			rval = read(msgsock, &cmd, sizeof(int));
    161			if (rval < 0) {
    162				fprintf(stderr, "Error reading stream message");
    163			} else {
    164				if (cmd != CLOSE_CONN)
    165					fprintf(stderr, "Recv unknown cmd = %d\n", cmd);
    166				listening = 0;
    167				break;
    168			}
    169		} while (rval > 0);
    170	}
    171	close(msgsock);
    172	close(sock);
    173	unlink(SOCKET_NAME);
    174
    175	/* Unset fd for given ifindex */
    176	err = bpf_xdp_detach(ifindex, 0, NULL);
    177	if (err) {
    178		fprintf(stderr, "Error when unsetting bpf prog_fd for ifindex(%d)\n", ifindex);
    179		return err;
    180	}
    181
    182	return 0;
    183
    184cleanup:
    185	close(msgsock);
    186close_sock:
    187	close(sock);
    188	unlink(SOCKET_NAME);
    189	return err;
    190}