zhangguanzhang's Blog

[持续更新] - Openwrt USB 网络

字数统计: 2.1k阅读时长: 11 min
2021/09/03

about

记录下 openwrt 下 usb 网络的折腾,后续折腾这块内容的话也在这个文章内更新

N1 上的 usb 网络共享折腾

固件依赖

暂时没完全区分 usb 网络共享和 usb-cdc 的关系,所以我编译的时候把很多 usb-net-xxx 都编译进去了

听其他大佬说编译的时候主要有下面的包:

  • 安卓: kmod-usb-net kmod-usb-net-rndis
  • 苹果: kmod-usb-net-ipheth usbmuxd

建议下面这些也安装上方便调试:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
CONFIG_PACKAGE_luci-proto-3g=y
CONFIG_PACKAGE_luci-proto-ncm=y
CONFIG_PACKAGE_luci-proto-qmi=y

CONFIG_BUSYBOX_DEFAULT_LSPCI=y
CONFIG_BUSYBOX_DEFAULT_LSUSB=y
CONFIG_BUSYBOX_DEFAULT_IPROUTE=y

CONFIG_PACKAGE_usb-modeswitch=y
CONFIG_PACKAGE_usbutils=y
CONFIG_PACKAGE_usbreset=y
CONFIG_PACKAGE_qmi-utils=y
CONFIG_PACKAGE_libqmi=y

CONFIG_PACKAGE_bind-dig=y
CONFIG_PACKAGE_tcpdump=y

CONFIG_PACKAGE_pciutils=y

这些好像是 usb 4g 网卡的包,一般是 E3372(联通4G) 和 E8372(全网通4G版本) ,

缺省应该都可以用hilink模式,把下面这些驱动装上即可:

1
2
3
4
5
hilink mode: hilink mode 的网卡名 是  ethX 也可以说 usb0,ncm模式的则是wwan0, lsusb 或者 usb-mode -l 查看设备识别否
kmod-usb-net-rndis kmod-usb-net kmod-usb2 usb-modeswitch

NCM mode:
gcom kmod-usb-net-huawei-cdc-ncm kmod-usb2 usb-modeswitch kmod-usb-serial-wwan
1
2
CONFIG_PACKAGE_uqmi=y
kmod-usb-acm kmod-usb-net kmod-usb-net-qmi-wwan kmod-usb-ohci kmod-usb-serial kmod-usb-serial-option

实战

N1 建议开下无线,虽然辣鸡,但是它只有一个网口,方便我们操作。我是我的 redmi k30s usb 网络共享插给 N1,另一个手机连 N1 无线后 ssh 上去敲命令的。

先备份下网络配置文件,防止后面搞崩了。

1
cp /etc/config/network /etc/config/network.bak

插上去后有个 usb0 网卡

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
root@OpenWrt:~# ip a s
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: sit0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN group default qlen 1000
link/sit 0.0.0.0 brd 0.0.0.0
3: ip6tnl0@NONE: <NOARP> mtu 1452 qdisc noop state DOWN group default qlen 1000
link/tunnel6 :: brd :: permaddr d636:b99c:d56d::
4: eth0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc mq master br-lan state DOWN group default qlen 1000
link/ether 0e:02:db:93:b8:20 brd ff:ff:ff:ff:ff:ff
5: tunl0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN group default qlen 1000 link/ipip 0.0.0.0 brd 0.0.0.0
6: dummy0: <BROADCAST,NOARP> mtu 1500 qdisc noop state DOWN group default qlen 1000
link/ether f2:09:65:33:97:88 brd ff:ff:ff:ff:ff:ff
7: bond0: <BROADCAST,MULTICAST,MASTER> mtu 1500 qdisc noop state DOWN group default qlen 1000
link/ether 7e:ad:dd:05:72:66 brd ff:ff:ff:ff:ff:ff
8: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel master br-lan state UP group default qlen 1000
link/ether 0e:02:db:93:b8:1f brd ff:ff:ff:ff:ff:ff
inet6 fe80::c02:dbff:fe93:b81f/64 scope link
valid_lft forever preferred_lft forever
9: br-lan: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether 0e:02:db:93:b8:20 brd ff:ff:ff:ff:ff:ff
inet 192.168.1.1/24 brd 192.168.1.255 scope global br-lan
valid_lft forever preferred_lft forever
inet6 fd4e:8614:5748::1/60 scope global noprefixroute
valid_lft forever preferred_lft forever
inet6 fe80::c02:dbff:fe93:b820/64 scope link
valid_lft forever preferred_lft forever
10: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:14:ab:d8:da brd ff:ff:ff:ff:ff:ff
inet 172.31.0.1/24 brd 172.31.0.255 scope global docker0
valid_lft forever preferred_lft forever
11: usb0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
link/ether 82:e0:7e:db:2c:25 brd ff:ff:ff:ff:ff:ff

使用 udhcpc 发送 dhcp 请求

1
2
3
4
5
6
root@OpenWrt:~# udhcpc -i usb0
udhcpc: started, v1.33.1
udhcpc: sending discover
udhcpc: sendto: Network is down
udhcpc: read error: Network is down, reopening socket
udhcpc: sending discover

查看下 usb,确实有我的 手机,居然要手动 up 它

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
root@OpenWrt:~# lsusb
Bus 001 Device 004: ID 2717:ff80 Xiaomi M2007J3SC
Bus 002 Device 001: ID 1d6b:0003 Linux 5.13.13-flippy-63+ xhci-hcd xHCI Host Controller
Bus 001 Device 001: ID 1d6b:0002 Linux 5.13.13-flippy-63+ xhci-hcd xHCI Host Controller

root@OpenWrt:~# ip link set usb0 up
root@OpenWrt:~# ip a s usb0

13: usb0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UNKNOWN group default qlen 1000
link/ether 0a:01:0f:46:3a:e6 brd ff:ff:ff:ff:ff:ff
inet6 fe80::801:fff:fe46:3ae6/64 scope link
valid_lft forever preferred_lft forever
root@OpenWrt:~# udhcpc -i usb0
udhcpc: started, v1.33.1
udhcpc: sending discover
udhcpc: sending select for 192.168.42.128
udhcpc: lease of 192.168.42.128 obtained, lease time 3599
udhcpc: ip addr add 192.168.42.128/255.255.255.0 broadcast 192.168.42.255 dev usb0
udhcpc: setting default routers: 192.168.42.129

请求过程中也把默认路由设置为它了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
root@OpenWrt:~# ip r g 1
1.0.0.0 via 192.168.42.129 dev usb0 src 192.168.42.128 uid 0
cache
root@OpenWrt:~# ping baudu.com
^C
root@OpenWrt:~# ping 114.114.114.114
PING 114.114.114.114 (114.114.114.114): 56 data bytes
64 bytes from 114.114.114.114: seq=0 ttl=64 time=73.218 ms
64 bytes from 114.114.114.114: seq=1 ttl=70 time=45.460 ms
64 bytes from 114.114.114.114: seq=2 ttl=71 time=43.823 ms
64 bytes from 114.114.114.114: seq=3 ttl=81 time=40.963 ms
^C
--- 114.114.114.114 ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max = 40.963/50.866/73.218 ms
root@OpenWrt:~#

去 web 上,网络接口,把 wan 的口子(如果没有就添加),dhcp客户端,接口设选 usb0。添加后设置下新添加接口的 防火墙设置 ,将其设置为 wan: ,要注意,上面后的 dns 是 dhcp 获取的,也就是 dnsmasq 使用 解析文件:

1
/tmp/resolv.conf.auto

你使用自己的dns 例如 adg 之类的,可以关闭上面的:

1
2
3
4
uci set dhcp.@dnsmasq[0].server='127.0.0.1#5300'
uci set dhcp.@dnsmasq[0].noresolv='1'
uci commit dhcp
/etc/init.d/dnsmasq reload

hotplug 脚本

自行百度或者谷歌了解基础,先获取基础信息:

1
2
3
4
5
6
7
8
9
10
cat > /etc/hotplug.d/net/01_usb-rndis.sh <<'EOF'
#!/bin/sh

# "$DEVTYPE" = usb_device
# [ "$ACTION" = add -a "$DEVTYPE" = usb_device ] || exit 0

. /lib/functions.sh
. /lib/netifd/netifd-proto.sh
logger -t RNDIS: "$(env)"
EOF

手机插 usb 后,logread 查看日志:

1
2
3
user.notice RNDIS:: DEVNAME=bus/usb/001/003 USER=root ACTION=add SHLVL=1 HOME=/ SEQNUM=2012 BUSNUM=001 MAJOR=189 HOTPLUG_TYPE=usb DEVPATH=/devices/platform/17000000.usb/usb1/1-1 LOGNAME=root DEVICENAME=1-1 TERM=linux SUBSYSTEM=usb PATH=/usr/sbin:/usr/bin:/sbin:/bin MINOR=2 TYPE=0/0/0 DEVNUM=003 PRODUCT=2717/ff88/419 PWD=/ DEVTYPE=usb_device

user.notice RNDIS:: USER=root ACTION=add SHLVL=1 HOME=/ SEQNUM=2059 IFINDEX=17 HOTPLUG_TYPE=net DEVPATH=/devices/platform/17000000.usb/usb1/1-1/1-1:1.0/net/usb0 LOGNAME=root DEVICENAME=usb0 TERM=linux SUBSYSTEM=net PATH=/usr/sbin:/usr/bin:/sbin:/bin INTERFACE=usb0 PWD=/

