Linux 网络堆栈:使用 LKM 和 dev_add_pack 添加协议

发布于 2024-09-01 07:47:50 字数 931 浏览 5 评论 0原文

我最近一直在尝试熟悉 Linux 网络堆栈和设备驱动程序(都有类似名称的 O'Reilly 书籍),最终目标是卸载 UDP。我已经在 NIC 上实现了 UDP,但现在困难的部分...

而不是在这个更大的目标上寻求帮助,我希望有人能为我澄清一个特定的片段,我发现它是注册新协议的 LKM 的一部分( OTP)充当设备驱动程序和网络堆栈之间的过滤器。

http://www. phrack.org/archives/55/p55_0x0c_Building%20Into%20The%20Linux%20Network%20Layer_by_lifeline%20&%20kossak.txt

(注意:这篇 Phrack 文章包含三个不同的模块,OTP 的代码位于页面)

在他的示例的 init 函数中,他有:(

    otp_proto.type = htons(ETH_P_ALL); 
    otp_proto.func = otp_func;
    dev_add_pack(&otp_proto);

如果我理解正确的话)应该将 otp_proto 注册为数据包嗅探器并将其放入 ptype_all 数据结构中。我的问题是关于 dev_add_pack 的。

注册为过滤器的协议是否总是放置在 L2 和设备驱动程序之间的这一层?或者,例如,我可以使用相同的进程在应用程序层和传输层之间进行此类过滤(分析套接字参数)吗?

如果这令人困惑,我深表歉意 - 当涉及到改变内核堆栈功能的模块时,我在理解更大的图景时遇到了一些麻烦。

谢谢

I have recently been trying to familiarize myself with the Linux Networking stack and device drivers (have both similarly named O'Reilly books) with the eventual goal of offloading UDP. I have already implemented UDP on the NIC but now the hard part...

Rather than ask for assistance on this larger goal I was hoping someone could clarify for me a particular snippet I found that is part of a LKM which registeres a new protocol (OTP) that acts as a filter between the device driver and network stack.

http://www.phrack.org/archives/55/p55_0x0c_Building%20Into%20The%20Linux%20Network%20Layer_by_lifeline%20&%20kossak.txt

(Note: this Phrack article contains three different modules, code for the OTP is at the bottom of the page)

In the init function of his example he has:

    otp_proto.type = htons(ETH_P_ALL); 
    otp_proto.func = otp_func;
    dev_add_pack(&otp_proto);

which (if I understand correctly) should register otp_proto as a packet sniffer and put it into the ptype_all data structure. My question is about the dev_add_pack.

Is it the case that the protocol being registered as a filter will always be placed at this layer between L2 and the device driver? Or, for instance could I make such a filtering occur between the application and transport layers (analyze socket parameters) using the same process?

I apologize if this is confusing - I am having some trouble wrapping my head around the bigger picture when it comes to modules altering kernel stack functionality.

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

埖埖迣鎅 2024-09-08 07:47:51

当您使用 dev_add_pack 注册协议处理程序时,当数据包到达时将调用处理程序回调函数。这就是 IP 协议处理程序的工作原理。来自inet_init:

static int __init inet_init(void)
{
    ...
    rc = proto_register(&tcp_prot, 1);
    ...
    rc = proto_register(&udp_prot, 1);
    ...
    dev_add_pack(&ip_packet_type);
    ....

当NIC为到达的数据包引发中断时,NIC中断处理程序将运行,最终将调用netif_rx(或__napi_schedule),这将引发softirq net_rx_action。这最终将为每个注册的协议处理程序调用 Deliver_skb 。来自 __netif_receive_skb_core

static int __netif_receive_skb_core(struct sk_buff *skb, bool pfmemalloc)
{
    ...
    list_for_each_entry_rcu(ptype, &ptype_all, list) {
        if (pt_prev)
            ret = deliver_skb(skb, pt_prev, orig_dev);
        pt_prev = ptype;
    }

所以是的,您的协议处理程序回调函数将与 IP 协议处理程序的 ip_rcv 一起在 L2 上调用。

如果您想在该层调用,您可以使用“proto_register”在 L3 注册协议处理程序。

When you register a protocol handler with dev_add_pack, the handler callback function will be called when a packet arrives. This is how the IP protocol handler works. From inet_init:

static int __init inet_init(void)
{
    ...
    rc = proto_register(&tcp_prot, 1);
    ...
    rc = proto_register(&udp_prot, 1);
    ...
    dev_add_pack(&ip_packet_type);
    ....

When an interrupt is raised by the NIC for a packet that arrives, the NIC interrupt handler will run, which will end up calling netif_rx (or __napi_schedule), which will raise softirq net_rx_action. This will end up calling deliver_skb for each protocol handler registered. From __netif_receive_skb_core

static int __netif_receive_skb_core(struct sk_buff *skb, bool pfmemalloc)
{
    ...
    list_for_each_entry_rcu(ptype, &ptype_all, list) {
        if (pt_prev)
            ret = deliver_skb(skb, pt_prev, orig_dev);
        pt_prev = ptype;
    }

So yes, your protocol handler callback function will be called on L2, together with ip_rcv for the IP protocol handler.

You can register a protocol handler at L3 with 'proto_register', if you want to be called at that layer.

烟凡古楼 2024-09-08 07:47:51

注册为过滤器的协议是否会出现这种情况?
总是放置在 L2 和设备驱动程序之间的这一层?或者,
例如我可以在之间进行这样的过滤吗
应用程序和传输层(分析套接字参数)使用
相同的过程?

是的。您注册的包类型的 .func() 在设备的 rx 处理程序处理之前在 __netif_receive_skb() 中调用。

Is it the case that the protocol being registered as a filter will
always be placed at this layer between L2 and the device driver? Or,
for instance could I make such a filtering occur between the
application and transport layers (analyze socket parameters) using the
same process?

Yes. .func() of the package type you registered is called in __netif_receive_skb(), before the rx handler of the device handles it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文