如何解决使用 eBPF TC 程序处理 IPv6 数据包的 MSS 问题
2024-05-26 14:02:14
解决使用 eBPF TC 程序处理 IPv6 数据包的 MSS 问题
简介
使用 eBPF 技术优化网络性能时,有时会出现意想不到的问题。本文将重点讨论一个常见问题:当使用 eBPF TC 程序处理 IPv6 出站数据包时,如果最大段大小 (MSS) 大于 1424,则数据包可能会被丢弃。本文将深入探讨这个问题,并提供分步指南来解决它。
问题陈述
在具有 1500 MTU 的网络中,如果使用 eBPF TC 程序向 IPv6 数据包添加扩展头,同时 MSS 大于 1424,则这些数据包可能会被丢弃。这是因为内核会尝试使用 MSS 重新计算 IP 和 TCP 校验和,但这会导致校验和错误。
解决方案
要解决这个问题,我们需要采取以下步骤:
- 调整 MSS: 将 MSS 调整到小于 MTU 的值。对于 1500 MTU 的网络,建议将 MSS 设置为 1460。
- 更新 eBPF 程序: 在 eBPF 程序中使用
bpf_skb_set_tc_flags
函数设置TC_OFFSET_MANGLE
标志。这将指示内核在重新计算校验和之前更新偏移量。
示例代码
struct bpf_map_def SEC("maps") my_map = {
.type = BPF_MAP_TYPE_HASH,
.key_size = sizeof(u32),
.value_size = sizeof(u32),
.max_entries = 1024,
};
static __always_inline int handle_ipv6(struct __sk_buff *skb)
{
struct ethhdr *eth = (struct ethhdr *)skb->data;
struct ipv6hdr *ip6 = (struct ipv6hdr *)(eth + 1);
struct tcphdr *tcp = (struct tcphdr *)(ip6 + 1);
u32 key = ip6->saddr.s6_addr32[3];
u32 *value;
value = bpf_map_lookup_elem(&my_map, &key);
if (!value) {
value = bpf_map_lookup_elem(&my_map, &key);
if (!value)
return TC_ACT_SHOT;
}
tcp->check = bpf_csum_diff(tcp->check, htons(tcp->check),
htons(tcp->seq), htons(tcp->seq + *value),
sizeof(tcp->seq));
return TC_ACT_OK;
}
static __always_inline int handle_tcp(struct __sk_buff *skb)
{
struct ethhdr *eth = (struct ethhdr *)skb->data;
struct ipv6hdr *ip6 = (struct ipv6hdr *)(eth + 1);
if (ip6->nexthdr != IPPROTO_TCP)
return TC_ACT_OK;
return handle_ipv6(skb);
}
SEC("tc")
int tc_prog(struct __sk_buff *skb)
{
struct ethhdr *eth = (struct ethhdr *)skb->data;
if (eth->h_proto != htons(ETH_P_IPV6))
return TC_ACT_OK;
return handle_tcp(skb);
}
结论
通过遵循本文中概述的步骤,你可以解决 eBPF TC 程序在处理具有较大 MSS 的 IPv6 出站数据包时丢弃数据包的问题。调整 MSS 和更新 eBPF 程序对于确保数据包能够顺利通过网络至关重要。
常见问题解答
-
为什么 MSS 大于 1424 时会出现问题?
因为内核会使用 MSS 重新计算 IP 和 TCP 校验和,但当 MSS 大于 MTU 时,这会导致校验和错误。 -
如何调整 MSS?
你可以使用bpf_set_tc_mpls_hdr()函数来调整 MSS。 -
如何更新 eBPF 程序以设置 TC_OFFSET_MANGLE 标志?
你可以使用bpf_skb_set_tc_flags()函数来设置 TC_OFFSET_MANGLE 标志。 -
我需要在代码中做哪些其他更改才能解决这个问题?
除了调整 MSS 和更新 eBPF 程序外,你可能还需要修改 eBPF 程序以处理扩展头。 -
实施这些更改后,还有什么其他需要注意的事项?
确保在部署任何更改之前对其进行彻底测试。此外,监视网络以确保这些更改不会对性能或稳定性产生负面影响。