【问题标题】:Track a packet as it goes through the kernel (linux)跟踪通过内核的数据包 (linux)
【发布时间】:2011-12-21 09:48:55
【问题描述】:

我有两台机器设置为使用 Ip-Security,机器 A(我们称它们为 A 和 B)有一个套接字,该套接字绑定到本地机器上的特定 UDP 端口,它经常轮询它以查看是否任何东西都可以在上面收到。

当我禁用 Ip-security 时,两台机器之间的数据可以正常传输,并且我可以正常发送和接收数据包。但是当启用 Ip-Security 时,数据包不会到达机器 B 发送的机器 A 上的那个套接字。

我在两台机器上都执行了tcpdump,我可以看到(加密的)数据包从机器 B 发出并在机器 A 上接收。但在那之后,数据包进入内核和某个地方数据包解密或在其他某个阶段,数据包被丢弃。

我希望能够在数据包通过内核时对其进行跟踪,并查看它被丢弃的位置。是否有一些/proc 可以用于此目的?我能想到的另一种方法是在整个内核中插入调试语句并重新编译它,然后尝试再次发送数据包并进行调试。

感谢和抱歉这么长的信息,但这是必要的。

【问题讨论】:

    标签: c sockets networking linux-kernel packet


    【解决方案1】:

    请参考名为SystemTap的项目。它允许您将用户友好的脚本插入到任何内核代码中,而无需重新编译内核。例如:

    probe function("ip_rcv").call {
        printf("%d:   ->ip_rcv()\n", gettimeofday_ms()) 
    }
    

    它将为网络层中每个接收到的数据包发出内核打印。当然,您需要阅读源代码才能从那里更深入地了解网络堆栈。

    SystemTap 功能非常强大,并且记录了可以插入的各种挂钩。

    【讨论】:

    • 哦,我今天才看到这个。我插入了100条调试语句,重新编译内核,发现问题。但这对于未来的需求来说很棒。非常感谢。
    【解决方案2】:

    是的,正如 Dan 所说,SystemTap 很有用。但我最喜欢的是 ftrace。

    供参考:

    Path of UDP packet in linux kernel

    因此,为了跟踪一般的网络流量,请将以下内容放入 bash shell 并以 root 身份运行:

    mkdir /debug
    mount -t debugfs nodev /debug
    mount -t debugfs nodev /sys/kernel/debug
    echo '*' >/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$$
    

    等等接收入口路径:

     5)               |              tcp_recvmsg() {
     5)               |                lock_sock_nested() {
     5)   0.042 us    |                  _cond_resched();
     5)               |                  _raw_spin_lock_bh() {
     5)   0.040 us    |                    local_bh_disable();
     5)   0.414 us    |                  }
     5)   0.040 us    |                  _raw_spin_unlock();
     5)   0.040 us    |                  local_bh_enable();
     5)   1.814 us    |                }
     5)               |                skb_copy_datagram_iovec() {
     5)   0.042 us    |                  _cond_resched();
     5)   0.588 us    |                }
     5)   0.042 us    |                tcp_rcv_space_adjust();
     5)               |                __kfree_skb() {
     5)               |                  skb_release_all() {
     5)               |                    skb_release_head_state() {
     5)   0.044 us    |                      sock_rfree();
     5)   0.670 us    |                    }
     5)               |                    skb_release_data() {
     5)               |                      put_page() {
     5)   0.049 us    |                        put_compound_page();
     5)   0.449 us    |                      }
    

    还有这个:

    Netlink 处理:

     6)               |          rtnetlink_rcv() {
     6)               |            mutex_lock() {
     6)   0.090 us    |              _cond_resched();
     6)   1.455 us    |            }
     6)               |            netlink_rcv_skb() {
     6)               |              rtnetlink_rcv_msg() {
     6)   0.150 us    |                mutex_unlock();
     6)               |                __netlink_dump_start() {
     6)               |                  netlink_lookup() {
     6)   0.091 us    |                    _raw_read_lock();
     6)   0.100 us    |                    netlink_compare();
     6)   1.791 us    |                  }
     6)               |                  mutex_lock() {
     6)   0.095 us    |                    _cond_resched();
     6)   0.913 us    |                  }
     6)   0.100 us    |                  try_module_get();
     6)   0.090 us    |                  mutex_unlock();
    

    这也是入口:

     3)               |                                                tcp_v4_rcv() {
     3)               |                                                  sk_filter() {
     3)               |                                                    security_sock_rcv_skb() {
     3)   0.076 us    |                                                      cap_socket_sock_rcv_skb();
     3)   0.867 us    |                                                    }
     3)   1.630 us    |                                                  }
     3)   0.076 us    |                                                  _raw_spin_lock();
     3)   0.477 us    |                                                  tcp_prequeue();
     3)               |                                                  tcp_v4_do_rcv() {
     3)   0.088 us    |                                                    tcp_md5_do_lookup();
     3)   0.109 us    |                                                    tcp_parse_md5sig_option();
     3)   0.072 us    |                                                    ipv4_dst_check();
     3)               |                                                    tcp_rcv_established() {
     3)   0.076 us    |                                                      tcp_parse_aligned_timestamp.part.34();
     3)               |                                                      tcp_queue_rcv() {
     3)               |                                                        tcp_try_coalesce.part.41() {
     3)   0.835 us    |                                                          skb_try_coalesce();
     3)   1.722 us    |                                                        }
     3)   2.637 us    |                                                      }
    

    这是出口(从系统调用“sendmsg()”开始):

     5)               |  SyS_sendmsg() {
     5)               |    __sys_sendmsg() {
     5)               |      sockfd_lookup_light() {
     5)   0.080 us    |        fget_light();
     5)   0.502 us    |      }
     5)               |      ___sys_sendmsg() {
     5)   0.117 us    |        copy_msghdr_from_user();
     5)   0.101 us    |        verify_iovec();
     5)               |        sock_sendmsg() {
     5)               |          security_socket_sendmsg() {
     5)               |            apparmor_socket_sendmsg() {
     5)   0.092 us    |              aa_revalidate_sk();
     5)   0.580 us    |            }
     5)   1.044 us    |          }
     5)               |          unix_stream_sendmsg() {
     5)   0.113 us    |            wait_for_unix_gc();
     5)               |            security_socket_getpeersec_dgram() {
     5)   0.044 us    |              apparmor_socket_getpeersec_dgram();
     5)   0.479 us    |            }
     5)               |            sock_alloc_send_pskb() {
     5)               |              __alloc_skb() {
     5)               |                kmem_cache_alloc_node() {
     5)   0.042 us    |                  _cond_resched();
     5)   0.648 us    |                }
     5)               |                __kmalloc_reserve.isra.27() {
     5)               |                  __kmalloc_node_track_caller() {
     5)   0.074 us    |                    kmalloc_slab();
     5)   0.040 us    |                    _cond_resched();
     5)   0.504 us    |                    __slab_alloc();
     5)   1.878 us    |                  }
     5)   2.276 us    |                }
     5)   0.175 us    |                ksize();
     5)   4.217 us    |              }
    

    希望你喜欢......

    【讨论】:

    • 您是否有任何理由使用 function_graph 跟踪器而不仅仅是 function 跟踪器?
    • 两者是不同的输出:见lwn.net/Articles/365835,它显示了两种不同的类型。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-06-20
    • 2016-01-10
    • 2014-03-20
    • 1970-01-01
    • 2011-06-11
    • 2016-11-24
    • 2020-12-31
    相关资源
    最近更新 更多