本文介绍:

  • AIX内核扩展,允许来往于指定主机的指定百分比的TCP / IP数据包被随机丢弃,以模拟不利的网络状况。
  • 加载,激活和卸载内核扩展的实用程序。
  • C和Java™实用程序,用于监视到达目标主机的总数据包吞吐量和实际丢弃的数据包。
  • 使用C和Java实用程序进行内核扩展的完整源代码,以便可以根据本地要求构建,定制和开发该软件。

本文提供了构建和运行此数据包丢弃模拟器所需的所有组件,这些组件是可下载的压缩文件。 “ 如何按提供的方式构建和使用内核扩展”部分使您可以尽快上手并使用它。

内核扩展旨在在单个源节点上激活,从该源扩展中,它将选择性地丢弃出站到目标节点或从目标节点接收到的数据包。 无需在目标节点上安装数据包丢弃模拟器。 目标节点本身甚至不需要基于AIX,而仅需要支持TCP / IP协议。

本文首先介绍了TCP / IP性能的一些背景知识,以及为什么丢弃的数据包会严重影响应用程序性能。 然后,您将看到所提供的如何构建和使用内核扩展。 这使您可以快速启动并运行它。

提供的功能故意非常简单。 它允许您设置给定百分比的TCP / IP数据包,以随机方式将其丢弃到指定主机或从该主机中丢弃,而所有其他主机和协议均不受影响,并且没有保留的历史记录。 因为在实践中,您可能需要根据自己的需求向内核扩展添加更多功能,所以还将向您显示有关该扩展如何工作以及如何进行自定义的详细信息。 然后,如果需要,您可以决定这样做:

  • 允许数据包往返于多个主机。
  • 为每个主机支持不同的数据包丢失率。
  • 创建双向接收,传输和丢弃的总数据包的历史日志。
  • 与编写软件时使用的版本不同,在不同版本的AIX或C编译器上实现数据包丢弃模拟器。

可以很容易地进一步开发内核扩展,以模拟可能引起性能问题的其他网络问题,例如数据包损坏,数据包乱序到达和抖动。

建议内核扩展仅在非生产系统上使用。

背景

首先,让我们回顾一些在考虑网络性能,带宽,延迟和拥塞时非常重要的基本术语。

带宽是网络的容量,即可以在其上推送数据的速率。 通常以每秒兆位(Mbps)为单位,其中1兆位是10 ^ 6位。 可以认为是网络管道的宽度。

延迟是一条数据穿越网络所花费的时间。 通常以毫秒为单位。 可以将其视为网络管道的长度。

带宽和等待时间之间的差异如图1所示。

图1.延迟和带宽以及网络管道

拥塞是大量使用网络的结果。 它可能导致数据传播延迟,数据包丢失导致数据包重新传输以及无法建立与网络的连接。 数据包丢失通常以百分比衡量。 TCP通常可以处理高达0.1%的损失,几乎没有直接影响。 如果损失增加到此以上,则影响可能会更严重。

网络延迟,带宽和拥塞会对应用程序性能产生严重影响。 例如,考虑一种情况,其中一个系统上的前端应用程序通过网络频繁调用另一个宿主该应用程序使用的数据库的系统。 跨网络到数据库的流量可能包含许多小数据突发,或者可能包含较少的相对较大的数据传输集。 无论哪种方式,网络可靠而快速地传输数据的能力都是影响客户感知应用程序端到端性能的重要因素。

应用程序开发团队通常可以访问隔离的高速网络,该网络与部署应用程序的环境相比,使用率要低得多。 这可能意味着在开发和测试应用程序的环境中可能永远不会观察到不良的网络性能对应用程序的影响。 反过来,这可能意味着在客户环境中观察到的性能可能与在其进行测试的环境中观察到的性能非常不同。

本文重点介绍丢包对特定应用程序性能的影响。 由于在前端系统和后端系统之间传输的数据包数量可能非常多,因此传输这些应用程序包的模式非常特定于前端和后端的性质应用程序,了解对应用程序影响的最简单方法是模拟数据包的丢弃。

在系统之间传输数据时,可能会丢弃数据包,原因有两个:

  • 大量的网络利用率并导致拥塞
  • 网络硬件或连接器故障

TCP被设计为能够在网络上丢包时做出React。 当数据包成功传递到其目的地时,目标系统将确认消息发送回源系统。 如果在某个时间间隔内未收到此确认,则可能是由于目标系统从未收到该数据包,或者是因为包含该确认的数据包本身丢失了。 在任何一种情况下,如果源系统在给定的时间内未收到确认,则源系统会假设目标系统从未接收到该消息并重新发送该消息。 不难看出,如果网络性能不佳,首先会丢失数据包,而这些重传消息所增加的负载只会进一步增加网络上的负载,这意味着将会丢失更多的数据包。 此行为可能导致非常快速地在网络上造成严重情况。

有一些免费提供的高级软件产品,可以帮助模拟变化的网络性能的不同特征。 这些包括:

  • WANem :从基于KnoppixLinux®的CD运行
  • ipfilter :公共领域的软件,但未完全移植到AIX
  • 虚拟网(FreeBSD)
  • ALTQ(FreeBSD)

WANem从基于Knoppix的CD运行,可以模拟各种不同的网络特性。 它确实具有丢弃带有过滤选项的随机数据包的功能,但是可能需要在源系统和目标系统之间的单独系统上运行,这可能不方便,例如如果源系统和目标系统安装在专用系统上高速网络。构建内核扩展和实用程序

