linux内核中UDP包的路径

时间:2013-01-18 20:54:39

标签: networking linux-kernel udp

我想在Linux内核中找到UDP数据包的路径。为此,我想阅读一些文档(到目前为止我有this,这是针对TCP的),然后在相关的内核函数中有一些printk语句来确认。我将通过重新编译内核代码来完成此操作。

这是怎么回事?你有什么建议/参考吗?

4 个答案:

答案 0 :(得分:5)

具体回答您的问题,要了解IPv4的UDP处理,您可以使用ftrace,如下所示:

在入口处(接收方):

 96882  2)               |                                ip_local_deliver_finish() {
 96883  2)   0.069 us    |                                  raw_local_deliver();
 96884  2)               |                                  udp_rcv() {
 96885  2)               |                                    __udp4_lib_rcv() {
 96886  2)   0.087 us    |                                      __udp4_lib_lookup();
 96887  2)               |                                      __skb_checksum_complete_head() {
 96888  2)               |                                        skb_checksum() {
 96889  2)               |                                          __skb_checksum() {
 96890  2)               |                                            csum_partial() {
 96891  2)   0.161 us    |                                              do_csum();
 96892  2)   0.536 us    |                                            }
 96893  2)               |                                            csum_partial() {
 96894  2)   0.167 us    |                                              do_csum();
 96895  2)   0.523 us    |                                            }
 96896  2)               |                                            csum_partial() {
 96897  2)   0.158 us    |                                              do_csum();
 96898  2)   0.513 us    |                                            }
 96899  2)               |                                            csum_partial() {
 96900  2)   0.154 us    |                                              do_csum();
 96901  2)   0.502 us    |                                            }
 96902  2)               |                                            csum_partial() {
 96903  2)   0.165 us    |                                              do_csum();
 96904  2)   0.516 us    |                                            }
 96905  2)               |                                            csum_partial() {
 96906  2)   0.138 us    |                                              do_csum();
 96907  2)   0.506 us    |                                            }
 96908  2)   5.462 us    |                                          }
 96909  2)   5.840 us    |                                        }
 96910  2)   6.204 us    |                                      }

下面的跟踪节目的另一部分:

 98212  2)               |                              ip_rcv() {
 98213  2)               |                                ip_rcv_finish() {
 98214  2)   0.109 us    |                                  udp_v4_early_demux();
 98215  2)               |                                  ip_route_input_noref() {
 98216  2)               |                                    fib_table_lookup() {
 98217  2)   0.079 us    |                                      check_leaf.isra.8();
 98218  2)   0.492 us    |                                    }

对于网络代码的出口,下面提取了一些片段:

 4)   0.547 us    |  udp_poll();
 4)               |  udp_sendmsg() {
 4)               |    udp_send_skb() {
 4)   0.387 us    |      udp_error [nf_conntrack]();
 4)   0.185 us    |      udp_pkt_to_tuple [nf_conntrack]();
 4)   0.160 us    |      udp_invert_tuple [nf_conntrack]();
 4)   0.151 us    |      udp_get_timeouts [nf_conntrack]();
 4)   0.145 us    |      udp_new [nf_conntrack]();
 4)   0.160 us    |      udp_get_timeouts [nf_conntrack]();
 4)   0.261 us    |      udp_packet [nf_conntrack]();
 4)   0.181 us    |      udp_invert_tuple [nf_conntrack]();
 4)   0.195 us    |      udp_invert_tuple [nf_conntrack]();
 4)   0.170 us    |      udp_invert_tuple [nf_conntrack]();
 4)   0.175 us    |      udp_invert_tuple [nf_conntrack]();
 4)               |      udp_rcv() {
 4) + 15.021 us   |        udp_queue_rcv_skb();
 4) + 18.829 us   |      }
 4) + 82.100 us   |    }
 4) + 92.415 us   |  }
 4)               |  udp_sendmsg() {
 4)               |    udp_send_skb() {
 4)   0.226 us    |      udp_error [nf_conntrack]();
 4)   0.150 us    |      udp_pkt_to_tuple [nf_conntrack]();
 4)   0.146 us    |      udp_get_timeouts [nf_conntrack]();
 4)   1.098 us    |      udp_packet [nf_conntrack]();
 4)               |      udp_rcv() {
 4)   1.314 us    |        udp_queue_rcv_skb();
 4)   3.282 us    |      }
 4) + 20.646 us   |    }

以上在ftrace中称为函数图:

How to make a linux kernel function available to ftrace function_graph tracer?

我跟踪udp的bashscript如下(以root身份运行):

#!/bin/bash

mkdir /debug
mount -t debugfs nodev /debug
mount -t debugfs nodev /sys/kernel/debug
echo udp_* >/debug/tracing/set_ftrace_filter
echo function_graph >/debug/tracing/current_tracer
echo 1 >/debug/tracing/tracing_on
sleep 20
echo 0 >/debug/tracing/tracing_on
cat /debug/tracing/trace > /tmp/tracing.out$$

现在输出文件位于/tmp/tracing.out内,其中是shell脚本进程。 20秒的目的是允许用户空间活动发生 - 此时只需启动大量UDP活动。您还可以从上面的脚本中删除“ echo udp_ *> / debug / tracing / set_ftrace_filter ”,因为默认情况下是跟踪所有内容。

答案 1 :(得分:4)

linux网络堆栈是内核的一大部分,您需要花一些时间来研究它。 我认为这本书可能有所帮助(专注于旧内核2.4和2.6,但最新内核3.x的逻辑保持不变):

Understanding Linux Network Internals

The Linux Networking Architecture - Design and Implementation of Network Protocols in the Linux Kernel

您还可以查看以下链接:

http://e-university.wisdomjobs.com/linux/chapter-189-277/sending-the-data-from-the-socket-through-udp-and-tcp.html

http://www.linuxfoundation.org/collaborate/workgroups/networking/kernel_flow

http://wiki.openwrt.org/doc/networking/praxis

http://www.ibm.com/developerworks/linux/library/l-linux-networking-stack/?ca=dgr-lnxw01lnxNetStack

http://gicl.cs.drexel.edu/people/sevy/network/Linux_network_stack_walkthrough.html

您还需要浏览内核源代码:

http://lxr.linux.no/#linux+v3.7.3/

使用此功能开始您的网络子系统: 收到数据包时调用的ip_rcv。 然后调用其他函数(ip_rcv_finiship_local_deliverip_local_deliver_finish =>此函数负责选择良好的传输层)

答案 2 :(得分:1)

如果您更喜欢更直观的方式,请尝试flame-grahps。以下是UDP传输流的示例(使用netperf传输UDP数据包): enter image description here

这是在udp_send_skb上放大的相同图表: enter image description here

您可以对内核中的任何相关流程执行相同操作。您还可以搜索特定功能或关键词并放大/缩小。这也让您了解流程中较重的功能。

希望这有帮助。

答案 3 :(得分:0)

这个链接也不错。它讨论了 udp 和底层 IP、NIC 等:

https://blog.packagecloud.io/eng/2017/02/06/monitoring-tuning-linux-networking-stack-sending-data/