gpt4 book ai didi

linux - 自定义 ebtables 模块 && skb 操作 && 内核 panic

转载 作者:太空宇宙 更新时间:2023-11-04 04:03:49 25 4
gpt4 key购买 nike

不久前,我基于 Ashwin Kashyap 的 vnat 模块实现了 ebtables 模块( http://www.research.rutgers.edu/~ashwink/misc_projs/ebt_vnat.html )。模块可用于 broute 表中的 BROUTING 链,用于剥离 vlan 标记并将 vlan id 放入 nf 标记中。模块还允许根据 nat 表的 POSTROUTING 链中的 nf 标记值添加 vlan 标记。模块在桥接流量上工作没有任何问题。系统坚如磐石稳定。一旦我将 tproxy 拦截添加到其中,问题就开始了。这会导致运行一段时间后出现内核 panic 。我强调这样一个事实,即在经过几分钟的 tproxied 流量流后,我没有看到第一个数据包后出现内核 panic 。看来我破坏 SKB 的方式对于 L3+ 处理来说不够干净。顺便说一句,我正在开发 2.6.32 内核。请找到该模块的关键部分,并附有以下注释:

// code for adding vlan tag based on skb->mark value
if (!skb_make_writable(skb, 0))
return EBT_DROP;

if(skb->mark > 0){
// maybe we should always seek VLAN_HLEN+ETH_HLEN instead of using condition?
if (skb_headroom(skb) < (skb->mac_len == 0 ? VLAN_HLEN + ETH_HLEN : VLAN_HLEN ) ) {
struct sk_buff *sk_tmp = skb;
skb = skb_realloc_headroom(sk_tmp, VLAN_HLEN );
kfree_skb(sk_tmp);

if (skb == NULL) {
return EBT_DROP;
}
}

// we need 4 more bytes for 802.1q header, so push!...I can almost see the head(er)
skb_push(skb, VLAN_HLEN);

skb->mac_header-=VLAN_HLEN;
skb->network_header-=VLAN_HLEN;
skb->transport_header-=VLAN_HLEN;
veth = (struct vlan_ethhdr *) eth_hdr(skb);

// move dst/src mac addresses (12b of header) 4 bytes back to make room for
// 802.1q header
memmove( skb->head + skb->mac_header, skb->head + skb->mac_header + VLAN_HLEN, 12);

// fill 802.1q header
veth->h_vlan_proto = __constant_htons(ETH_P_8021Q);
veth_TCI = skb->mark & 0xfff;
veth->h_vlan_TCI = htons(veth_TCI);
}

// code for stripping vlan tag and putting it into skb->mark value
veth = (struct vlan_ethhdr *)eth_hdr(skb);
if(veth->h_vlan_proto == __constant_htons(ETH_P_8021Q)){

if (!skb_make_writable(skb, 0))
return EBT_DROP;

// determine vlan id
vid=(ntohs(veth->h_vlan_TCI) & 0xfff);
mark = vid;

// copy dst/src mac addresses (12b) 4 bytes fwd, so it covers 802.1q header
memmove(skb->head + skb->mac_header + VLAN_HLEN, skb->head + skb->mac_header, 12);

// adapt header pointers
skb->mac_header+=VLAN_HLEN;
skb->mac_len = ETH_HLEN;
skb->network_header+=VLAN_HLEN;
skb->transport_header+=VLAN_HLEN;
skb->data += VLAN_HLEN;
skb->len -= VLAN_HLEN;

eth = eth_hdr(skb);
skb->protocol=eth->h_proto;
}
skb->mark=mark;

如果有任何指点(只要它们至少是 64 位长),我将不胜感激。谢谢!

最佳答案

您的代码应该更改 MAC header 以添加或删除 802.1q header 。现在我很可能是错的,但是为什么需要将指针转移到网络和传输层 header ?

我希望 MAC header 能够扩展和收缩到 skb 净空,而数据包的其余部分在任何情况下都保持不变。移动网络和传输 header 会导致上层 (3+) 读取错误的前 4 个字节。

(注意,我会把这个写成评论而不是答案,因为我不确定自己是对的,但我最近一直在为 ebtables 开发 VLAN 标签转换模块,这是我第一次为 SO 做出贡献,所以我的声誉显然不够高)。

关于linux - 自定义 ebtables 模块 && skb 操作 && 内核 panic ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22053028/

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