尽管ipfilter看起来非常有前途,但是它只是部分移植到了AIX 5.3,并且很明显,编写一个定制的实用程序以提供所需的最小功能比将整个ipfilter移植到AIX 6.1和7.1更快。

dummynet是FreeBSD操作系统的一个组件,还已移植到其他平台,包括Linux和Microsoft®Windows®。 但是,使用它的缺点是要模拟源自AIX主机的数据包的丢包,必须使用虚拟网络来配置和设置中间FreeBSD / Linux主机。

ALTQ是备用排队框架,主要在BSD路由器上帮助提供带宽控制。

也有其他商用软件包,例如LANforge ICE,但出于成本原因被排除在外。 LANforge还需要专用硬件。

如何构建和使用提供的内核扩展

要求

数据包丢弃模拟器是在以下环境中构建和测试的:

  • 带有gcc V4.7.2-1的AIX V7.1.4.0
  • 带有gcc V4.2.0的AIX V6.1.2.0
  • 带有gcc V4.2.0的AIX V6.1.4.0

使用gcc编译器编译了内核扩展和相关的C程序。 如果需要,可以使用AIX C编译器直接进行替换,尽管有些编译标志需要更改。

请注意,有必要安装AIX bos.adt.syscalls文件集以构建内核扩展。 这将在您的AIX安装介质上可用。 如果仅要部署内核扩展,则只要AIX级别与构建系统相同,系统上就不需要文件集。 如果两个系统之间的AIX级别存在差异,则应在每个系统上构建内核扩展。

内核扩展,用于加载和激活它的kctrl实用程序以及C示例控件和监视器都是使用AIX make工具构建的。 可下载的zip文件中包含用于构建所有这些组件的makefile。

预防措施

使用此实用程序之前,应牢记两个重要因素:

1)开发和测试任何内核扩展时都应格外小心。 错误通常会导致系统故障。 专用的测试系统是理想的,但请避免使用也用于其他目的或由其他用户使用的系统。 如果系统位于远程数据中心,则还应确保您有能力在需要时重新启动(如果它不会自动重新启动)。

2)避免使用泛洪ping在共享网络上测试实用程序,因为这可能会严重影响其他用户。

构建内核扩展和实用程序

首先,请确保您已满足上述开发系统上的要求。

接下来,将可下载附件解压缩到目标AIX系统上您选择的工作目录中。

该下载不包括预构建的二进制文件,以避免在不兼容的操作系统级别上运行它的风险。 因此,一旦提取软件,就需要构建该软件。 为此,将目录更改为上面创建的工作目录,然后按如下所示运行make命令:

# makegcc -Wall -maix64 -ffreestanding -msoft-float   -o pdrop_kernex64.o -cpdrop_kernex.cld -b64 -o pdrop_kernex64 pdrop_kernex64.o -e pdrop_init -bI:/home/jerry/kernext/kernex.exp -bI:/home/jerry/kernext/netinet.exp -bE:/home/jerry/kernext/pdrop_syscall.exp -lsys -lcsysrm -f pdrop_kernexar -X64 -r -v pdrop_kernex pdrop_kernex64ar: Creating an archive file pdrop_kernex.a - pdrop_kernex64gcc -Wall -maix32 -o pdrop_ccm32  .c -Xlinker -bI:/home/jerry/kernext/pdrop_syscall.expgcc -Wall -maix64 -o pdrop_ccm64 pdrop_ccm.c -Xlinker -bI:/home/jerry/kernext/pdrop_syscall.expgcc -maix64 -o kctrl kctrl.cgcc -Wall -I/usr/java6/include -I. -shared -fPIC pdrop_jni.c -o libpdrop_jni.so -Xlinker -bI:/home/jerry/kernext/pdrop_syscall.exp
Target "all" is up to date.
#

成功运行make命令后,使用它所需的数据包丢弃实用程序的所有C组件都可以使用。

请注意,Java控制和监视应用程序需要按照“ 控制和监视应用程序”部分中的说明分别构建。

加载并激活内核扩展

在下一步中将要构建的二进制文件之一是kctrl程序。 这允许内核扩展被加载,激活和卸载。 要加载并激活内核扩展,请按照下列步骤操作:

# ./kctrl /home/jerry/kernext/pdrop_kernex64Enter choice, (l)oad, (u)nload, (i)nit, (t)erm, (q)uery or (e)nd
l
Extension Successfully loaded, kmid is 1353523200Enter choice, (l)oad, (u)nload, (i)nit, (t)erm, (q)uery or (e)nd
iExtension InitializedEnter choice, (l)oad, (u)nload, (i)nit, (t)erm, (q)uery or (e)nd
e
#

此时,内核扩展将被加载并处于活动状态,但在使用C或Java控件和监视器实用程序之前,不会将任何数据包丢弃到目标主机。

启动数据包丢弃和监控

加载并初始化了内核扩展之后,现在您可以看到如何使用提供的C实用程序pdrop_ccm来控制和监视目标主机的数据包设置。

使用指定内核扩展构建位置,目标主机名和删除率的参数调用pdrop_ccm

# ./pdrop_ccm64 /home/jerry/kernext/pdrop_kernex64
Usage: ./pdrop_ccm64 <kernel_extension> <TargetIP> <drop_percentage>
#

例如,您可以将其与主机名fred一起使用,并将丢失率设置为0.5%,如下所示:

