Linux ipvlan L2 vs L3 模式的 bridge 与 promiscuous 模式需求

1次阅读

必须开 promiscuous,因 ipvlan l2 模式依赖宿主机网卡接收匹配容器 mac 的帧,而物理口 mac 与容器不同,不开启则驱动丢弃帧;l3 模式无需混杂模式,靠 ip 路由转发。

Linux ipvlan L2 vs L3 模式的 bridge 与 promiscuous 模式需求

ipvlan L2 模式下必须开 promiscuous 吗?

必须开,但不是因为协议限制,而是因为 linux 内核的 ipvlan L2 实现依赖宿主机网卡接收所有目标 MAC 匹配的帧——而容器/子接口的 MAC 与宿主机物理口 MAC 不同,不开启混杂模式(promiscuous),网卡驱动会直接丢弃这些帧。

常见错误现象:ping 宿主机通、容器间不通,tcpdump -i eth0 看不到发给容器的 ARP 或 IP 包;ip link show eth0 显示 PROMISC 标志缺失。

  • 开启方式:运行 ip link set eth0 promisc on(注意:重启网络服务或网卡可能重置该状态)
  • bridge 不参与转发:L2 模式下 ipvlan 不走 bridge 设备,哪怕你创建了 br0 并把物理口加进去,只要用的是 ipvlan L2,bridge 就是冗余的,还可能干扰 MAC 学习
  • 兼容性注意:某些云厂商网卡(如 AWS ENA、azure Accelerated Networking)禁用 promiscuous,L2 模式根本不可用

ipvlan L3 模式为什么可以关 promiscuous?

L3 模式不依赖 MAC 层交付,内核直接根据目的 IP 查路由表,匹配到 ipvlan 子接口后做三层转发。物理网卡只收发自己 IP 对应的包(或广播/组播),不需要接收其他 MAC 的帧。

使用场景:多容器共享宿主机公网 IP、需严格隔离二层广播域、对接不支持 promisc 的虚拟化平台。

  • 典型配置:宿主机 eth0 配 IP,ipvlan 子接口(如 ipvlan0)配不同网段 IP,启用 sysctl -w net.ipv4.conf.eth0.forwarding=1
  • 关键区别:ip link add link eth0 ipvlan0 type ipvlan mode l3 —— 必须显式指定 mode l3,否则默认是 L2
  • 性能影响:L3 模式绕过桥接和 MAC 学习,转发路径更短,但无法跨子网二层通信(比如容器不能直连同一交换机下的另一台物理机的 MAC)

bridge 设备在 ipvlan 场景里到底有没有用?

绝大多数情况下没用,强行加反而出问题。ipvlan 是独立于 bridge 的网络类型,它的子接口不挂载到 bridge 上,也不受其 STP、FDB 表影响。

容易踩的坑:dockerdpodman 默认用 bridge 驱动,如果手动配了 ipvlan 却又让容器连到 docker0,结果就是双网络混乱,流量走向不可控。

  • 真要用 bridge:只在 L3 模式下,且仅用于连接多个 ipvlan L3 子接口(例如把 ipvlan0ipvlan1 加进 br0 做内部互通),此时 br0 相当于一个纯三层路由器的“内部接口”,不对外暴露
  • 别碰 brctl addif:ipvlan 接口不能被 brctlip link set master 加入传统 bridge,会报错 Operation not supported
  • 替代方案:需要二层互通时,用 macvlan;需要灵活策略路由时,用 L3 + ip rule + 多张路由表

怎么验证当前 ipvlan 是 L2 还是 L3?

看创建命令和运行时属性。内核不会在 ip link show 里直接写 “L2” 或 “L3”,得靠线索交叉判断。

常见错误现象:用 mode l3 创建却仍要开 promiscuous,大概率是创建时没生效(比如命令输错、旧接口残留、命名空间没切对)。

  • 查创建参数:ip link show ipvlan0 输出中若含 ipvlan mode l3 字样,说明是 L3;若无,基本是 L2(默认)
  • 查设备类型:cat /sys/class/net/ipvlan0/device/name 返回 eth0 是正常;若返回 br0,说明误绑到了 bridge 上,已失效
  • 快速验证:关闭 promisc 后,从外部 ping ipvlan 接口 IP —— 通则是 L3,不通且 tcpdump 在物理口看不到包,基本确定是 L2 且 promisc 关了

最麻烦的点往往不在模式选型,而在网络命名空间隔离没做好:宿主机路由、iptables 规则、netns 切换时机,都可能让看似正确的 ipvlan 配置静默失效。

text=ZqhQzanResources