前言

这次在 Jetson Orin NX 上同时连接普通设备和 Livox Mid-360S 时,连续遇到了两个问题:

  1. 主板有两个物理网口,但系统只能看到一个网口。
  2. 第二个网口修好后,两个网口仍然只能连接一个,连接第二个时第一个会断开。

最后确认并不是 Jetson 的两个网口硬件互斥,而是第二个 Realtek 网卡缺少驱动,同时两个网口错误地共用了同一个 NetworkManager 配置。由于两个网口还在同一个 192.168.1.0/24 网段,又产生了路由冲突。

本文先给出可以直接使用的一键脚本,再解释问题原因和手动排查方法。

适用边界:下面的脚本是针对本文记录的 Jetson Orin NX、Realtek RTL8125/RTL8168 网卡和同网段地址规划验证的。其他载板、内核版本、网卡芯片或 IP 规划需要先修改配置并核对驱动,不应直接照搬。

一、当前设备配置

这台 Jetson 的网络规划如下:

用途 网口 Jetson IP 对端设备 IP
普通设备网 enP7p1s0 192.168.1.123/24 根据实际设备确定
Mid-360S 专用网 enP8p1s0 192.168.1.102/24 192.168.1.199
SSH 和默认网络 wlP1p1s0 DHCP 路由器

实际网卡控制器:

1
2
enP7p1s0 -> Realtek RTL8125      -> r8125
enP8p1s0 -> Realtek RTL8111/8168 -> r8168

执行脚本会重新连接两个有线网口。如果当前 SSH 正通过其中一个有线口连接,脚本会停止。建议通过 Wi-Fi、显示器或串口执行。

二、一键解决脚本

在 Jetson 上创建脚本:

1
nano ~/enable_jetson_dual_eth.sh

复制下面的全部内容。如果自己的网口名或 IP 不同,只修改最上方的“需要修改的配置”部分。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
#!/usr/bin/env bash
set -Eeuo pipefail

# ============================================================
# 需要修改的配置
# ============================================================

# 普通设备网口
GENERAL_IF="enP7p1s0"
GENERAL_IP="192.168.1.123/24"
GENERAL_PROFILE="device-enP7"

# Mid-360S 专用网口
LIDAR_IF="enP8p1s0"
LIDAR_HOST_IP="192.168.1.102/24"
LIDAR_PROFILE="102"
LIDAR_IP="192.168.1.199"

# ============================================================

if [[ $EUID -ne 0 ]]; then
echo "请使用 sudo 运行:sudo bash $0"
exit 1
fi

for command_name in lspci ip nmcli awk grep modprobe; do
if ! command -v "$command_name" >/dev/null 2>&1; then
echo "缺少命令:$command_name"
exit 1
fi
done

if [[ "$GENERAL_IF" == "$LIDAR_IF" ]]; then
echo "两个用途不能配置到同一个网口"
exit 1
fi

echo "普通设备网口:$GENERAL_IF -> $GENERAL_IP"
echo "雷达专用网口:$LIDAR_IF -> $LIDAR_HOST_IP"
echo "Mid-360S:$LIDAR_IP"

# 当前 SSH 如果正经过目标有线口,直接重连可能导致脚本执行一半时断线。
if [[ -n "${SSH_CONNECTION:-}" ]]; then
SSH_CLIENT_IP="${SSH_CONNECTION%% *}"
SSH_ROUTE="$(ip -4 route get "$SSH_CLIENT_IP" 2>/dev/null | head -n 1 || true)"
if [[ "$SSH_ROUTE" == *" dev $GENERAL_IF "* || "$SSH_ROUTE" == *" dev $LIDAR_IF "* ]]; then
echo "当前 SSH 正通过待重配网口连接:$SSH_ROUTE"
echo "请改用 Wi-Fi、显示器或串口后重新运行"
exit 1
fi
fi

echo "[1/5] 检查 RTL8168 驱动"

