用C语言写一个内核端bpf创建map的完整示例
时间: 2024-05-12 11:21:09 浏览: 301
下面是一个内核端bpf创建map的C语言示例:
```c
#include <linux/bpf.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <linux/if_ether.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#define MAP_TYPE BPF_MAP_TYPE_HASH
#define KEY_SIZE sizeof(__u32)
#define VALUE_SIZE sizeof(__u64)
#define MAP_SIZE 256
int main(int argc, char **argv) {
int map_fd, i, ret;
__u32 key;
__u64 value;
struct bpf_insn prog[] = {
BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
BPF_LD_MAP_FD(BPF_REG_2, map_fd),
BPF_MOV32_IMM(BPF_REG_3, 1),
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -ETH_HLEN),
BPF_STX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, BPF_REG_3),
BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
BPF_LD_MAP_FD(BPF_REG_2, map_fd),
BPF_MOV32_IMM(BPF_REG_3, 1),
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -ETH_HLEN + offsetof(struct iphdr, protocol)),
BPF_LD_ABS(BPF_W, BPF_REG_4),
BPF_STX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, BPF_REG_3),
BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
BPF_LD_MAP_FD(BPF_REG_2, map_fd),
BPF_MOV32_IMM(BPF_REG_3, 1),
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -ETH_HLEN + sizeof(struct iphdr)),
BPF_LD_ABS(BPF_W, BPF_REG_4),
BPF_STX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, BPF_REG_3),
BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
BPF_LD_MAP_FD(BPF_REG_2, map_fd),
BPF_MOV32_IMM(BPF_REG_3, 1),
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -ETH_HLEN + sizeof(struct iphdr) + offsetof(struct tcphdr, dest)),
BPF_LD_ABS(BPF_W, BPF_REG_4),
BPF_STX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, BPF_REG_3),
BPF_MOV64_IMM(BPF_REG_0, 0),
BPF_EXIT_INSN(),
};
struct bpf_program prog_struct = {
.len = sizeof(prog) / sizeof(struct bpf_insn),
.insn = prog,
};
map_fd = syscall(__NR_bpf, MAP_TYPE, KEY_SIZE, VALUE_SIZE, MAP_SIZE, 0);
if (map_fd < 0) {
perror("Failed to create map");
exit(1);
}
ret = bpf_prog_load(BPF_PROG_TYPE_SOCKET_FILTER, &prog_struct, prog_struct.len, "GPL", 0, NULL, 0);
if (ret < 0) {
perror("Failed to load program");
exit(1);
}
printf("Successfully created map with fd %d and program fd %d\n", map_fd, ret);
close(map_fd);
close(ret);
return 0;
}
```
这个示例程序创建了一个类型为HASH、键大小为4字节、值大小为8字节、大小为256的map,并通过BPF程序将目的端口地址的值存储在map中。它使用了Linux系统调用`bpf()`创建map,并使用`bpf_prog_load()`将BPF程序加载到内核中。在完成后,它关闭了map和BPF程序的文件描述符。
阅读全文