/
网络支持技术实现

网络支持技术实现

选择lxc容器

fde使用lxc容器,而lxc有多种网络虚拟类型,veth是waydroid原生使用的网络虚拟类型,他会在host和container(安卓)两边都创建虚拟以太网设备。

我们的目的是容器直接共享host的网络,而lxc的none网络虚拟类型刚好就是这种需求,关于lxc的网络配置可以参考注释①。

下面关于代码的修改都是基于问题为导向来调试,目前对lxc和安卓及linux关于网络的现有实现认知还比较有限,所做的修改可能在整个系统层面并不合理。

要使用lxc的none网络虚拟类型,host和container都要做一定修改。

host端

涉及 waydroid/data/configs/config_3waydroid/data/scripts/waydroid-net.sh

  • config_3 配置文件对应目前使用的 LXC 版本,而其他 config_N 配置文件是兼容很老的 LXC 版本,并且不再进行修改。在 config_3 中,只需将 LXC 的 veth 网络虚拟类型修改为 none (lxc.net.0.type = none)。LXC 在内部会根据该配置来设置网络。

  • 这里只要修改 lxc 的 veth 网络虚拟类型为 none(lxc.net.0.type = none),lcx 内部会根据该配置去设置网络。waydroid-net.sh 这个脚本文件主要作用是在 host 端创建一个网桥设备,设置各种地址信息和路由表以及启动 dns 相关的程序 dnsmasq;

  • 使用 none 类型时,waydroid-net.sh 基本不用再干什么事情,仅保留了原先的创建和删除标志文件逻辑,用于标识网络的 start 和 stop,并额外添加了防止容器对网络的操作导致的网络问题影响到 host。而增加了备份和设置网络的逻辑(安卓端已经屏蔽了对网络接口的设置,现在应该不会出现导致 host 网络不重启无法恢复的问题)。

container端

当涉及安卓端适配 LXC 的 none 网络类型时,您只需修改 config_ethernet_iface_regex 配置,该配置用于表示需要使用的以太网名称的正则表达式匹配。安卓原生默认为 eth\\d,即匹配以 eth0、eth1 等命名的接口。

根据已知的使用场景,我们需要支持以太网、USB WiFi 和手机 USB 共享网络三种类型的接口名匹配。参考 Linux 对网络接口的命名规则,正则表达式可以设置为 (en.+|wl.+|usb\\d)。基于已经做出的修改,目前已支持以太网和手机 USB 共享网络,这两种方式都支持 DHCP。

对于需要静态 IP 配置的场景,还需要进行其他相关的修改。frameworks/opt/net/ethernet 仓库实现了以太网相关功能。在使用某个网络接口时,它会读取 /data/misc/ethernet/ipconfig.txt 文件中的静态网络配置信息。因此,需要增加将静态网络配置记录在 ipconfig.txt 的逻辑,并实现读取静态网络配置的代码。这部分代码可以直接参考 Redroid 或 Anbox 的代码,它们实现了类似的功能。最后,在 rc 文件中添加程序的执行时机。

具体的代码可以参考 phytium/fde/{init.fde.rc,ipconfigstore}。现在已经可以支持以太网静态 IP 配置的场景。但是,在使用过程中可能会有一个不太好的体验。当通过 SSH 连接到主机时,启动 FDE 会导致网络断开连接,因为安卓启动时会清除网络接口的地址并设置配置,这会导致网络断开一次。

在安卓中,关于网络的大体逻辑如下:安卓框架层对网络执行的相关操作最终会由后台程序 netd 统一处理。netd 监听内核发出的 netlink 事件,并通知框架层。因此,当框架层设置网络配置后,需要等待内核事件的反馈。其他网络模块也会根据这些事件判断是否可以建立 "可用网络环境"(参考注释②)。

在 FDE 启动之前,主机的网络已经可用,实际上不需要再执行针对网络接口的地址清除和配置设置操作。然而,如果仅仅简单屏蔽这些操作,会导致安卓网络生效的延迟问题。通常情况下,在桌面启动后,需要等待2分钟(有时甚至更长时间,例如5分钟以上)才能正常使用网络。

经过调试发现,这是因为其他网络模块需要等待适当的 netlink 事件才能建立 "可用网络环境"。目前还不清楚为什么最终会收到这个 netlink 事件,因为还没有研究过 Linux 的 netlink 机制。为了解决网络生效延迟的问题,找到了一种解决方案:在 packages/modules/NetworkStack 中,通过已知的静态网络配置填充原本应由 netlink 事件传递的信息,以触发建立 "可用网络环境"。

关于 WiFi 的支持:当使用 USB WiFi 时,驱动程序会创建一个以 "wl" 开头的网络接口。然而,原生的 Redroid 并不能正常使用 USB WiFi。参考《深入理解 Android WiFi NFC 和 GPS 卷(邓凡平)》一书中的相关章节,通过加入一些工程的编译、创建必要的目录、关闭 shutdown WiFi、适配非固定的 wlan0 名称等修改,可以实现基本的 WiFi 上网功能。


具体代码修改见:

frameworks/opt/net/wifi device/phytium/fde
  • 调试过程中针对一些特定的使用场景也做了相应的考虑,假设host在fde启动前网络还未配置好,当使用以太网静态Ip配置时,临时将host网络配置好,按安卓原生的逻辑还是无法使用网络,解决办法是,增加在网络状态改变且为up的情况读静态配置的逻辑;

  • usb wifi反复插拔会出现网络无法使用的问题,针对手里测试的硬件设备发现是加载wifi驱动时,有个网络接口改名的动作导致安卓接收的netlink事件混乱,无法创建"可用网络环境",现在的解决办法是针对wifi设备,接收到设备移除事件时,依然保留之前的配置;

具体代码修改见:

frameworks/opt/net/ethernet

还可以考虑优化的方向:

  • wifi设备目前也只是支持了基本的上网功能,一般wifi设备能作为不同的角色实现不同的功能,

  • 驱动层面也会加载不同的模块;各种小概率的使用场景还缺乏探索

所有涉及的代码目录(目前均为network_dev分支):

安卓端: device/phytium/fde/ frameworks/base/ frameworks/opt/net/ethernet/ frameworks/opt/net/wifi/ packages/modules/NetworkStack/ system/netd/ 宿主机端: waydroid

注释:
https://linuxcontainers.org/lxc/manpages/man5/lxc.container.conf.5.html
②"可用网络环境"想表达的意思是网络正常可访问时,各个模块合理的状态

 

Add label

Related content

2.3 兼容性设置设计
2.3 兼容性设置设计
Read with this
网络支持技术实现
网络支持技术实现
More like this
2.6 桌面设计
2.6 桌面设计
Read with this
1.5 vscode lldb远程调试
1.5 vscode lldb远程调试
More like this
3.2.1 Linux APP融合
3.2.1 Linux APP融合
Read with this
5.1 版本更新记录
5.1 版本更新记录
More like this