根据此信息编写出我自己的 usb-rndis 的 hotplug 脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
cat > /etc/hotplug.d/net/01_usb-rndis.sh << 'EOF'
#!/bin/sh

# [ "$DEVICENAME" = usb0 ]
echo $DEVPATH | grep -Eq '/net/usb0$' || exit 0

. /lib/functions.sh
. /lib/netifd/netifd-proto.sh
case "$ACTION" in
add)
if [ -L /sys/class/net/usb0 ];then
ip link set usb0 up
udhcpc -i usb0
#sleep 1
key_name=ifname
uci show network.loopback | grep -Eq '\.device=' && key_name=device
uci set network.mobile=interface
uci set network.mobile.proto='dhcp'
uci set network.mobile.${key_name}='usb0'
# 设置本机 dns 好像会 loop
# op_local_ip=$(ip r s | grep -Ev 'docker|usb0' | awk '$0~"src"{print $NF}')
# uci set network.mobile.dns="${op_local_ip}"
uci show network.mobile.dns 2>/dev/null && uci delete network.mobile.dns || true

uci commit network
#sleep 1
ifup mobile

wan_zone_network=$(uci get firewall.@zone[1].network)

if ! echo "$wan_zone_network" | grep -q mobile;then
uci set firewall.@zone[1].network="$wan_zone_network mobile"
uci commit firewall
fi
if ! grep -Eq '^\s*nameserver ' /etc/resolv.conf;then
echo 'nameserver 127.0.0.1 # sed-for-rndis' >> /etc/resolv.conf
fi
fi
;;
esac
EOF

理论上获取配置和修改配置应该使用 /lib/functions.sh 里提供的函数,但是我没细看,上面脚本我在非 N1 设备测试的。

命令设置 wifi

1
2
3
4
5
6
7
8
9
10
11
12
13
# https://openwrt.org/docs/guide-quick-start/basic_wifi

uci set wireless.default_radio0.ssid='OpenWrt-5G'
uci set wireless.default_radio0.encryption='psk-mixed'
uci set wireless.default_radio0.key='password'
uci set wireless.radio0.legacy_rates='1'

uci set wireless.default_radio1.ssid='OpenWrt'
uci set wireless.default_radio1.encryption='psk-mixed'
uci set wireless.default_radio1.key='password'
uci set wireless.radio1.legacy_rates='1'
uci commit wireless
wifi reload

手机和 WIFI 断开

发现连 OP WIFI 的手机上玩游戏经常断开,查看日志:

1
2
3
4
5
6
7
8
9
$ logread
Wed Jul 24 14:12:00 2024 daemon.info hostapd: phy1-ap0: STA 28:16:7f:3d:xx:xx IEEE 802.11: disconnected due to excessive missing ACKs
Wed Jul 24 14:12:00 2024 daemon.notice hostapd: phy1-ap0: AP-STA-DISCONNECTED 28:16:7f:3d:xx:xx
Wed Jul 24 14:12:23 2024 daemon.info hostapd: phy1-ap0: STA 28:16:7f:3d:xx:xx IEEE 802.11: authenticated
Wed Jul 24 14:12:23 2024 daemon.info hostapd: phy1-ap0: STA 28:16:7f:3d:xx:xx IEEE 802.11: associated (aid 2)
Wed Jul 24 14:12:23 2024 daemon.notice hostapd: phy1-ap0: AP-STA-CONNECTED 28:16:7f:3d:xx:xx auth_alg=open
Wed Jul 24 14:12:23 2024 daemon.info hostapd: phy1-ap0: STA 28:16:7f:3d:xx:xx RADIUS: starting accounting session 9DECBE0A8AF1BB8A
Wed Jul 24 14:12:23 2024 daemon.info hostapd: phy1-ap0: STA 28:16:7f:3d:xx:xx WPA: pairwise key handshake completed (RSN)
Wed Jul 24 14:12:23 2024 daemon.notice hostapd: phy1-ap0: EAPOL-4WAY-HS-COMPLETED 28:16:7f:3d:xx:xx

/etc/config/wireless 下的 wifi-iface 下增加了 option disassoc_low_ack '0'(对应 web 上 在低 Ack 应答时断开连接) 后执行 wifi 命令。

参考:

CATALOG
  1. 1. about
  2. 2. N1 上的 usb 网络共享折腾
    1. 2.1. 固件依赖
    2. 2.2. 实战
    3. 2.3. hotplug 脚本
    4. 2.4. 命令设置 wifi
    5. 2.5. 手机和 WIFI 断开
  3. 3. 参考: