如何为IP/CIDR创建LPM trie记录切片以使用ebpf批量API
用cilium/ebpf的BatchUpdate/BatchDelete优化XDP防火墙IP黑名单批量操作
第一步:定义LPM Trie键结构体
eBPF的LPM trie map要求键必须包含前缀长度和IP地址两个字段,先在Go代码里定义对应的结构体(要和你的eBPF程序中LPM map的键结构完全一致):
// LPMKey 对应IPv4 LPM trie的键结构 type LPMKey struct { PrefixLen uint32 // 前缀长度,比如/32对应值为32 IP [4]byte // IPv4地址的字节数组 }
第二步:将CIDR字符串转换为LPMKey切片
写一个工具函数,把传入的CIDR列表转换成Batch API需要的键格式:
import "net" func cidrsToLPMKeys(cidrs []string) ([]LPMKey, error) { var keys []LPMKey for _, cidr := range cidrs { ipNet, err := net.ParseCIDR(cidr) if err != nil { return nil, err } // 提取CIDR前缀长度 prefixLen, _ := ipNet.Mask.Size() // 将IPv4地址转换为[4]byte格式 var ipBytes [4]byte copy(ipBytes[:], ipNet.IP.To4()) keys = append(keys, LPMKey{ PrefixLen: uint32(prefixLen), IP: ipBytes, }) } return keys, nil }
第三步:替换原有单条更新逻辑为BatchUpdate
原来的代码是循环调用Update逐个添加IP,现在用Batch方法批量操作:
import "github.com/cilium/ebpf" import "log" func main() { // 假设你已经完成LPM map的初始化(变量名lpmMap) // 你的黑名单IP列表 denyIPs := []string{"10.11.15.114/32", "127.0.0.1/32"} // 转换为LPM键切片 lpmKeys, err := cidrsToLPMKeys(denyIPs) if err != nil { log.Fatalf("转换CIDR失败: %v", err) } // 构建批量更新条目 var batchEntries []ebpf.BatchEntry for _, key := range lpmKeys { batchEntries = append(batchEntries, ebpf.BatchEntry{ Key: &key, Value: &struct{}{}, // 替换成你实际需要存储的值类型(比如xdp-firewall中的bool类型) Op: ebpf.BatchUpdate, // 指定操作为更新 }) } // 执行批量更新 successCount, err := lpmMap.Batch(batchEntries, nil) if err != nil { log.Fatalf("批量更新失败: %v,已成功执行%d条", err, successCount) } }
第四步:批量删除IP(BatchDelete)
如果需要批量移除黑名单IP,只需要修改Op为ebpf.BatchDelete即可:
// 构建批量删除条目 var deleteBatch []ebpf.BatchEntry for _, key := range lpmKeys { deleteBatch = append(deleteBatch, ebpf.BatchEntry{ Key: &key, Op: ebpf.BatchDelete, // 指定操作为删除 }) } // 执行批量删除 successCount, err := lpmMap.Batch(deleteBatch, nil) if err != nil { log.Fatalf("批量删除失败: %v,已成功执行%d条", err, successCount) }
注意事项
- 确保Go侧的
LPMKey结构体和eBPF程序中LPM map的键定义完全一致(字段顺序、类型、字节序),否则会导致操作失败 Batch方法返回的successCount是已经成功执行的条目数,即使部分失败也会返回这个值,你可以根据需求做重试或部分处理- 第三个参数可以传入
ebpf.BatchOptions设置超时等参数,默认传nil使用配置
内容的提问来源于stack exchange,提问作者99Linux
相关产品推荐
相关产品推荐

