Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
sudo: required
language: bash
dist: bionic
services:
- docker

env:
global:
- PROJECT_NAME='libbpf'
- AUTHOR_EMAIL="$(git log -1 --pretty=\"%aE\")"
- REPO_ROOT="$TRAVIS_BUILD_DIR"
- CI_ROOT="$REPO_ROOT/travis-ci"
- VMTEST_ROOT="$CI_ROOT/vmtest"

addons:
apt:
packages:
- qemu-kvm
- zstd
- binutils-dev
- elfutils
- libcap-dev
- libelf-dev
- libdw-dev
- python3-docutils

jobs:
include:
- stage: Builds & Tests
name: Kernel LATEST + selftests
language: bash
env: KERNEL=LATEST
script: $CI_ROOT/vmtest/run_vmtest.sh || travis_terminate 1
4 changes: 3 additions & 1 deletion samples/bpf/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ tprogs-y += syscall_tp
tprogs-y += cpustat
tprogs-y += xdp_adjust_tail
tprogs-y += xdpsock
tprogs-y += xdpsock_ctrl_proc
tprogs-y += xsk_fwd
tprogs-y += xdp_fwd
tprogs-y += task_fd_query
Expand Down Expand Up @@ -105,6 +106,7 @@ syscall_tp-objs := syscall_tp_user.o
cpustat-objs := cpustat_user.o
xdp_adjust_tail-objs := xdp_adjust_tail_user.o
xdpsock-objs := xdpsock_user.o
xdpsock_ctrl_proc-objs := xdpsock_ctrl_proc.o
xsk_fwd-objs := xsk_fwd.o
xdp_fwd-objs := xdp_fwd_user.o
task_fd_query-objs := bpf_load.o task_fd_query_user.o $(TRACE_HELPERS)
Expand Down Expand Up @@ -204,7 +206,7 @@ TPROGLDLIBS_tracex4 += -lrt
TPROGLDLIBS_trace_output += -lrt
TPROGLDLIBS_map_perf_test += -lrt
TPROGLDLIBS_test_overhead += -lrt
TPROGLDLIBS_xdpsock += -pthread
TPROGLDLIBS_xdpsock += -pthread -lcap
TPROGLDLIBS_xsk_fwd += -pthread

# Allows pointing LLC/CLANG to a LLVM backend with bpf support, redefine on cmdline:
Expand Down
8 changes: 8 additions & 0 deletions samples/bpf/xdpsock.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,12 @@

#define MAX_SOCKS 4

#define SOCKET_NAME "sock_cal_bpf_fd"
#define MAX_NUM_OF_CLIENTS 10

#define CLOSE_CONN 1

typedef __u64 u64;
typedef __u32 u32;

#endif /* XDPSOCK_H */
184 changes: 184 additions & 0 deletions samples/bpf/xdpsock_ctrl_proc.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
// 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)
return -errno;

sock = socket(AF_UNIX, SOCK_STREAM, 0);
if (sock < 0) {
fprintf(stderr, "Opening socket stream failed: %s", strerror(errno));
exit(EXIT_FAILURE);
}

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));
exit(EXIT_FAILURE);
}

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;
}
Loading