Итак, я пытался отправить некоторые данные из космической программы ядра в пользовательскую космическую программу, используя perf_submit.
Я провел некоторые исследования и здесь (https://github.com/iovisor/bcc/issues/2423), yonghong-song ответил (последний комментарий), что программа socket_filter не может получить доступ к помощнику bpf_perf_event_output и, следовательно, его можно использовать только для отслеживания типов программ.
Однако на B CC ссылочный сайт (https://github.com/iovisor/bcc/blob/master/docs/reference_guide.md#2 -bpf_perf_output ), если вы ctrl + f и ищете: 3. perf_submit (), в пятой строке говорится, что «для программ SOCKET_FILTER вместо этого должна использоваться структура __sk_buff * skb». Я полагаю, что из этого следует, что perf_submit () можно использовать и для программ socket_filter?
Так что мне трудно понять, действительно ли perf_submit () можно использовать для программы фильтрации сокетов. Может быть, некоторые функции были добавлены после того, как Yonghong-song ответил на вопрос выше?
Я проверяю, будет ли 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))