Linux kernel 在一公里内何时使用网络系统呼叫vs.sk_buff

Linux kernel 在一公里内何时使用网络系统呼叫vs.sk_buff,linux-kernel,kernel-module,kernel,Linux Kernel,Kernel Module,Kernel,在尝试了解有关linux内核网络的更多信息时。。。我有一个内核模块,它包含一个运行在TCP之上的协议。这几乎是我正在试验的应用层协议。这些调用通过从用户空间执行的正常系统调用接口传入 因此,我的(TCP之上的层)模块中的网络调用通常如下所示 ret = sock->ops->connect(sock, (struct sockaddr *) &myprot.daddr, sizeof(myprot.daddr), flags); 在我的KM中,我成功地使用了send

在尝试了解有关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);
我现在想了解的是如何以及何时使用sku buff做同样的事情。也就是说,何时使用系统调用,如我上面使用的调用,何时通过sku buff直接访问网络堆栈以发送和接收数据

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

更新以澄清。

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

如果我在传输层工作,并且希望访问网络堆栈中任何位置的数据(例如传输、ip、mac),我可以直接访问sk_buff,但如果我在传输层上工作,我将使用与系统调用相对应的抽象协议特定成员函数。毕竟,他们最终都在为sku爱好者工作


我猜我的困惑,或者我试图通过了解这两种访问sku buff的方式的区别以及从哪里访问sku buff来确认我所做的是对的还是错的,是。。。如果我在内核中通过TCP传输发送数据,那么我可以只使用与TCP相关的proto_ops系统调用,除非我需要更多的控制,然后我会使用较低级别的skb函数来管理队列。

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


如果可能的话,就不可能用sk_buff做同样的
proto_ops
,这些结构中的一个是无用的。

也许这就是我的困惑所在,因为在我看来,proto_ops的成员函数在更高级别上对sk_buff起作用,但也可以选择直接使用sk_buff,控制力更强。所以在某种程度上,你可以用其中任何一个做同样的事情。我编辑了这篇文章,试图澄清我的困惑。