gpt4 book ai didi

c - 无法在 Raspberry Pi 上加载 eBPF/XDP 代码

转载 作者:行者123 更新时间:2023-11-30 14:37:59 25 4
gpt4 key购买 nike

主要问题是我无法在网络接口(interface) (XDP) 中加载 eBPF 代码。

我尝试在 Raspberry Pi 3 上加载,配置如下:

  • Raspbian GNU/Linux 10(巴斯特)
  • 内核 4.19.50-v7+

我使用 ip 命令如下:

$ sudo ip -force link set dev wlan0 xdp obj portfilter.o sec filter

在此之前,我通过apt执行了clang-7安装,并且ma​​ke命令工作正常(生成对象)。

Makefile源代码如下:

# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)

LLVM_VERSION ?= -7 #update with correct LLVM / clang version
LLVM := $(shell clang$(LLVM_VERSION) --version)
CLANG_FLAGS ?= -W -Wall \
-Wno-compare-distinct-pointer-types

SRCS=$(wildcard *.c)
OBJS=$(patsubst %.c,%.o,$(SRCS))
Q ?= @

INCLUDE_DIRS ?= -Iheaders/

%.o: %.c
@echo "\tLLVM CC $@"
$(Q) clang$(LLVM_VERSION) $(INCLUDE_DIRS) -O2 -emit-llvm -c $< $(CLANG_FLAGS) -o $(patsubst %.o,%.llvm,$@)
$(Q) llc$(LLVM_VERSION) -march=bpf -filetype=obj -o $@ $(patsubst %.o,%.llvm,$@)
$(Q) rm $(patsubst %.o,%.llvm,$@)

ifeq ($(LLVM),)
all:
$(warning Install LLVM to compile BPF sources)
else
all: $(OBJS)
endif

clean:
rm -f *.llvm
rm -f *.o

.PHONY: all clean

以及预计加载的portfilter.c源代码:

#include <stdbool.h>
#include <stddef.h>
#include <string.h>
#include <linux/bpf.h>
#include <linux/icmp.h>
#include <linux/if_ether.h>
#include <linux/in.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/udp.h>
#include "bpf_endian.h"
#include "bpf_helpers.h"

/* 0x3FFF mask to check for fragment offset field */
#define IP_FRAGMENTED 65343

/* Port number to be dropped */
#define PORT_DROP 80

static __always_inline int process_packet(struct xdp_md *ctx, __u64 off){

void *data_end = (void *)(long)ctx->data_end;
void *data = (void *)(long)ctx->data;
struct iphdr *iph;
struct tcphdr *tcp;
__u16 payload_len;
__u8 protocol;

iph = data + off;
if (iph + 1 > data_end)
return XDP_PASS;
if (iph->ihl != 5)
return XDP_PASS;

protocol = iph->protocol;
payload_len = bpf_ntohs(iph->tot_len);
off += sizeof(struct iphdr);

/* do not support fragmented packets as L4 headers may be missing */
if (iph->frag_off & IP_FRAGMENTED)
return XDP_PASS;

if (protocol == IPPROTO_TCP) {
tcp = data + off;
if(tcp + 1 > data_end)
return XDP_PASS;

/* Drop if using port PORT_DROP */
if(tcp->source == bpf_htons(PORT_DROP) || tcp->dest == bpf_htons(PORT_DROP))
return XDP_DROP;
else
return XDP_PASS;

} else if (protocol == IPPROTO_UDP) {
return XDP_PASS;
}

return XDP_PASS;
}


SEC("filter")
int pfilter(struct xdp_md *ctx){

void *data_end = (void *)(long)ctx->data_end;
void *data = (void *)(long)ctx->data;
struct ethhdr *eth = data;
__u32 eth_proto;
__u32 nh_off;

nh_off = sizeof(struct ethhdr);
if (data + nh_off > data_end)
return XDP_PASS;
eth_proto = eth->h_proto;

/* demo program only accepts ipv4 packets */
if (eth_proto == bpf_htons(ETH_P_IP))
return process_packet(ctx, nh_off);
else
return XDP_PASS;
}

不幸的是,ip命令后的实际输出如下:

mkdir /sys/fs/bpf failed: Operation not permitted
Continuing without mounted eBPF fs. Too old kernel?

Prog section 'filter' rejected: Function not implemented (38)!
- Type: 6
- Instructions: 38 (0 over limit)
- License:

Verifier analysis:

Error fetching program/map!

但预期的结果是模块在网络接口(interface)中正确加载。

此代码可在运行 Ubuntu 18 且内核为 4.15.0-54-generic 的笔记本电脑上运行

请问有人知道如何正确配置树莓派以使用此代码吗?

最佳答案

您的内核可能未使用 BPF 支持进行编译(我的 4.15 Raspbian 没有)。您可以通过以下步骤进行检查:

sudo modprobe configs
zgrep -E "(BPF|XDP)" /proc/config.gz

CONFIG_BPFCONFIG_BPF_SYSCALL 均应启用。如果不是,那么您需要在启用这些配置的情况下重新编译内核

关于c - 无法在 Raspberry Pi 上加载 eBPF/XDP 代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56924815/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com