开源无线路由器固件上 Bug 的故事(二)

上一篇文章花了很大的气力讲了开放源代码第三方家用无线路由器固件的基本情况和绕过这个 bug 的办法。绕过 bug 在很多时候不失为一种有效的选择,特别是像之前我遇到的情况:开发组在一年内都没有对 bug report 作出任何响应。所以在失望之余也只好另辟奚径了,再用俗话说一遍就是“惹不起,躲得起”。 😉

下面把话说回来,毕竟文章的主题是 Bug 的故事,所以还是要接着往下说。只是后面的东西更偏向于技术,所以比较枯燥一点。

3. Bug 的认定和定位

这个 Bug 之所以让我记恨于心,的确是因为它太复杂了:从 bug 的发现认定,到 bug 定位和 bugfix,由于没有正式的官方支持,OpenSource Community 这种散兵游勇的开发全靠分散在各地的个人,每一步的进展都很艰难。

这个 Bug 造成的问题是目的MAC地址为 00-80-C2-00-00-03 的 802.1X 多播认证包被无线路由器丢弃(不会转发到 WAN 口),这样在路由器上运行的 Supplicant 程序在发出 logon request 之后便再也收不到回复。问题其实很明显,因为使用同一个程序,把网线插到 PC  上便能通过认证,显然就是路由器处理的问题。

那为什么说 bug 认定是一件麻烦事呢?因为后来才确定这个 bug 只存在于 Broadcom® 公司的 Roboswitch™ 系列交换芯片中。早期的 Linksys WRT54G 路由器使用的是 ADM6996L 交换芯片(ADMTek 已经被 Infineon 收购),在进行认证的时候是没有问题的。所以这个问题在此型号的机器上无法重现,再加上大家都从软件角度来思考(其实这是个硬件问题)。最后导致了两种声音:一种声音坚定地说自己遇到了 OpenWRT 的 bug,另一种声音说,这个 bug 在我的机器上无法重现,不能认定。这两种声音可以在 OpenWRT Trac 上的 Ticket 1862 看到。

 接下来有人发现“It has also worked for me on WRT54G 1.0-2.0. On WRT54G 4.0 it does not work.”,大家这才意识到这是 BCM5325 交换芯片搞的鬼。后来的 BCM5352 和 BCM5354 芯片内部都集成了一个交换模块,因此也理所当然地继承了这个 bug 。

修订:根据 jacky235 的消息,8230-4 和 WZR-G108 使用了 BCM5325A2KQM 交换芯片,但可以通过认证。而 OpenWRT Ticket 1862 上出现问题的是 BCM5325E 交换芯片,此芯片支持额外的管理功能和 802.1x EAPOL filtering 。所以将出问题的交换芯片定位到 BCM5325E 上面。集成了交换芯片的 BCM5352 和BCM5354 依然有问题,这个我自己可以证实。

此 Bug 的产生机理是什么呢?其实话说回来,这本来是 Braodcom 设计出来的 feature ,目的是为了使交换芯片的工作模式更加灵活一些,可是 Broadcom 的保守和封锁让这个 feature 在这里适得其反。(关于bug 和feature 的辩证关系,请看 atppp 的文章)如果芯片工作在 Default Mode ,那么会丢弃 802.1x 认证多播包 00-80-c2-00-00-03 ,如果芯片工作在 Frame-Management Mode ,则会把此包转发到 Frame Management Port 。如此简单的逻辑

4. Bugfix 和当前问题

这个 bug 的修复就更棘手了。人们总算搞清楚了问题的所在,但就是没办法去修复它。因为你无论是 Google、Yahoo 还是百度都找不到详细的 BCM5325 芯片资料。所有宣称有 Datasheet 的网站上下载回来的只有两页纸的 Product Brief。这东东在 Broadcom 自己的网站上就能下载到,无非就是花一页纸吹了一下自己这个芯片有如何如何的 feature 云云,然后再花了一页纸作 Overview,扔一个架构图上去完事儿,真是印证了 Brief 这个词。

后来我才从某个网页上无意得知,Broadcom 的 Datasheet 一般是不公开的。只在有渠道的代理商那儿有,只有从人家那儿拿货然后签订一个保密协议,人家才会给你一份 PDF 文档。当然给你的文档是没法传播的:每一页纸上面都斜贯着长长的一串水印——谁泄露出去了谁承担责任。Broadcom 这招的确狠,可也给 bugfix 工作设置了最大的屏障。

针对这个 bug 给出解决方案的是 Jouke Witteveen。他的解决方案没有去 patch OpenWRT,而是给 wpa_supplicant 上的 wired Driver 作出了修正。他提出了一个新的 roboswitch driver 专门用于 Roboswitch 上的 802.1X 认证。我现在寝室里用的 Buffalo WHR-HP-G54 上就使用此程序通过了学校的 802.1X 认证。然后再运行一个 mytunet 来打开网关上的出校访问权限。这样就可以在全天时间使用无线网络了。(熄灯停电时除外……)

