Openwrt netifd解析

Overview

Openwrt为网络接口管理和配置创建了一个单独的project,netifd。不同于其他发行版上针对同样问题领域采用的方案,netifd的目标是更适合在嵌入式的home-gateway上使用,因此也具有一些特点。

Package组成

netifd包含下面这些组件:

  1. Shell脚本:/sbin/ifup, /sbin/ifdown(link to ifup), /sbin/ifstatus, /sbin/devstatus
  2. init.d脚本:/etc/init.d/network
  3. hotplug2脚本:/etc/hotplug.d/iface/00-netstate, /etc/hotplug.d/iface/10-sysctl
  4. udhcpc脚本:/usr/share/udhcpc/default.script
  5. netifd守护进程binary: /sbin/netifd

下面对这些组件,逐一进行分析,以期理解netifd的基本工作机制.

Shell脚本

/sbin/ifup

如前所述,ifdown实际上是指向ifup的符号链接,因此这两个脚本由同一个文件ifup实现。下面是其语法:

ifup的脚本里面,关于wifi的操作是通过/sbin/wifi脚本执行的,所以在这里暂时不讨论。关于normal的if down/up操作,这个脚本是通过ubus命令来实现的。下面是一个if_call() function:

可以看到这个function有一个参数,是interface,然后还使用了一个全局参数, modes, 在ifup脚本里面被定义,如下:

所以当执行ifdown lan时,对应的ubus命令为”ubus call network.interface.lan down”;执行ifup lan时,ubus命令为两条,先执行”ubus call network.interface.lan down”,然后是”ubus call network.interface.lan up”.

ubus & ubusd

Openwrt提供了一个ubus系统,它类似于桌面Linux系统的dbus,目标也是提供系统级的IPC和RPC。ubus在设计理念上与dbus基本保持一致,区别在于简化的API和简练的模型,以适应于embedded router的特殊环境。
基本上来说, openwrt的ubus由下面几个组件组成:

  1. ubusd,这个是ubus系统的后台进程,负责注册unix domain socket,分派ubus消息和事件等;
  2. ubus,这是一个CLI utility,可以通过它访问ubus系统. ubus的帮助信息如下:

    ubus提供的command有4种: list, call, listen & send, 通过这四种command,可以访问注册到ubus系统的服务
  3. 最后是使用ubus的各个应用程序。这些应用程序可以在ubus系统中注册RPC接口,提供相应的服务。而其他程序可以使用这些接口,来访问这些服务。

      netifd的ubus RPC接口

      netifd在ubus系统中注册了的object如下:

      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
      root @ OpenWrt : / # ubus list -v
      'network' @ 25a06dad
      "restart" : { }
      "reload" : { }
      "add_host_route" : { "target" : "String" , "v6" : "Boolean" }
      "get_proto_handlers" : { }
      'network.device' @ 9d97d655
      "status" : { "name" : "String" }
      "set_alias" : { "alias" : "(unknown)" , "device" : "String" }
      "set_state" : { "name" : "String" , "defer" : "Boolean" }
      'network.interface.lan' @ f9e7258b
      "up" : { }
      "down" : { }
      "status" : { }
      "prepare" : { }
      "add_device" : { "name" : "String" }
      "remove_device" : { "name" : "String" }
      "notify_proto" : { }
      "remove" : { }
      "set_data" : { }
      'network.interface.loopback' @ 6d026db0
      "up" : { }
      "down" : { }
      "status" : { }
      "prepare" : { }
      "add_device" : { "name" : "String" }
      "remove_device" : { "name" : "String" }
      "notify_proto" : { }
      "remove" : { }
      "set_data" : { }
      'network.interface.wan' @ ade92c65
      "up" : { }
      "down" : { }
      "status" : { }
      "prepare" : { }
      "add_device" : { "name" : "String" }
      "remove_device" : { "name" : "String" }
      "notify_proto" : { }
      "remove" : { }
      "set_data" : { }

      每个object所提供的RPC接口名称,以及接口参数类型都可以通过ubus得到。

      netifd interface RPC

      netifd为每个interface object注册了一组相同的methods,如下:

      然后可以发现,netifd里面还有一个protocol handler的概念,也就是对不同的interface protocol,可以提供不同的handler,来响应各种可能的事件。最常见的static类型的protocol,内置在netifd中。而dhcp,pppoe等类型的协议,则以shell script的形式提供。

      netifd protocol handler插件

      netifd的protocol handler插件位于/lib/netifd/proto/目录下,名称统一为*.sh。

      • 0
        点赞
      • 1
        收藏
        觉得还不错? 一键收藏
      • 0
        评论

      “相关推荐”对你有帮助么?

      • 非常没帮助
      • 没帮助
      • 一般
      • 有帮助
      • 非常有帮助
      提交
      评论
      添加红包

      请填写红包祝福语或标题

      红包个数最小为10个

      红包金额最低5元

      当前余额3.43前往充值 >
      需支付:10.00
      成就一亿技术人!
      领取后你会自动成为博主和红包主的粉丝 规则
      hope_wisdom
      发出的红包
      实付
      使用余额支付
      点击重新获取
      扫码支付
      钱包余额 0

      抵扣说明:

      1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
      2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

      余额充值