# ./pdrop_ccm64 /home/jerry/kernext/pdrop_kernex64 fred 0.5
Kernel extenstion is loaded.
Setting drop ip to: x.y.z.l
Drop rate:  0.50.Total In In dropped  PC in dropped  Total Out  Out dropped  PC out dropped0         0           0.00             0          0           0.00
10120     57           0.56           10174       53           0.52
22224    134           0.60           22340      116           0.52
#

在此示例中,在启动pdrop_ccm之后不久,我们开始向目标主机发送IP通信。 pdrop_ccm实用程序将一直运行,直到被ctrl + c中断为止,并将每10秒打印一次更新行。

请注意,第一个命令行参数,即内核扩展名,必须完全与加载kctrl时指定的一样。

丢弃百分比参数是可选的。 如果未提供,则pdrop_ccm将仅显示当前的丢弃率,并且不会重新设置它。

还提供了基于Java的控制和监视实用程序,“ 控制和监视应用程序”部分对此进行了描述。

这就是内核扩展入门的全部。

本文的其余部分提供了有关内核扩展如何工作以及如何开发和定制供个人使用的控制和监视应用程序的更多详细信息。

内核扩展如何工作

AIX内核扩展是用C编程语言编写的。 内核函数通过一组系统调用公开对其的访问。 C和Java控制和监视应用程序利用这些系统调用来驱动内核扩展,以给定的速率丢弃数据包并往返于特定主机。 对于Java环境,JNI包装器类提供了从Java对内核扩展的系统调用的访问。

内核扩展本身包括:

  • 一组系统调用,用于控制数据包的丢弃和数据包统计信息的收集
  • 挂接到内核网络层的两个功能。 其中一个用于入站流量,另一个用于出站流量。 每当接收到数据包或将其分派以控制数据包的丢弃时,就会调用这些功能。

用户级别的代码访问系统调用,以设置应将传入和传出数据包丢弃到哪个远程系统以及应丢弃多少百分比的数据包的远程系统。 这些系统调用还包含检索定义在入站和出站方向上丢弃了多少个数据包的计数器的功能,以及复位计数器的功能。

对于C环境,这些系统调用直接在示例控制和监视应用程序pdrop_ccm.c中使用,我们在上面的“ 启动数据包丢弃和监视”部分中使用了它。 对于Java环境,可以使用JNI使用系统调用。 然后,定制的Java应用程序可以使用JNI包装器来控制和监视数据包的丢弃。 再次,本文提供了一个示例Java应用程序作为下载资源。 这称为pdrop_jcm.java。 有关示例Java实用程序的更多详细信息,请参见Java控制和监视部分。

图2说明了内核扩展的不同组件以及通过它的数据流。 以下两节讨论通过扩展的数据包流,要发送到目标节点的出站数据和从目标节点接收的入站数据。

出站流量

首先,考虑出站流量的情况,在这种情况下,被测应用程序提交要在网络上传输的数据。 请参考图2中的点A。该应用程序向内核提交一组数据,以发送到网络上的远程节点。 TCP子系统将其分解为许多数据包,然后通常将这些数据包发送到适当的网络设备驱动程序以在网络上进行分发。 但是,当使用内核扩展时,在IP层中设置了钩子outbound_fw,这将导致为每个分派的数据包调用内核扩展的出站过滤器函数pdrop_outbound_filter 。 这将从数据包中检索IP标头,并将其与要丢弃数据包的目标节点进行匹配。 如果节点不匹配,则调用函数ip_output_post_fw ,该函数将数据包路由到主机上的相应接口。 如果该节点确实匹配,则根据是否要丢弃的数据包数量对是否通过数据包进行随机决策。 如果此决定是应发送数据包,则调用ip_output_post_fw函数并传递数据包。 否则,将释放保存数据的mbuf,并且出站筛选器将返回,并且不会发送数据包。

入站流量

对于入站流量,当设备驱动程序从网络接收数据时,将应用相应的操作。 请参阅图2中的点B。设备驱动程序将数据包转发到TCP / IP子系统。 现在,这将调用入站过滤器,该过滤器inbound_fw内核扩展通过将入站钩子inbound_fw分配给pdrop_inbound_filter函数而设置的。 该功能决定是否通过数据包。 如果数据包不是来自要丢弃数据包的目标节点,则通过调用ipintr_noqueue_post_fw函数自动传递该数据包。 如果来自目标节点,则根据要丢弃的数据包的所需百分比再次做出是否通过数据包的随机决策。 如果决定发送数据包,则 ipintr_noqueue_post_fw函数并传递数据包。 否则,将释放保存数据的mbuf,并且入站过滤器将返回,并且数据包将不会传递到更高的层。

IBM AIX 7.1信息中心对上述AIX IP筛选挂钩和内核服务进行了说明。

图2.丢包内核扩展

入站过滤器

这是入站筛选器功能:

/*
** This function is the filter for incoming traffic
*/
void pdrop_inbound_filter(ifp, m, args)
struct ifnet *ifp;
struct mbuf *m;
inbound_fw_args_t *args;
{struct ip *ip_in;if (PDROP_TRUE == amDropping) {ip_in = mtod(m, struct ip *);if ( (ip_in->ip_p == IPPROTO_TCP) &&(dropip.s_addr == ip_in->ip_src.s_addr)){fetch_and_addlp((atomic_l) &total_in, 1);if (dropMod != 0){if ( (pdrop_random() % dropMod) == 1){fetch_and_addlp((atomic_l) &nin_dropped, 1);if (m != NULL){m_freem(m);}return;}}}
}
ipintr_noqueue_post_fw(ifp, m, args);
return;
}

