include/linux/skbuff.h -> union skb_shared_tx中的hardware标志:

网卡驱动用它来判断发送报文是否需要硬时标(当然还有其它方式可以判断),driver/net/igb驱动在报文发送完毕后,就是靠这个标志作为条件,来决定是否需要取硬时标,那么这个标志是在哪里初始化的呢(总之不是在网卡驱动里)。

int sock_tx_timestamp(struct msghdr *msg, struct sock *sk,union skb_shared_tx *shtx)
{
 shtx->flags = 0;
 if (sock_flag(sk, SOCK_TIMESTAMPING_TX_HARDWARE))
  shtx->hardware = 1; //天杀的hardware标志,废了我一下午时间才找到你在这里赋值的
 if (sock_flag(sk, SOCK_TIMESTAMPING_TX_SOFTWARE))
  shtx->software = 1;
 return 0;
}

sock_tx_timestamp 被raw_sendmsg或udp_sendmsg调用

 

上面的源码已经写的很清楚了,这个hardware标志是在socket的发送函数里被赋值的,就是说当通过socket ioctl设置了SOCK_TIMESTAMPING_TX_HARDWARE标志时,shtx->hardware将被赋予“1”,然后网卡驱动在发送完报文以后,就知道需要取硬时标(当然硬时标功能早已在网卡驱动初始化时被使能了)。

相反,网卡驱动在接收完一帧数据后,则直接取接收报文的硬时标,不需要判断hardware标志,hardware这个标志是发送报文时专用的。

问题来了,如果在内核态直接构造skb发送(调用dev_queue_xmit),不走socket,那hardware标志怎么初始化呢,这种问题居然也问,当然是构造skb的时候直接对其赋值了,hardware是skb的成员变量啊。