【问题标题】:Linux recvmsg() not getting a software timestamp from socketLinux recvmsg()没有从套接字获取软件时间戳
【发布时间】:2021-10-10 00:13:33
【问题描述】:

我正在通过 recvmsg() 接收数据包并期望 3 个时间戳:

  1. 软件
  2. 硬件 (NIC) 转换为软件
  3. 硬件 (NIC)

我看到了第一个和第三个时间戳,但第二个时间戳为零。

我的代码基于这个 Onload 示例:

https://github.com/Xilinx-CNS/onload/blob/master/src/tests/onload/hwtimestamping/rx_timestamping.c

我为时间戳导出环境变量:

export EF_RX_TIMESTAMPING=1

我预加载了 onload 库。

我设置了套接字选项:

int enable = SOF_TIMESTAMPING_RX_HARDWARE | SOF_TIMESTAMPING_RAW_HARDWARE |
                 SOF_TIMESTAMPING_SYS_HARDWARE | SOF_TIMESTAMPING_SOFTWARE;
assert(setsockopt(sock, SOL_SOCKET, SO_TIMESTAMPING, &enable, sizeof(int)) == 0);

我创建消息头并使用recvmsg() 来检索数据包:

  while(_running)
  {
      struct iovec iov;
      char control[1024];
      struct msghdr msg;

      iov.iov_base = buffer;
      iov.iov_len = 2048;
      msg.msg_iov = &iov;
      msg.msg_iovlen = 1;
      msg.msg_namelen = sizeof(struct sockaddr_in);
      msg.msg_control = control;
      msg.msg_controllen = 1024;

      int num bytes = recvmsg(sock, &msg, 0);
      handle_time(&msg);
      LOG("Got packet");
  }

我阅读了时间戳:

static void handle_time(struct msghdr* msg)
{
  struct timespec* ts = NULL;
  struct cmsghdr* cmsg;

  for( cmsg = CMSG_FIRSTHDR(msg); cmsg; cmsg = CMSG_NXTHDR(msg,cmsg) ) {
    if( cmsg->cmsg_level != SOL_SOCKET )
      continue;

    switch( cmsg->cmsg_type ) {
    case SO_TIMESTAMPNS:
      ts = (struct timespec*) CMSG_DATA(cmsg);
      break;
    case SO_TIMESTAMPING:
      ts = (struct timespec*) CMSG_DATA(cmsg);
      break;
    default:
      /* Ignore other cmsg options */
      break;
    }
  }

  print_time(ts);
}

static void print_time(struct timespec* ts)
{
  if( ts != NULL ) {
    /* Hardware timestamping provides three timestamps -
     *   system (software)
     *   transformed (hw converted to sw)
     *   raw (hardware)
     * in that order - though depending on socket option, you may have 0 in
     * some of them.
     */
    printf("timestamps " TIME_FMT TIME_FMT TIME_FMT "\n",
      (uint64_t)ts[0].tv_sec, (uint64_t)ts[0].tv_nsec,
      (uint64_t)ts[1].tv_sec, (uint64_t)ts[1].tv_nsec,
      (uint64_t)ts[2].tv_sec, (uint64_t)ts[2].tv_nsec );
  } else
  {
    printf( "no timestamp\n" );
  }
}

接收第二个时间戳有什么遗漏吗?

【问题讨论】:

    标签: c linux sockets network-programming


    【解决方案1】:

    可能是网络接口驱动需要从硬件中添加时间戳。我们在谈论什么样的硬件?你能显示一些ethanol 的输出吗?

    【讨论】:

    • 这是一个 Solarflare 适配器。当我们在界面上运行ethtool -T 时,它会列出功能下的所有四个标志。
    猜你喜欢
    • 2021-04-07
    • 1970-01-01
    • 1970-01-01
    • 2017-10-27
    • 2023-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多