summaryrefslogtreecommitdiff
path: root/samples/bpf/xdpsock_ctrl_proc.c
diff options
context:
space:
mode:
authorJakub Kicinski <kuba@kernel.org>2020-12-04 07:48:11 -0800
committerJakub Kicinski <kuba@kernel.org>2020-12-04 07:48:12 -0800
commita1dd1d86973182458da7798a95f26cfcbea599b4 (patch)
tree1adda22ea30ccfac7651a7eed7b7c90356f8243a /samples/bpf/xdpsock_ctrl_proc.c
parent55fd59b003f6e8fd88cf16590e79823d7ccf3026 (diff)
parenteceae70bdeaeb6b8ceb662983cf663ff352fbc96 (diff)
Merge https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next
Alexei Starovoitov says: ==================== pull-request: bpf-next 2020-12-03 The main changes are: 1) Support BTF in kernel modules, from Andrii. 2) Introduce preferred busy-polling, from Björn. 3) bpf_ima_inode_hash() and bpf_bprm_opts_set() helpers, from KP Singh. 4) Memcg-based memory accounting for bpf objects, from Roman. 5) Allow bpf_{s,g}etsockopt from cgroup bind{4,6} hooks, from Stanislav. * https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next: (118 commits) selftests/bpf: Fix invalid use of strncat in test_sockmap libbpf: Use memcpy instead of strncpy to please GCC selftests/bpf: Add fentry/fexit/fmod_ret selftest for kernel module selftests/bpf: Add tp_btf CO-RE reloc test for modules libbpf: Support attachment of BPF tracing programs to kernel modules libbpf: Factor out low-level BPF program loading helper bpf: Allow to specify kernel module BTFs when attaching BPF programs bpf: Remove hard-coded btf_vmlinux assumption from BPF verifier selftests/bpf: Add CO-RE relocs selftest relying on kernel module BTF selftests/bpf: Add support for marking sub-tests as skipped selftests/bpf: Add bpf_testmod kernel module for testing libbpf: Add kernel module BTF support for CO-RE relocations libbpf: Refactor CO-RE relocs to not assume a single BTF object libbpf: Add internal helper to load BTF data by FD bpf: Keep module's btf_data_size intact after load bpf: Fix bpf_put_raw_tracepoint()'s use of __module_address() selftests/bpf: Add Userspace tests for TCP_WINDOW_CLAMP bpf: Adds support for setting window clamp samples/bpf: Fix spelling mistake "recieving" -> "receiving" bpf: Fix cold build of test_progs-no_alu32 ... ==================== Link: https://lore.kernel.org/r/20201204021936.85653-1-alexei.starovoitov@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'samples/bpf/xdpsock_ctrl_proc.c')
-rw-r--r--samples/bpf/xdpsock_ctrl_proc.c187
1 files changed, 187 insertions, 0 deletions
diff --git a/samples/bpf/xdpsock_ctrl_proc.c b/samples/bpf/xdpsock_ctrl_proc.c
new file mode 100644
index 000000000000..384e62e3c6d6
--- /dev/null
+++ b/samples/bpf/xdpsock_ctrl_proc.c
@@ -0,0 +1,187 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright(c) 2017 - 2018 Intel Corporation. */
+
+#include <errno.h>
+#include <getopt.h>
+#include <libgen.h>
+#include <net/if.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+
+#include <bpf/bpf.h>
+#include <bpf/xsk.h>
+#include "xdpsock.h"
+
+static const char *opt_if = "";
+
+static struct option long_options[] = {
+ {"interface", required_argument, 0, 'i'},
+ {0, 0, 0, 0}
+};
+
+static void usage(const char *prog)
+{
+ const char *str =
+ " Usage: %s [OPTIONS]\n"
+ " Options:\n"
+ " -i, --interface=n Run on interface n\n"
+ "\n";
+ fprintf(stderr, "%s\n", str);
+
+ exit(0);
+}
+
+static void parse_command_line(int argc, char **argv)
+{
+ int option_index, c;
+
+ opterr = 0;
+
+ for (;;) {
+ c = getopt_long(argc, argv, "i:",
+ long_options, &option_index);
+ if (c == -1)
+ break;
+
+ switch (c) {
+ case 'i':
+ opt_if = optarg;
+ break;
+ default:
+ usage(basename(argv[0]));
+ }
+ }
+}
+
+static int send_xsks_map_fd(int sock, int fd)
+{
+ char cmsgbuf[CMSG_SPACE(sizeof(int))];
+ struct msghdr msg;
+ struct iovec iov;
+ int value = 0;
+
+ if (fd == -1) {
+ fprintf(stderr, "Incorrect fd = %d\n", fd);
+ return -1;
+ }
+ iov.iov_base = &value;
+ iov.iov_len = sizeof(int);
+
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+ msg.msg_flags = 0;
+ msg.msg_control = cmsgbuf;
+ msg.msg_controllen = CMSG_LEN(sizeof(int));
+
+ struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg);
+
+ cmsg->cmsg_level = SOL_SOCKET;
+ cmsg->cmsg_type = SCM_RIGHTS;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(int));
+
+ *(int *)CMSG_DATA(cmsg) = fd;
+ int ret = sendmsg(sock, &msg, 0);
+
+ if (ret == -1) {
+ fprintf(stderr, "Sendmsg failed with %s", strerror(errno));
+ return -errno;
+ }
+
+ return ret;
+}
+
+int
+main(int argc, char **argv)
+{
+ struct sockaddr_un server;
+ int listening = 1;
+ int rval, msgsock;
+ int ifindex = 0;
+ int flag = 1;
+ int cmd = 0;
+ int sock;
+ int err;
+ int xsks_map_fd;
+
+ parse_command_line(argc, argv);
+
+ ifindex = if_nametoindex(opt_if);
+ if (ifindex == 0) {
+ fprintf(stderr, "Unable to get ifindex for Interface %s. Reason:%s",
+ opt_if, strerror(errno));
+ return -errno;
+ }
+
+ sock = socket(AF_UNIX, SOCK_STREAM, 0);
+ if (sock < 0) {
+ fprintf(stderr, "Opening socket stream failed: %s", strerror(errno));
+ return -errno;
+ }
+
+ server.sun_family = AF_UNIX;
+ strcpy(server.sun_path, SOCKET_NAME);
+
+ setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(int));
+
+ if (bind(sock, (struct sockaddr *)&server, sizeof(struct sockaddr_un))) {
+ fprintf(stderr, "Binding to socket stream failed: %s", strerror(errno));
+ return -errno;
+ }
+
+ listen(sock, MAX_NUM_OF_CLIENTS);
+
+ err = xsk_setup_xdp_prog(ifindex, &xsks_map_fd);
+ if (err) {
+ fprintf(stderr, "Setup of xdp program failed\n");
+ goto close_sock;
+ }
+
+ while (listening) {
+ msgsock = accept(sock, 0, 0);
+ if (msgsock == -1) {
+ fprintf(stderr, "Error accepting connection: %s", strerror(errno));
+ err = -errno;
+ goto close_sock;
+ }
+ err = send_xsks_map_fd(msgsock, xsks_map_fd);
+ if (err <= 0) {
+ fprintf(stderr, "Error %d sending xsks_map_fd\n", err);
+ goto cleanup;
+ }
+ do {
+ rval = read(msgsock, &cmd, sizeof(int));
+ if (rval < 0) {
+ fprintf(stderr, "Error reading stream message");
+ } else {
+ if (cmd != CLOSE_CONN)
+ fprintf(stderr, "Recv unknown cmd = %d\n", cmd);
+ listening = 0;
+ break;
+ }
+ } while (rval > 0);
+ }
+ close(msgsock);
+ close(sock);
+ unlink(SOCKET_NAME);
+
+ /* Unset fd for given ifindex */
+ err = bpf_set_link_xdp_fd(ifindex, -1, 0);
+ if (err) {
+ fprintf(stderr, "Error when unsetting bpf prog_fd for ifindex(%d)\n", ifindex);
+ return err;
+ }
+
+ return 0;
+
+cleanup:
+ close(msgsock);
+close_sock:
+ close(sock);
+ unlink(SOCKET_NAME);
+ return err;
+}