Normal view

There are new articles available, click to refresh the page.
Before yesterdayTimeForget

近两年基础设施的升级和更新

By: Erease
11 July 2023 at 08:00

正如About所描述的,希望在这里记录一些难以查找的信息:网络接入和局域网设备升级踩的坑

网络接入

OpenWrt + 4G 手机

历经多次宽带因为单一运营商垄断,价格高到离谱,之前在学校测过4G是可以跑到100Mbps的下行速率的,买过4G路由器做接入,后来因为SIM卡不够用就出掉了

在5G时代,闲置的4G手机完全可以用来作为网络接入设备,我用刷了OpenWrt的小米R3G有线连接退役的iPhone SE做了一个简单的4G路由器,找个4G信号好的地方固定,测速还行就可以开始用了

因为有部分模块依赖于内核,加上平时编译不太方便,所以采用官方固件,参考官网教程 Smartphone USB tethering

我记录的一些需要装的包

# 换源
sed -i 's_downloads\.openwrt\.org_mirrors.ustc.edu.cn/lede_' /etc/opkg/distfeeds.conf
# 装包
opkg install kmod-usb-net-ipheth kmod-usb-net kmod-usb-ohci kmod-usb-uhci kmod-usb2 libimobiledevice-utils libusbmuxd-utils usbmuxd 
opkg install luci-compat

用了一段时间后发现了如下问题,当然也还有其他的手机可以尝试,但是我觉得4G的问题更大:

  • 4G的信号不佳,经常达不到预期的100Mbps,这个和户型、运营商都有关
  • 4G的网速在不同时间段表现差别很大,高峰期几乎无法上网

ios更新14之后,以上教程提到的方法就失效了,后续就没有在ios上再尝试过了;随着第一代5G手机在2022年陆陆续续退役,5G手机USB共享网络给OpenWrt路由器却没有达到预想中的那么快,考虑到在手机上经过了一次NAT,存在硬件开销以及调度和功耗限制,这还是不适合作为一个长期方案

5G CPE

于是开始关注5G CPE,恰好就遇到了2020年刚上市的华为的5G CPE Pro 2 (型号H122-373,以下简称H122),幸好买的早,后来芯片荒价格一路水涨船高,直到后来智选的5G CPE铺货

当时刚好手上有可以跑千兆5G卡,至少在下载速率上可以超过绝大多数家庭宽带了,缺点也还是有的:

  • H122虽然可以放开防火墙,但是只是放开了入站的Input的流量(外部能够ping通CPE),会拒绝Forward的流量,即使下面的终端设备可以获取到IPv6地址,但是也无法从外网直接访问
  • 如果长时间高负载,即使内置了一个散热风扇,内部的温度还是比较高的,具体影响是SIM卡会热到变形,所以需要买一个SIM卡接口延长线
  • SIM卡不支持热插拔,经常需要换卡的话,要重启CPE,考虑到插槽寿命,SIM卡接口延长线必不可少
  • 最想吐槽的一点,CPE的桥模式在某次更新之后就没有了,桥模式可以使得下面的主路由可以自行控制防火墙,如果需要配置IPv6外网访问的话是必要的
  • WLAN to 2*LAN 最大只有千兆,让局域网内怎么都跑不满到160MHz WiFi6的速率(一般为实测1.2Gbps以上),充分说明了CPE还是以5G接入为主,5G to WLAN应该是能跑满的
  • 支持5G和有线WAN并发,但是实测效果一般,如果有线WAN只有IPv4的话,5G部分可以补充IPv6

写出来有点多,但不可否认的是在很长一段时间里H122就是能买到的最强的5G CPE,在我这稳定运行了三年,因为是价格低位购入,还能直接用天际通物联网卡(23年已经限速到200Mbps,没有了5G SA,只能用4G)

最后需要担心的其实是流量问题,因为5G的流量消耗速度非常快,实时监控流量消耗情况也是必要的,如用iOS小组件;因为华为5G CPE当前已经无法收到短信,流量告警只能自行编写脚本等方式实现

OpenWrt + 4G模块

这里使用的是DJI增强图传模块连接OpenWrt路由器USB接口接入的4G网络

  • 个人认为只能算是驱动了基础的QMI拨号上网功能,缺少产品本身完整功能及驱动的说明
  • 加了DIY的无人机上的天线,信号还是比手机略差,实测50Mbps-10Mbps传输的速率
  • 发热情况在28度的室内属于可以接受,上网基本是稳定的,游戏偶尔会跳ping,4G网络期望不能太高

2022年大疆在Mavic3发布之后发布了与之配套的4G图传模块(DJI Cellular),然而自带的增强图传服务只有一年的套餐,后续如果要继续使用就需要以每年99续费增强图传服务,对于只是想超视距飞行过把瘾的人来说,增强图传服务到期之后模块自然就闲置了(大疆2023年新品不兼容该模块),二手市场上挂出的非常多,感觉出手比较困难(原价699,2023.11二手大把的450),而全新的同规格的Cat4速率的4G USB网卡120可以买到,既然如此,还不如留着当4G网卡发挥余热

驱动的方法

该方法在ImmortalWrt 23.05.1的ARM和MT7621的路由器上测试成功

  1. 安装QMI拨号需要的包
    opkg install qmi-utils usb-modeswitch kmod-mii kmod-nls-base kmod-usb-core kmod-usb-ehci kmod-usb2 kmod-usb-net kmod-usb-wdm kmod-usb-net-qmi-wwan wwan uqmi luci-proto-qmi
    
  2. USB连接4G模块,执行识别驱动的命令,命令如果没有报错的话,ls /dev/应该看到cdc-wdm3这个设备了
    echo "2ca3 4006 0 2c7c 0125" > /sys/bus/usb/drivers/qmi_wwan/new_id
    
  3. 创建QMI拨号的接口,例如命名为DJI,在调制解调器设备一栏填入/dev/cdc-wdm3(最关键,下图是借用的其他教程的截图作为参考),其余的信息保持默认; 在防火墙设置,给这个接口分配防火墙区域为wan,保存设置即可

如果此时4G图传模块上的灯是绿色的,即模块正常连上了4G网络,很快能看到刚刚创建的接口已经获取到了IPv6的地址,并且系统自动生成了名为DJI_4的IPv4地址的虚拟接口,此时路由器应该就能通过4G模块访问互联网

第一次成功驱动并设置好QMI拨号的接口后,可以将命令

  echo "2ca3 4006 0 2c7c 0125" > /sys/bus/usb/drivers/qmi_wwan/new_id

添加到开机启动脚本中(网页LuCI界面->系统->启动项->本地启动脚本),添加到文本框中exit 0这一行之前即可,后续重启也无需任何的操作,随时插入4G模块后一段时间就能正常上网了

探索的过程

在大疆论坛上有用户尝试了Windows上驱动并成功让PC能接入4G网络,后续大疆又发布了模块的Windows驱动,其中主要提供了以下的信息:

  • PC直接识别的型号是EG25G-QDC507,其中EG25是移远(Quectel)的产品:一款Cat4速率的4G模组
  • 4G模块正常驱动后显示的生产商为Baiwang,查不到驱动和规格相关的信息