过滤器函数的参数包括一个包含接收数据的mbuf。 mtod宏用于将指向mbuf的指针转换为指向接收到的数据的指针,该指针作为IP标头寻址。 维护了从目标地址接收的数据包总数的计数器。

然后,该功能将选择丢弃的IP地址与接收到的数据包中指定的源地址进行比较。 如果这些匹配,则调用pdrop_random()函数,该函数使用模函数选择所需的丢包百分比。 如果要丢弃数据包,则丢弃数据包的内部计数器会增加。 如果不丢弃,则调用ipint_noqueue_post_fw函数将数据包传递给TCP进行处理。

调用fetch_and_addlp系统函数fetch_and_addlp已接收和已丢弃数据包总数的计数。 这些确保计数保持原子状态,以便线程安全。

从此示例可以看到,可以指定要过滤的协议。 在这种情况下,我们仅丢弃TCP协议的数据包。 对于测试,最好使其使用其他协议(例如Internet控制消息协议(ICMP)),以便然后将数据包丢弃程序与诸如ping命令一起使用。 为此,将上述测试中的IPPROTO_TCP常量更改为IPPROTO_ICMP。

注意:以上摘录中的amDroppingdropipdropMod被定义为全局变量。

出站过滤器

这是出站筛选器功能:

/*
** This function is the filter for outbound network traffic
*/
int pdrop_outbound_filter(ifp, m, args)
struct ifnet *ifp;
struct mbuf *m;
outbound_fw_args_t *args;
{struct ip *ip_out;if (PDROP_TRUE==amDropping) {ip_out = mtod(m, struct ip *);if  ( (ip_out->ip_p == IPPROTO_TCP) &&(dropip.s_addr == ip_out->ip_dst.s_addr)){fetch_and_addlp((atomic_l) &total_out, 1);if (dropMod != 0){if ( (pdrop_random() % dropMod ) == 1){fetch_and_addlp((atomic_l) &nout_dropped, 1);if (m != NULL){m_freem(m);}return 0;}}}
}ip_output_post_fw(ifp, m, args);
return 0;
}

这与入站过滤器非常相似。 维护针对目标IP地址的数据包总数和丢弃的出站数据包总数的计数器。

如果要丢弃数据包,则释放指向mbuf的指针。

注意:以上摘录中的amDroppingdropipdropMod被定义为全局变量。

随机丢弃数据包

对于内核扩展来说,随机选择要丢弃的数据包非常重要。 如果说在发送了一定数量的数据包后数据包被丢弃,那么这不一定是对频繁使用的网络上发生的情况的真实仿真。 此外,当被测软件丢失规则和不规则间隔的数据包时,其行为可能会有所不同。

用于生成随机数的标准C库rand()调用不能在内核扩展中使用。 这是因为在可重入的内核环境中使用这些功能并不安全。 如果尝试使用此功能,则从内核扩展调用系统时可能会失败。

因此,使用了一个模拟随机调用的简单函数。 这将根据以下输入生成一个长随机数:

  • 当前时间的秒数字段
  • 当前时间的纳秒字段
  • 随机函数的调用次数
  • 自系统启动以来的处理器滴答数

这是内核扩展中使用的随机函数的来源。

long pdrop_random()
{static long calls = 0;struct timestruc_t ts;long x = 0;curtime(&ts);// lbolt is the number of clock ticks since boot, see HZ in /usr/include/sys/m_param.h for number of ticks/secfetch_and_addlp((atomic_l) &x,(long) ts.tv_nsec + (long) ts.tv_sec +(long) lbolt +calls++);return x;
}

当然,这不是真正的随机函数,而是足够好的机制,用于确保以足够不规则的方式丢弃数据包。 由于calls变量是静态的,因此它会通过fetch_and_addlp内核服务以原子方式递增。

数据包丢弃内核扩展中提供的系统调用

在本节中,将显示内核扩展中提供的各种系统调用的详细信息。 如果您需要编写自己的控件和监视应用程序或自定义内核扩展,这些将很有趣。

设置目标地址: int pdrop_set_drop_address(struct in_addr *block_addr)

此函数将指向in_addr struct的指针作为参数。 可以从应用程序级别从基于字符串的主机名中调用该方法,如下所示:

int setDropAddress(char *hostname)
{int status = 0;struct in_addr block_addr;if (1 == inet_aton(hostname, &block_addr)){if (PDROP_TRUE == pdrop_set_drop_address(&block_addr))status = 1;}return status;
}

检索目标地址: int pdrop_get_drop_address()

此函数以32位无符号整数形式返回目标地址。

设置丢包率: extern void pdrop_setDropMod(long m);

此函数采用一个很长的输入值,该值表示应该丢弃数据包的频率。 解决方法是内核扩展生成一个随机数,然后采用具有长值的该随机数的模数。 如果结果为1,则丢弃数据包,否则将其传递。

该调用是通过这种方式设计的,因为无法在内核扩展内执行浮点运算。

这是一种基于双倍百分比值从应用程序级别调用pdop_setDropMod()的简单方法:

void setDropPC(double d)
{long x = 0;x = 100.0 /d;pdrop_setDropMod(x);
}

因此,例如,如果需要丢弃0.1%的数据包,则d将为0.1,并且传递给pdrop_setDropMod的long值将为1000。

检索丢包率: extern long pdrop_getDropMod();

此函数返回应丢弃数据包的频率的长表示形式,其表示方式与对pdrop_setDropMod();的调用相同pdrop_setDropMod();