RTL8168_INFO="$(lspci -nnk -d 10ec:8168 2>/dev/null || true)"
if [[ -n "$RTL8168_INFO" ]] && ! grep -q "Kernel driver in use:" <<<"$RTL8168_INFO"; then
echo "发现 RTL8168,但没有驱动,开始安装 r8168-dkms"

if [[ ! -e "/lib/modules/$(uname -r)/build" ]]; then
echo "缺少与 $(uname -r) 匹配的 Jetson 内核头文件"
echo "请先安装当前 L4T 对应的 nvidia-l4t-kernel-headers"
exit 1
fi

apt-get update
env DEBIAN_FRONTEND=noninteractive apt-get install -y r8168-dkms
modprobe r8168
udevadm settle || true
else
echo "RTL8168 已经有驱动,跳过安装"
fi

for interface_name in "$GENERAL_IF" "$LIDAR_IF"; do
if [[ ! -d "/sys/class/net/$interface_name" ]]; then
echo "找不到网口:$interface_name"
echo "当前网口如下,请修改脚本顶部的网口名:"
ip -br link
exit 1
fi
done

echo "[2/5] 备份 NetworkManager 配置"

BACKUP_DIR="/var/backups/jetson-dual-ethernet/$(date +%Y%m%d-%H%M%S)"
mkdir -p "$BACKUP_DIR"
if [[ -d /etc/NetworkManager/system-connections ]]; then
cp -a /etc/NetworkManager/system-connections "$BACKUP_DIR/"
fi
echo "配置已备份到:$BACKUP_DIR"

configure_profile() {
local profile_name="$1"
local interface_name="$2"
local address="$3"
local route_metric="$4"
local autoconnect_priority="$5"

if ! nmcli connection show "$profile_name" >/dev/null 2>&1; then
nmcli connection add \
type ethernet \
ifname "$interface_name" \
con-name "$profile_name"
fi

nmcli connection modify "$profile_name" \
connection.interface-name "$interface_name" \
802-3-ethernet.mac-address "" \
connection.autoconnect yes \
connection.autoconnect-priority "$autoconnect_priority" \
ipv4.method manual \
ipv4.addresses "$address" \
ipv4.gateway "" \
ipv4.dns "" \
ipv4.ignore-auto-dns yes \
ipv4.never-default yes \
ipv4.route-metric "$route_metric" \
ipv4.routes "" \
ipv6.method disabled
}

echo "[3/5] 为两个网口创建独立配置"

nmcli device set "$GENERAL_IF" managed yes
nmcli device set "$LIDAR_IF" managed yes

configure_profile "$GENERAL_PROFILE" "$GENERAL_IF" "$GENERAL_IP" 100 50
configure_profile "$LIDAR_PROFILE" "$LIDAR_IF" "$LIDAR_HOST_IP" 500 100

# 两个网口处于同一 /24 网段时,强制 Mid-360S 从雷达专用口访问。
nmcli connection modify "$LIDAR_PROFILE" \
ipv4.routes "$LIDAR_IP/32 0.0.0.0 10"

echo "[4/5] 激活两个网口"

nmcli connection reload
nmcli connection down "$GENERAL_PROFILE" >/dev/null 2>&1 || true
nmcli connection down "$LIDAR_PROFILE" >/dev/null 2>&1 || true
nmcli connection up "$GENERAL_PROFILE" ifname "$GENERAL_IF"
nmcli connection up "$LIDAR_PROFILE" ifname "$LIDAR_IF"

echo "[5/5] 验证结果"

nmcli -f DEVICE,TYPE,STATE,CONNECTION device status
ip -4 -br address show dev "$GENERAL_IF"
ip -4 -br address show dev "$LIDAR_IF"

echo "Mid-360S 实际选路:"
ip -4 route get "$LIDAR_IP"

if ping -I "$LIDAR_IF" -c 3 -W 1 "$LIDAR_IP"; then
echo "配置成功:两个网口已独立启用,Mid-360S 可以访问"
else
echo "两个网口配置已完成,但 Mid-360S 没有响应 ping"
echo "请检查雷达电源、网线和 LIDAR_IP"
exit 1
fi