搜索OpenWrt上驱动模块的资料,发现在OpenWrt上移植EG25驱动的经验是空白的,主要都是移植EC2X的,其中《挂载移远EC20、EC21、EC25、AG35等4G模块》参考了官方的Linux驱动文档,EG25在文档发中和EC25的PID和VID是相同的(2C7C, 0125),但是与4G图传模块的(2CA3, 4006)不同,即使移植了EG25的驱动也未必能识别到4G图传模块

直到看到论坛里有人发了4G图传模块用于Linux系统上网尝试,用到了将USB设备的PID和VID写入/sys/bus/usb/drivers/…/new_id处理驱动识别的方法,另外又查到了23年11月的OpenWrt 下实现移远 4G 模块上网 中提到在OpenWrt 22.03在无需改内核代码就能驱动EC20

在运行echo "2ca3 4006 0 2c7c 0125" > /sys/bus/usb/drivers/qmi_wwan/new_id后,可以用cat /sys/kernel/debug/usb/devices查看到4G模块被qmi_wwan驱动(设备对应的信息出现Driver=qmi_wwan字样)

/dev目录下可以看到/dev/cdc-wdm[0-3]一共4个设备,最开始尝试了/dev/cdc-wdm0发现无法拨号就差点放弃,最后尝试了下/dev/cdc-wdm3发现拨号可以获取到IP了

查看信号及IPv6情况

uqmi命令可以与模块通信并输出一些状态的信息,其中个人比较关注的主要是信号

root@XDR6088:~# uqmi -d /dev/cdc-wdm3 --get-signal-info
{
	"type": "lte",
	"rssi": -55,
	"rsrq": -6,
	"rsrp": -79,
	"snr": 14.800000
}

4G模块的速率标准为Cat4(下行速率最高150Mbps,上行最高为50Mbps),实测在以上信号强度的电信4G上下行均为50Mbps左右,日常用这速率也算能接受吧,联想到我测试过最快的4G是2018年在iPhoneSE(4G Cat6最高下行速率300Mbps)上跑出了100Mbps的下行

关于IPv6,首先路由器时可以获取到公网IPv6地址的(以及64位前缀的PD),并且在LAN默认的IPv6设置下,可以向下分配地址,另外就是传入连接的连接性,实测发现有运营商的差异:移动的IPv6地址无法从外网访问路由器,联通和电信的IPv6地址则可以

CPE/4G模块下的二级路由

由于CPE和4G模块获取的IPv6地址是不含短于64位的前缀的,所以在使用二级路由的情况下,二级路由下的设备无法获取公网IPv6地址,这个时候需要配置“IPv6中继+NDP代理”,OpenWrt 23.05的LuCI界面的设置过程如下:

  1. 比如wan6接口已经获取到IPv6地址,下面都是在默认的设置上修改的,第一张图的设置不需要改
  2. wan6接口的设置勾选指定的主接口,接下来三个地址分配的选项选中继,学习路由要勾选
  3. lan接口的设置,三个地址分配的选项选中继,学习路由要勾选
  4. 删除ULA前缀(这里是经验之谈) 正常情况下,连接在路由器下面的设备就能获取到公网IPv6地址了,但是可能还打不开IPv6网站:http://test6.ustc.edu.cn,这个时候可能需要ping一下wan6接口的IPv6地址,让地址被NDP代理学习(可以用ip -6 neigh和LuCI上的系统->路由表->IPv6邻居看IPv6地址对应的接口来观察NDP代理的效果)

我的网络结构是CPE做一级路由,OpenWrt做二级路由,因为华为5G CPE本身防火墙的原因,二级路由下面的设备可以获取到IPv6地址,但是无法从外网访问

但是如果CPE或者4G模块支持桥模式,那么OpenWrt路由器大概率是不受CPE或者4G模块的防火墙影响的,放开OpenWrt的防火墙之后,只剩下运营商屏蔽了传入连接的可能性

局域网

局域网肯定还是要用一台OpenWrt路由器作为主路由,如果一台主路由能解决问题是最好,列出来的要求有点多:

  1. 网口足够多,早期的路由器一般是5个千兆口(1 x WAN + 4 x LAN),勉强够用(PC + NAS + xx),如果带USB口的话,还能额外扩展网口
  2. 最好有2.5G以上的网口,因为160MHz WiFi6已经可以跑到1.6Gbps以上了,当前NAS的机械硬盘读写大多能超过200MB/s,2.5G网口的设备会越来越多
  3. WiFi 4T4R(4x4 MIMO)信号更好,有MU-MIMO的情况下,当前主流2x2 MIMO的多台设备可以同时高速传输
  4. 有良好的OpenWrt支持,这里特指最好是有OpenWrt官方的支持,开源的固件能确保基本的功能正常(21年之前WiFi6的开源驱动很少有能用的)

在从2020年到2023年这一段时间里,涌现了一大批可以刷OpenWrt的WiFi6路由器:Qnap-301w、红米AX6,AX6000、中兴NX30 Pro,以及可能有QSDK固件的小米万兆路由,对比以上的要求有明显的短板,直到某一天看到B站上有人给TP-LINK XDR6088刷机的教程:TP-link路由器XDR6088、6086、4288刷openWRT,我终于发现了一台有潜力的机器:

  • 带2个2.5G网口 + 4个1G网口 + 一个USB3.0接口
  • 支持4T4R 160MHz的5G频段WiFi6
  • 4*A53@2.0GHz的CPU,128MB的闪存在2023年够路由器装常用插件了,看拆机散热算是比较好的

XDR6088刷OpenWrt

可以查到的获取终端操作权限刷入U-boot(bootloader)的方法源于:TP-LINK XDR6086/XDR6088 反弹 SHELL 并开启 SSH

综合亲手实践以及上面的视频教程,有几点需要特别注意

  • 实测在1.0.24版本到1.0.23都可以通过反弹shell注入命令,切记每次发完post请求之后,禁用用户触发反弹shell完成后,删除用户,这样下一个Post请求才能发送成功
  • 发Post请求的客户端软件有特别的要求,我试过OpenWrt,CentOS,群晖,Postman的curl命令/Post请求发送均无法创建VPN用户,最后还是重装了一个Ubuntu的WSL才成功:返回{"error_code":0}
  • 在Windows下使用nc导出路由器备份的mtdblock的时候,Windows上一定要用CMD运行nc并重定向nc -l -p 9995 > backup.img),不能用Powershell(备份传输完成后,校验的话就会发现用Powershell运行同样的命令会得到不一样的文件),因为这一条操作失误导致我刷OpenWrt后刷回原厂系统的过程中导致变砖
  • 视频教程中的UBoot刷完后,通过这个UBoot是无法直接刷入官方的OpenWrt固件的,原因是分区结构不一样,本文后面有记录刷到官方的方法

一些简单的测试

我只刷了视频教程的固件,基本上是截至到当时最新的R23.5.1,2.5G网口和WiFi稳定的运行两周,这里先放下收集到的参数的对比,至少CPU的参数在当前WiFi6末期可刷机硬路由中基本上是第一档的

路由器 CPU RAM ROM
Newifi Y1 MT7620 1C@580MHz 128MB 16MB
K2P MT7621AT 2C4T@880MHz 128MB 16MB
XDR6088 MT7986A 12nm 4*A53@2.0GHz 512MB DDR3 128MB
NX30 Pro MT7981B 12nm 2*A53@1.3GHz 256MB DDR3 128MB
Qnap-301w IPQ8072A 12nm 4*A53@2.2GHz 1GB DDR3-1600 4GB
K3 BCM4709 40nm 2*A9@1.4GHz 512MB DDR3-1600 128MB
N1 S905D 28nm 4*A53@1.5Ghz 2GB 8GB
  • 近距离WiFi6设备测速,用支持160MHz的小米13可以跑出1.6~1.8Gbps的速率,支持80MHz的iPad Pro能跑到900Mbps 同一房间,无遮挡用AX200也能跑到1.6Gbps左右
  • 中距离WiFi6设备测速,一堵墙的情况下,XDR6088能跑1Gbps,对比4T4R 80MHz的K3能跑400Mbps左右
  • 夏天室内29度左右,长时间开机运行,CPU温度不超过60度,机身有热感

救砖

上文提到Powershell下使用nc命令重定向的备份大小异常的问题,相关的原因查明在:Powershell与bash的重定向的差异,在搞清楚其中的原理后,我理解无法通过简单的操作使得备份还原,于是在论坛找到了别人的备份的mtdblock9尝试救砖,参考

因为我之前给T440s修改BIOS买了CH341A编程器和8pin的夹子,所以就鼓起勇气拆机,经过艰难的掰卡口后,很快就遇到了问题:

  • 红米AX6000救砖中提到建议改CH341的输出电压为3.3v,这个要飞线,我没有工具:

  • 我查了下ThinkPad BIOS芯片W25Q32V的datasheet,发现支持的也是2.7~3.6V,之前成功刷上了BIOS,通过不严谨的推测,不修改CH341的输出电压也能刷2.7~3.6V的F50L1G41LB

  • 店家给的CH341的编程器刷写软件不支持F50L1G41LB,红米AX6000救砖中提到“NeoProgrammer不知道如何写入单独分区,我选择了SNANDer”:

    • SNANDer大概是缺少说明,我这里用的不太顺利,最后还是选了NeoProgrammer,因为后者能成功识别到芯片并读写
  • 最棘手的问题在于,F50L1G41LB相比W25Q32V,夹子的触点难以夹到芯片的针脚,无法稳定连接就无法写入,红米AX6000救砖中用的漆包线飞线

    • 我买了电烙铁,尝试飞线,但是实在是不会用锡焊,意识到用力过猛可能会损坏芯片,遂另寻他路
    • 最后在网上看到了生产用的治具,有一个工作台能将探针垂直于主板放置,探针尖直接接触芯片针脚,然而治具带工作台价格上百,WSON8探针(匹配芯片尺寸8*6mm)比CH341编程器加上夹子还贵一些,自己拼凑了一个固定探针的框,如图:

刷入官方OpenWrt

在OpenWrt官方23.05正式版支持XDR-6088的固件后,参考了TL-XDR6088/6086 刷入官方 Openwrt/Immortalwrt,原文已经记录的相当的详细,此处仅摘录用到的步骤(因为独立博客的域名过期之后就很可能找不到原文了)

本文写作时,最新的是23.05.0-rc3版。将来请用更新的稳定版本,目前Immortalwrt官方固件已经支持:

  • 双 2.5Gb 网口的正常驱动(但LED灯还不亮)
  • WiFi6 160Mhz
  • 硬件流量分载
  • WED (Wireless Ethernet Dispatch) 无线加速
  • 硬件 NAT 加速
  • Fullcone NAT

4.2 如果路由器已经刷了其它版本的 Openwrt

在 Openwrt 中运行cat /proc/mtd,得到mtd设备的真实命名,再用命令来写入(将下面的BL2或FIP改成你在上面看到的名字,注意大小写)

md5sum /tmp/preloader.bin
mtd erase BL2
mtd write /tmp/preloader.bin BL2
mtd verify /tmp/preloader.bin BL2

md5sum /tmp/bl31-uboot.fip
mtd erase FIP
mtd write /tmp/bl31-uboot.fip FIP
mtd verify /tmp/bl31-uboot.fip FIP

注意查看上传的两个文件 md5 并和本地文件对比,查看两次 mtd verify 最后是否输出输出 Success,没问题才可进行下一步。

5. 通过 tftp 载入 recovery 镜像

这时候你可以拔掉路由器的电源,然后插上。直接拔电源可能是最安全的,因为如果你用 reboot 命令,可能会有一些后台程序运行(包括可能你之前在慌乱中没有杀掉的误操作了的 dd)导致路由器变砖。别问我是怎么知道的。

此时 tftp 服务器上应该已经有提示了,路由器在请求的文件名为 openwrt-mediatek-filogic-tplink_tl-xdr6088-initramfs-recovery.itb 。你只需要把结尾为 recovery.itb 的文件,改名为这个就行了。

如果没动静,你可以拔下电源,然后顶住 reset 孔不放,同时插入电源,应该会看到 LAN 口的灯齐闪一下。大约10秒钟,应该就会进入 recovery 模式。确保网线插在 1Gb LAN 口上,网口的灯应该会亮的。

NAS加装万兆网卡

前面提到了WiFi6 160MHz普及之后,局域网传输的瓶颈主要在千兆的有线网口上,考虑到外置USB网卡(USB 3.0外置网卡最大速率为5Gbps)可能因为发热等因素不稳定,首选的话还是PCIe的网卡,而且由于数据中心万兆网卡下架,市面上有较多的低成本的选择,在网络讨论的最多的是浪潮X540-T2拆机卡,价格大概70左右,特别之处在于PCIE插槽是X8+X1,如果要用的话x1要绝缘屏蔽,我实际使用发现卡兼容性不太好:

  • 铝制的小面积散热片,只要插上PCIe插槽就非常烫
  • 插在群晖的NAS上发现无法识别
  • 插在z370主板上,概率性无法识别,或者iperf3测速不稳定
  • 最后是X540本身,由于年代久远,不支持协商以太网的2.5G速率

最后捡到一张180的带华为物料编码的x540,有几乎覆盖整个卡面的黑色散热片,插上群晖DS1621可以直接用,对于装了驱动的Z370-I也是

简单测了下,这张x540的空载功耗大约是8w,看卡背面的便签写着silicom PE210G2I40E,查到了silicom官网关于电口万兆网卡的功耗,找到了“电口功耗高”的依据:

PE开头的NIC(网卡)均为silicom官网上的网卡的功耗数据(均为所有端口Link/Idel 的功耗的整卡功耗),可以看到x540的功耗一骑绝尘,考虑到网卡的成本以及长期电费,最后我找了一张AQC107的网卡LREC6880BT,也把数据列到了下面:

NIC Controller 无Link GE XGE  
PE310G2I50-T X550-AT2 4.62W 5.4W 8.16W x4 PCIe 3.0
PE210G2I40-T X540 7.23W 7.92W 14.28W x8 PCIe 2.1
PE310G2I71-T X710-AT2 3.6W 5.52w 8.28W x8 PCIe 3.0
PE310G2I71 X710BM2 3~4W   4.6~4.8W x8 PCIe 3.0
PE210G2SPI9A 82599ES 4~6W   6W x8 PCIe 2.0
LREC6880BT AQC 107     网卡4.7W x4 PCIe v2.1

