一张路由表配错,车载网关让CAN报文跨域乱跑

一张路由表配错,车载网关让CAN报文跨域乱跑
2025年4月某自主品牌在OTA升级后收到了大量售后投诉部分车辆仪表盘偶尔闪现车道保持不可用的黄色告警持续2-3秒后自行消失。排查费时三周——最后在网关的路由规则表里找到了罪魁祸首。升级后的固件中网关的动力域→车身域的转发规则里多了一条通配路由0x1** → BodyCAN。本意是将ESP的制动辅助信号转发给车身域做舒适联动但0x1**这个掩码覆盖了动力域上包括ABS、BMS、MCU在内的27个CAN ID。其中BMS每100ms上报的电池组温度帧(0x180)被转发到了车身域总线上与原本车身域BCM使用的同ID自定义帧发生了碰撞——车身域总线上同时出现了两个0x180帧BCM在仲裁失败后进入Bus Off触发了车道保持降级。这是一次教科书级的网关路由配置事故。但反过来说如果网关根本就没有这条路由规则——或者有但经过了严格的掩码限制——这次事件根本不会发生。一、车载网关的架构与路由模型现代车辆通常采用域集中式E/E架构网关是各域间通信的唯一通道┌──────────┐ ┌──────────┐ ┌──────────┐ │ 动力域 │ │ 车身域 │ │ 信息娱乐域 │ │ CAN-FD │ │ CAN 500k │ │ CAN 500k │ │ 2Mbps │ │ │ │ │ └────┬─────┘ └────┬─────┘ └────┬─────┘ │ │ │ └──────┬──────┴──────┬──────┘ │ │ ┌───┴─────────────┴───┐ │ 中央网关 │ │ (Gateway MCU) │ │ CAN ×5 ETH ×2 │ └─────────────────────┘网关的核心职责不只是转发而是有选择地转发。路由规则定义了哪些CAN ID可以从域A转发到域B转发时可以修改哪些字段转发的速率限制是多少转发优先级是否降低二、路由规则引擎的实现在实际项目中网关路由表通常是一张白名单——默认拒绝所有只放行明确定义的规则。/* 车载网关路由规则引擎 - 白名单模型 */#defineMAX_ROUTE_RULES256#defineROUTE_MASK_FULL0xFFFF// 全掩码 精确匹配typedefenum{CAN_IF_POWER0,// 动力域CAN接口CAN_IF_BODY1,// 车身域CAN接口CAN_IF_INFOTAIN2,// 信息娱乐域CAN接口CAN_IF_DIAG3,// 诊断CAN接口CAN_IF_MAX}can_interface_t;typedefstruct{uint16_tsrc_can_id;// 源CAN IDuint16_tsrc_can_mask;// 源ID匹配掩码can_interface_tsrc_if;// 源域接口can_interface_tdst_if;// 目标域接口uint16_tnew_can_id;// 转发后ID (0保持不变)uint8_trate_limit_hz;// 转发速率限制(Hz), 0无限制uint8_tpriority_drop;// 优先级降级(0-7), 0不降级uint8_tenabled;// 1启用chardesc[32];// 规则描述}route_rule_t;/* 白名单路由表 - 每个规则精确描述一条转发路径 */staticroute_rule_troute_table[]{// ESP车速信号 → 车身域 (用于自动落锁){0x1A0,ROUTE_MASK_FULL,CAN_IF_POWER,CAN_IF_BODY,0x1A0,10,0,1,ESP_Speed_to_Body_Lock},// BMS SOC信号 → 信息娱乐域 (用于仪表盘电量显示){0x180,ROUTE_MASK_FULL,CAN_IF_POWER,CAN_IF_INFOTAIN,0x180,2,0,1,BMS_SOC_to_Infotain},/* 下面这条就是事故原因 - 掩码太宽 */// {0x100, 0xF00, CAN_IF_POWER, CAN_IF_BODY,// 0x100, 0, 0, 1, POWER_BCAST_to_Body}, // 错误覆盖了太多ID/* 正确写法 - 精确匹配每一个需要转发的ID */{0x1A1,ROUTE_MASK_FULL,CAN_IF_POWER,CAN_IF_BODY,0x1A1,10,0,1,ESP_BrakeSig_to_Body},{0x1A2,ROUTE_MASK_FULL,CAN_IF_POWER,CAN_IF_BODY,0x1A2,10,0,1,ESP_YawRate_to_Body},};/* 路由检查函数 - 每个经过网关的CAN帧调用 */intgateway_route_check(can_interface_tsrc_if,uint16_tcan_id,can_interface_t*dst_if,uint16_t*new_can_id){for(inti0;isizeof(route_table)/sizeof(route_rule_t);i){constroute_rule_t*rroute_table[i];// 源接口和ID都匹配if(r-enabledr-src_ifsrc_if(can_idr-src_can_mask)(r-src_can_idr-src_can_mask)){*dst_ifr-dst_if;*new_can_id(r-new_can_id0)?can_id:r-new_can_id;return0;// 放行}}return-1;// 拒绝转发}这条代码的关键教训是src_can_mask的值设定。用0xF00作掩码时0x100-0x1FF的所有帧都会被匹配——这正是出事那条通配路由的写法。三、域隔离的防火墙策略路由白名单只是第一层。第二层是域间防火墙——对转发的帧做内容级别的检查。/* 域间防火墙 - 内容过滤 */typedefstruct{uint16_tcan_id;uint8_tbyte_offset;// 检查的起始字节uint8_tbyte_len;// 检查的字节数uint8_tmin_val[8];// 各字节最小值uint8_tmax_val[8];// 各字节最大值uint8_tcheck_rate;// 采样率 (1全检, 101/10采样)}firewall_rule_t;staticfirewall_rule_tfirewall_rules[]{/* BMS帧(0x180)的Byte0电池电压高字节, 正常400-500V (0x190-0x1F4) */{0x180,0,2,{0x01,0x90},{0x01,0xF4},1},/* 车速信号 Byte2-3, 正常0-240km/h (0-240) */{0x1A0,2,2,{0x00,0x00},{0x00,0xF0},5},};intfirewall_content_check(uint16_tcan_id,constuint8_t*data,uint8_tdlc){for(inti0;isizeof(firewall_rules)/sizeof(firewall_rule_t);i){constfirewall_rule_t*rfirewall_rules[i];if(r-can_id!can_id)continue;if(dlcr-byte_offsetr-byte_len)continue;for(intb0;br-byte_len;b){if(data[r-byte_offsetb]r-min_val[b]||data[r-byte_offsetb]r-max_val[b]){return-1;// 内容异常丢弃该帧}}}return0;}防火墙过滤了超出正常物理范围的信号值。在开头的BMS帧碰撞事件中如果防火墙规则也在运行——它会发现车身域BMS帧的电压值不在400-500V范围内车身域根本没有电池从而拦截。四、三层纵深防御架构综合路由白名单、域间防火墙、速率限制网关的三层防御架构如下防御层机制拦截对象延迟开销Layer 1路由白名单未授权的ID/CAN-IF对5μsLayer 2域间防火墙合法ID但异常载荷3μsLayer 3速率限制器合法ID合法载荷但频率异常2μs总计10μs三层总延迟10μs在500kbps CAN总线上对应约0.5位时间对报文转发时序几乎没有影响。五、踩坑记录坑1网关自身CAN ID冲突网关本身也是一个CAN节点也有自己的通信ID。某车型网关使用0x700作为心跳帧但诊断CAN总线上0x700是UDS Bootloader的保留ID——接入诊断仪时网关心跳和Bootloader响应帧在诊断总线上碰撞。解决方案极其简单网关在每个CAN接口上使用不同的诊断响应ID接口号基地址偏移。坑2路由规则数量爆炸最初设计时以为一个车型最多50条路由规则实际量产时发现需要230条每个车型配置不同。但网关MCU的Flash只有2MB路由表太大挤占了OTA分区的空间。优化方案是压缩路由表表示——将连续的CAN ID用范围表示起始ID数量将路由表从230条压缩到67条。坑3防火墙规则误拦OTA帧防火墙配置了对0x7DFUDS功能寻址的速率限制限制10Hz但OTA期间诊断仪以100Hz发送0x7DF帧。OTA流程走到一半时网关开始丢诊断帧导致SBL擦除超时。修复方案是设置维护模式标志位进入OTA/诊断模式时临时放宽防火墙限制。结语车载网关的安全不只是配好路由表这么简单。路由规则的错误配置、防火墙的边界条件、速率限制对正常业务的误伤——这些问题在实车验证阶段才会暴露而一旦暴露就可能影响行驶安全。关于车载网关的域隔离你更倾向于硬件防火墙芯片如NXP SJA1110内置规则引擎“还是MCU纯软件方案”成本与灵活性的取舍各有道理。欢迎评论区讨论。