2017-01-23 11 views
5

私はnetwork timestampingのLinuxカーネルのドキュメントを読んできましたが、それは私には分かりません。LinuxカーネルUDP受信タイムスタンプ

SO_TIMESTAMPNSで提供されているタイムスタンプはどこにありますか?ハードウェアやカーネルでは?もしそうなら、新しいパケットの割り込みが発生すると直ちにゲーティングされますか?

SO_TIMESTAMPINGも、ハードウェアタイムスタンプの生成を許可する必要があります。これはすべてのNICでサポートされていますか?どのようにしてSO_TIMESTAMPINGオプション付きSOF_TIMESTAMPING_RX_HARDWARE andSO_TIMESTAMPNS? その場合、システムクロックまたはNICクロックを参照するハードウェアタイムスタンプはありますか? 2番目のケースでは、NICクロックを取得して経過時間を計算する方法はありますか?

+3

ハードウェアを。通常、このようなハードウェアはPTPのようなものを使用してカードを同期させますので、クロックに関連してタイムスタンプを受け取るようにしてください(単調であることは確かではありません - 他の誰かがコメントできるかもしれません...) – Nim

+0

@Nimサポートされていればハードウェアを返しますか? SO_TIMESTAMPNS?ハードウェアタイムスタンプを有効にする必要がありますか? – Maverik

+0

通常、この機能をサポートするハードウェアはソケットオプション( 'SO_TIMESTAMPNS'または' SO_TIMESTAMP')を見て、パケットをスタンプします。たとえば、適切な太陽フレアカードがある場合、オプションを設定すると、カードにタイムスタンプが設定されます。それ以外の場合は、カーネルによって管理されます。率直に言って、タイムスタンプを実際に得るためには、コントロールヘッダーを読まなければならないのは本当に好きではありません。恐ろしいインターフェイスです。 – Nim

答えて

4

ソフトウェアのタイムスタンプに使用されるsocket属性は、SO_TIMESTAMPNSです。このソケット属性は、システムクロックから時刻を返します。ハードウェアで生成されるのではなく、ソフトウェアで割り込みが処理されるシステム時間のスナップショットです。私たちは使用して、ソケットのペイロードの一部ではない補助的なデータ(CMSG)を介してこのタイムスタンプにアクセスすることができます。

int level, type; 
struct cmsghdr *cm; 
struct timespec *ts = NULL; 
for (cm = CMSG_FIRSTHDR(&msg); cm != NULL; cm = CMSG_NXTHDR(&msg, cm)) 
{ 
    level = cm->cmsg_level; 
    type = cm->cmsg_type; 
    if (SOL_SOCKET == level && SO_TIMESTAMPNS == type) { 
     ts = (struct timespec *) CMSG_DATA(cm); 
     printf("SW TIMESTAMP %ld.%09ld\n", (long)ts[0].tv_sec, (long)ts[0].tv_nsec); 
    } 
} 

SO_TIMESTAMPINGソケットオプションは、多くの異なるフラグを提供しています、そのうちのいくつかはある、

SOF_TIMESTAMPING_TX_HARDWARE // Transmit timestamp generated in hardware by NIC clock 
SOF_TIMESTAMPING_RX_HARDWARE // Receive timestamp generated in hardware by NIC clock 
SOF_TIMESTAMPING_TX_SOFTWARE // Transmit timestamp generated in kernel driver by NIC clock 
SOF_TIMESTAMPING_RX_SOFTWARE // Receive timestamp generated in kernel driver by NIC clock 

このソケットオプションは、すべてのネットワークインターフェイスカード(NIC)でサポートされていません。現在、多くのイーサネットNICがSO_TIMESTAMPINGをサポートしています。

ethtool -T ethX // where X corresponds to your particular interface 

これは、すべてのソケットがethXをがタイムスタンプのためにサポートしている属性が返されます:特定のインタフェースドライバがSO_TIMESTAMPING、使用をサポートしているかどうか見つけるために。

のコードを使用し、特定のNICによって提供されるハードウェアタイムスタンプ機能を使用するには、次のサポート、他のカーネルならば

int flags; 
flags = SOF_TIMESTAMPING_TX_HARDWARE 
      | SOF_TIMESTAMPING_RX_HARDWARE 
      | SOF_TIMESTAMPING_TX_SOFTWARE 
      | SOF_TIMESTAMPING_RX_SOFTWARE 
      | SOF_TIMESTAMPING_RAW_HARDWARE; 
    if (setsockopt(sd, SOL_SOCKET, SO_TIMESTAMPING, &flags, sizeof(flags)) < 0) 
     printf("ERROR: setsockopt SO_TIMESTAMPING\n"); 

int level, type; 
struct cmsghdr *cm; 
struct timespec *ts = NULL; 
for (cm = CMSG_FIRSTHDR(&msg); cm != NULL; cm = CMSG_NXTHDR(&msg, cm)) 
{ 
    if (SOL_SOCKET == level && SO_TIMESTAMPING == type) { 
     ts = (struct timespec *) CMSG_DATA(cm); 
     printf("HW TIMESTAMP %ld.%09ld\n", (long)ts[2].tv_sec, (long)ts[2].tv_nsec); 
     } 
} 
関連する問題