数据中心下架的卡基本上都有些年头了,关于网卡的控制器、发布时间、制程、TDP,2022年末的二手价如下:

NIC Controller TDP Release Process Price
华为SP230电 X540-AT2 12.5W 12Q1 40nm 250左右
Intel X550 X550-AT2 11W 15Q4 28nm 1200左右
Intel X710-T4 XL710-BM1 7W 15Q4 28nm 2450
X520-DA1 82599ES   09Q2 65nm  
LREC6880BT AQC107 6W 17Q4 28nm  

在网上看到说Intel的X540和X550在群晖的DSM系统中是免驱的(其实是DSM的Linux带了驱动),因为X550太贵,所以把目光投向了价格和功耗都合适的AQC107,因为群晖E10G18-T1 10G等群晖官方的万兆电口卡也是用的AQC107,我天真的以为第三方AQC107也是免驱的

群晖DSM7.1编译AQC107网卡驱动

网上我能找到两个中文的经验:

详细的要二次编译成功再补充,大概是下次DSM系统版本/内核版本更新

Z370-ITX使用64GB内存

因为不涉及到后面的修改BIOS文件就能上64GB内存,这里直接上结论:

  • 实测在华硕Z370-I的1410版本的BIOS,可以识别到64GB内存并开机正常使用,使用的内存是2条金士顿Fury DDR4 32GB 3200MHz

在我的平台上,用最新的3005的BIOS反而会导致莫名其妙的自动重启

  • 关于CMD运行命令“wmic memphysical get maxcapacity会显示最大支持的内存”,实测是不准确的
  • 华硕这块ITX的主板的BIOS文件的 最大内存限制的二进制位 与 已有经验反馈的ATX主板BIOS文件的不同,所以最后还是实践出真理

因为在互联网上找不到Z370-I成功实践的经验,所以这里留个记录:

Asus Z370-I是一块ITX主板,只有两个内存插槽,装机的时候切好碰上DDR4内存天价,所以很长一段时间里只有双通道16GB 3000MHz,这块主板在官网上参数写着最大支持32GB内存,也就是2X16GB,然而随着内存降价,发现23年单条32GB的内存已经很便宜了,想着直接上到双通道64GB,以后这台机器退役也能当服务器用

32G单条内存的颗粒检索

因为是捡垃圾买到的“Fury DDR4 32GB 3200MHz”,想要知道超频情况,无法在thaiphoon burner中识别出具体的镁光颗粒,所以只能通过拆内存条散热马甲查看颗粒的FBGA Code(或者叫Market Code:颗粒第二行的编码,例如比较流行的镁光超频内存条C9BJZ),然后在官网Micron FBGA and component marking decoder查询,然而如下的丝印代码在官网是查不到的:

3CE22 
Z9XJP

最后是在电子元器件网站上检索到了颗粒的型号(Part Number):MT40A4G8VNE-062H ES:B;根据镁光的PART NUMBER命名规则表,可以获取到如下信息:

  • 频率:062对应3200MHz
  • 内存条单面八颗粒,叠die颗粒(4G8 4Gb*8 为2Gb的2G8的叠die版本)MT40A4G8 这个是叠die的颗粒
  • 然后是ES是工程样片,对应Market Code第一位为Z

然后因为网上搜索不到相同的颗粒,所以超频抄作业可以不用想了,只能搜索到酷兽银甲单条32g 颗粒分析和超频也是叠die颗粒超频:“3200频率下1.45V时序可压c14-18-18-34,这里简单调了下一二时序,能效可以达到4.8w左右”,我看到了这个之后就按照文中提到的时序调整,实测不需要以上那样的参数,1.35v c14-18-18-32即可,其他的时序参考网上的超频教程进一步收紧,TM5跑不过就放开一点(tRFC为500),最后时延能控制在52ns左右(收紧的话可以49ns但是TM5报错)

修改BIOS提升内存支持上限

我搜到了CHH的帖子:首发!Z170/Z370 突破内存64g可用的上限限制,精华在评论里,总结如下:

如何使 H310C/B365/Z370 的 BIOS 支持最大 128G 内存:

1.UEFITool提取SiInitPreMem模块,GUID为A8499E65-A6F6-48B0-96DB-45C266030D83 2.UEFITool搜索“C786….000000….00”,其中“..”为任意HEX值 3.第一处“….”不用理会,第二处“….”如果是“8000”那么就是最大64G,如果是“0001”就是最大128G 4.将“8000”修改为“0001”可破除64G限制 5.100/200系BIOS内也有此内容,理论上6-9代的IMC支持的内存没差,6700+Z170也能128G内存(已测试可行) 6.我这边看,MSI的Z370,18年底的BIOS还是8000,19年4月的BIOS就是0001了,ASUS的BIOS一水的都还是8000 7.ME 需要禁用(修改Flash Descriptor的HAP Bit,但要注意部分主板有校验不允许这么改,改后无法开机) 8.部分BIOS需设置 Chipset->System Agent (SA) Configuration->Above 4GB MMIO BIOS assignment->Disabled 不同 BIOS 位置不同,且可能被隐藏,无法直接修改

注:参考后面的引用,第七步为:将 0x102h的位置 +1

Z370-I的BIOS的修改追踪

限制内存大小的字段,在我的主板上看到的是

# 3005 BIOS (2000 我觉得是单条16G,或者单DIMM 32G)
#Hex pattern "C786....000000....00" found as "C7866F25000000200000" in TE image section at header-offset 388FCh
C7 86 6F 25 00 00 00 20 00 00 EB 20
6A 00 56 E8 B4 E0 FE FF 59 59 0F B6

# 纯血的370ROG已经提供了128G的bios( 2021-2-15 )
# 3004 BIOS 2021-04-16 发生了变化,没有了老版的第二行
C7 86 6F 25 00 00 00 20 00 00 EB 20

# 1802 BIOS
C7 86 6F 25 00 00 00 20 00 00 EB 0A 
C7 86 6F 25 00 00 00 80 00 00

# 1410 BIOS
Hex pattern "C786....000000800000" found as "C7866F25000000800000" in TE image section at header-offset 384ACh
C7 86 6F 25 00 00 00 20 00 00 EB 0A 
C7 86 6F 25 00 00 00 80 00 00 8B C3

“18年底的BIOS还是8000,19年4月的BIOS就是0001了”的这一行去掉发生3004(更新日志:主要是添加了Win11的支持,没有提内存上线变化),我找了M10H ROG MAXIMUS X HERO BIOS变更日志中有内存上限修改(Support Max DRAM Total Capacity up to 128 GB.)的新老BIOS看了下,也是去掉了8000这一行

恩杰H1自带140水冷老化

这个问题能搜索到公开的文字信息不多,主要的问题是用了一段时间之后散热能力迅速衰减,比如新购入可以压制170w发热的CPU(已经开盖换液态金属),然而老化之后散热能力在CPU功耗80w左右温度就冲击100度,网上能搜索到的维修和拆解分析的经验:

我拆开水冷头之后,果然如上面引用所述是杂志堵塞了水冷头的微水道,用蒸馏水冲洗了几轮水路,最后换了蒸馏水之后散热能力重回170w,另外水冷的大风扇,对内存散热也要更友好(换用了一段时间的AXP100,内吹的时候内存太烫了)

折腾两台Haswell时代的设备

By: Erease
30 May 2021 at 08:00

Haswell架构是Intel在2013年推出的“酷睿第四代”CPU架构,Haswell刚推出那年配了自己第一台台式机,后来上大学又捡了一台Haswell的笔记本T440s,毕业后又凑了一台M73小主机…台式机至今还在家用,笔记本已到垂暮之年,修改BIOS之后装上AX200依旧是顺手的全能笔电,M73目前主要是作为Linux环境主机

T440s刷BIOS

之所以要刷BIOS,是因为T440s大部分的BIOS有网卡白名单,基本完全限制住了自行升级网卡,自带的AC7260是Intel最早的2x2 AC网卡,信号和速度已经远远落后如今的AX网卡,T440s现在主要是处理器跟不上了,其他方面放到现在也是非常优秀的:

  • 接口丰富(主要是有RJ45),有廉价的拓展坞
  • 1.4KG的重量,同重量下优秀的键盘键程
  • 支持2242和2.5inch的共两块SSD
  • 使用PD转方口可以使用PD充电头

另外还有几个比较有意思的地方:

  • i7-4600U处理器可以在XTU拉4倍频,本来最高3.3GHz可以拉高到3.7GHz(实测还是要手动加些电压,加太多功耗高,容易死机,实际只见过3.6GHz)
  • 可以换装72WH的外置电池
  • 没有不耐用的类肤质涂层

在如今是市场里确实很难找到合适自己用的笔记本(定位高,接口丰富,不用拓展坞),所以还是想多延续下T440s的使用期,一直比较头痛的就是更换网卡的问题,之前并非没有查过刷BIOS,但是教程太复杂,时过境迁,2020年搜到有不少人都能自己刷了,下面进入正题

参考教程

虽然写的是T440p,但是实测对T440s基本适用,本文对以上的材料做下补充:

  • BIOS芯片的位置

  • 夹上编程器的样子

  • 用工具读取到的BIOS芯片型号和教程可能不同,以卖家附赠的工具为准

  • 教程还带有解锁高级菜单的部分,但是实测貌似没什么用(主要想解锁功耗,15w下散热还是压得住的)

黑苹果

换了AX200的网卡之后在160MHz下实测无线可以跑满1000Mbps,另外一个在2020年的新闻就是Intel的网卡在MacOS下终于可以日常使用了:itlwm,因为手头空闲的机器不多,所以就尝试给T440s上黑苹果试一试,好在Clover的EFI不难找

实测黑苹果日常使用确实比Win10流畅不少(主要是少了一些莫名其妙的高占用),但是多开还是有些吃力的

M73

缘起于之前为了收一个小机箱和MATX主板,被学长捆绑了一颗ES版的CPU,最开始说是E3,用CPU-Z看也是志强,但是根据顶盖上的四位编号QEDH,在某宝上搜索指向的是i7-4770s的ES版本,4c8t @ 3.0GHz,TDP 83W,并且带核显;尝试过作为家用win10主机使用过,但是核显实在太鸡肋,单核心主频低导致部分应用速度比较慢

最后我还是决定装一台低功耗的Mini Server,准系统选择了Haswell时代的M73(相比戴尔的9020散热更好),M73可以用ThinkPad系的方口电源也是一大优势(家里方口电源多…)

装机及散热测试

准系统的安装很简单,但是这里有些插曲,一个是CPU的散热问题,相比带T后缀的45W的低功耗CPU,以及家用台式机的65W标压处理器,QEDH的83W还是很吓人的,之前在B85 ATX主板上实测,解锁功耗烤机满载也确实可以跑到80W以上,所以对于65W以下的准系统M73,我选择了把顶盖到Die的导热材料换成液金,然后测试下M73能否在编译时跑满这颗CPU

这里选择CentOS下,初次编译OpenWrt作为负载,编译时,温度抵近90度,基本上就是达到默认风扇下的上限了,如果把风扇转速拉满,温度大概80左右,但是噪音太大了;使用s-tui可以在软件层面查看功耗和频率信息,CPU功耗接近60W,主频2.8GHz,因为可以用Type-C的方口诱骗线供电,所以也顺带看了下整机的功耗,基本在65W以下(用95W的电源);编译的时间对比win10下使用WSL2的i7-8700K,M73这套平台耗时是其两倍,可以接受的水平;另外日常待机功耗12W左右

Docker下载机

之前用NAS时,用的比较多的就是Docker版本的qBittorrent以及网络共享功能,其实在Linux下实现这些并不难,M73用这一套的优势是相比传统NAS噪音很小,且小体型放置随意;这里使用和NAS上一样的容器镜像源,主要是qBittorrent作为下载软件

以下设置仅针对CentOS 7.9,其他发行版可能不同,其中Docker启动命令如下(记得建立挂卷的目录):


docker run -d \
  --name=qbittorrent \
  --network=host \
  -e PUID=1000 \
  -e PGID=1000 \
  -e TZ=Europe/London \
  -e WEBUI_PORT=8080 \
  -v /home/qbittorrent/config:/config \
  -v /home/downloads:/downloads \
  --restart unless-stopped \
  linuxserver/qbittorrent

可能遇到的问题

  1. 3.1X的内核可能存在qbt启动异常的问题,/usr/bin/qbittorrent-nox: error while loading shared libraries: libQt5Core.so.5: cannot open shared object file: No such file or directory参考群晖

  2. Linux的防火墙可能会阻止访问8080端口

    firewall-cmd --zone=public --add-port=8080/tcp --permanent
    firewall-cmd --reload
    

    部分运营商的家用宽带也会在上游阻隔8080端口的访问,此时建议将Docker启动命令的监听端口修改为8081

  3. 添加证书设置开启HTTPS访问后无法打开网页

    需要修改证书的key的权限为所有人可读

    chmod +044 keyfilepath
    

    这个在使用供应商的证书 对比 通过ACME申请的Let’s Ecrypt证书发现的差异,因为ps -ef | grep -i qbit可以看到实际使用证书的程序的UID是abc而不是root,acme在使用root权限执行申请到的证书key对abc用户是不可读的

    root       255     1  0 18:26 ?        00:00:00 s6-supervise qbittorrent
    abc        333   255  1 19:15 ?        00:00:00 /usr/bin/qbittorrent-nox --webui-port=8081
    

文件服务

SMB共享

  1. 基于系统的用户创建SMB用户

  2. 设置SMB共享目录

  3. 关闭SELinux(否则只能看到目录而看不到文件)

    临时关闭(不用重启机器)
    setenforce 0  
       
    修改/etc/selinux/config 文件
    将SELINUX=enforcing改为SELINUX=disabled
    重启机器即可
    

