ifconfig dropped rx packets
ifconfig dropped rx packets

一、问题现象

上面的图已经很能描述问题,现网某业务反馈,其对应的几台主机发现active-backup的bond网卡接口对应的备用网卡,rx包基本上全都是dropped状态,而且一直在持续增长。登陆确认后,查看主机配置未发现异常,同时对比了下邻近主机的ifconfig输出(不同网段,不同业务)发现也存在该问题。

二、问题分析

1、初步分析结果

在检查配置未发现异常,而且从理论分析上来说,备用网卡是不走流量的(除非主用异常,备用切换为主),理论上来说,应该基本没有包通过才对。既然说不通,那就先tcpdump抓包看下内容:

tcpdump-dropped抓包
tcpdump-dropped抓包

从抓包分析结果来看,都是来自于网关设备的VRRP组播包和ARP包。而交换机之间主备是走的VRRP协议。上面的192.168.40.2就是其中一台交换机配置的真实IP地址。又检查了下主机上确认未安装keepalive高可用包。于是考虑是否是网络设备配置有问题。

联合网络组同事进行排障分析,网络同事表示,这是组播包,是针对该网络所有主机发送的,这与广播类似,只不过一个是发送1次,一个是发送n次。备用网卡上收到这个包正常,因为所有的网卡上都会收到这样的包。

从理论上来讲,确实说的通。但在排障时,随机抽取了另一个机房的一台主机(主网络架构基本相同,都是交换机VRRP主备,主机网卡a-b bond模式),发现在该主机上备用网卡不存在丢弃包的问题。其通过在另一机房抓包反证,证明B机房的备用网卡上也有同样的包存在。通过对比认为还是系统的问题,可能和系统版本相关。因为发现redhat系统上没有该问题。

而在现网A、B两个机房分别找不同版本的OS对比发现如下结果:

  • SUSE11sp2之前的版本都不存在该问题,SUSE11 SP2及其后所有版本有该问题;
  • rhel5、rhel6所有版本不存在该问题(rhel7主要是虚拟机,未进行对比)

2、最终结果

既然版本不同,结果不一样,很可能新版本里某些参数发生了变化,我能想到的是sysctl 参数、 /boot/config-XXX配置的kernel启动项,如果找到相应的项,就能忽略网关设备发送的这种包造成的dropped。而在对比了不同OS版本下tcp/ip、cast、接口等相关的sysctl参数后,未发现有对应的控制项。在/boot/config-xx文件中也未找到有相对应的值。

放狗查询,发现翻墙用的google程序用不了了。退而求其次通过bing查询,在SUSE和redhat相应的knowledge页中找到了答案。(吐槽下,技术文档检索,百度做的不是一般的烂)。

三、问题结果

在SUSE的kb中可以发现如下内容:

Beginning with kernel 2.6.37, it has been changed the meaning of dropped packet count. Before, dropped packets was most likely due to an error. Now, the rx_dropped counter shows statistics for dropped frames because of:

从2.6.37内核以后,改变了dropped包的统计方式,其不再是以错误包的方式统计,以下情况也会计入dropped包。其值只是做为一种状态统计了。

  • Softnet backlog full — (Measured from /proc/net/softnet_stat)
  • Bad / Unintended VLAN tags
  • Unknown / Unregistered protocols
  • IPv6 frames when the server is not configured for IPv6

下面还有两句说的更直白了:

This effect is seen starting from SLES 11 SP2, as it utilizes a 3.x kernel series. Previous SLES versions do not exhibit it (that are using kernels prior to 2.6.37)
Please also note, for an active/backup bond setup it is common that the inactive device drops all packages.

尤其最后一句,在bond主备模式中,备用网卡接到的所有包都会计入dropped。

而redhat和其他发行对应的发行版如SUSE、ubuntu等来比,kernel和包都相对版本要低一些,这和其策略有关,未确认稳定的,不会加入到当前的发行版本中(说白了,让别人先踩坑,感觉合适了,我再用)。在未单独升级过kernel 的情况下,其只在rhel7中才会有该情况发生,而且其kb给出了前后统计方式不同的源码,具体变化在rt_kernel core/dev.c文件中,rhel7版本使用的如下:

 1static int __netif_receive_skb(struct sk_buff *skb)
 2.
 3.
 4.
 5        if (sk_memalloc_socks() && skb_pfmemalloc(skb)
 6                                && !skb_pfmemalloc_protocol(skb))
 7                goto drop;
 8.
 9.
10.
11       if (pt_prev) {
12                if (unlikely(skb_orphan_frags(skb, GFP_ATOMIC)))
13                        goto drop;
14                else
15                        ret = pt_prev->func(skb, skb->dev, pt_prev, orig_dev);
16        } else {
17drop:
18                atomic_long_inc(&skb->dev->rx_dropped); <---- Counter is incremented
19                kfree_skb(skb);

而在rhel6之前的kernel版本中,没有这些变化:

1if (pt_prev) {
2        ret = pt_prev->func(skb, skb->dev, pt_prev, orig_dev);
3} else {
4        kfree_skb(skb);
5        /* Jamal, now you will not able to escape explaining
6         * me how you were going to use this. :-)
7         */
8        ret = NET_RX_DROP; <---- silently dropped
9}

SUSE ---ifconfig shows dropped rx packets
https://www.suse.com/support/kb/doc/?id=7007165

https://www.novell.com/support/kb/doc.php?id=7007165

Redhat---Why am I seeing the rx_dropped ifconfig counter increase on rt_kernel/RHEL7?
https://access.redhat.com/solutions/657483