[openwrt]ubus (OpenWrt微总线架构)

为了在OpenWrt中提供各种守护程序和应用程序之间的进程间通信,开发了一个名为ubus的项目。它由几个部分组成,包括守护进程、库和一些额外的助手。

这个项目的核心是ubusd守护进程。它为其他守护进程提供了一个接口来注册自己以及发送消息。对于那些好奇的人,这个接口是使用Unix套接字实现的,它使用TLV(类型-长度-值)消息。

为了简化使用ubus(连接到它)的软件开发,已经创建了一个称为libubus的库。

每个守护进程都会在一个特定的命名空间下注册一组路径。每个路径都可以提供包含任意数量的参数的多个处理流程。每个处理流程回复一个响应消息。

ubus命令行客户端

ubus命令行工具允许与ubusd服务器(与所有当前注册的服务)交互。它对于调查/调试已注册的名称空间以及编写shell脚本非常有用。对于调用具有参数的过程和返回响应,它使用用户友好的JSON格式。下面是对其命令的解释。

root@OpenWrt:~# ubus

Usage: ubus [<options>] <command> [arguments...]

Options:

-s <socket>: Set the unix domain socket to connect to

-t <timeout>: Set the timeout (in seconds) for a command to complete

-S: Use simplified output (for scripts)

-v: More verbose output

-m <type>: (for monitor): include a specific message type

(can be used more than once)

-M <r|t> (for monitor): only capture received or transmitted traffic

Commands:

- list [<path>] List objects

- call <path> <method> [<message>] Call an object method

- listen [<path>...] Listen for events

- send <type> [<message>] Send an event

- wait_for <object> [<object>...] Wait for multiple objects to appear on ubus

- monitor Monitor ubus traffic

list

要找出当前在总线上运行的哪些服务,只需使用ubus列表命令。这将显示在RPC服务器上注册的所有名称空间的完整列表:

root@OpenWrt:~# ubus list

dhcp

dnsmasq

file

iwinfo

log

luci

luci-rpc

network

network.device

network.interface

network.interface.lan

network.interface.loopback

network.interface.wan

network.interface.wan6

network.rrdns

network.wireless

service

session

system

uci

您可以通过指定一个服务路径来筛选该列表:

root@OpenWrt:~# ubus list network.interface.*

network.interface.lan

network.interface.loopback

network.interface.wan

network.interface.wan6

通过-v参数可以参数某一个对象的调用参数:

root@OpenWrt:~# ubus -v list network.interface.lan

'network.interface.lan' @099f0c8b

"up": { }

"down": { }

"status": { }

"prepare": { }

"add_device": { "name": "String" }

"remove_device": { "name": "String" }

"notify_proto": { }

"remove": { }

"set_data": { }

call

调用给定名称空间内的给定过程,并可选地向其传递参数:

root@OpenWrt:~# ubus call network.interface.wan status

{

"up": true,

"pending": false,

"available": true,

"autostart": true,

"uptime": 86017,

"l3_device": "eth1",

"device": "eth1",

"address": [

{

"address": "178.25.65.236",

"mask": 21

}

],

"route": [

{

"target": "0.0.0.0",

"mask": 0,

"nexthop": "178.25.71.254"

}

],

"data": {

}

}

参数必须是一个有效的JSON字符串,并根据函数签名设置键和值:

root@OpenWrt:~# ubus call network.device status '{ "name": "eth0" }'

{

"type": "Network device",

"up": true,

"link": true,

"mtu": 1500,

"macaddr": "c6:3d:c7:90:aa:da",

"txqueuelen": 1000,

"statistics": {

"collisions": 0,

"rx_frame_errors": 0,

"tx_compressed": 0,

"multicast": 0,

"rx_length_errors": 0,

"tx_dropped": 0,

"rx_bytes": 0,

"rx_missed_errors": 0,

"tx_errors": 0,

"rx_compressed": 0,

"rx_over_errors": 0,

"tx_fifo_errors": 0,

"rx_crc_errors": 0,

"rx_packets": 0,

"tx_heartbeat_errors": 0,

"rx_dropped": 0,

"tx_aborted_errors": 0,

"tx_packets": 184546,

"rx_errors": 0,

"tx_bytes": 17409452,

"tx_window_errors": 0,

"rx_fifo_errors": 0,

"tx_carrier_errors": 0

}

}

listen

设置侦听套接字并监控传入事件:

root@OpenWrt:~# ubus listen &

root@OpenWrt:~# ubus call network.interface.wan down

{ "network.interface": { "action": "ifdown", "interface": "wan" } }

root@OpenWrt:~# ubus call network.interface.wan up

{ "network.interface": { "action": "ifup", "interface": "wan" } }

{ "network.interface": { "action": "ifdown", "interface": "he" } }

{ "network.interface": { "action": "ifdown", "interface": "v6" } }

{ "network.interface": { "action": "ifup", "interface": "he" } }

{ "network.interface": { "action": "ifup", "interface": "v6" } }

send

发送事件通知:

root@OpenWrt:~# ubus listen &

root@OpenWrt:~# ubus send foo '{ "bar": "baz" }'

{ "foo": { "bar": "baz" } }

ubus http客户端

有一个叫做uhttpd-mod-ubus的uhttpd插件,它允许ubus call使用HTTP协议。例如,在LuCI2中可以通过/ubus URL(除非被ubus_prefix选项更改)来发送POST请求。

当通过ssh登录时,您可以直接、完全地访问ubus。然而,当您在uhttpd中访问/ubus url时,uhttpd首先查询您的呼叫是否被允许使用,以及提供ubus会话的人。*名称空间负责实现访问控制:

ubus call session access '{ "ubus_rpc_session": "xxxxx", "object": "requested-object", "function": "requested-method" }'

ubus Lua 客户端

这甚至可以在lua脚本中使用ubus。当然,在lua中不可能直接使用本机库,因此已经创建了一个额外的模块。它只是称为ubus,是lua脚本和ubus之间的一个简单接口(它内部使用libubus)。

LUCI客户端

ubus vs dbus

D-Bus非常臃肿,它的C API使用起来非常烦人,并且需要编写大量的样板代码。事实上,纯C API非常烦人,以至于它自己的API文档说:“如果你直接使用这个低级别的API,你就会注册一些痛苦。”

ubus很小,其优点是易于使用常规的C代码,并且自动使所有导出的API功能也可以用于shell脚本,无需额外的努力。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

李小白20200202

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值