在weave的1.2版本之后,考虑到原先sleeve模式的网络性能很差,增加了fastdp的模式,该模式是weave启动时默认模式,在fastdp模式中使用了kernel中的openvswitch.ko模块,在做报文封装时使用内核中的vxlan。最近遇到一个问题,在使用qemu-kvm虚拟的云主机上,如果安装的是centos7.0,并且内核版本为kernel-3.10.123,会造成virtio_net虚拟网卡无法发送数据包,导致整个虚拟机的网络中断的问题。
造成网络断开的原因是因为触发了内核的一个bug,内核bug的链接地址为:
有两种方式可以解决该问题:
1)
升级大于等于
3.13
的内核
2
) 关闭虚拟机网卡的
ufo
特性
Weave会发送一个60000字节的UDP数据包进行PMTU的探测,而且Weave发送使用的是raw socket,因此触发了内核bug,导致了virtio_net使用的内存被污染,表现的现象就是无法通知到宿主机上vhost取数据,在接口上看到发送报文的计数始终不会增加。该问题不是只有weave才能触发,使用普通的应用程序只要在建立socket时,使用是raw socket,并且在发送数据时,发送的数据大于接口的MTU值,接口的UFO功能是打开的,都极有可能触发该问题。
centos7.1的kernel-3.10.229内核已经修复了该问题。下图是WEAVE使用fastdp模式的数据流程图:
![](/attachment/201606/6/20788636_14652138190D7u.png)
底层virtio_net中的处理流程:
造成网络断开的原因是因为触发了内核的一个bug,内核bug的链接地址为:
点击(此处)折叠或打开
- diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
- index dd637fc..05686c4 100644
- --- a/net/ipv4/ip_output.c
- +++ b/net/ipv4/ip_output.c
- @@ -843,7 +843,8 @@ static int __ip_append_data(struct sock *sk,
- cork->length += length;
- if (((length > mtu) || (skb && skb_is_gso(skb))) &&
- (sk->sk_protocol == IPPROTO_UDP) &&
- - (rt->dst.dev->features & NETIF_F_UFO) && !rt->dst.header_len) {
- + (rt->dst.dev->features & NETIF_F_UFO) && !rt->dst.header_len &&
- + (sk->sk_type == SOCK_DGRAM)) {
- err = ip_ufo_append_data(sk, queue, getfrag, from, length,
- hh_len, fragheaderlen, transhdrlen,
- maxfraglen, flags);
- diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
- index 12f7ef0..d7907ec 100644
- --- a/net/ipv6/ip6_output.c
- +++ b/net/ipv6/ip6_output.c
- @@ -1294,7 +1294,8 @@ emsgsize:
- if (((length > mtu) ||
- (skb && skb_is_gso(skb))) &&
- (sk->sk_protocol == IPPROTO_UDP) &&
- - (rt->dst.dev->features & NETIF_F_UFO)) {
- + (rt->dst.dev->features & NETIF_F_UFO) &&
- + (sk->sk_type == SOCK_DGRAM)) {
- err = ip6_ufo_append_data(sk, getfrag, from, length,
- hh_len, fragheaderlen,
- transhdrlen, mtu, flags, rt);
Weave会发送一个60000字节的UDP数据包进行PMTU的探测,而且Weave发送使用的是raw socket,因此触发了内核bug,导致了virtio_net使用的内存被污染,表现的现象就是无法通知到宿主机上vhost取数据,在接口上看到发送报文的计数始终不会增加。该问题不是只有weave才能触发,使用普通的应用程序只要在建立socket时,使用是raw socket,并且在发送数据时,发送的数据大于接口的MTU值,接口的UFO功能是打开的,都极有可能触发该问题。
centos7.1的kernel-3.10.229内核已经修复了该问题。下图是WEAVE使用fastdp模式的数据流程图:
![](/attachment/201606/6/20788636_14652138190D7u.png)
底层virtio_net中的处理流程:
![](/attachment/201606/6/20788636_1465213967689R.png)