简介这份 bridge-utils-1.0.4-rc3.tar.gz 是面向 Linux 网络管理、虚拟化部署与网络实验学习者的桥接控制工具源码包围绕 brctl 命令解决网桥创建、端口管理以及生成树、虚拟局域网等配置问题适合具备一定系统管理基础、希望深入理解桥接机制的中高级读者。压缩包共 47 个文件约 157KB以 8 个 C 源文件、7 个配置模板和 3 个头文件为核心并附带测试脚本与说明文档整体构成从编译配置、核心库实现到功能验证的较完整源码结构。目前已有 273 人学习下载说明其在桥接工具学习中具有一定参考价值。读者可从中获取 brctl 及其底层库函数的实现代码梳理用户态命令与内核桥接子系统之间的调用关系结合测试脚本观察桥接命令的实际行为并借助说明文档理解网桥在虚拟机通信、网络隔离与故障排查中的使用边界其中核心库负责设备接口与桥接实例管理命令工具封装常用操作测试用例覆盖功能与压力场景便于按模块追踪实现细节。轻量目录也便于分层阅读适合作为桥接功能定制、参数含义梳理与源码级学习的参考资料并辅助实验环境搭建与问题定位理解二三层转发与广播域隔离等基础概念。1. 内核先点头bridge-utils 1.0.4-rc3 不是解压就能 make 的东西有台机器要挂虚拟机某开发者上去就敲brctl addbr br0回了一句add bridge failed: Package not installed。他以为是 bridge-utils 没装翻出 bridge-utils-1.0.4-rc3.tar.gz 解压、./configure、make结果第一屏就停在checking for linux/if_bridge.h... no。一个一百来 K 的小源码包卡了两个多小时。装 bridge-utils 这件事真正难的不是 make是它前面挂着三层前置内核里得有 bridge 模块系统里得有匹配的内核头文件编译链里得有一套能编 C 的 gcc/make。三层任意一层缺brctl 都装不起来或者装起来了也建不了桥。这套环境在虚拟机宿主机、容器网络、二层透传这些场景里天天遇到装不好最直接的后果就是网卡被桥接搞丢机器失联。这篇适合两类人看要在一台老机器上把 brctl 重新编出来的运维以及手上拿着内核头文件、想搞清 configure 到底在找什么的人。2. 编译前的环境清点模块、头文件与工具链拿到源码包先别急着./configure花五分钟把环境点一遍比后面猜报错快得多。这一章按「内核 → 头文件 → 编译工具」的顺序走每一步都给可执行的检查命令跑完心里就有底。2.1 先确认内核里的 bridge 模块在不在brctl只是用户态的一个小程序它干的所有事都是通过 ioctl 交给内核的 bridge 子系统去办。内核里没有这个子系统brctl 编得再漂亮也只能返回一个笼统的错误。# 1. 看内核版本后面所有路径都依赖它 uname -r # 2. 先看是否编译进内核y还是编成模块m # 有 /proc/config.gz 的系统走第一种没有就走第二种 zcat /proc/config.gz | grep -E CONFIG_BRIDGE grep -E CONFIG_BRIDGE /boot/config-$(uname -r) # 3. 是模块的话看看 .ko 在不在然后加载 ls /lib/modules/$(uname -r)/kernel/net/bridge/ modprobe bridge # 4. 确认加载成功 lsmod | grep -E ^bridge第一步uname -r不是走流程后面找头文件、找模块目录全指望它。第二步的两种读法要按发行版选打开/proc/config.gz需要内核开了CONFIG_IKCONFIG_PROC没开就只能读/boot下那份。输出的值有两种y表示已经被编进内核主体这种情况下/lib/modules/.../bridge/目录里不会有bridge.ko别以为装漏了m才需要用modprobe加载。第四步的^bridge锚点是必要的因为系统里可能同时存在br_netfilter、bridge两个模块不锚定会看混。顺带一句br_netfilter不是装 brctl 的必需项但如果这台机器后面要让 iptables 管桥上的流量通常的做法是把它一起加进开机加载echo br_netfilter /etc/modules-load.d/bridge.conf这种写法在各发行版上都能用。如果第 2 步的输出是空的那就别往下走了内核根本没编 bridge 子系统得先换内核或者装带 bridge 的内核包。2.2 内核头文件与 gcc 工具链的版本取舍configure那行checking for linux/if_bridge.h... no就是在找这个头文件。它有两个常见来源优先级不一样来源典型路径适用场景发行版内核头文件包/usr/include/linux/if_bridge.h日常编译最省事内核源码树 build 目录/lib/modules/$(uname -r)/build/include/uapi/linux/if_bridge.h头文件包缺失、或要跟内核严格对齐先查第一个ls -l /usr/include/linux/if_bridge.h # 顺带把头文件里的关键定义看一眼确认不是个空壳 grep -n SIOCBRADDBR\|SIOCBRADDIF /usr/include/linux/if_bridge.hSIOCBRADDBR和SIOCBRADDIF这两个 ioctl 号是 brctl 干活的核心头文件里只要有这两行编译就不会因为缺定义失败。如果文件不存在装内核头文件包即可包名在多数发行版里叫kernel-headers或linux-headers带上uname -r的版本号装别装成通用那份。工具链这边要注意的是 gcc 版本。1.0.4 这个年代的代码是 C89 风格函数声明散落、变量声明在块首用现在的 gcc 编会刷出一屏implicit declaration of function和old-style function definition。这些绝大多数是警告不影响生成二进制但某些发行版默认开了-Werror的构建策略警告就变成了错误。我一般的处理是不去改源码直接在 configure 时压掉# 关掉把警告当错误的开关同时把标准压回 gnu89 ./configure CFLAGS-O2 -g -stdgnu89 -Wno-error-stdgnu89让 gcc 用老标准解析能消掉大部分 KR 风格的抱怨-Wno-error是兜底防止环境里某个全局 CFLAGS 把警告提级。-O2 -g是常规的优化加调试符号出问题时还能gdb看一眼。还有一个版本差异值得提前说清1.0.4 这一支的 brctl 全程走 ioctl不依赖 libsysfs。如果你手上换成了 1.4 之后的包configure会额外去找libsysfs缺了会报checking for sysfs_open_device in -lsysfs... no那时候才需要装sysfsutils的开发包。这两件事别混混了会在错误的方向上折腾半天。2.3 解压位置与 configure 参数怎么配解压别放在/tmp也别放在家目录。这套东西装完是要进/usr/sbin的源码留在/usr/local/src下将来想重编、想对照版本都方便。# 建一个固定的源码存放点后面重编还回这儿 mkdir -p /usr/local/src tar -xzf bridge-utils-1.0.4-rc3.tar.gz -C /usr/local/src cd /usr/local/src/bridge-utils-1.0.4-rc3 # 先看这个版本的 configure 支持哪些参数别照抄网上的 ./configure --help | head -40 # 正式配置二进制进 /usr/sbinman 页进 /usr/share/man ./configure \ --prefix/usr \ --sbindir/usr/sbin \ --mandir/usr/share/man--prefix/usr而不是默认的/usr/local原因是 brctl 属于系统管理工具放/usr/local/sbin会跟 PATH 顺序打架——某些系统的 root PATH 里/usr/local/sbin排在/usr/sbin后面将来装了新版 brctl 却一直在调老的那个排查起来非常费劲。--sbindir和--mandir是把这两个子目录从 prefix 里剥出来单独指定老版本 autoconf 生成的脚本对这两个变量支持是稳的。--help | head -40这一步别省。老包和新包的参数集不一样网上抄来的--with-linux-headers在这个版本里未必存在先看再写能省掉一次unrecognized option的报错。如果确实看到了这个参数而系统里又没有标准的头文件包那就用它指向内核源码树# 仅当 configure --help 里确实有 --with-linux-headers 时才这么写 ./configure --prefix/usr \ --with-linux-headers/lib/modules/$(uname -r)/build这个参数的语义是告诉 configure「去哪找linux/if_bridge.h」它最终会变成-I拼进编译命令。指向 build 目录时要留意内核源码树里的头文件在include/uapi/下面老版本 configure 可能只认include/所以更保险的做法还是回到 2.2 节直接用 CFLAGS 把路径塞进去-I/lib/modules/$(uname -r)/build/include/uapi这一条写在 CFLAGS 里比赌 configure 的探测逻辑靠谱。configure 跑完会打印一份摘要重点看两行checking for linux/if_bridge.h... yes和最后那行config.status: creating Makefile。第二行出现说明 Makefile 已经生成可以进入编译。3. 编译与安装make 报错的三条修正路径与产物落点环境清点完编译这一步反而是最短的。但短不代表不会翻车这一章把 configure 失败、make 失败、install 之后找不到命令这三种情况拆开讲每种都给具体的修正动作。3.1 configure 检测失败时的三条修正路径checking for linux/if_bridge.h... no是最常见的拦路虎按代价从低到高有三条路。第一条装对应版本的头文件包。这是最干净的做法装完头文件落在/usr/include/linux/下configure 默认就会去那儿找# 版本号必须和 uname -r 对得上装通用包没用 apt-get install -y linux-headers-$(uname -r) # Debian 系 # 或者 yum install -y kernel-devel-$(uname -r) # RedHat 系 # 装完确认文件真的落地了 ls -l /usr/include/linux/if_bridge.h第二条头文件包装不上老内核源已下架、离线机器没有源就手动指路径。这时候别指望 configure 的参数直接改 CFLAGS# 把内核 build 目录的 uapi 子目录加进头文件搜索路径 ./configure --prefix/usr \ CFLAGS-O2 -g -stdgnu89 -I/lib/modules/$(uname -r)/build/include/uapi这里-I后面必须是include/uapi这一层不是include。较新的内核把对外暴露的 uapi 头文件整体挪进了uapi/子目录老的路径下面要么没有if_bridge.h要么是个转发用的空壳。第三条从别的机器拷一份头文件过来。这条我不太推荐但离线环境里确实常用从一台内核版本接近的机器上scp一份/usr/include/linux/if_bridge.h过去放到相同位置。之所以能这么干是因为 brctl 用到的只是几个 ioctl 常量和struct ifreq这些东西在内核版本之间非常稳定。拷之前顺手diff一下两边的内核大版本差太多就别偷这个懒。3.2 make 与 make install产物落到哪、DESTDIR 怎么用配置过了编译本身很少出问题# 老包并行编译基本没问题用 -j2 保守一点出错了看得清是哪一条 make -j2 # 装到系统里 make install-j2而不是-j$(nproc)是因为这种几百行的老工程并行收益接近零但真出错的时候多线程输出会交错反而难定位。为了省几秒把日志搅乱不划算。make install会把brctl拷到--sbindir指定的目录同时装 man 页。如果是给打包用、不想污染当前系统就加DESTDIR# 装到一个临时根目录方便打包或者先检查产物 make install DESTDIR/tmp/bridge-stage # 看看到底装了什么 find /tmp/bridge-stage -type fDESTDIR是 makefile 层面的安装根它会把--prefix里写的路径整体挂在这个根下面。用它可以先看清单再决定要不要真装——老包的 makefile 偶尔会把东西装到意料之外的位置先 stage 一遍最稳。如果 make 阶段报的是undefined reference to sysfs_open_device这类链接错误那是你手上的包其实不是 1.0.4 这一支得回头补libsysfs开发包跟 2.2 节说的版本差异对一下号再动手。3.3 装完立刻做的两件事找得到、跑得起来安装完别急着建桥先确认两件事这两步能挡掉后面一大半命令找不到版本不对的麻烦。# 1. 确认系统 PATH 里调用的是刚装的那个而不是某个残留的旧版本 which -a brctl ls -l /usr/sbin/brctl # 2. 确认动态库依赖是齐的没有 not found ldd /usr/sbin/brctl # 3. 不带参数跑一次看它自己能列出哪些子命令 brctl第一步用which -a而不是which就是为了把 PATH 上所有同名程序都列出来。老机器上经常出现/usr/local/sbin/brctl和/usr/sbin/brctl并存的情况只跑which会掩盖问题。第二步的ldd输出里如果出现not found说明运行库缺失最常见的是libc.so.6版本不匹配在很老的系统上编、拿到更老的系统上跑。这时候要么在目标机上重编要么静态编一份。第三步不带参数直接跑 brctl它会把 usage 打出来。这比试--version更能说明问题usage 里列出的子命令就是这套 brctl 的全部能力。1.0.4 这一支的 usage 里不会有showstp之外的太多花活能看到addbr、delbr、addif、delif、show、showmacs、showstp、stp、setageing、setbridgeprio、setfd、sethello、setmaxage、setpathcost、setportprio这些就说明装对了。缺哪个多半是版本跟你以为的不一样。4. 把桥建起来addbr、addif、参数设置的一套顺序装完只是有了工具真正落地是建一座能用的桥。这一章的三个小节按「建 → 调 → 存」推进顺序不能乱乱一步最常见的结果就是主机失联。4.1 addbr / addif / up 的顺序不能乱建桥的标准流程是这样每一步都有它的道理# 1. 确保模块在重启后可能掉了 modprobe bridge # 2. 建桥 brctl addbr br0 # 3. 关键一步先把要加入桥的物理网卡 down 掉 ip link set dev eth1 down # 4. 把物理网卡挂到桥上 brctl addif br0 eth1 # 5. 起接口先起成员再起桥 ip link set dev eth1 up ip link set dev br0 up # 6. 看结果 brctl show ip link show br0第 3 步是最容易被跳过的一步。之所以要先 down是因为网卡处于 up 状态时可能带着 ARP 缓存、组播成员关系和一整套队列状态直接塞进桥里在老内核上会报device or resource busy在新内核上虽然能过但瞬时会有几秒钟的流量黑洞。养成先 down 再 addif 的习惯能省掉一类加进去了但就是不通的玄学问题。第 5 步的起接口顺序也有讲究成员先 up、桥后 up。反过来的话桥会先进入转发状态而成员还没准备好STP 会重新收敛一次白白多等几十秒。brctl show的输出是三列桥名、bridge id、STP 状态下面挂一行eth1interfaces那一栏里能看到它。ip link show br0看到的是state DOWN还是UP如果 addbr 之后忘了第 5 步桥是 DOWN 的什么流量都不会过。这里有个必须提前说的血泪经验物理网卡上原有的 IP 地址不会自动迁移到桥上。如果你把eth1带着管理 IP挂进br0机器的管理地址会跟着 eth1 一起沉到桥里从外部直接失联。正确做法是在挂之前先把 IP 从 eth1 上摘掉挂完再配到 br0 上# 先记住原地址再摘掉 ip addr show eth1 ip addr del 192.0.2.10/24 dev eth1 # 挂进桥之后把地址配到桥上 ip addr add 192.0.2.10/24 dev br0 ip route add default via 192.0.2.1这套顺序在远程操作时必须一次敲对所以我的习惯是把这几条写成脚本nohup起一个延时回滚任务再执行真出问题机器自己会把配置退回去。4.2 STP、forward delay 与 ageing time 的参数取舍桥建起来默认就能转发但参数是默认值很多场景下不合适。# 开 STP防止误接成环 brctl stp br0 on # 转发延迟默认 15 秒虚拟机场景压到 2 秒 brctl setfd br0 2 # hello 时间STP 交换 BPDU 的间隔默认 2 秒 brctl sethello br0 2 # 最大老化时间默认 20 秒 brctl setmaxage br0 20 # MAC 地址学习表老化时间默认 300 秒 brctl setageing br0 300 # 桥优先级数值越小越可能成为根桥 brctl setbridgeprio br0 32768setfd是这里最值得改的一个。默认 15 秒的转发延迟加上 listening 和 learning 两个阶段一座新桥从起到真正转发流量要等 30 秒左右。在虚拟机宿主机上这个等待非常难受——虚机网卡刚起来DHCP 请求已经发完三轮了桥还没进入 forwarding 状态。压到 2 秒是常见做法代价是拓扑变化时的收敛保护变弱物理交换机互联的场景别这么干。setageing决定 MAC 地址表里的条目多久没被刷新就丢掉。默认 300 秒适合稳定的物理网络如果这台机器上虚机频繁创建销毁、MAC 地址一直在变表会越积越大压到 60120 秒更合适。反过来如果桥两端是跨机房的慢速链路老化太快会导致大量泛洪。stp在只有两个端口的简单桥接场景里其实可以关掉关了就没有 30 秒等待也没有 BPDU 开销。但只要桥接的网段有可能出现第二条路径比如两台宿主机之间不小心接了两根线就必须开否则广播风暴几秒钟就能把整段网络打瘫。这里再强调一次版本差异1.0.4 这一支的 brctl 通过 ioctl 设置参数设完之后没法从 sysfs 读回来。想在运行时确认参数生效只能用brctl showstp br0# 1.0.4 下这是唯一能看参数的手段 brctl showstp br0输出的bridge br0段落里会有designated root、hello time、max age、forward delay这几行跟你设的值对一遍。1.4 之后的版本参数会落进/sys/class/net/br0/bridge/下的一堆文件里直接cat就能看那是另一套机制别拿新版本的排查经验套在老版本上。4.3 持久化重启之后桥还在的写法brctl建出来的桥是运行时状态重启就没了。持久化有三种路子按环境选。第一种写 systemd unit最通用不依赖发行版的网络脚本# /etc/systemd/system/bridge-br0.service [Unit] DescriptionCreate br0 and attach eth1 Afternetwork.target Beforenetwork-online.target [Service] Typeoneshot RemainAfterExityes # 建桥 ExecStart/usr/sbin/brctl addbr br0 # 挂端口前先把成员 down 掉和手工操作顺序保持一致 ExecStart/bin/sh -c /sbin/ip link set dev eth1 down ExecStart/usr/sbin/brctl addif br0 eth1 ExecStart/sbin/ip link set dev eth1 up ExecStart/sbin/ip link set dev br0 up # 参数 ExecStart/usr/sbin/brctl stp br0 on ExecStart/usr/sbin/brctl setfd br0 2 ExecStart/usr/sbin/brctl setageing br0 300 # 停止时的清理顺序和创建相反 ExecStop/usr/sbin/brctl delif br0 eth1 ExecStop/usr/sbin/brctl delbr br0 [Install] WantedBymulti-user.targetTypeoneshot配RemainAfterExityes是这类跑几条命令就完事的服务标准写法不加RemainAfterExit的话服务跑完就被标记为 inactivesystemctl status看着像失败了。Afternetwork.target保证网卡设备已经就绪Beforenetwork-online.target保证桥在依赖网络的服务起来之前就位。# 启用 systemctl daemon-reload systemctl enable --now bridge-br0.service # 验证手动重启一次再查 systemctl status bridge-br0.service brctl show第二种走发行版自带的网卡配置在对应的配置文件里加BRIDGEbr0之类的字段。这种做法在发行版之间写法差异很大而且不同版本的脚本对 brctl 参数的暴露程度不一样setfd、setageing这类细粒度参数经常没地方写。我一般只在必须跟已有配置体系保持一致时才用它。第三种把上面的 unit 换成一段/etc/rc.local里的命令。虽然老派但在一堆没有 systemd 的老机器上这是唯一可行的一招写完记得chmod x /etc/rc.local。5. 排查现场brctl 五个报错的现象、原因与解前面按正常流程走完了这一章专门对付不正常的情况。下面五条都是我自己或者身边人真遇到过的现象、原因、解决按顺序写对着报错关键词找就能命中。5.1add bridge failed: Package not installed现象brctl addbr br0直接返回这行命令退出码非零brctl show也是空的。原因这行报错来自内核返回的ENOPKG字面意思是包没装实际指的是内核里的 bridge 子系统不存在。两种情况会撞上内核编译时没开CONFIG_BRIDGE或者开成了模块但没加载。解决先按 2.1 节的命令查CONFIG_BRIDGE。是m就modprobe bridge加载完再试是y还报这个错那说明当前跑的内核跟/boot下的配置对不上换过内核没重启uname -r和/boot里的文件名对一遍。配置里压根没有这一项就只能换内核。5.2add bridge failed: Operation not permitted现象主机上能建桥进到某个容器或者某个 network namespace 里同样的命令报权限错误。原因建桥需要CAP_NET_ADMIN能力。容器默认的能力集里通常没有它另外如果/proc/sys是以只读方式挂进来的桥接相关的 sysctl 也写不进去会连带出一串失败。解决容器场景下要么用--cap-addNET_ADMIN起要么直接把网络交给宿主机管容器里只做业务。namespace 场景下用ip netns exec时要确认是有特权的 shell。这条不用深究本质是权限边界不是 brctl 的问题。5.3 挂完端口主机直接失联现象远程 SSH 敲完brctl addif br0 eth0连接立刻断ping 也不通只能去机房接显示器。原因eth0上配着管理 IP挂进桥之后这个 IP 就变成了桥成员上的地址内核不再用它响应外部请求。这是最常见也最致命的一个坑跟 brctl 版本无关纯配置顺序问题。解决按 4.1 节写的那样先摘 IP、再挂端口、最后把 IP 配到 br0 上。已经失联的话本地登录进去执行brctl delif br0 eth0把 IP 从 br0 上删掉、重新配回 eth0网络就回来了。从那以后我远程改桥配置一律先挂一个sleep 300 回滚命令的定时任务五分钟内不取消就自动退回去。5.4 参数设了不生效/sys/class/net/br0/bridge/也读不到现象brctl setfd br0 2执行成功没报错但抓包看桥还是等了三十秒才转发想cat /sys/class/net/br0/bridge/forward_delay确认提示文件不存在。原因1.0.4 这一支的 brctl 只用 ioctl参数存在内核的运行态结构里不往 sysfs 暴露。/sys/class/net/br0/bridge/那套文件是后来的版本配套的内核接口老工具配新内核时会出现工具不写、内核不建的错位。解决用brctl showstp br0看参数这是老版本唯一可靠的读取方式。真要落到 sysfs 上就得换成 1.4 之后的 brctl或者直接用ip link set br0 type bridge forward_delay 200这种 iproute2 写法。两种工具别混着用混用会出现一边设了另一边看不到的情况。5.5brctl show里端口在但状态一直是 disabled现象brctl show能看到eth1brctl showstp br0里eth1那一节的state却是disabled流量不通。原因三个常见来源——成员网卡本身没 up网卡已经被别的桥或 bond 占用了物理链路本身没起来网线没插、对端交换机端口关着。解决先ip link show eth1看state是 DOWN 就ip link set eth1 up再看brctl show里有没有别的桥也挂着 eth1有就先delif摘掉最后ethtool eth1看Link detected是 no 就是物理层的事跟 brctl 无关。6. 装完怎么验证三层验证确认桥真的在转发到这一步 brctl 装好了、桥也建起来了但命令不报错和桥能用是两件事。我的习惯是分三层验每层用一种手段全过了才算这套环境真的跑通。第一层验结构看桥和端口的组织关系对不对# 桥列表br0 在STP 状态和 interfaces 数量对得上 brctl show # 每个成员端口的状态和开销 brctl showstp br0 # 接口层面确认桥是 UP 的 ip -br link show br0 ip -br link show eth1ip -br是简写输出一行一个接口比完整输出快得多。这一层主要抓端口挂错桥桥是 DOWN成员没 up这类结构性问题命令全绿才能往下走。第二层验转发看数据真的过不过# 在桥的一端抓包加上 -e 把 MAC 头打出来 tcpdump -i br0 -e -nn icmp # 另一端发起 ping ping -c 4 192.0.2.20-e这个参数是关键它会把源 MAC 和目的 MAC 打出来。看到请求包进去、应答包出来且两边的 MAC 都对得上说明桥在二层正常转发。只看到请求看不到应答问题多半在对端而不是桥上。这条命令我一般会一直挂着边测边看比事后翻日志直观。第三层验学习看 MAC 地址表有没有正常建立# 看桥学到了哪些 MAC以及它们挂在哪个端口上 brctl showmacs br0输出里每一行是一个 MAC 条目port no那一列对应端口编号is local?那一列标出是不是桥自己的地址。正常转发的桥跑完第二层的 ping 之后表里应该能看到对端的 MAC 挂在正确的端口上ageing timer那一列在倒数。如果表一直是空的说明流量根本没进桥如果表里有条目但端口号不对说明网络里存在环路得回头查 STP。三层验完我通常还会加一个重启验证reboot一次起来之后不敲任何 brctl 命令直接brctl show和ip -br link show br0。这一步验的是持久化配置4.3 节那个 unit到底有没有生效。很多人的桥在手工配置下跑得好好的一重启就没了前面所有测试白做。下面这张表是我自己用的验收清单每次装完照着对一遍层次检查项命令期望结果安装调用的是新装的 brctlwhich -a brctl只有/usr/sbin/brctl一个安装动态库无缺失ldd /usr/sbin/brctl无not found结构桥存在且 UPip -br link show br0br0 UP结构成员正确挂载brctl showinterfaces 列出现 eth1参数转发延迟等生效brctl showstp br0forward delay 为设定值转发二层数据可达tcpdump -i br0 -e -nn icmp双向报文可见学习MAC 表建立brctl showmacs br0对端 MAC 挂在正确端口持久化重启后仍在reboot后brctl show自动恢复为 bridge-br0.service这张表里最后一行才是真正拉开差距的地方前面七项手工都能过第八项过了才算这套安装真的交付出去。装完 bridge-utils 1.0.4-rc3 这套东西踩过的坑比命令本身多得多尤其是物理网卡 IP 迁移和参数读不回来这两处几乎每次换机器都要重新确认一遍。从那以后我每次装完不管多急都强制把三层验证加一次重启跑一遍宁可多花十分钟也不想半夜被告警叫起来。希望帮到你。本文还有配套的精品资源点击获取
阅读完成 · 觉得有帮助?