这个 bugfix 我用了大半年了,还是比较顺利的。只是最近在恩山无线论坛上看到了很多人受困于 H3C 和锐捷的私有 802.1X 认证。于是有人打算在路由器上运行 Linux 版的认证程序从而通过校园网认证。无奈的是这个 bug 再一次阻止了一大部分人的企图…… 很多人新买的路由器比如 WHR-HP-G54、WL-520gU、WHR-G125 等都有 roboswitch 的身影,移植过来的认证程序在 PC 上跑跑当然可以,可惜是没有针对性地解决 Broadcom roboswitch 的问题。自然也逃不过此 bug 的追杀,恩山上铩羽而归的人不在少数。

幸运一些的人有两种可能。一种是使用的 Belkin 7231-4p(不管有没有经过恩山无线的改版)它使用了 ADM6996L 交换芯片,没有此问题。另外一种是像 felix021 同学那样的,虽然路由器是使用 BCM5354 芯片的 WL-520gU,但校园网认证协议使用广播包(MAC为 FF-FF-FF-FF-FF-FF)而不是多播包。所有的交换模块接到了广播包当然是无条件转发。因此也能顺利通过认证。

不幸运的该怎么办呢? 😈  可以移植 Jouke Witteveen 在 roboswitch 中使用过的方法,在私有协议的认证程序中加入 Broadcom 芯片的支持,则有希望通过认证了。我已经跟 Jouke Witteveen 取得联系,他毫无保留地提供了一份 leaked document 给我作参考,十分感谢。 🙂

PS: 发现 WordPress 链接到自己文章的时候会发送 pingback,看上去真傻……只好装了一个 No-self-ping 插件。

