- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
所以我尝试使用 perf_submit 将一些数据从内核空间程序发送到用户空间程序。
我做了一些研究,在这里(https://github.com/iovisor/bcc/issues/2423),yonghong-song 回答(最后一条评论)socket_filter 程序无法访问 bpf_perf_event_output 助手,因此它只能用于跟踪程序类型。
但是,在 BCC 引用站点 ( https://github.com/iovisor/bcc/blob/master/docs/reference_guide.md#2-bpf_perf_output ) 上,如果您按 ctrl+f 并搜索: 3. perf_submit(),它在第五行说“对于 SOCKET_FILTER 程序,必须改用 struct __sk_buff *skb”。我相信这意味着 perf_submit() 也可以用于 socket_filter 程序?
所以我很难确定 perf_submit() 是否确实可以用于套接字过滤器程序。可能宋永红回答了上面的问题后又增加了一些功能?
我正在检查 perf_submit() 是否可以与套接字过滤器一起使用,实际上并没有一行代码可以获取 perf_submit 输出的数据,因为内核程序中的 addint perf_submit() 已经忽略了一个错误。
这是我的程序的代码:
from bcc import BPF
# Network interface to be monoitored
INTERFACE = "br-netrome"
bpf_text = """
#include <uapi/linux/ptrace.h>
#include <net/sock.h>
#include <bcc/proto.h>
#include <linux/bpf.h>
#define IP_TCP 6
#define IP_UDP 17
#define IP_ICMP 1
#define ETH_HLEN 14
BPF_PERF_OUTPUT(events); // has to be delcared outside any function
int packet_monitor(struct __sk_buff *skb) {
u8 *cursor = 0;
u64 saddr;
u64 daddr;
u64 ttl;
u64 hchecksum;
struct ethernet_t *ethernet = cursor_advance(cursor, sizeof(*ethernet));
if (!(ethernet -> type == 0x0800)) {
return 0; // drop
}
struct ip_t *ip = cursor_advance(cursor, sizeof(*ip));
/*
if (ip->nextp != IP_TCP)
{
if (ip -> nextp != IP_UDP)
{
if (ip -> nextp != IP_ICMP)
return 0;
}
}
*/
saddr = ip -> src;
daddr = ip -> dst;
ttl = ip -> ttl;
hchecksum = ip -> hchecksum;
events.perf_submit(skb, &saddr, sizeof(saddr));
// bpf_trace_printk("saddr = %llu, daddr = %llu, ttl = %llu", saddr, daddr, ttl); // only three arguments can be passed using printk
// bpf_trace_printk("Incoming packet!!\\n");
return -1;
}
这是错误代码:
R0=inv2048 R6=ctx(id=0,off=0,imm=0) R7=inv0 R10=fp0,call_-1
4: (20) r0 = *(u32 *)skb[26]
5: (7b) *(u64 *)(r10 -8) = r0
6: (18) r2 = 0xffff9bde204ffa00
8: (18) r7 = 0xffffffff
10: (bf) r4 = r10
11: (07) r4 += -8
12: (bf) r1 = r6
13: (18) r3 = 0xffffffff
15: (b7) r5 = 8
16: (85) call bpf_perf_event_output#25
unknown func bpf_perf_event_output#25
Traceback (most recent call last):
File "packet_monitor.py", line 68, in <module>
function_skb_matching = bpf.load_func("packet_monitor", BPF.SOCKET_FILTER)
File "/usr/lib/python2.7/dist-packages/bcc/__init__.py", line 397, in load_func
(func_name, errstr))
最佳答案
TL;DR. BPF_PROG_TYPE_SOCKET_FILTER
类型的 BPF 程序只能使用 bpf_perf_event_output
starting with Linux 5.4 .
给定 BPF 程序可以访问哪些帮助器由对象 struct bpf_verifier_ops
的 get_func_proto
成员定义。你可以通过阅读函数find_prog_type()
找到哪个bpf_verifier_ops
对象对应哪个程序类型。和文件 bpf_types.h
. 在BPF_PROG_TYPE_SOCKET_FILTER
的情况下,对应的函数是sk_filter_func_proto()
.
如果你 git blame
在最近的内核源代码上运行,你会得到类似下面的东西(你可以用 GitHub 的 blame 功能做同样的事情):
$ git blame net/core/filter.c
[...]
2492d3b867043 (Daniel Borkmann 2017-01-24 01:06:27 +0100 6080) static const struct bpf_func_proto *
5e43f899b03a3 (Andrey Ignatov 2018-03-30 15:08:00 -0700 6081) sk_filter_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
2492d3b867043 (Daniel Borkmann 2017-01-24 01:06:27 +0100 6082) {
2492d3b867043 (Daniel Borkmann 2017-01-24 01:06:27 +0100 6083) switch (func_id) {
2492d3b867043 (Daniel Borkmann 2017-01-24 01:06:27 +0100 6084) case BPF_FUNC_skb_load_bytes:
2492d3b867043 (Daniel Borkmann 2017-01-24 01:06:27 +0100 6085) return &bpf_skb_load_bytes_proto;
4e1ec56cdc597 (Daniel Borkmann 2018-05-04 01:08:15 +0200 6086) case BPF_FUNC_skb_load_bytes_relative:
4e1ec56cdc597 (Daniel Borkmann 2018-05-04 01:08:15 +0200 6087) return &bpf_skb_load_bytes_relative_proto;
91b8270f2a4d1 (Chenbo Feng 2017-03-22 17:27:34 -0700 6088) case BPF_FUNC_get_socket_cookie:
91b8270f2a4d1 (Chenbo Feng 2017-03-22 17:27:34 -0700 6089) return &bpf_get_socket_cookie_proto;
6acc5c2910689 (Chenbo Feng 2017-03-22 17:27:35 -0700 6090) case BPF_FUNC_get_socket_uid:
6acc5c2910689 (Chenbo Feng 2017-03-22 17:27:35 -0700 6091) return &bpf_get_socket_uid_proto;
7c4b90d79d0f4 (Allan Zhang 2019-07-23 17:07:24 -0700 6092) case BPF_FUNC_perf_event_output:
7c4b90d79d0f4 (Allan Zhang 2019-07-23 17:07:24 -0700 6093) return &bpf_skb_event_output_proto;
2492d3b867043 (Daniel Borkmann 2017-01-24 01:06:27 +0100 6094) default:
2492d3b867043 (Daniel Borkmann 2017-01-24 01:06:27 +0100 6095) return bpf_base_func_proto(func_id);
2492d3b867043 (Daniel Borkmann 2017-01-24 01:06:27 +0100 6096) }
2492d3b867043 (Daniel Borkmann 2017-01-24 01:06:27 +0100 6097) }
[...]
如您所见,BPF_FUNC_perf_event_output
最近才添加到这些 BPF 程序可以调用的助手列表中。添加此支持的提交,7c4b90d79d0f4
, 在 Linux v5.4 中被合并:
$ git describe --contains 7c4b90d79d0f4
v5.4-rc1~131^2~248^2~20
关于bpf - eBPF 的 perf_submit() 也可以用在 socket_filter 程序中吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59624275/
我正在尝试在 Linux 源代码中编译示例 bpf 程序。于是我下载了当前的内核源代码,进入samples/bpf文件夹 apt source linux cd linux-*/samples/bpf
我最近一直在研究 BPF,但由于一个非常基本的问题,它没有继续进行。 我按照 man bpf(2) 中的描述包含了 linux/bpf.h,但是 GCC 找不到 bpf 函数。此代码仅用于测试以确保
尝试运行示例 hello_world.py 时出现以下错误。 Traceback (most recent call last): File "/usr/share/bcc/examples/he
我有一个函数 f(),它返回 0 或 1 - 0 表示假,1 表示真。我想做的是用 seccomp-bpf 设置一个规则,这样系统调用“fopen”只有在 f( --fopen 的第一个参数 -- )
我正在尝试加载一个 BPF 程序,它只是复制 tty_write 的 buf 参数。到 BPF 堆栈。我的程序如下: #define BUFSIZE 256 SEC("kprobe/tty_write
我知道 bpf 程序可以通过不同的方式加载到内核中,tc/kprobe/socket ... 而且我想知道有没有一个接口(interface)之类的东西,通过它我可以得到我加载的所有bpf程序?如果没
我正在尝试重定向 NIC 和 WIFI 之间的流量。我正在尝试从 eth0 转发数据包,通过 wlan0 发送偶数数据包,通过 wlan1 发送奇数数据包。 我无法成功地将数据包从一个接口(inter
我查看了不同类型的 BPF 程序,并注意到对于不同的程序类型,上下文的传递方式不同。 例子: 对于程序类型BPF_PROG_TYPE_SOCK_OPS,类型为struct bpf_sock_ops_k
我想了解 bpfilter。我不能使用 netfilter(太慢)、nftables(没有我的功能集)。 内核说: CONFIG_BPFILTER:│ │ 这构建了旨在 │ │ 通过 BPF 提供 n
我写了几个生产 BPF 代理,但我的方法是 非常迭代直到我取悦验证者并可以继续。我又到了极限。 这是一个如果我少一个就可以工作的程序 &&条件 - 否则会中断。令人困惑的部分是警告暗示 103 ins
我想使用 bpf 过滤数据包。我研究了bpf手册并编写了过滤器。这是我的过滤器的最后一行: BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 16), 我加载了ip包长度。现在我要回siz
我正在尝试编写一个示例 eBPF 程序,它可以访问 __sk_buff 成员并将其转储到 /sys/内核/调试/跟踪/跟踪。 #include #include #include SEC("du
我正在编写一个 BPF_PROG_TYPE_SOCKET_OPS 程序,我在 /sys/kernel/debug/tracing/trace_pipe 中看到以下内容: -12586 [001] ..
我正在尝试编写一个 BPF 程序来检查调用 tty_write 内核函数的任何进程的 session ID。为了检索 ID,我需要从一个指向当前 task_struct 的指针跟随一些字段,但是从一个
上下文 在 Linux Debian 64 位上研究 Berkeley 数据包过滤器以过滤打开的套接字接收的数据包。 我使用 AF_PACKET 所以我什至管理数据包的第 2 层。 到目前为止,它工作
我正在使用 Scapy 并希望根据目标 mac 地址进行过滤。 但是,我得到显示的数据包,其中目标 MAC 地址不是过滤器中指定的地址。 这是一个代码片段: from scapy.all import
我正在研究 seccomp-bpf 的实现细节,这是从 3.5 版开始引入 Linux 的系统调用过滤机制。我从 Linux 3.10 查看了 kernel/seccomp.c 的源代码,想问一些关于
bcc使用python编译ebpf程序,有什么方便的方法可以将这些python脚本生成可执行文件,以便我可以在没有安装clang和llvm环境的服务器上运行这些跟踪程序? 最佳答案 TL;DR. 不,
对于下面的程序,我从验证器那里得到一个错误,说它超过了 1M 指令,即使它不应该。该程序查找 HTTP 数据包的主机名。 #include #include struct server_name
关闭。这个问题需要debugging details .它目前不接受答案。 想改善这个问题吗?更新问题,使其成为 on-topic对于堆栈溢出。 3个月前关闭。 Improve this questi
我是一名优秀的程序员,十分优秀!