问题澄清:
1. 凡是调用dev_queue_xmit的对象都是一个网络设备。
解答:这个思路是错误的。因为dev_queue_xmit是有网络设备无关层调用的函数,调用对象调用该函数之后,函数会判断skb中的dev字段,根据这个字段指示的设备调用该设备的发送函数hard_start_xmit来对skb进行转发。
2. 凡是由dev_queue_xmit调用hard_start_xmit发送出来的帧都是封装好的以太帧。
解答:这个思路还是有问题,因为对于是否将skb进一步封装成为以太帧的形式,其实是由hard_start_smit函数的具体实现来决定的,如果在hard_start_xmit中调用了hard_header函数,那么就会将skb进一步封装,如果没有调用,那么就没有将skb进行进一步封装。也就是说,上层在需要发送skb的时候会选择调用dev_queue_xmit,那么至于下层是怎么传递该skb的,上层根本就不用关心,这就是所谓的各层的独立性原理。所以对skb具体的发送处理过程,可以由下层网络接口的hard_queue_xmit来处理。比如说上层需要发送一个广播帧,那么它就将skb->pkt_type赋值为PACKET_BROADCAST,然后调用dev_queue_xmit将其发送出去之后就不管下层是否将这个广播帧真的放到网络中进行广播。而下层如果是一个与上层绑定好了的虚拟网络设备的话,它可以在自己的hard_start_xmit中对skb->pkt_type字段为PACKET_BROADCAST的skb进行特定的处理,这里指的特定就是说,不一定非要将这个skb放到网络中进行广播。
3. 对于注册的协议类型。
解答:注册协议类型是由具有该协议类型的本层来注册的,当netif_rx判断是某层注册的协议时,则会主动调用该协议的处理函数来对接收的帧进行处理。
linux驱动问题讲解
内容版权声明:除非注明,否则皆为本站原创文章。