如何用C语言获取rt_igb驱动网卡的链路状态与速率?
问题:rt_igb驱动网卡通过ETHTOOL获取链路状态/速率失败
我使用rt_igb驱动的网卡,尝试用C语言通过ETHTOOL接口获取链路状态和速率,但调用ioctl时返回Operation not supported错误。内核日志显示网卡能正常识别链路上下线及速率,求解决方法。
测试代码
#include <linux/ethtool.h> #include <linux/if.h> #include <linux/sockios.h> #include <netinet/in.h> #include <sys/ioctl.h> #include <sys/socket.h> #include <stdio.h> #include <stdlib.h> #include <string.h> int main(void) { struct ethtool_cmd edata = {.cmd = ETHTOOL_GSET}; struct ifreq ifr = {.ifr_name = "rteth0", .ifr_data = &edata}; int sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP); if (sock < 0) { perror("socket"); return EXIT_FAILURE; } if (ioctl(sock, SIOCETHTOOL, &ifr) < 0) { perror("ioctl"); return EXIT_FAILURE; } switch (ethtool_cmd_speed(&edata)) { case SPEED_10: printf("10Mbps\n"); break; case SPEED_100: printf("100Mbps\n"); break; case SPEED_1000: printf("1Gbps\n"); break; case SPEED_2500: printf("2.5Gbps\n"); break; case SPEED_10000: printf("10Gbps\n"); break; default: printf("Speed returned is %d\n", edata.speed); } }
运行输出
Operation not supported
内核日志(插拔网线时)
Apr 10 13:38:32 laptop kernel: [16948.074380] rt_igb: rteth0: igb: rteth0 NIC Link is Down Apr 10 13:41:26 laptop kernel: [17122.113260] rt_igb: rteth0: igb: rteth0 NIC Link is Up 100 Mbps Full Duplex, Flow Control: RX
解决方法
原因分析
ETHTOOL_GSET是旧版ETHTOOL接口,rt_igb驱动仅支持新版的ETHTOOL_GLINKSETTINGS接口,导致旧接口调用失败。内核日志已证明驱动能正常获取链路信息,只需更换接口即可。
修改后的代码
#include <linux/ethtool.h> #include <linux/if.h> #include <linux/sockios.h> #include <netinet/in.h> #include <sys/ioctl.h> #include <sys/socket.h> #include <stdio.h> #include <stdlib.h> #include <string.h> int main(void) { struct ethtool_link_settings ls = {.cmd = ETHTOOL_GLINKSETTINGS}; struct ifreq ifr = {.ifr_name = "rteth0", .ifr_data = &ls}; int sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP); if (sock < 0) { perror("socket"); return EXIT_FAILURE; } if (ioctl(sock, SIOCETHTOOL, &ifr) < 0) { perror("ioctl"); return EXIT_FAILURE; } // 输出链路状态信息 if (ls.link_mode_mask & ETHTOOL_LINK_MODE_Autoneg_BIT) { printf("自动协商: 已启用\n"); } else { printf("自动协商: 已禁用\n"); } if (ls.link_status == ETHTOOL_LINK_UP) { printf("链路状态: 已连接\n"); printf("速率: %u Mbps\n", ls.speed); printf("双工模式: %s\n", ls.duplex == DUPLEX_FULL ? "全双工" : "半双工"); } else { printf("链路状态: 已断开\n"); } close(sock); return EXIT_SUCCESS; }
代码说明
- 使用新版
struct ethtool_link_settings结构体替换旧版struct ethtool_cmd,命令改为ETHTOOL_GLINKSETTINGS - 新增链路连接状态(Up/Down)的判断逻辑
- 直接读取
ls.speed获取速率,无需依赖旧版宏定义 - 支持自动协商状态、双工模式的获取
编译运行
编译时链接标准库:
gcc -o link_status link_status.c ./link_status
内容的提问来源于stack exchange,提问作者Tam Tran
相关产品推荐
相关产品推荐

