linux内核中UDP包的路径

Pha*_*ani 4 networking udp linux-kernel

我想在Linux内核中找到UDP数据包的路径.对于这一点,我想在一些文档(我读了这个迄今为止,这是TCP),然后在相应的内核函数的一些printk的声明,以确认.我将通过重新编译内核代码来完成此操作.

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

Pet*_*eoh 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    |                                      }
Run Code Online (Sandbox Code Playgroud)

跟踪的另一部分显示如下:

 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    |                                    }
Run Code Online (Sandbox Code Playgroud)

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

 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   |    }
Run Code Online (Sandbox Code Playgroud)

以上在ftrace中称为函数图:

如何使一个Linux内核函数可用于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$$
Run Code Online (Sandbox Code Playgroud)

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


TOC*_*TOC 4

Linux 网络堆栈是内核的一大块,你需要花一些时间研究它。我认为这本书可能会有所帮助(重点关注较旧的内核 2.4 和 2.6,但最新内核 3.x 的逻辑保持不变):

了解 Linux 网络内部结构

Linux 网络架构 - Linux 内核中网络协议的设计与实现

您还可以查看此链接:

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_deliver= ip_local_deliver_finish> 该函数负责选择良好的传输层)