“开源无线路由器固件上 Bug 的故事(二)”的61个回复

  1. 那8230-4和wzr-g108都是BCM5325(用的是tomato固件)
    我们网络是多播的
    用的是xclient源码编译的客户端,正常拨号
    ………………………………….

  2. @jacky235
    十分感谢你的反馈!
    我刚才又搜索了一下,了解到 BCM5325 交换芯片分为几个型号。根据拆解图片,8230-4 和 WZR-G108 都是使用的 BCM5325A2KQM ,而根据 WRT54G 的 Wikipedia 页面,它使用的是 BCM5325EKQM。对比了一下 BCM5325 和 BCM5325E 的 Product Brief(官网上有下载,但 Datasheet 不公开),我判断是这两种芯片上还是有差别的。BCM5325E 的 Product Brief 上说:

    In addition, BCM5325E supports other advance L2 managed features including port-based and 802.1Q VLAN, 802.1x EAPOL protocol filtering, IGMP snooping, and mirroring.

    所以这个 bug 应该被缩小到 BCM5325E 交换芯片了。不管怎么说,你能通过认证,值得恭喜~!

  3. @陶陶
    开源的东西在遵守协议的情况下拿来做商业应用还是有它自己的成本和维护优势的。之前磊科就发布了 NW618 支持 DD-WRT。TP-Link 在国内占据消费级市场的条件下是该向中高端发力了。一如 Windows Server 向 Unix 争夺市场一样。

    换主题是因为我之前一直在等作者发布这个…… 他发布不久我就连忙换上了。这个主题比较精致,适合我的喜好。 🙂

  4. “移植 Jouke Witteveen 在 roboswitch 中使用过的方法,在私有协议的认证程序中加入 Broadcom 芯片的支持,则有希望通过认证了。”

    这个貌似有点难度啊,Jouke给出的认证程序应该是标准的supplicant,那个roboswitch 的driver用到自定协议的认证程序里边不知道博主解决了没有?

    呵呵,不过这些东西都是一时兴起吧,希望博主都还有研究这个东东的兴趣,呵呵!

    刚入手一台150N,准备试试把客户端移植到路由器里边去,谢谢博主这篇文章,启发很大啊!

  5. @Awayfar
    我跟 Jouke Witteveen 联系过,他解释了他的方法原理,现在我能明白。只是我当前没有登录 802.1x 的需求,再加上我没有 Linux 下嵌入式 C 语言编程的经验,所以一时恐难以完成。
    前几个月有一位读者曾发信给我说好像已经移植了这个方法。不知道他为什么没有发布。
    建议你先移植看看,如果有问题再仔细下来研究研究。
    至于文章,发出来就是给人看的,能帮助到个把人,很是欣慰。 🙂

  6. 你好,看了这篇文章才知道自己遇上这个bug了。
    我学校采用的是中兴的认证,linux下的认证程序自己基本已经写好了(本人学软件开发的),在ubuntu下可以正常登录,但是在编译给路由运行后发现无法发出数据包,反复查看不知道是什么原因,后来查看了这篇文章才知道自己是遇上bug了。
    我的交换机芯片是bcm5354,学校采用广播认证,目前无解,看到你的文章说“移植 Jouke Witteveen 在 roboswitch 中使用过的方法,在私有协议的认证程序中加入 Broadcom 芯片的支持,则有希望通过认证了。”很希望了解该如何加入该支持。如果方便的话可以发份资料到我邮箱吗?万分感谢!我的邮箱是zzb402953049@qq.com

  7. @Oo笨蛋
    已经把参考文档通过邮件发给你,请查收。
    不过你说“学校采用广播认证”这个是否为笔误?如果是广播认证的话是可以通过的,因为广播包可以顺利地传达到 WAN 口上,而多播包则由于芯片内部的 logic 导致无法成功转发。关于广播包的处理方法你可以参考一楼的 Felix021 同学,他在已经在 WL-520gU 上成功了的,因为这机器也是 BCM5354 的芯片。

  8. 嗯,不过后来我试了下,我们学校不管是使用标准组播地址,锐捷私有组播地址,广播地址,还是使用认证服务器的物理地址(抓包得到,单播),都能通过认证,应该是可以避开这个bug了。
    你所说的相关的手册哪里能下载到?

  9. 你好,很早前就看过你这篇文章,当时没留意。最近换了个网络环境,变成了发送多播包认证,发现改了认证软件为多播也死活认证不上,各个方面都检查到了,最后才发现是遇到这个bug了.
    看到你说有roboswitch driver 相关的资料,能否发一份给我,邮箱 linchen987(at)gmail.com
    谢谢了 🙂

  10. 你好,我的路由器是BCM5354的芯片,看到你的文章说“移植 Jouke Witteveen 在 roboswitch 中使用过的方法,在私有协议的认证程序中加入 Broadcom 芯片的支持,则有希望通过认证了。”很想了解该如何加入该支持,以解决组播认证的问题。如果方便的话可以发份资料到我邮箱吗?谢谢!

  11. @William
    Jouke 他已经写出了相应的程序,你使用新版 wpa-supplicant 中的 roboswitch 驱动就可以了。但只限于标准的 802.1x 认证协议,如果是 H3C、锐捷的私有协议的话无能为力了。

  12. 你好,我最近也碰到这个问题。路由器是bcm6358芯片,用linchenlc的方法在运行wpa_supplicant的时候出现加载驱动错误:
    wpa_driver_roboswitch_init: Invalid phy address (not a RoboSwitch?)
    Failed to initialize driver interface

    系统启动的dmesg里面又这么一行,看起来应该是roboswitch的芯片啊?
    roboswitch: Probing device eth1: found a 5325! It’s a 5350.

  13. @seth
    看样子是你在命令行里的接口指定不对,虽然 eth1 显示的是 bcm 芯片,但是这个驱动要求你指定 WAN 口所在的接口名称,所以接口不对芯片对了也不一定能工作。 一般来说接口应该是 eth0.1 请你再试试。
    另,参考资料已发送。

  14. @xiaoding
    应该不是命令行的问题。看起来还是硬件的问题,貌似这个解决方案是针对5365的,我的路由器用的是6358,虽然也用了BCM5325E的交换芯片,也有同样的bug,但是硬件上还是有区别的。估计就是这个原因了。

    呵呵,我这个路由器比较尴尬。还是谢谢你的资料!

  15. 还有就是我已经通过了路由器锐捷的认证,现在的疑问是如何在关闭secureWRT后,保持刚才运行的Mentohust,就是一个软件咯。我发现关闭之后,Mentohust也被关闭了~

  16. @Irvine
    你试一下后台命令,就是在命令行后面加上一个 & 符号
    再不行就把命令行写在 路由器的启动脚本里,这样就可以在启动时连接

    你问的这些是 Linux/Unix 基础知识,建议找个入门的论坛补习一下。

  17. 唉唉 说起来 我也是被openwrt的一个bug折磨了1年多,ticket号是1212
    而且也是tmd broadcom的switch的问题 好像就是BCM5325 症状是有些使用这个交换芯片的路由器(包括我的)在2.6的kernel上驱动不了,看了lz的文章看来5325还不是都一样 这样解释了为什么有的路由器没有这个问题

    经验是再也不买broadcom相关的产品了

  18. @hayate
    broadcom 在技术上不够开放,所以导致这些问题。。
    不过 DD-WRT 和 Tomato 都有成熟支持 2.6 kernel 的 ND(NewDriver) 版本,按说这个问题应该解决了的。 而且这个 Ticket 1212 是四年前的了,那时候 kernel2.6 肯定支持不好。

  19. 在学交叉编译,试试把wpa supplicant到我在用1.28tomato dualwan固件的500gp v2上〔芯片5354,5325e交换……现在无法获取ip〕

  20. @xiaoding

    对啊,我在openwrt看到有wpa_supplicant新版

    在tomato固件下我ipkg install wpa_supplicant 结果安装给我的是旧版不带驱动的版本~郁闷,无用,带驱动的貌似要0.6.9以后才有

    xiaoding你交叉编译出来的在tomato是不是会提示没有空间?

  21. 一直想解决这个问题,家里每次只能允许一个人上网,太不方便了,看完你的文章和底下的评论,解决方案就是买早期的没有BUG交换芯片的路由器?

  22. @Roger
    对,相对来说比较方便的解决方案就是买一个早期的芯片没问题的路由器。
    其实后来的BCM5352/5354都有解决方案了,就是对于一般的用户来说解决起来相当地麻烦,除非具有一定的 Linux/Unix 使用经验。

  23. 买了个FAST FW150R的路由器,可以刷成TP-LINK 741N的固件,自然可以刷DD-WRT,cpu用的是AR7420,不知道交换芯片用的是什么,现在找不到什么好的802.1X的多播的源码,请赐教。

  24. 借博主人气来说一下,现在的路子:)

    当初也是被这个3252E困扰了一阵,后来发现我的路由器Linksys wrt150n没有这个问题,之前不能通过是其他原因。这样愉快的用了一年多,中间也帮同事装过几个。

    最近的一次,因为老的这种型号的二手机器买不到了,网上考古了一下,发现去年底的时候已经有人把市面上非常便宜的TP-Link系列路由器装上ddwrt和openwrt了,我自己测试了一下,Atheros最近的芯片也没有这个BUG了,所以需要锐捷路由的朋友不妨考虑一下这些机型,我自己测试过的有:TP-Link 841n v7、741n v1,水星MW-150r v2(注意这些机型的版本号,新出的版本可能缩水没法刷机,可以寻找替代品),都能顺利锐捷拨号并路由上网。问题只是刷官方对应ddwrt的固件的话,没有jffs2空间不能保存mentohust等文件;如果是openwrt,因为它的文件系统是开放的,可以直接装程序进去,所以推荐这个。具体有关路由器和锐捷的信息可以到right.com.cn和mentohust.googlecode.com上查。

    因为测试可用,所以来这里说下atheros的芯片没有这个BUG可以放心用。感谢博主这篇帖子让我找到方法,也为其他来这里的朋友多一个参考。

  25. 43#同学,这个路由器跟水星150r是一样的,刷741n以后再刷Openwrt,配置一下mentohust就可以用了,放心没有组播的BUG,我已经测试成功了!

  26. 楼主您好,我先在做无线路由的硬件研究。十分需要BCM5352的资料,您要有的话能发给我一份吗?721428529@qq.com 不胜感激。还有就是您知道BCM5352EKPBG和BCMKPBG是否有区别?有的话区别在哪里?非常感谢

  27. @zhoujc
    十分抱歉,我也没有BCM5352的资料,如文中所言这些东西只能从经销商那儿得到。网上是没有渠道的。你说的两个型号我只听过前者,后者没听过,因此也无法回答,抱歉。

  28. @xiaoding
    看到你说“其实后来的BCM5352/5354都有解决方案了”我的是BCM5352,不知道有没有方法不用wpa_supplicant?另外能不能发一份资料给我ayanamist at foxmail dot com,我想整合到MentoHUST里

  29. 刚刚确认Broadcom 4712一样有这个问题,麻烦楼主更新进去。我买的Buffalo WBR2-G54一样不能认证锐捷

  30. ayanamist :
    刚刚确认Broadcom 4712一样有这个问题,麻烦楼主更新进去。我买的Buffalo WBR2-G54一样不能认证锐捷

    不好意思,搞错了,是这个路由器特殊的配置误导了我,ifconfig才发现,wan口居然对应的是vlan1……

  31. 麻烦高手给推荐款完美支持h3c的802.1x的无线路由?最好新一点,好买些?32m的路由空间是否够用啊?还有就是路由带个usb端口是不是刷机方便点?问题比较多,菜鸟发问,谢谢

  32. @802.1x
    新一点的没怎么关注了。我只知道 WRT54GL v1.0 版本的可以完美支持 802.1x(此路由使用 ADM6996L 交换芯片),其它的就不保证了。
    对于 802.11g 标准的来说 8M Flash 32MB RAM 已经够用了
    USB 端口只能用来接外设,刷机用不到的。 个人觉得路由拿来脱机下载实在有点不伦不类的,不如另外准备一个 NAS 来负责存储。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注