C dev_net_set在Linux中做什么?

C dev_net_set在Linux中做什么?,c,linux-kernel,linux-device-driver,C,Linux Kernel,Linux Device Driver,我正在基于环回驱动程序编写一个简单的网络设备驱动程序,并希望注册我的net\u设备结构。在写一个网络设备的页面上说只需调用register\u netdev。但他们正在用PCI express和其他复杂的东西编写花哨的驱动程序 因此,如果我只想要类似环回驱动程序的东西,我应该假定我的代码基于loopback.c。我的问题是,loopback\u net\u init中这段代码的第一行做什么: dev_net_set(dev, net); err = register_netdev(dev);

我正在基于环回驱动程序编写一个简单的网络设备驱动程序,并希望注册我的
net\u设备
结构。在写一个网络设备的页面上说只需调用
register\u netdev
。但他们正在用PCI express和其他复杂的东西编写花哨的驱动程序

因此,如果我只想要类似环回驱动程序的东西,我应该假定我的代码基于
loopback.c
。我的问题是,
loopback\u net\u init
中这段代码的第一行做什么:

dev_net_set(dev, net);
err = register_netdev(dev);
显然,
net
是由
net\u namespace.c
中的代码决定的:

register_pernet_device(ops) ...
__register_pernet_operations(list, ops)
   for_each_net(net) ...

这是什么循环?如果跳过
dev\u net\u set
调用,可能会出现什么问题?为什么其他人不使用它?

好吧,net是一种允许内核与设备交互的结构。您需要它来注册设备并在模块清理功能中将其删除。例如,请查看linux/net/8021q/下的代码。

AFAIK,循环发生在套接字级别(第5-7层),而net_dev被用作内核组件,当您实际想要使用say、以太网卡或SLIP、PLIP传输帧(第2-0层)时,它会立即与驱动程序交互。环回发生在内核的网络子系统级别,位于与硬件交互的驱动程序之上。所以我不明白为什么需要一个驱动程序来使用环回功能。然而,也有一条规定可以在net_dev中注册一个虚拟设备,尽管我不知道这是否是您想要的

这就是说,如果您的目的是简单地使用一些驱动程序来模拟实际的物理设备,而不使用驱动程序,并反映它接收到的数据包,这也是可能的。基本上直到net_dev层,内核完成所有的协议工作(TCP/IP),最后将数据包传递给设备驱动程序向net_dev注册的某个句柄或类似的东西。类似地,在接收数据时,设备触发中断,驱动程序执行DMA操作,内核从那里接管。因此,您可以制作一个模块,而不是执行DMA操作的代码,该模块只需传递一个与以太网/TCP/IP兼容的静态数据包。在绝大多数情况下,所有这些方面(网络和其他子系统)都与底层总线细节无关,即以太网卡是否连接到PCI或ISA并不重要,但也可能存在例外情况。因此,IMHO,您正在尝试做一些只有在对网络子系统有了透彻的理解,并且对整个内核有了足够的理解之后才能尝试的事情。在那之前,你将在黑暗中射击。有时你可能会打,但往往你会错过

网络名称空间在逻辑上是网络堆栈的另一个副本, 拥有自己的路由、防火墙规则和网络设备

因此,
对于每个网络,
在这些名称空间上循环,并在每个名称空间中创建所有“每网络”网络设备的副本


使用
ip网络列表
确定您是否正在使用网络名称空间。通常不使用它们,因此驱动程序不一定需要使用
dev\u net\u set

是的,我正在尝试了解内核和网络子系统,以便我的驱动程序按预期运行,我正在编写类似于驱动程序的环回,因此我不关心PCI等。观察结果很好。然而,我不认为每个网络的
可能与L5+有关。它正在对多个对象调用
register\u netdev
,因此它正在管理多个L2,因此如果有任何对象,它必须是L2以下的对象。是的,所有与网络开发相关的对象都是L2-L0。请参阅,loop back是一个功能的名称,其中数据包只是反弹到主机系统,而不是发送到另一个主机。该功能最容易在套接字(L5+)级别实现。然而,尽可能地绕过它,使数据通过所有协议(TCP/IP)(L5-L2),将其发送到虚拟设备/驱动程序(L2-L0),并使该驱动程序以某种适当的方式将该数据包发送回主机设备。当然,本教程旨在教学生(L2-L0)网络堆栈的细节。