激活丢弃数据包: void pdrop_startDropping()

启动内核扩展后,直到调用pdrop_startDropping()函数,数据包才会被丢弃。 在设置目标地址和丢包率后,应调用此函数。

停止丢弃数据包: void pdrop_stopDropping()

此功能停止丢弃数据包。 可以根据需要调用函数pdrop_startDropping()pdrop_stopDropping()来启用和禁用数据包丢失。

查询数据包是否被丢弃: int pdrop_amDropping()

如果内核扩展当前正在丢弃数据包,则此函数返回1,否则返回0。

检索内核扩展计数器: void pdrop_getstats(struct pdrop_stats *p)

该函数返回一个包含以下详细信息的结构:

  • 从目标地址接收到的数据包总数
  • 从目标地址接收的丢弃的数据包总数
  • 发送到目标地址的数据包总数
  • 发送到目标地址的已丢弃的数据包总数。

所用结构的定义在头文件kernext_pdrop.h中。

这是一个如何从应用程序级别接收计数器的示例:

pdrop_stats_t j;
pdrop_getstats(&j);printf("Total in: %d.\n",  j.total_in);
printf("In dropped: %d.\n", j.nin_dropped;);
printf("Total out: %d.\n",  j.total_out);
printf("Out dropped: %d.\n", j.nout_dropped);

重置内部内核扩展计数器: void pdrop_reset_counters()

此函数用于将pdrop_getstats返回的计数器重置为零。

配置内核扩展

提供的“ 如何构建和使用内核扩展”部分提供了有关如何构建内核扩展及其实用程序的信息。 本节提供:

  • 有关构建过程的更多详细信息
  • 有关AIX 6.1和AIX 7.1构建问题的信息
  • 有关将内核扩展中提供的系统调用导出到应用程序级别的详细信息
  • 有关加载和激活内核扩展的详细信息
  • 有关使用系统日志记录扩展加载和卸载时间的信息

AIX 6.1和AIX 7.1构建问题

从AIX 6.1开始,AIX操作系统仅提供64位内核,从而简化了其内核环境。 如上所述,AIX 6.1和AIX 7.1与以前的AIX版本保持应用程序二进制兼容性,但是仅32位的设备驱动程序和内核扩展不能在AIX 6.1或AIX 7.1上构建。

正如本文所介绍的内核扩展适用于AIX 6.1和AIX 7.1一样,它是在64位模式下构建的。

建立过程

本文随附的压缩文件中包含一个Makefile。 这可用于构建内核扩展和与其相关的应用程序。 请注意,该Makefile已编写用于AIX make实用程序,如果您希望使用gnu make,则需要对其进行修改。

内核扩展本身是使用以下命令构建的:

gcc -maix64 -ffreestanding -msoft-float -o pdrop_kernex64.o -c pdrop_kernex.cld -b64 -o pdrop_kernex64 pdrop_kernex64.o -e pdrop_init -bI:/usr/lib/kernex.exp -bI:
/usr/lib/netinet.exp -bE:/home/jerry/kernext/pdrop_syscall.exp -lsys -lcsys

如前所述,内核扩展被构建为64位二进制文​​件。 -ffreestanding-msoft-float选项用于防止使用浮点指令来操纵某些数据结构。 这在AIX 7.1上是必需的,但在AIX 6.1上不是必需的。

ld命令指定内核扩展的入口点,在本例中为pdrop_init()函数。 激活内核扩展时将调用此函数。

ld命令还引用文件kernex.exp和netinet.exp。 这些文件与bos.adt.syscalls文件集一起提供。 该文件集可能未安装在测试系统上,在这种情况下,您将需要请系统管理员来安装它。

注意,有必要对/usr/include/sys/socketvar.h头文件进行一些小的修改,以使gcc令人满意地编译内核扩展。 您应该保留该文件的安全副本,并找到以下行:

extern struct free_sock_hash_bucket free_sock_hash_table[];

这应该更改为:

extern struct free_sock_hash_bucket * free_sock_hash_table;

内核扩展在源代码中进行了#define

#define _MSGQSUPPORT 1

这是防止fd_select()系统调用对内核扩展不可用所必需的。 使用#definefd_select()调用更改为原始的select()调用,该扩展可用于内核扩展。

导出提供的系统调用

pdrop_syscall.exp文件定义了导出到应用程序级别的内核扩展系统调用。 该文件的内容如下:

#!/unix
pdrop_set_drop_address syscall3264
pdrop_get_drop_address syscall3264
pdrop_setDropMod syscall3264
pdrop_getDropMod syscall3264
pdrop_startDropping syscall3264
pdrop_stopDropping syscall3264
pdrop_amDropping syscall3264
pdrop_getstats syscall3264
pdrop_reset_counters syscall3264

如果您需要自定义内核扩展以包括更多的系统调用,则需要修改此文件。 每行末尾的syscall3264标识符使系统调用可用于32位和64位进程。 该标志还可以被设置为syscall32到支持呼叫从仅32位进程或syscall64为只有64位的进程。 如果未为正确的目标进程环境设置该标志,则在进行系统调用时,该进程将失败并出现分段错误。 有关如何设置此标识符的更多详细信息,请参阅主题导出内核服务和系统调用 。

使用kctrl控制内核扩展的加载