在使用SMB作为局域网内的文件共享方式有以下的缺点:

  • Android和IOS的播放器软件使用SMB协议播放视频时,无法达到带宽的上限(据说是受限于移动端的APP的SMB协议版本
  • SMB协议基本上只能用于局域网内的文件传输,无法作为一种安全的公网传输方式

优点:

  • 兼容性较好,Windows,MacOS自带的文件浏览器支持直接访问
  • SMB3在NAS上支持多路径,可以使用普通的千兆路由器路由器达到较快的网速

Alist

首先说WebDav协议,这个最早在群晖的NAS上只要安装就能使用,主要就是用于公网访问文件,然而我在很长一段时间,都没有在Linux上寻找一款配置简单,易用的服务端,在此期间用gohttpserver作为多端访问服务器文件的方式

之前听闻Alist可以挂载云盘后对外提供WebDav协议的访问,所以就看了下文档,其简介为:“一个支持多种存储的文件列表程序”,打开发现其实也是支持挂载本地存储的,又有网页端,完全可以实现gohttpserver的功能,初次之外页面上的分享功能也方便将Alist本身作为网盘分享文件

这里因为考虑到方便的挂载本地目录(主要是qbittorrent的下载目录)以及使用HTTPS(证书周期性的需要更换),所以使用了本地直接部署的方式,采用官网的一键脚本

curl -fsSL "https://alist.nn.ci/v3.sh" | bash -s install

特别留意首次安装后,日志会显示默认的随机密码

之后就是用nPlayer等播放器挂载webdav目录了,留意url的路径http[s]://domain:port/dav/中的dav,如果是Android的话,nPlayer可能常年没有更新了,推荐Reex

NextCloud

Nextcloud挂载SMB提供多种外部访问方式,体验下来还是SMB为主,Nextcloud的优势在于有完善的移动APP,2022年发现还是Alist更轻量好用

docker run -d \
  --name=nextcloud \
  --network=host \
  -e PUID=1000 \
  -e PGID=1000 \
  -e TZ=Asia/Shanghai \
  -v /home/nextcloud/config:/config \
  -v /home/nextcloud/data:/data \
  --restart unless-stopped \
  linuxserver/nextcloud

可能遇到的问题:nextcloud会识别首次登陆的IP之类的信息,导致无法二次访问

解决办法:需要到docker指定的config目录下修改才可以换用域名或者新的IP访问

vi ./nextcloud/config/www/nextcloud/config/config.php
<?php
$CONFIG = array (
  'memcache.local' => '\\OC\\Memcache\\APCu',
  'datadirectory' => '/data',
  'instanceid' => 'xxx',
  'passwordsalt' => 'xxx',
  'secret' => 'xxx',
  'trusted_domains' =>
  array (
    0 => '192.168.8.114',
    1 => preg_match('/cli/i',php_sapi_name())?'127.0.0.1':$_SERVER['SERVER_NAME'],
  ),
  'dbtype' => 'sqlite3',
  'version' => '21.0.0.18',
  'overwrite.cli.url' => 'https://192.168.8.114',
  'installed' => true,
);

路由负载均衡:ECMP

By: Erease
3 November 2019 at 08:00

介绍了Linux系统中等效多径路由(ECMP)及其在网络负载均衡上的应用,给出了OpenWrt下的启用的方法

参考

因为偶然发现了Linux内核中的ECMP这种负载均衡的方法,然后查了些资料,这里整理下(业余水平);文末留下了当时发现ECMP的记录

ECMP在工程方面用的很多,能找到的多是说明文档,介绍特性和成套的解决方案,但是基础的材料并不是那么好找,个人也是刚刚接触到ECMP,水平有限,这里先给出本文的主要参考文献

关于负载均衡,[译] 现代网络负载均衡与代理导论(2017)有一个较为全面的介绍,其中作者提到

关于现代网络负载均衡和代理的入门级教学材料非常稀少(dearth)。我问自己:为什么会这样呢?负载均衡是构建可靠的分布式系统最核心的概念之一。因此网上一定有高质量的相关材料?我做了大量搜索,结果发现信息确实相当稀少。 Wikipedia 上面负载均衡 和代理服务器 词条只介绍了一些概念,但并没有深入 、这些主题,尤其是和当代的微服务架构相关的部分。Google 搜索负载均衡看到的大部分都 是厂商页面,堆砌大量热门的技术词汇,而无实质细节。本文将给读者一个关于现代负载均衡和代理的中等程度介绍,希望以此弥补这一领域的信息缺失。

对此个人在经历一番搜索之后也是感同身受,所以才有了总结的想法;如果觉得上文过于“导论”(和本文的关系不大),华为的文档更贴近本文的主题一些,尽量看英文:Introduction to Load Balancing

Jakub Sitnicki’s Blog的系列博文:对Linux内核中的ECMP的实现深入浅出地做了介绍,如果感兴趣的话可以看看

最后是一篇相对详尽的中文资料,重点是ECMP在内核中的变更历史:ECMP在Linux内核的实现

原理及概念

ECMP也就是下面的路由表的情形,就是到某一个目的地址可以有多个下一跳路径可选

root@K2P:~# ip r
default metric 1
        nexthop via 10.170.72.254 dev pppoe-VWAN21 weight 1
        nexthop via 10.170.72.254 dev pppoe-VWAN22 weight 1
        nexthop via 10.170.72.254 dev pppoe-VWAN31 weight 1
        nexthop via 10.170.72.254 dev pppoe-VWAN32 weight 1
root@K2P:~# ip -6 r default
default metric 1
        nexthop via fe80::96db:daff:fe3e:8fcf dev pppoe-VWAN21 weight 1
        nexthop via fe80::96db:daff:fe3e:8fcf dev pppoe-VWAN22 weight 1
        nexthop via fe80::96db:daff:fe3e:8fcf dev pppoe-VWAN31 weight 1
        nexthop via fe80::96db:daff:fe3e:8fcf dev pppoe-VWAN32 weight 1 pref medium

看起来很简单,要弄清楚这个具体能做到什么程度就需要了解下具体的实现,这里一步一步来看

Packet/Flow

Packet对应的是IP分组(数据报、数据包),是数据在L3上传输的单元

对路由器而言,流(Flow)是共享某些特性的packet序列,比如同一个请求(连接)的packets有相同的路由路径

根据负载均衡的对象分:有Per-Packet和Per-Flow两种方式,文档中的两张图对此有个直观的对比

自然而然的会想到L4 Per-Packet负载均衡:每一个的Flow的Packets会被分流,可以实现多拨对看直播都可以加速的效果,然而本文并不会涉及:

Existing Multipath Routing implementation in Linux is designed to distribute flows of packets over multiple paths, not individual packets. Selecting route in a per-packet manner does not play well with TCP, IP fragments, or Path MTU Discovery.

故默认下文都是Per-Flow负载均衡,这就需要利用Packet的header fields信息把一个个的Packet和Flow联系起来,再进行下一跳的路由选择:

  • IPv4 L3 hash

     { Source Address, Destination Address }
    
  • IPv4 L4 hash

    { Source Address, Destination Address, Protocol, Source Port, Destination Port }
    
  • IPv6 L3 hash

    { Source Address, Destination Address, Flow Label, Next Header (protocol) }
    

    IPv6分组因为有Flow Label的存在,IPv6即使只用到L3 Hash也可以实现L4负载均衡

IPv6 Flowlabel IPv6数据报(packet)中有一个20字节的字段:流标号(流标签);进而可以用流标号取代路由表来处理流的路由,加速路由器对分组的处理;在ECMP中却提供了Flow的信息,故IPv6 ECMP是比较容易做的

L3/L4

更关键的还是负载均衡的层级,比如在多拨的情况下使用策略路由也可以做“负载均衡”,下面的命令往往提高BT的速度,这属于L3 Per-Flow负载均衡(左图):只在IP地址层级分流

ip rule add table 916
ip route add 10.173.0.0/16 via 10.170.72.254 dev pppoe-VWAN31 table 916
ip route add 10.170.0.0/16 via 10.170.72.254 dev pppoe-VWAN32 table 916

类似的方法对HTTP多线程下载并没有加速作用,对连接分流,需要L4负载均衡:多线程下载的请求之间source port不同,故L4 hash值基本不同,故会被分到不同的路径上,这样一来L4负载均衡是面向连接的就很好理解了,而内核在IPv4/IPv6上实现到一步有一段很长的历史:

Linux内核中ECMP

Linux内核的Git Commit,对发展历程感兴趣的还可以参考博文Celebrating ECMP in Linux,其中还讨论了设备的出站流量和转发流量的ECMP效果的不同,这里把ECMP的变更历史整理到一张表格中,以及对应时间的OpenWrt的内核版本信息:

Linux Kernel OpenWrt 内核版本 ECMP变更 ECMP形式
1997 | 2.1.68   IPv4 ECMP 加入内核 L3 Per-packet + route cache -> L3 Per-flow
2007 | 2.6.23   IPv4 multipath cached 移除 L3 Per-packet + route cache -> L3 Per-flow
2012.9 | 3.6   IPv4 route cache 被移除 L3 Per-packet -> L3 Per-packet
2012.10 | 3.8   IPv6 ECMP 加入内核 IPv6 Flowlabel -> IPv6 L4 Per-flow
2015.9 | 4.4 15.05 | 3.18 IPv4 ECMP:使用L3 Hash L3 Per-packet + L3 hash -> L3 Per-flow
2016.4 | 4.7   IPv4 ECMP: 增加邻居健康检查  
2017.2 17.01 | 4.4    
2017.3 | 4.12   IPv4 ECMP: 增加 L4 Hash L3 Per-packet + L3/L4 hash -> L3/L4 Per-flow
2017.11 | 4.14   IPv6 ECMP: ICMPv6 修复  
2018.1 | 4.16   IPv6 ECMP: 支持指定权重  
2018.4 | 4.17   IPv6 ECMP: 增加 L4 Hash  
2018.7 18.06 | 4.9/4.14    
2018.10 | 4.19      
2019.11 19.07 | 4.14.151    

这里可以推出(实际早期版本我也没有测试过),在默认的编译选项和内核版本下,较为实用的L4负载均衡,IPv4需要在18.06及之后的版本

IPv6由于使用了Flowlabel作为Hash的对象,根据表格,OpenWrt在15.05之后的版本就可以启用L4负载均衡

本文考虑更多的还是OpenWrt中的应用,更多信息参考本博客中的Speed_Up

启用ECMP

准备部分是从排查问题的角度来看的

在启用之前可以确认下编译内核时的下面选项,即IP: equal cost multipath,ECMP支持,较新版本的OpenWrt默认是打开的

  • CONFIG_IP_ROUTE_MULTIPATH=y

暂时不清楚使用下面的多个nexthop命令添加ECMP路由的依赖,只知道命令ip route的源于iproute2,如果出现如下报错:

Error: either “to” is a duplicate, or “nexthop” is a garbage.

可以尝试:

  • 安装ip-full再尝试,OpenWrt默认是ip-tiny,某些情况下也能使用多个nexthop命令添加ECMP路由
  • 使用route命令多次添加静态路由,可以启用IPv6的ECMP(详见文末的后记),实测在原版的OpenWrt可行
    route -A inet6 add 2000::/3 gw fe80::96db:daff:fe3e:8fcf dev pppoe-VWAN2
    route -A inet6 add 2000::/3 gw fe80::96db:daff:fe3e:8fcf dev pppoe-VWAN3
    

添加ECMP路由

这里直接引用iproute2的user Guide的Multipath routing部分:

ip route add ${addresss}/${mask} nexthop via ${gateway 1} weight ${number} nexthop via ${gateway 2} weight ${number}

Multipath routes make the system balance packets across several links according to the weight (higher weight is preferred, so gateway/interface with weight of 2 will get roughly two times more traffic than another one with weight of 1). You can have as many gateways as you want and mix gateway and interface routes, like:

ip route add default nexthop via 192.168.1.1 weight 1 nexthop dev ppp0 weight 10

Warning: the downside of this type of balancing is that packets are not guaranteed to be sent back through the same link they came in. This is called “asymmetric routing”. For routers that simply forward packets and don’t do any local traffic processing such as NAT, this is usually normal, and in some cases even unavoidable.

If your system does anything but forwarding packets between interfaces, this may cause problems with incoming connections and some measures should be taken to prevent it.

可以补充的是如果用的多个等带宽的PPPoE Interface的话,可以使用多个nexthop dev ${pppoe-dev}

修改内核运行参数

仅仅是上一步的话,可以见到在使用P2P下载时已经有负载均衡了,但是对HTTP的多线程下载并没有加速效果,因为一些Linux内核对IPv4的ECMP默认设置到L3 Hash,而且也没有开启邻居健康检查,所以需要修改下内核的运行参数,相关的具体的参数说明如下:

fib_multipath_hash_policy - INTEGER Controls which hash policy to use for multipath routes. Only valid for kernels built with CONFIG_IP_ROUTE_MULTIPATH enabled. Default: 0 (Layer 3) Possible values: 0 - Layer 3 1 - Layer 4 2 - Layer 3 or inner Layer 3 if present

fib_multipath_use_neigh - BOOLEAN Use status of existing neighbor entry when determining nexthop for multipath routes. If disabled, neighbor information is not used and packets could be directed to a failed nexthop. Only valid for kernels built with CONFIG_IP_ROUTE_MULTIPATH enabled. Default: 0 (disabled) Possible values: 0 - disabled 1 - enabled

echo "net.ipv4.fib_multipath_hash_policy=1" >> /etc/sysctl.conf
echo "net.ipv4.fib_multipath_use_neigh=1" >> /etc/sysctl.conf
sysctl -p

其他相关的内核运行参数(IPv6 Flowlabel等)可以参考ip-sysctl.txt

OpenWrt上启用ECMP

熟练的话完全根据上面的方法做了,以下是在校园网PPPoE接入下实践的,如果PPPoE拨号多播数量较多可以参考如何提高网速

准备

  • 在启用之前可以确认下编译内核时的选项CONFIG_IP_ROUTE_MULTIPATH=y(OpenWrt 18.06之后的版本默认已经开启)
  • IPv6 ECMP只在IPv6 NAT下测试过,受限于当前OpenWrt正式版的内核版本,未对内核参数做进一步测试
  • 加速的前提是下多拨可以加速(ISP限制)

添加虚拟网卡

OpenWrt安装kmod-macvlan后就可以添加虚拟网卡到不同的VLAN上

opkg update && opkg install macvlan

路由器上的RJ45网口是绑定到VLAN上的,如果是添加虚拟网卡到一个VLAN上就是单线多拨,添加到多个VLAN上就可以做多线多拨了

这里的eth0.2对应于WAN口(在Interface -> Switch可以看到WAN绑定在VLAN 2上),不同的设备可能有些许不同,这里在eth0.2上添加两个虚拟网卡

for i in  `seq 1 2`
do
  ip link add link eth0.2 name veth$i type macvlan
done

拨号

还是用脚本省事,填上用户名和密码即可,拨数为2,填下账号密码

#!/bin/sh
username=
password=
for i in  `seq 1 2`
do
  uci set network.VWAN$i=interface
  uci set network.VWAN$i.proto='pppoe'
  uci set network.VWAN$i.username="$username"
  uci set network.VWAN$i.password="$password"
  uci set network.VWAN$i.metric="$((i+1))"  
  uci set network.VWAN$i.ifname="veth$i"
  uci set network.VWAN$i.ipv6='1'
done
uci commit network

添加所有PPPoE接口到wan zone(担心影响到其他的网络环境的话手动也可以)

for i in `uci show network | grep pppoe | awk -F. '{print $2}'`
do
  uci add_list firewall.@zone[2].network=$i
done
uci commit firewall

添加ECMP路由

只用nexthop dev ${pppoe-dev}:

#IPv4
ip route replace default metric 1 nexthop dev  pppoe-VWAN1 nexthop dev  pppoe-VWAN2
#IPv6
ip -6 route replace default metric 1 nexthop dev  pppoe-VWAN1 nexthop dev pppoe-VWAN2

做完这一步就可以使用ip rip -6 r命令检查下路由表

修改内核运行参数

echo "net.ipv4.fib_multipath_hash_policy=1" >> /etc/sysctl.conf
echo "net.ipv4.fib_multipath_use_neigh=1" >> /etc/sysctl.conf
sysctl -p

测试

通过东北大学IPv6测速以及IPv4测速测试负载均衡的速度叠加效果,或者使用iftop命令查看各个接口上路由的实时速率

传入连接的问题

添加ECMP路由之后传入连接偶尔连的上,偶尔连不上,但是PT的上传之类的貌似又没有问题(可能因为上传也可以是主动发出的连接),如果有这方面需求的话需要添加策略路由,为某一接口上的地址指定路由规则,下面是IPv4的,完成之后可以从外部访问之类的,但是对其他的影响就不太清楚了,IPv6部分暂时没有测试条件…

ip rule add perf 20 from IP table 20
ip route add default table 20 dev INTERFACE

此处参考自Linux 平台上之 Multipath Routing 應用,非常难得的详细的文章,还是2001年的

后记:偶然发现的ECMP

这里保留当时的发现过程:(当时发现了这个功能非常开心,现在来看部分内容不准确,但是文末的脚本的效果要好于ECMP默认的方法)

只在K2P OpenWrt 18.06上面实践过,对LEDE 17.01无效

下面是在操作一番之后的路由表,对IPv6的测速显示网速翻了四倍

root@OpenWrt:~# ip -6 route | grep pppoe
default from 2001:250:1006:dff0::/64 via fe80::96db:daff:fe3e:8fcf dev pppoe-VWAN4 proto static metric 512 pref medium
2000:::/3 dev pppoe-VWAN4 proto static metric 256 pref medium
        nexthop via fe80::96db:daff:fe3e:8fcf dev pppoe-wan weight 1
        nexthop via fe80::96db:daff:fe3e:8fcf dev pppoe-VWAN2 weight 1
        nexthop via fe80::96db:daff:fe3e:8fcf dev pppoe-VWAN3 weight 1
        nexthop via fe80::96db:daff:fe3e:8fcf dev pppoe-VWAN4 weight 1

大致可以看出这已经是做了负载均衡,需要的只是安装好luci-app-mwan3,简单操作一下路由表,这里的网关地址和dev需要看具体情况

2000::/3 就是IPv6的单播(Unicast)地址了,在不做任何操纵的情况下,无PD的路由表(单拨)

default from 2001:250:1006:dff0::/64 via fe80::96db:daff:fe3e:8fcf dev pppoe-VWAN3 proto static metric 512 pref medium
2001:250:1006:dff0::/64 dev pppoe-VWAN3 proto static metric 256 pref medium
...

之后通过下面两条常规的添加路由表条目的命令:

route -A inet6 add 2000::/3 gw fe80::96db:daff:fe3e:8fcf dev pppoe-VWAN2
route -A inet6 add 2000::/3 gw fe80::96db:daff:fe3e:8fcf dev pppoe-VWAN3

发现路由表就出现了nexthup和负载均衡中的weight标记

root@OpenWrt:~# ip -6 route | grep pppoe
default from 2001:250:1006:dff0::/64 via fe80::96db:daff:fe3e:8fcf dev pppoe-VWAN3 proto static metric 512 pref medium
2000::/3 dev pppoe-VWAN3 proto static metric 256 pref medium
        nexthop via fe80::96db:daff:fe3e:8fcf dev pppoe-VWAN2 weight 1
        nexthop via fe80::96db:daff:fe3e:8fcf dev pppoe-VWAN3 weight 1
...

类似的网关添加过程对IPv4效果并不好,这里稍后再细说

之后还需要修改一下防火墙,这里用的还是NAT6中的那条命令

因为对路由表的修改在路由器重启之后会重置,所以还是要添加到开机的启动脚本或者添加到自定的防火墙规则之中,如果已经在NAT6配置过程中配置好了的话这一步就可以忽略了

ip6tables -t nat -I POSTROUTING -s `uci get network.globals.ula_prefix` -j MASQUERADE

实测的峰值速度可以到达双网口的满速,但是一样的问题,在UT,IDM,Thunder这种多线程下载软件下轻松满速,而在YouTube视频应用下,只有半速(甚至包括用IDM下载的情况下)

目前最新版本的mwan3也开始支持IPv6多拨了,但是个人还是觉得日常使用的话用以上的方法更加快捷,不过需要对网络有一定的了解,下面是一段针对IPv6 NAT的多拨hotplug脚本,用了一些OpenWrt开发时推荐的写法,比较实验性

#!/bin/sh
[ "$ACTION" = ifup ] || exit 0
ifaces=$(ubus call network.interface dump | jsonfilter -e '$.interface[@.proto="dhcpv6" && @.up=true].interface')
for iface_6 in $ifaces
do
  [ "$INTERFACE" = $iface_6 ]  || continue
  devices=$(ubus call network.interface dump | jsonfilter -e '$.interface[@.proto="dhcpv6" && @.up=true].device')
  ipv6_gw=$(ifstatus $iface_6 | jsonfilter -e '$.route[1].nexthop')
  for ipv6_dev in $devices
  do
    status=$(route -A inet6 add 2000::/3 gw $ipv6_gw dev $ipv6_dev 2>&1)
    logger -t NAT6 "Gateway: $ipv6_dev: Done $status"
  done
  exit 0
done
❌
❌