4. 车载以太网网络层:IPv4/IPv6双栈、ARP协议、ICMPv6与邻居发现协议(NDP)

网络层,说白了就是给数据包找路的。在车载以太网里,这条路比普通IT网络要复杂得多。你想想看,一辆车上有几十个ECU,还有T-Box、ADAS摄像头、激光雷达,它们既要跟车内设备通信,又要跟云端交互。这就逼着网络层必须同时支持IPv4和IPv6——也就是所谓的双栈。

我个人习惯把网络层比作一个交通系统。IPv4是老城区,地址快用完了;IPv6是新开发区,地址多到可以给每个传感器都分配一个全球唯一IP。但在车上,这两个系统必须共存,而且切换要无缝。

4.1 IPv4/IPv6双栈:为什么车上必须同时支持?

很多刚入行的朋友问我:车上直接用IPv6不行吗?省得维护两套协议栈。我的回答是:不行,至少现在不行。

原因有三:

  • 云端兼容性:大部分云平台的后端服务还是IPv4为主,车机必须能跟它们握手。
  • 诊断工具:OBD诊断、UDS刷写这些传统工具,很多只认IPv4。我在项目中遇到过,一台新款的ADAS域控制器只配了IPv6地址,结果产线诊断仪连不上,折腾了两天加了个IPv4辅助地址才搞定。
  • 过渡期:IPv6的部署是渐进式的,车厂不可能一夜之间把所有ECU都换成IPv6。

双栈的核心原则:同一块网卡,同时绑定IPv4和IPv6地址。应用层发数据时,协议栈根据目标地址类型自动选择走哪条路。

在Linux车载系统里,双栈配置其实很简单。我一般会在/etc/network/interfaces或者用NetworkManager配成下面这样:

# 车载T-Box双栈配置示例
auto eth0
iface eth0 inet static
    address 192.168.1.100
    netmask 255.255.255.0
    gateway 192.168.1.1

iface eth0 inet6 static
    address 2001:db8:100::100
    netmask 64
    gateway 2001:db8:100::1

嗯,这里要注意:车载环境里,IPv6的地址分配不一定用SLAAC(无状态自动配置),很多时候车厂会要求用DHCPv6,因为要记录每个ECU的地址分配日志,方便售后排查。

4.2 ARP协议:IPv4世界的地址翻译官

ARP(地址解析协议)干的事很简单:已知目标IP,问出目标MAC。在车载以太网里,ARP是个老熟人,但也是个麻烦精。

为什么说它麻烦?因为ARP是广播的。你想想,车上一个域控制器发个ARP请求,整个网段的所有ECU都得停下来看看是不是找自己。如果网络里有几十个ECU,ARP广播风暴能把总线带宽吃掉一大半。

我曾经踩过的坑:在某量产项目中,ADAS摄像头频繁断连。排查了三天,最后发现是ARP表老化时间设置太短,导致摄像头每30秒就要发一次ARP请求,而域控制器处理不过来。后来把ARP表老化时间从30秒改到300秒,问题解决。

ARP协议的工作流程,我习惯用一张表来记:

步骤 动作 报文类型 目标地址
1 主机A想找主机B的MAC ARP请求 广播 (FF:FF:FF:FF:FF:FF)
2 主机B回应自己的MAC ARP应答 单播 (主机A的MAC)
3 主机A更新ARP缓存 — —
4 后续通信直接使用MAC — —

在车载环境里,我建议你开启ARP防欺骗功能。因为有些恶意设备可以伪造ARP应答,把流量引到自己那里去。虽然车内的封闭网络相对安全,但T-Box如果被攻破,ARP欺骗就能让攻击者拿到所有ECU的通信内容。

4.3 ICMPv6与邻居发现协议(NDP):IPv6的ARP替代者

IPv6里没有ARP了。那它怎么找到邻居的MAC地址?答案是NDP(邻居发现协议)。NDP是ICMPv6的一部分,它干的事比ARP多得多。

我刚开始学IPv6时,觉得NDP太复杂了,不如ARP简单直接。但用久了才发现,NDP的设计其实更优雅——它把地址解析、路由器发现、地址自动配置、重复地址检测全整合到了一起。

4.3.1 NDP的五大核心功能

  • 地址解析:相当于IPv4的ARP,但用的是ICMPv6的邻居请求(NS)和邻居通告(NA)报文。
  • 路由器发现:主机通过路由器请求(RS)和路由器通告(RA)找到网关。
  • 前缀发现:主机知道哪些地址是本地链路,哪些需要走路由器。
  • 地址自动配置:SLAAC,主机自己根据前缀和接口ID生成IPv6地址。
  • 重复地址检测(DAD):在配置地址前,先发NS看看有没有人用这个地址。

个人经验:在车载项目里,我最常用的是NDP的路由器发现功能。T-Box上电后,通过RS/RA报文就能知道网关是谁,不需要像IPv4那样硬编码网关地址。这对OTA升级场景特别有用——网关换了,ECU自动就能发现。

4.3.2 NDP报文类型速查

ICMPv6类型 报文名称 功能 类似IPv4协议
133 路由器请求 (RS) 主机请求路由器发送RA —
134 路由器通告 (RA) 路由器广播自己的存在和前缀 DHCP Offer(部分)
135 邻居请求 (NS) 请求目标MAC地址 ARP请求
136 邻居通告 (NA) 回应自己的MAC地址 ARP应答
137 重定向 告诉主机有更好的下一跳 ICMP重定向

4.3.3 NDP地址解析流程

这个流程跟ARP很像,但用的是组播而不是广播。我画了一张图帮你理解:

NDP地址解析流程(IPv6替代ARP) 节点A (2001::A) 节点B (2001::B) ① NS: 目标地址2001::B的MAC? (组播: ff02::1:ff00:B) ② NA: 我是2001::B, 我的MAC是 00:1A:2B:3C:4D:5E (单播到节点A) ③ 更新邻居缓存 ③ 记录节点A信息 ④ 直接单播通信 (不再需要NDP) 关键区别 ARP使用广播(打扰所有设备) → NDP使用组播(只打扰目标设备所在的组播组) 车载网络带宽更宝贵,NDP的组播机制比ARP的广播机制更友好

4.4 双栈环境下的避坑指南

在实际项目中,双栈不是配好就能跑的。我总结了几条血泪教训:

  1. DNS解析顺序:很多应用默认优先IPv6,但如果IPv6路由不通,就会超时。我建议在/etc/gai.conf里把IPv4优先级调高,或者让应用层做fallback。
  2. NDP邻居缓存大小:车载ECU的内存有限,默认的NDP缓存可能只有几十条。如果网络里有上百个节点,缓存满了就会丢包。记得根据实际节点数调大net.ipv6.neigh.default.gc_thresh3。
  3. ARP表与NDP表的互斥:同一个目标,如果同时有IPv4和IPv6地址,ARP表和NDP表是各自独立的。别指望查ARP表能找到IPv6邻居的信息。
  4. RA报文间隔:路由器发送RA报文的默认间隔是200秒。在车上,这个间隔太长了。ECU上电后可能等很久才知道网关是谁。我一般把RA间隔调到30秒,同时配合net.ipv6.conf.all.forwarding=1让ECU主动发RS。

一句话总结:IPv4/IPv6双栈是车载网络绕不开的现实。ARP和NDP虽然干的事差不多,但NDP更高效、更安全。在车上,我建议优先用IPv6 + NDP,但保留IPv4做兼容兜底。