如前所述,使用kctrl程序来加载和卸载内核扩展。 应该使用内核扩展的完整路径名来调用该程序。 然后,它以交互方式接受以下命令:

  • q –检查内核扩展是否已加载
  • l –加载内核扩展
  • I –初始化内核扩展
  • t –终止内核扩展
  • u –卸载内核扩展
  • e –退出实用程序

这是一个使用kctrl来查询,加载,初始化,终止,卸载和退出实用程序的示例:

# ./kctrl /home/jerry/kernext/pdrop_kernexEnter choice, (l)oad, (u)nload, (i)nit, (t)erm, (q)uery or (e)nd
qExtension is not loadedEnter choice, (l)oad, (u)nload, (i)nit, (t)erm, (q)uery or (e)nd
l
Extension Successfully loaded, kmid is 1353052160Enter choice, (l)oad, (u)nload, (i)nit, (t)erm, (q)uery or (e)nd
iExtension InitializedEnter choice, (l)oad, (u)nload, (i)nit, (t)erm, (q)uery or (e)nd
qExtension is loaded, with kmid   1353052160Enter choice, (l)oad, (u)nload, (i)nit, (t)erm, (q)uery or (e)nd
e
#

您还可以使用AIX genkex命令检查是否已加载内核扩展,例如:

# genkex  | grep -i kern
f1000000c02be000     2000 /home/jerry/kernext/kernext_hello
#

在此示例中, kctrl可执行文件与交互式用户输入一起使用。 修改kctrl以将该命令作为命令行上的另一个参数很容易,从而可以轻松地将其合并到系统启动和关闭脚本中。 但是,鉴于实用程序的性质,通常不建议这样做。

登录内核扩展

内核扩展使用syslogd守护程序来记录扩展的加载和卸载时间。 这对于调试或审核目的很有用。 要启用此日志记录:

  • 确保在/etc/syslog.conf中启用了日志记录。 例如,以下行可以附加到此文件:
*.debug              /var/log/syslog.out     rotate size 100k files 4
  • 确保在/etc/syslog.conf中启用的日志文件存在。
  • 刷新syslogd子系统( refresh -s syslogd

与其他IP协议一起使用

尽管该扩展名主要用于TCP / IP,但对其进行更改以使其与其他基于IP的网络协议兼容将很容易。 内核扩展的工作原理部分对此进行了讨论。

控制和监视应用程序

提供了两个可以使用内核扩展公开的系统调用的示例应用程序。 一种用于C环境,另一种用于Java环境。

这些应用程序向您展示了如何编写自己的自定义应用程序以控制数据包丢弃。 如果需要编写自己的自动化测试框架来模拟不同的网络条件,则可以决定执行此操作。

应当注意,只有直接从内核扩展收集统计信息的应用程序才能提供有关已丢弃数据包的有意义的统计信息。 操作系统提供的用于报告丢弃的数据包的实用程序将不包括通过内核扩展丢弃的数据包的详细信息。 这是因为数据包在通过TCP / IP子系统进行分发或传递之前被扩展名丢弃。

C控制与监控

本文的下载部分提供了测试应用程序pdrop_ccm.c。 在命令行上使用目标主机名和删除百分比来调用它。 该应用程序将目标主机的详细信息和丢包率传递给内核扩展,然后每10秒监视到目标系统的入站和出站数据包。

数据包丢弃系统调用可以从32位和64位应用程序中调用。 所提供的makefile通过构建32位和64位版本的控制和监视应用程序来证明这一点。 这些分别称为pdrop_ccm32和pdrop_ccm64。

pdrop_ccm显示输入和输出数据包的总数,已丢弃的输入和输出数据包的数量,以及丢弃的数据包的百分比。 它以内核扩展的名称,目标主机的名称作为参数以及指定目标删除率的可选值。 如果未在命令行上指定此第三个参数,则不会更改删除率。 这是正在使用的应用程序的示例:

# ./pdrop_ccm /home/jerry/kernext/pdrop_kernex64 fred 1.0Extension is loaded, with kmid   1353052160
Official name is: fredIP addresses: 9.20.XXX.YYY
Target IP address: 9.20.XXX.YYY.Total In   In dropped       PC in dropped   Total Out    Out dropped     PC out dropped
0               0                0.00           0               0                0.00
0               0                0.00           0               0                0.00
13138           138              1.05           13283           144              1.08
29158           275              0.94           29460           302              1.03
43738           423              0.97           44206           467              1.06
58320           564              0.97           58952           632              1.07
72653           721              0.99           73437           784              1.07
87227           872              1.00           88153           926              1.05
#

在这里,我们可以看到要丢弃数据包的主机是fred,并且要丢弃数据包的1.0%。 然后以10秒为间隔显示总数据包和丢弃数据包的状态更新。

测试应用程序调用pdrop_reset_counters()方法来重置内核扩展计数器。 10秒后,您可以看到目标系统的网络活动已启动,并且显示了数据包统计信息。

请注意,该示例仅控制单个目标系统。 If you run the pdrop_ccm command again and specify a different target host name, packets to and from the original host will no longer be dropped.

Java control and monitor

A sample Java application, PDrop_jcm.java , is also provided, which demonstrates how to use the packet drop simulator from the Java environment.

PDrop_jcm.java uses JNI to access the C environment for controlling and monitoring the kernel extension. The shared library libpdrop_jni.so provides native methods which can be called from the Java environment. This shared library is built as part of the build process described earlier from the source, pdrop_jni.c .

The JNI wrapper provides the following native methods at the Java level which map to the functions in the shared library:

public native boolean isExtensionLoaded(String extName);public native boolean setDropAddress(String hostname);private native String getDropAddress();public native boolean amDropping();public native int setDropping(boolean doDrop);public native void resetCounters();public native void setDropHostName();public native void setDropPC(float d);public native float getDropPC();public native long getTotalIn();public native long getTotalOut();public native long getInDropped();public native long getOutDropped();

When these native methods are invoked, the corresponding function in the shared library will be called and the result will be returned to the Java environment.

To build and use this test Java application, first, make sure that you have set the PATH to the Java SDK environment correctly, for example:

export PATH=/usr/java6/bin:${PATH}

Next, set the LIBPATH environment variable to reference the directory where the kernel extension is located, so the shared library libpdrop_jni.so can be resolved:

export LIBPATH=/home/jerry/kernext:/usr/lib

Now compile the PDrop_jcm.java application, for example:

javac -d . PDrop_jcm.java

Optionally, if you need to regenerate the JNI header file, run the following command. It mightnot be necessary to run unless you have customized the kernel extension and changed or added to the native methods:

javah -d . PDrop_jcm

If you have regenerated the header, you will need to rebuild the shared library using the process described earlier.

The Java application is then run with the path to the kernel extension, target host name, and optional new drop rate as arguments, as in the C example above:

# java PDrop_jcm /home/jerry/kernext/pdrop_kernex64 fred 1.0
Ext name: /home/jerry/kernext/pdrop_kernex64.Extension is loaded, with kmid   1353052160
Drop address is: 9.20.XXX.YYY
Drop PC: 1.0
Dropping enabled
Total In   In dropped      PC in dropped    Total Out       Out dropped     PC out dropped
0               0                0.0            0               0                0.0
0               0                0.0            0               0                0.0
13189           145              1.09           13307           118              0.88
28515           295              1.03           28782           267              0.92
44306           461              1.04           44701           395              0.88
59216           609              1.02           59753           537              0.89
72979           756              1.03           73688           709              0.96
88606           910              1.02           89455           849              0.94
102550          1054             1.02           103567          1017             0.98
104522          1071             1.02           105551          1029             0.97
104522          1071             1.02           105551          1029             0.97

In this example, you can see that when monitoring started there were zero packets sent or received to or from the target host, but there was then network activity that caused packets to be dropped in both directions. In this example, the drop rate had been configured at 1%.

Measuring non-simulated packet loss

It was mentioned earlier that operating system utilities should not be used to monitor packets dropped through the use of the kernel extension. However, these will be required when you need to access packets that are actually dropped across the network. This section gives some useful hints and tips for using these utilities.

The ping utility displays the packet loss on the ICMP packets being sent across the network. You can see the packet loss statistics in the above example, where it is zero. However, this measurement is only based on these packets being transferred from and to the ping utility and do not measure any other packets traversing the network.

On some systems, ping also supports an option to write ICMP packets as fast as possible onto the network and again gives you the loss statistics at the end. This is a so called flood ping. You should use this with caution as it is likely to impact general network performance while running. It should be run only for a few seconds and only under test conditions.

The netstat utility can also be used to see how many packets have been dropped on a network. Here is an example output from netstat -D on AIX.

Using netstat to report packet drops (AIX):

# netstat -DSource                         Ipkts                Opkts     Idrops     Odrops
-------------------------------------------------------------------------------
ent_dev0                    26820670             16079610          0          0---------------------------------------------------------------
Devices Total               26820670             16079610          0          0
-------------------------------------------------------------------------------
ent_dd0                     26820670             16079610          0          0---------------------------------------------------------------
Drivers Total               26820670             16079610          0          0
-------------------------------------------------------------------------------
ent_dmx0                    26820664                  N/A          6        N/A---------------------------------------------------------------
Demuxer Total               26820664                  N/A          6        N/A
-------------------------------------------------------------------------------
IP                          50335154             44013816    1110616     147099
IPv6                            1473                 1473          0          0
TCP                         43110957             40986657       6235          0
UDP                          6105902              2045877    5022268          0---------------------------------------------------------------
Protocols Total             99552013             87046350    6139119     147099
-------------------------------------------------------------------------------
en_if0                      26820664             16079528          0          0
lo_if0                      27970975             27975366       4652          0---------------------------------------------------------------
Net IF Total                54791639             44054894       4652          0
-------------------------------------------------------------------------------
NFS/RPC Client                    23                  N/A          0        N/A
NFS/RPC Server                     0                  N/A          0        N/A
NFS Client                     14949                  N/A          8        N/A
NFS Server                         0                  N/A          0        N/A---------------------------------------------------------------
NFS/RPC Total                    N/A                14977          8          0
-------------------------------------------------------------------------------
(Note:  N/A -> Not Applicable)
#

On AIX, the netstat -Zs -p tcp command can be used to reset the protocol statistics before running the promotion activity.

If packet drops are consistently in excess of 0.1%, then you should raise this with your network administrator.

Retransmitted packets can be seen using the following command:

$ netstat -s -p tcp | grep retrans

Statistics of interest from the output of this command are:

  • Packets sent
  • Data packets
  • Data packets retransmitted
  • Packets received
  • Completely duplicate packets
  • Retransmit timeouts

结论

This article provided reference material and instructions to build, use, and customize a simple utility to simulate dropped TCP packets on AIX. Such a utility is invaluable when writing cross network software to model how it will behave under non-ideal network conditions.

The tool may be adapted as required and can easily be enhanced to support simulation of other network issues that can give rise to performance problems, such as packet corruption, packets arriving out of order, and jitter.

致谢

The author would like to thank the following people for helping to review this article:

  • Kavitha Baratakke, IBM Systems and Technology Group, Systems Solution Development, IBM USA.
  • Joshua Carr, WebSphere Service Registry and Performance, IBM UK.
  • Sukesh Chulliyote, Sr Quality Assurance Engineer, Oracle Corporation
  • Nigel Griffiths, IBM Sales and Distribution, Systems and Technology Group Sales, IBM UK.
  • Paul Harris, WebSphere MQ Performance, IBM UK.

翻译自: https://www.ibm.com/developerworks/aix/library/au-aix-packet-dropping/index.html

ibm aix 抓包命令_在IBM AIX上模拟丢弃的TCP / IP数据包相关推荐

  1. TCP/IP数据包结构具体解释

    [关键词] TCP IP 数据包 结构 具体解释 网络 协议 一般来说,网络编程我们仅仅须要调用一些封装好的函数或者组件就能完毕大部分的工作,可是一些特殊的情况下,就须要深入的理解 网络数据包的结构, ...

  2. 网络技术入门 :HTTP报文和TCP/IP数据包

    本章把HTTP报文和TCP/IP数据包放在一起.是因为: 报文是一个完成的有意义的数据. 数据包可以理解为组成报文的传输单元. 应用程序的数据一般都比较大,因此TCP会按照网络包的大小对数据进行拆分. ...

  3. JAVA网络编程:TCP/IP数据包结构

    2019独角兽企业重金招聘Python工程师标准>>> 一般来说,网络编程我们仅仅须要调用一些封装好的函数或者组件就能完毕大部分的工作,可是一些特殊的情况下,就须要深入的理解网络数据 ...

  4. TCP,IP数据包结构

    TCP/IP协议中各层的数据报结构是一个比较抽象的内容,大家在日常学习过程中往往难以理解和掌握,常常是死记硬背把它记住了事.本文首先利用Sniffer工具捕获了FTP命令操作过程中的所有数据包,然后对 ...

  5. TCP/IP数据包结构分解

    一般来说,网络编程我们只需要调用一些封装好的函数或者组件就能完成大部分的工作,但是一些特殊的情况下,就需要深入的理解 网络数据包的结构,以及协议分析.如:网络监控,故障排查等-- IP包是不安全的,但 ...

  6. TCP/IP数据包结构分析

    一般来说,网络编程我们只需要调用一些封装好的函数或者组件就能完成大部分的工作,但是一些特殊的情况下,就需要深入的理解 网络数据包的结构,以及协议分析.如:网络监控,故障排查等-- IP包是不安全的,但 ...

  7. TCP/IP数据包结构详解

    一般来说,网络编程我们只需要调用一些封装好的函数或者组件就能完成大部分的工作,但是一些特殊的情况下,就需要深入的理解 网络数据包的结构,以及协议分析.如:网络监控,故障排查等-- IP包是不安全的,但 ...

  8. 【计算机网络 24】TCP/IP数据包结构详解

    一.前言 一般来说,网络编程我们只需要调用一些封装好的函数或者组件就能完成大部分的工作,但是一些特殊的情况下,就需要深入的理解 网络数据包的结构,以及协议分析.如:网络监控,故障排查等. IP包是不安 ...

  9. Linux 系统应用编程——网络编程(TCP/IP 数据包格式解析)

    图中括号中的数字代表的是当前域所占的空间大小,单位是bit位. 黄色的是数据链路层的头部,一共14字节 绿色的部分是IP头部,一般是20字节 紫色部分是TCP头部,一般是20字节 最内部的是数据包内容 ...

最新文章

  1. CPU 有个禁区,内核权限也无法进入!
  2. python面向对象三大特性之继承
  3. datagridview绑定xml
  4. WSGI、uwsgi和uWSGI
  5. python代码覆盖率测试_利用coverage工具进行Python代码覆盖率测试
  6. /etc/profile、/etc/bashrc、~/.bash_profile、~/.bashrc(转载)
  7. NAS服务器局域网内IPad、手机、电视盒子等联网播放
  8. 前端学习(2307):react之props和state
  9. docker 安全性_使用最新的安全性增强来调整Docker
  10. Flex与ASP.NET通过Remoting方式交互说明文档
  11. Python一些很实用的知识
  12. 【算法学习】将MSRCR中的模糊处理由FFT修改为时域纯高斯模糊
  13. 蠕虫Sexy View短信攻击诺基亚3250等手机
  14. Win10 64bit安装VC6+VC6助手
  15. DBSCAN聚类算法原理总结
  16. hdu 5455 Fang Fang 坑题
  17. IOS越狱--修复Cydia闪退(或打不开)的办法
  18. 详解Java中Comparable和Comparator接口的区别
  19. ROS 应用开发入门 发布者Publisher的编程
  20. 《第五项修炼,学习型组织的艺术与实践》读书笔记

热门文章

  1. qt 判断ctrl键被按下_直播 | 当世界被按下暂停键,幸有阅读可慰藉
  2. 计算机末端网络,计算机线缆末端的圆球是什么?
  3. 给寸照换底色(抠头发)
  4. Windows 10 各版本
  5. df命令和du命令-个人
  6. C# 判断两张图片是否一致,极快速。
  7. 如何用技术手段“干掉”优酷、腾讯视频 App 里讨厌的广告?
  8. gSOAP 源码分析(二)
  9. 自定义View——幸运转盘
  10. 熬夜读书最好吃什么东西补充能量类``