保存后执行:

1
2
chmod +x ~/enable_jetson_dual_eth.sh
sudo ~/enable_jetson_dual_eth.sh

脚本成功后,最后应看到:

1
2
3
4
enP7p1s0  ethernet  connected  device-enP7
enP8p1s0 ethernet connected 102

192.168.1.199 dev enP8p1s0 src 192.168.1.102

脚本可以重复运行。每次修改前都会将 NetworkManager 配置备份到:

1
/var/backups/jetson-dual-ethernet/

三、问题一:为什么第二个网口无法打开

先查看 PCI 网卡和驱动:

1
lspci -nnk -d 10ec:

当时可以看到两个控制器:

1
2
RTL8125 2.5GbE Controller
RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller

第一个控制器有:

1
Kernel driver in use: r8125

第二个 RTL8168 却没有 Kernel driver in use,并且执行下面的命令只能看到一个有线网口:

1
ip -br link

这说明 PCIe 已经识别到硬件,但内核没有为第二个控制器创建网络接口。此时执行 ip link set up 或在桌面网络设置中反复点击都没有用,必须先安装驱动:

1
2
sudo apt-get install -y r8168-dkms
sudo modprobe r8168

安装后验证:

1
2
3
dkms status | grep r8168
lspci -nnk -d 10ec:8168
ethtool -i enP8p1s0

这台 Jetson 的最终结果为:

1
2
3
r8168/8.049.02, 5.15.148-tegra, aarch64: installed
Kernel driver in use: r8168
driver: r8168

四、问题二:为什么打开一个网口,另一个就断开

驱动安装完成后,两个网口的 carrier 都是 1,说明物理连接正常:

1
2
3
4
for nic in enP7p1s0 enP8p1s0; do
printf '%s carrier=' "$nic"
cat "/sys/class/net/$nic/carrier"
done

继续查看 NetworkManager 配置:

1
2
3
4
nmcli -f NAME,TYPE,DEVICE,AUTOCONNECT connection show
nmcli -f \
connection.id,connection.interface-name,802-3-ethernet.mac-address,ipv4.addresses \
connection show 102

原来的 102 配置没有绑定网口:

1
2
connection.interface-name: --
802-3-ethernet.mac-address: --

NetworkManager 会把这个配置应用到任意一个兼容的有线网口。插入另一根网线时,同一个配置就在两个接口之间迁移,因此表现为“连接一个,另一个断开”。

正确做法是让每个接口拥有独立配置,并通过接口名固定:

1
2
device-enP7 -> enP7p1s0 -> 192.168.1.123/24
102 -> enP8p1s0 -> 192.168.1.102/24

脚本中的关键配置就是:

1
2
nmcli connection modify device-enP7 connection.interface-name enP7p1s0
nmcli connection modify 102 connection.interface-name enP8p1s0

五、两个网口在同一网段时的路由问题

两个有线口都使用 192.168.1.0/24,系统会产生两条相同网段的路由:

1
2
192.168.1.0/24 dev enP7p1s0 src 192.168.1.123 metric 100
192.168.1.0/24 dev enP8p1s0 src 192.168.1.102 metric 500

Linux 默认会选择 metric 更小的 enP7p1s0。这样即使 Mid-360S 接在 enP8p1s0,发往 192.168.1.199 的数据仍可能走错网口。

解决方法是添加一条更精确的 /32 路由:

1
2
sudo nmcli connection modify 102 \
ipv4.routes "192.168.1.199/32 0.0.0.0 10"

检查实际选路:

1
ip route get 192.168.1.199

必须看到:

1
192.168.1.199 dev enP8p1s0 src 192.168.1.102

如果可以修改设备网段,更推荐让两个网口使用不同网段,例如:

1
2
普通设备网:192.168.1.0/24
雷达设备网:192.168.2.0/24

不同网段不会产生这种路由歧义。

六、Mid-360S 配置同步

网络修好后,还要把 MID360s_config.json 中的 host_ip 改成雷达专用网口地址:

1
"host_ip": "192.168.1.102"

雷达地址保持:

1
"ip": "192.168.1.199"

如果这里仍然写成另一个网口的 192.168.1.123,可能出现能够 ping 通雷达,但 ROS 驱动收不到点云的情况。

启动驱动后验证:

1
ros2 launch livox_ros_driver2 msg_MID360s_launch.py

在另一个终端检查频率:

1
2
ros2 topic hz /livox/lidar --window 20
ros2 topic hz /livox/imu --window 100

这次实际测试结果为:

1
2
/livox/lidar  约 10 Hz
/livox/imu 约 200 Hz

七、快速排查命令

以后遇到类似问题,按照下面的顺序检查即可:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 1. PCIe 是否识别到两个控制器,驱动是否已经绑定
lspci -nnk -d 10ec:

# 2. 内核是否创建了两个网口
ip -br link

# 3. 两个接口分别使用什么驱动
ethtool -i enP7p1s0
ethtool -i enP8p1s0

# 4. 网线是否真正连接
cat /sys/class/net/enP7p1s0/carrier
cat /sys/class/net/enP8p1s0/carrier

# 5. 两个接口是否分别连接到独立 profile
nmcli -f DEVICE,TYPE,STATE,CONNECTION device status

# 6. 查看地址和路由
ip -4 -br address
ip -4 route

# 7. 确认 Mid-360S 最终走哪个网口
ip route get 192.168.1.199

# 8. 强制从雷达口测试
ping -I enP8p1s0 192.168.1.199

八、常见问题

1. 安装 r8168-dkms 时报找不到内核头文件

检查:

1
ls -ld "/lib/modules/$(uname -r)/build"

需要安装与当前 Jetson Linux/L4T 版本匹配的 nvidia-l4t-kernel-headers。不要使用与当前 *-tegra 内核不匹配的 generic 头文件。

2. 设置 MAC 后提示没有合适的设备

运行时 MAC、克隆 MAC 和永久 MAC 可能不同:

1
2
nmcli -f GENERAL.HWADDR,GENERAL.PERM-HWADDR device show enP7p1s0
ethtool -P enP7p1s0

如果接口名稳定,直接使用 connection.interface-name 绑定即可。本文脚本会清空 profile 中的 MAC 限制,避免当前 MAC 和永久 MAC 不一致导致连接失败。

3. 两个网口都显示 connected,但雷达仍然不通

重点检查实际路由,而不是只看网口状态:

1
ip route get 192.168.1.199

如果没有走 enP8p1s0,重新添加 /32 路由并激活配置:

1
2
3
sudo nmcli connection modify 102 \
ipv4.routes "192.168.1.199/32 0.0.0.0 10"
sudo nmcli connection up 102 ifname enP8p1s0

4. 重启后又恢复原状

检查两个 profile 是否开启自动连接并绑定正确接口:

1
2
3
4
5
6
7
nmcli -f \
connection.id,connection.interface-name,connection.autoconnect,ipv4.addresses,ipv4.routes \
connection show device-enP7

nmcli -f \
connection.id,connection.interface-name,connection.autoconnect,ipv4.addresses,ipv4.routes \
connection show 102

总结

本次问题由三个环节共同造成:

1
2
3
4
5
6
7
8
RTL8168 没有驱动
-> 第二个网口没有出现在系统中

两个网口共用一个未绑定接口的 NetworkManager profile
-> 连接一个时另一个断开

两个网口处于相同的 192.168.1.0/24 网段
-> 发往 Mid-360S 的数据可能走错网口

对应的解决方法是:

  1. 安装并加载 r8168-dkms
  2. 为两个网口创建独立 profile,并通过接口名绑定。
  3. 不给设备专用网口配置默认网关。
  4. 使用 /32 路由将 192.168.1.199 固定到 enP8p1s0
  5. 将 Livox 配置中的 host_ip 修改为 192.168.1.102

完成后,两个网口可以同时连接各自设备,并在 Jetson 重启后自动恢复。