Padavan插件开发笔记
背景⌗
月初偶然得知padavan固件在linux 3.4.x内核上有高人backport了3.7.x的SO_REUSEPORT
特性。对于拥有多核CPU的路由器来说,利用该特性可以显著提升SS所能承载的吞吐。手头上正好有个老旧的A3004NS,虽说有点不舍得荒野无灯的精致固件,还是拿来折腾一番。期间学习了一部分padavan固件编写插件的方法,下文以某插件为例,做简单的介绍及记录。
准备⌗
按照hanwckf
的rt-n56u说明准备编译环境。这个固件是在原版的padavan基础上增加了国内常用的一些插件,同时适配了不少常见的padavan兼容路由,在编译配置上做了简化,其他固件可能在一部分配置上有所出入。
插件相关文件⌗
trunk/
|-- configs
| |-- templates
| | |-- A3004NS.config // 路由器适配文件,新增的插件编译选项开关可在此处追加
| | └-- ...
| └-- ...
|-- user
| |-- Makefile // 控制所有插件的编译,和路由器配置联动达到插件可选化编译和打包
| |-- A_PLUGIN
| | |-- Makefile // 控制单个插件的编译、打包文件产出,参照其他插件例子即可
| | └-- ...
| |-- www // 页面文件,padavan中多数为asp
| | |-- Makefile // 新增插件若有相关页面文件,需要调整该文件
| | |-- state.js // 控制页面目录中的插件页面入口,新增插件需要调整该文件
| | |-- dict // i18n实现,按需调整
| | └-- n56u_ribbon_fixed
| | |-- PLUGIN_RELATED.asp // 插件页面相关的asp文件
| | └-- ...
| |-- httpd
| | |-- variables.c // 插件相关nvram持久化数据的变量结构体定义
| | |-- web_ex.c // 处理asp后端逻辑的核心文件,主要关注暴露出来的函数,如update_variables_ex
| | |-- common.h // 关注variable,为结构体属性的类型
| | └-- ...
| |-- shared
| | |-- defaults.c // 定义插件相关变量的默认值
| | └-- ...
| └-- ...
└-- ...
插件代码⌗
插件核心代码⌗
对应目录中trunk/user/A_PLUGIN
,主要通过Makefile编译插件并将产出的(部分)二进制文件加入固件。多数情况下需要调整编译选项,参考其他插件例子即可。需要注意的一点是,在整体编译固件时插件时若需要重新运行configure,要删除产出的config_done文件。
编译开关⌗
在trunk/user/Makefile
中关联对应插件的目录,如dir_y += transmission
,即可添加transmission到编译列表。
若需要通过路由器适配文件配置插件编译可选,则可以改为dir_$(CONFIG_FIRMWARE_INCLUDE_TRANSMISSION) += transmission
, 并在trunk/configs/templates/XXX.config
中配置CONFIG_FIRMWARE_INCLUDE_TRANSMISSION=y/n
页面代码⌗
页面代码一般简单插件仅需提供asp文件,若存在额外的js或css文件,同样放在trunk/user/www
目录下,调整trunk/user/www/Makefile
文件即可。
核心流程⌗
页面的核心逻辑是提交的数据通过httpd服务暴露的函数入口更新到nvram或持久化的文件中。对此padavan约定了一套处理的通用流程。
- 页面通过form post提交到
start_apply.htm
start_apply.htm
调用相应的后端update_variables
、asus_nvram_commit
以及notify_services
update_variables
通过参数中的sid_list
找到对应的在trunk/user/httpd/variables.c
中定义的结构体变量,同时将其他参数映射到结构体定义的成员变量上。校验通过后,逐一更新到nvram或写到相应文件(详见trunk/user/httpd/web_ex.c
中的update_variables_ex
函数逻辑)- 提交变更到nvram(持久化)
- 若需要,通知触发相关关服务,如系统重启等操作
nvram/文件内容输出⌗
- 页面上展示nvram中的变量,使用
<% nvram_get_x("","VARIABLE"); %>
- 页面上输出文件内容,使用
<% nvram_dump("PREFIX.VARIABLE", ""); %>
nvram变量更新⌗
一般情况无需关注,提交的参数名与插件结构体中的变量名相同即可。如:
|
|
http提交参数中包含dns_forwarder_server
,同时sid_list
指定为dnsforwarderConf;
, 即可更新到nvram中的dns_forwarder_server
变量。
文件内容更新⌗
关于rom storage中文件内容的更新,是通过将结构体变量单元(variable
,见trunk/user/httpd/common.h
)中的longname
设置为File
,以在trunk/user/httpd/web_ex.c
的validate_asp_apply
函数改写为对应的文件路径实现更新的。如:
|
|
|
|
通过阅读代码可知,文件类型的variable
有多个预定义的路径(见trunk/user/httpd/httpd.h
),普通插件一般使用scripts
目录即可,变量名格式需要为scripts.xxx
,有如下映射:
scripts.FILE_NAME
->/etc/storage/FILE_NAME