0

在尝试了解有关 linux 内核网络的更多信息时……我有一个内核模块,其中包含一个在 TCP 之上运行的协议。它几乎是我正在试验的一个应用层协议。调用是通过从用户空间执行的正常系统调用接口传入的。

因此,来自我的(TCP 之上的层)模块内部的网络调用通常看起来像这样......

ret = sock->ops->connect(sock, (struct sockaddr *) &myprot.daddr,
    sizeof(myprot.daddr), flags);

我已在我的 KM 中成功使用 sendmsg/recvmsg 将数据从客户端发送和接收到服务器(来自两个单独的内核实例)。KM 内的调用通常如下所示:

ret = sock->ops->sendmsg(iocb, myprot.skt, &msg, sizeof(struct msghdr));

ret = sock->ops->recvmsg(iocb, sock, msg, total_len, flags);

我现在想了解的是如何以及何时使用 sk_buff 来做同样的事情。即什么时候使用我上面使用的系统调用,什么时候通过sk_buff直接访问网络栈来发送和接收数据。

我找到了许多关于如何使用 sk_buff 从传输层内部发送和接收数据的示例,但没有来自传输层之上的层,该层也包含在内核模块中并使用 sk_buff。

更新澄清。

我已经覆盖了 struct proto_ops 并替换了我自己的协议使用的成员方法,这些方法确实对应于来自用户空间的系统调用。我知道 sk_buff 是内核的缓冲系统,是数据包排队的地方。然而。我看不出有什么理由不能使用 struct proto_ops 的协议特定功能,它也处理套接字和在它们上排队的数据(尽管在更高级别)。所以在我看来,有两种方法可以访问 sk_buffs,具体取决于一个人想要访问它们的位置。

如果我在传输层工作并且想要访问网络堆栈中任何位置的数据(例如传输、ip、ma​​c),我可以直接访问 sk_buffs,但如果我在传输层之上工作,我会使用抽象协议对应于系统调用的特定成员函数。毕竟,他们最终都在 sk_buffs 上工作。

我想我的困惑,或者我试图通过了解这两种访问 sk_buffs 的方式的区别以及从哪里来确认我做对或错的事情是......如果我通过传输从内核中的 TCP,我只能使用与 TCP 相关的 proto_ops 系统调用,除非我需要更多控制,然后我将使用较低级别的 skb 函数来管理队列。

4

1 回答 1

0

不确定是否理解,因为您想为同一目的使用不同的东西。proto_opsinsock->ops是在对应的系统调用期间调用的操作。sk_buff是内核的套接字缓冲系统;它是数据包排队的地方。

不可能做与proto_opswith相同的事情sk_buff,如果可能的话,这些结构之一是无用的。

于 2013-05-21T08:19:21.863 回答