History

bpf: Convert bpf_preload.ko to use light skeleton.

The main change is a move of the single line #include "iterators.lskel.h" from iterators/iterators.c to bpf_preload_kern.c. Which means that generated light skeleton can be used from user space or user mode driver like iterators.c or from the kernel module or the kernel itself. The direct use of light skeleton from the kernel module simplifies the code, since UMD is no longer necessary. The libbpf.a required user space and UMD. The CO-RE in the kernel and generated "loader bpf program" used by the light skeleton are capable to perform complex loading operations traditionally provided by libbpf. In addition UMD approach was launching UMD process every time bpffs has to be mounted. With light skeleton in the kernel the bpf_preload kernel module loads bpf iterators once and pins them multiple times into different bpffs mounts.

Alexei Starovoitov committed 4 years ago

Commit cb80ddc1 parent d7beb3d9 files · +70 −247Browse files

Showing the changes to kernel/bpf/preload/iterators (2 of 9 files). Show all

Unified · Split

2 files
  1. kernel/bpf/preload/iterators/bpf_preload_common.h +0 −13
  2. kernel/bpf/preload/iterators/iterators.c +0 −108
kernel/bpf/preload/iterators/bpf_preload_common.h+0−13
@@ -1,13 +0,0 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2#ifndef _BPF_PRELOAD_COMMON_H
3#define _BPF_PRELOAD_COMMON_H
4
5#define BPF_PRELOAD_START 0x5555
6#define BPF_PRELOAD_END 0xAAAA
7
8struct bpf_preload_info {
9 char link_name[16];
10 int link_id;
11};
12
13#endif
kernel/bpf/preload/iterators/iterators.c+0−108
@@ -1,108 +0,0 @@
1// SPDX-License-Identifier: GPL-2.0
2/* Copyright (c) 2020 Facebook */
3#include <errno.h>
4#include <stdio.h>
5#include <stdlib.h>
6#include <string.h>
7#include <unistd.h>
8#include <fcntl.h>
9#include <sys/resource.h>
10#include <bpf/libbpf.h>
11#include <bpf/bpf.h>
12#include <sys/mount.h>
13#include "iterators.lskel.h"
14#include "bpf_preload_common.h"
15
16int to_kernel = -1;
17int from_kernel = 0;
18
19static int __bpf_obj_get_info_by_fd(int bpf_fd, void *info, __u32 *info_len)
20{
21 union bpf_attr attr;
22 int err;
23
24 memset(&attr, 0, sizeof(attr));
25 attr.info.bpf_fd = bpf_fd;
26 attr.info.info_len = *info_len;
27 attr.info.info = (long) info;
28
29 err = skel_sys_bpf(BPF_OBJ_GET_INFO_BY_FD, &attr, sizeof(attr));
30 if (!err)
31 *info_len = attr.info.info_len;
32 return err;
33}
34
35static int send_link_to_kernel(int link_fd, const char *link_name)
36{
37 struct bpf_preload_info obj = {};
38 struct bpf_link_info info = {};
39 __u32 info_len = sizeof(info);
40 int err;
41
42 err = __bpf_obj_get_info_by_fd(link_fd, &info, &info_len);
43 if (err)
44 return err;
45 obj.link_id = info.id;
46 if (strlen(link_name) >= sizeof(obj.link_name))
47 return -E2BIG;
48 strcpy(obj.link_name, link_name);
49 if (write(to_kernel, &obj, sizeof(obj)) != sizeof(obj))
50 return -EPIPE;
51 return 0;
52}
53
54int main(int argc, char **argv)
55{
56 struct iterators_bpf *skel;
57 int err, magic;
58 int debug_fd;
59
60 debug_fd = open("/dev/console", O_WRONLY | O_NOCTTY | O_CLOEXEC);
61 if (debug_fd < 0)
62 return 1;
63 to_kernel = dup(1);
64 close(1);
65 dup(debug_fd);
66 /* now stdin and stderr point to /dev/console */
67
68 read(from_kernel, &magic, sizeof(magic));
69 if (magic != BPF_PRELOAD_START) {
70 printf("bad start magic %d\n", magic);
71 return 1;
72 }
73 /* libbpf opens BPF object and loads it into the kernel */
74 skel = iterators_bpf__open_and_load();
75 if (!skel) {
76 /* iterators.skel.h is little endian.
77 * libbpf doesn't support automatic little->big conversion
78 * of BPF bytecode yet.
79 * The program load will fail in such case.
80 */
81 printf("Failed load could be due to wrong endianness\n");
82 return 1;
83 }
84 err = iterators_bpf__attach(skel);
85 if (err)
86 goto cleanup;
87
88 /* send two bpf_link IDs with names to the kernel */
89 err = send_link_to_kernel(skel->links.dump_bpf_map_fd, "maps.debug");
90 if (err)
91 goto cleanup;
92 err = send_link_to_kernel(skel->links.dump_bpf_prog_fd, "progs.debug");
93 if (err)
94 goto cleanup;
95
96 /* The kernel will proceed with pinnging the links in bpffs.
97 * UMD will wait on read from pipe.
98 */
99 read(from_kernel, &magic, sizeof(magic));
100 if (magic != BPF_PRELOAD_END) {
101 printf("bad final magic %d\n", magic);
102 err = -EINVAL;
103 }
104cleanup:
105 iterators_bpf__destroy(skel);
106
107 return err != 0;
108}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t