使用bpf开发一个小程序来扩展数据包(即:添加mpls-encap(。设法在没有问题的情况下进行了扩展,但我写回了标题——s_mac和d_mac不正确。我假设,因为新的空间较小,我与原始的eth标头重叠,因此我得到了错误的值。
/* extend the packet for mpls header encapsulation */
if (bpf_xdp_adjust_head(ctx, 0 - (int)sizeof(struct mpls_hdr)))
return XDP_DROP;
data = (void *)(long)ctx->data;
data_end = (void *)(long)ctx->data_end;
/* relocate ethernet header to start of packet and set MACs */
new_eth = data;
old_eth = data + (int)sizeof(struct mpls_hdr);
//set new header while swaping src/dst mac
set_ethhdr(new_eth, old_eth, bpf_htons(ETH_P_MPLS_UC));
这就是我认为问题发生的地方,当我记忆到新的空间时,我正在咬旧的空间。有没有一种方法可以解决这个问题,将old_eth的值复制到另一个结构中,然后使用该结构创建new_eth?
static __always_inline void set_ethhdr(struct ethhdr *new_eth,
const struct ethhdr *old_eth,
__be16 h_proto)
{
memcpy(new_eth->h_source, old_eth->h_source, ETH_ALEN);
memcpy(new_eth->h_dest, old_eth->h_dest, ETH_ALEN);
new_eth->h_proto = h_proto;
}
一般来说,我对BPF和C都很陌生,所以不确定这是否真的是问题所在。
Thx。
我已经根据以下内容进行了更改。不确定这是否是解决它的最佳方法,但它适用于我的用例(poc(。
static __always_inline void set_ethhdr(struct ethhdr *new_eth,
const struct ethhdr *old_eth,
__be16 h_proto)
{
__u8 h_tmp_src[ETH_ALEN];
__u8 h_tmp_dst[ETH_ALEN];
__builtin_memcpy(h_tmp_src, old_eth->h_source, ETH_ALEN);
__builtin_memcpy(h_tmp_dst, old_eth->h_dest, ETH_ALEN);
__builtin_memcpy(new_eth->h_dest, h_tmp_src, ETH_ALEN);
__builtin_memcpy(new_eth->h_source, h_tmp_dst, ETH_ALEN);
new_eth->h_proto = h_proto;
}