该脚本只要完成IP地址、DNS和路由设置。由udhcpc程序调用。调用的函数在下面两个文件中定义:
. /lib/functions.sh:定义了一些基础操作,例如配置文件获取等
. /lib/netifd/netifd-proto.sh:定义了IP、DNS和路由的处理函数
在dhcp.script文件中setup_interface函数完成对接口的设置。标红的函数完成对路由信息的组装。
该函数在netifd-proto.sh文件中定义:
最终通过ubus接口将这些信息传递到netifd模块:
ubus中调用过程如下:
notify_proto进入的是netifd_iface_notify_proto函数,执行iface->proto->notify(iface->proto, msg);最终调用的是proto_shell_notify:
proto_shell_notify函数->proto_shell_run_command->netifd_start_process->创建子进程并执行
还有个问题没有解决是,最开始的dhcp.sh是如何被执行的?
该脚本执行有两个入口点,第一处在netifd初始化过程中
其执行了dhcp.sh '' dump,通过popen执行并返回json结果
第二处为proto_shell_handler->netifd_start_process->分配子进程执行
notify函数初始化:
在proto_shell_run_command 函数中增加如下打印:
打印信息为:
可以证明udhcpc进程是在该函数中拉起的。
那么dhcp.sh脚本是在何时调用呢?
在proto_shell_handler函数中增加如下打印:
打印结果如下,证明每个接口都是先调用dhcp.sh脚本,然后再创建udhcpc进程。
在openwrt中,udhcpc进程都是由netifd拉起的:
具体拉起udhcpc程序的脚本在/lib/netifd/proto/dhcp.sh文件中,代码如下:
执行ifstatus时是从哪里取的值?
在ubus.c文件中申请了一个静态的内存:
static struct blob_buf b;
struct blob_buf {
struct blob_attr *head;
bool (*grow)(struct blob_buf *buf, int minlen);
int buflen;
void *buf;
};
struct blob_attr {
uint32_t id_len;
char data[];
} __packed;
路由信息是从下面两个结构体中读取的:
在接收到notify的消息后,同时存储到该结构中:
netifd存储接口信息的结构为:
struct interface结构体中存在一个ubus结构体:
上面的代码是根据ubus结构指针获取interface结构指针 。
所以struct interface结构是netifid模块存储信息的总结构,该结构下保存着IP地址的所有设置:
主要的结构都挂接在该结构体中: