Learn about OpenWrt

Learn about OpenWrt

Contributing

Project

    ubus (OpenWrt micro bus architecture)

    See also:What is UBUS?

    To provideInter-process communication between various daemons and applications in OpenWrt a project calledubus has been developed.It consists of several parts including daemon, library and some extra helpers.

    The heart of this project is theubusd daemon.It provides an interface for other daemons to register themselves as well as sending messages.For those curious, this interface is implemented using Unix sockets and it usesTLV (type-length-value) messages.

    To simplify development of software usingubus (connecting to it) a library calledlibubus has been created.

    Every daemon registers a set of paths under a specific namespace.Every path can provide multiple procedures with any number of arguments.Procedures can reply with a message.

    The code is published underLGPL 2.1 license and can be found via git athttps://git.openwrt.org/project/ubus.git.

    Command-line ubus tool

    Theubus command line tool allows to interact with theubusd server (with all currently registered services).It's useful for investigating/debugging registered namespaces as well as writing shell scripts.For calling procedures with parameters and returning responses it uses the user-friendly JSON format.Below is an explanation of its commands.

    Help output

    # ubusUsage: 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 trafficCommands: - 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 - monitorMonitor ubus traffic

    list

    To find out which services are currently running on the bus simply use theubus list command.This will show a complete list of all namespaces registered with the RPC server:

    # ubus listdhcpdnsmasqfileiwinfologluciluci-rpcnetworknetwork.devicenetwork.interfacenetwork.interface.lannetwork.interface.loopbacknetwork.interface.wannetwork.interface.wan6network.rrdnsnetwork.wirelessservicesessionsystemuci

    You can filter the list by specifying a service path:

    # ubus list network.interface.*network.interface.lannetwork.interface.loopbacknetwork.interface.wannetwork.interface.wan6

    To find out which procedures/methods and their argument signatures a specific service provides add-v in addition to the namespace path:

    # 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

    Calls a given procedure within a given namespace and optionally pass arguments to it:

    # 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":{ }}

    The arguments must be a valid JSON string, with keys and values set according to the function signature:

    # 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

    Set up a listening socket and observe incoming events:

    # ubus listen &# ubus call network.interface.wan down{"network.interface":{"action":"ifdown","interface":"wan"}}# 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

    Send an event notification:

    # ubus listen &# ubus send foo '{ "bar": "baz" }'{"foo":{"bar":"baz"}}

    Access to ubus over HTTP

    There is anuhttpd plugin calleduhttpd-mod-ubus that allowsubus calls usingHTTP protocol.For example this is used inLuCI2.Requests have to be sent to the/ubusURL (unless changed byubus_prefix option) using thePOST method.This interface usesjsonrpc v2.0 There are a few steps that you will need to understand.

    If uhttpd-mod-ubus is installed, uhttpd automatically configures it and enables it, by default at /ubus, but you canconfigure thisAlso if you want to use the/ubus directly from a web client you need to specifyubus_cors=1 option.

    If you are using Nginx then you may trynginx-ubus-module.For other web servers like Lighttpd you may use theubus as CGI.

    See thePostman collection with some examples of calling UBUS overHTTP

    ACLs

    While logged in via ssh, you have direct, full access to ubus.When you're accessing the/ubus url in uhttpd however, uhttpd first queries whether your call is allowed, and whoever is providing the ubussession.* namespace is in charge of implementing the access control:

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

    This happens to berpcd at the moment, with thehttp-json interface, for friendly operation with browser code, but this is just one possible implementation.Because we're using rpcd to implement the ACLs at this time, this allows/requires (depending on your point of view) ACLs to be configured in/usr/share/rpcd/acl.d/*.json.Thenames of the files in/usr/share/rpcd/acl.d/*.json don't matter, but the top level keys define roles.The defaultACL, listed below,only defines the login methods, so you can log in, but you still wouldn't be able to do anything.

    {        "unauthenticated":{                "description":"Access controls for unauthenticated requests",                "read":{                        "ubus":{                                "session":["access","login"]}}}}

    An example of a complicatedACL, allowing quite fine grained access to different ubus modules and methods isavailable in the Luci2 project

    An example of a “security is for suckers” config, where asuperuserACL group is defined, allowing unrestricted access to everything, is shown below.This illustrates the usage of* definitions in the ACLs, but keep reading for better examples.

    Placing this file in/usr/share/rpcd/acl.d/superuser.json will help you move forward to the next steps.

    {        "superuser":{                "description":"Super user access role",                "read":{                        "ubus":{                                "*":["*"]},                        "uci":["*"],                        "file":{                                "*":["*"]}},                "write":{                        "ubus":{                                "*":["*"]},                        "uci":["*"],                        "file":{                                "*":["*"]},                        "cgi-io":["*"]}}}

    Below is an example of anACL definition that only allows access to some specific ubus modules, rather than unrestricted access to everything.

    {        "lesssuperuser":{                "description":"not quite as super user",                "read":{                        "ubus":{                                "file":["*"],                                "log":["*"],                                "service":["*"],},},                "write":{                        "ubus":{                                "file":["*"],                                "log":["*"],                                "service":["*"],},}}}

    Note: Before we leave this section, you may have noticed that there's both aubus and auci section, even though ubus has a uci method.Theuci scope is used for theuci api provided by rpcd to allow defining per-file permissions because using the ubus scope you can only sayuci set is allowed or not, but not specify that it is allowed to e.g. modify/etc/config/system but not/etc/config/network.If your application/ACL doesn't need UCI access, you can just leave out the UCI section altogether.

    Authentication

    Session management

    To login and receive a session id:

    $ curl-H'Content-Type: application/json'-d'{ "jsonrpc": "2.0", "id": 1, "method": "call", "params": [ "00000000000000000000000000000000", "session", "login", { "username": "root", "password": "secret"  } ] }'  http://your.server.ip/ubus {"jsonrpc":"2.0","id":1,"result":[0,{"ubus_rpc_session":"c1ed6c7b025d0caca723a816fa61b668","timeout":300,"expires":299,"acls":{"access-group":{"superuser":["read","write"],"unauthenticated":["read"]},"ubus":{"*":["*"],"session":["access","login"]},"uci":{"*":["read","write"]}},"data":{"username":"root"}}]}

    The session id00000000000000000000000000000000 (32 zeros) is a special null-session which only has the rights from theunauthenticated access group, only enabling thesession.login ubus call.A session has a timeout that can be specified when you login, otherwise it defaults to 5 minutes.

    If you ever receive a response like{“jsonrpc”:“2.0”,“id”:1,“result”:[6]}, that is a valid jsonrpc response, 6 is the ubus code forUBUS_STATUS_PERMISSION_DENIED (you'll get this if you try and login before setting up thesuperuser file, or any file that gives you more rights than just being allowed to attempt logins).

    To list all active sessions, tryubus call session list

    The session timeout is automatically reset on every use.There are plans to use these sessions even for luci1, but at present, if you use this interface in a luci1 environment, you'll need to manage sessions yourself.

    Actually making calls

    Now that you have aubus_rpc_session you can make calls, based on your ACLs and the available ubus services.ubus -v list is your primary documentation on what can be done, but see the rest of this page for more information.For example,ubus -v list file returns

    'file'@ff0a2c92"read":{"path":"String","base64":"Boolean"}"write":{"path":"String","data":"String","append":"Boolean","mode":"Integer","base64":"Boolean"}"list":{"path":"String"}"stat":{"path":"String"}"md5":{"path":"String"}"exec":{"command":"String","params":"Array","env":"Table"}

    The RPC-JSON container format is:

    {"jsonrpc":"2.0","id":<unique-id-to-identify-request>,"method":"call","params":[<ubus_rpc_session>,<ubus_object>,<ubus_method>,{<ubus_arguments>}]}

    The “id” key is merely echo'ed by the server, so it needs not be strictly unique, it's mainly intended for client software to easily correlate responses to previously made requests.Its type is either a string or a number, so it can be an UUID, sha1 hash, md5 sum, sequence counter, unix timestamp, etc.

    An example request to read a file/etc/board.json which contains device info would be:

    $ curl-H'Content-Type: application/json'-d'{ "jsonrpc": "2.0", "id": 1, "method": "call", "params": [ "c1ed6c7b025d0caca723a816fa61b668", "file", "read", { "path": "/etc/board.json" } ] }'  http://your.server.ip/ubus{"jsonrpc":"2.0","id":1,"result":[0,{"data":"{\n\t\"model\": {\n\t\t\"id\":\"innotek-gmbh-virtualbox\",\n\t\t\"name\":\"innotek GmbH VirtualBox\"\n\t},\n\t\"network\": {\n\t\t\"lan\": {\n\t\t\t\"ifname\":\"eth0\",\n\t\t\t\"protocol\":\"static\"\n\t\t}\n\t}\n}\n"}]}

    Here the first paramc1ed6c7b025d0caca723a816fa61b668 is theubus_rpc_session received during the login call.If you received a response like{“jsonrpc”:“2.0”,“id”:1,“error”:{“code”:-32002,“message”:“Access denied”}} then probably your session token was expired and you need to request a new one.

    To beautify output you can usejq utility:

    curl-s-H'Content-Type: application/json'-d'{ "jsonrpc": "2.0", "id": 1, "method": "call", "params": [ "c1ed6c7b025d0caca723a816fa61b668", "file", "read", { "path": "/etc/board.json" } ] }'  http://your.server.ip/ubus| jq{"jsonrpc":"2.0","id":1,"result":[0,{"data":"{\n\t\"model\": {\n\t\t\"id\":\"innotek-gmbh-virtualbox\",\n\t\t\"name\":\"innotek GmbH VirtualBox\"\n\t},\n\t\"network\": {\n\t\t\"lan\": {\n\t\t\t\"ifname\":\"eth0\",\n\t\t\t\"protocol\":\"static\"\n\t\t}\n\t}\n}\n"}]}

    In the response JSON document in theresult[1].data field contains escaped JSON with themodel andnetwork objects.To fetch the concrete model name you can parse the response with thejq program:

    curl -s -H 'Content-Type: application/json' -d '{ "jsonrpc": "2.0", "id": 1, "method": "call", "params": [ "c1ed6c7b025d0caca723a816fa61b668", "file", "read", { "path": "/etc/board.json" } ] }'  http://your.server.ip/ubus | jq -r '.result[1].data' | jq .model.name"innotek GmbH VirtualBox"

    As you can see in the example the router model is in fact just a OpenWrt runned onvirtual machine in VirtualBox.

    Lua module for ubus

    This is even possible to useubus inlua scripts.Of course it's not possible to use native libraries directly inlua, so an extra module has been created.It's simply calledubus and is a simple interface betweenlua scripts and theubus (it useslibubus internally).

    -- Load modulerequire"ubus"-- Establish connectionlocal conn= ubus.connect()ifnot connthenerror("Failed to connect to ubusd")end -- Iterate all namespaces and procedureslocal namespaces= conn:objects()for i, ninipairs(namespaces)doprint("namespace=".. n)local signatures= conn:signatures(n)for p, sinpairs(signatures)doprint("\tprocedure=".. p)for k, vinpairs(s)doprint("\t\tattribute=".. k.." type=".. v)endendend -- Call a procedurelocal status= conn:call("network.device","status",{ name="eth0"})for k, vinpairs(status)doprint("key=".. k.." value="..tostring(v))end -- Close connectionconn:close()

    Optional arguments toconnect() are a path to use for sockets (pass nil to use the default) and a per call timeout value (in milliseconds)

    local conn= ubus.connect(nil,500)-- default socket path, 500ms per call timeout

    Namespaces & Procedures

    As explained earlier, there can be many different daemons (services) registered inubus.Below you will find a list of the most common projects with namespaces, paths and procedures they provide.

    Path only contains the first context, e.g. network for network.interface.wan

    path Description Package
    dhcp dhcp server odhcpd
    file file rpcd
    hostapd acesspoints wpad/hostapd
    iwinfo wireless informations rpcd iwinfo
    log logging procd
    mdns mdns avahi replacement mdnsd
    network network netifd
    service init/service procd
    session Session management rpcd
    system system misc procd
    uci Unified Configuration Interface rpcd

    procd

    ubus system

    Package: procd

    Procedure Signature Description
    board {} returns board specific information like model and distribution code name, revision
    info {} returns real-time information about the system. “uptime”: 20756, “localtime”: 1444142264, “load”: [ 7264, 3040, 3520 ], “memory”: { “total”: 29601792, “free”: 7344128, “shared”: 458752, “buffered”: 2166784 }, “swap”: { “total”: 0, “free”: 0 }
    upgrade {} *TODO*
    watchdog {“frequency”:“Integer”,“timeout”:“Integer”,“stop”:“Boolean”,“magicclose”:“Boolean”} controls the watchdog. *ubus call system watchdog '{ “stop”: true“}'* only stops the thread triggering the watchdog. The watchdog is still counting down unless a second process is triggering the watchdog unless you enable 'magicclose', then you can manually tickle '/dev/watchdog'.
    signal {“pid”:“Integer”,”signum“:“Integer”} send a signal to a process. See man kill
    nandupgrade {“path”:“String”} *TODO*

    The values in load are the load averages over 1, 5, and 15 minutes. to get to the familiar values reported by uptime divide these numbers by 65536.0 and round to 2 decimals.

    There is a detailedblog post showing how to use, configure and manually take control over hardware watchdog with ubus commands.

    Examples

    See all methods ofsystem (to see all methods of all services registered to ubusd:ubus -v list):

    root@OpenWrt:/# ubus -v list system'system' @651f206c        "board":{}        "info":{}        "reboot":{}        "watchdog":{"frequency":"Integer","timeout":"Integer","magicclose":"Boolean","stop":"Boolean"}        "signal":{"pid":"Integer","signum":"Integer"}        "validate_firmware_image":{"path":"String"}        "sysupgrade":{"path":"String","force":"Boolean","backup":"String","prefix":"String","command":"String","options":"Table"}

    You can now call a remote method and receive a reply. A reply may be a simple integer return code or a more complete reply. Internally the bus uses a blob format, the CLI conveniently converts this to JSON.

    root@OpenWrt:/# ubus call system board{        "kernel": "4.9.198",        "hostname": "OpenWrt",        "system": "Qualcomm Atheros QCA956X ver 1 rev 0",        "model": "TP-Link TL-WR1043N\/ND v4",        "board_name": "tl-wr1043nd-v4",        "release": {                "distribution": "OpenWrt",                "version": "18.06.5",                "revision": "r7897-9d401013fc",                "target": "ar71xx\/generic",                "description": "OpenWrt 18.06.5 r7897-9d401013fc"        }}

    You can call a method and pass it some parameters by simply appending a JSON structure to the CLI command.

    root@OpenWrt:/# ubus call system signal '{ "pid": 123, "signum": 9 }'root@OpenWrt:/# echo $?0

    ubus service

    Package: procd

    service used by init scripts as well to register new services

    Path Procedure Signature Description
    serviceset{“name”:“String”,“script”:“String”,“instances”:“Table”,“triggers”:“Array”,“validate”:“Array”,“autostart”:“Boolean”,“data”:“Table”} *TODO*
    serviceadd{“name”:“String”,“script”:“String”,“instances”:“Table”,“triggers”:“Array”,“validate”:“Array”,“autostart”:“Boolean”,“data”:“Table”} *TODO*
    servicelist{“name”:“String”,“verbose”:“Boolean”} Return a list of all services and their instances. Can be filtered by name
    servicedelete{“name”:“String”,“instance”:“String”} Delete instance of a service
    serviceupdate_start{“name”:“String”} *TODO*
    serviceevent{“type”:“String”,“data”:“Table”} *TODO*
    servicevalidate{“package”:“String”,“type”:“String”,“service”:“String”} *TODO*
    serviceget_data{“name”:“String”,“instance”:“String”,“type”:“String”} *TODO*
    servicestate{“spawn”:“Boolean”,“name”:“String”} *TODO*

    netifd

    ubus network

    Package: netifd

    DESIGN document at repo of netifd

    Path Procedure Signature Description
    networkrestart{ } Restart the network, reconfigures all interfaces
    networkreload{ } Reload the network, reconfigure as needed
    network.devicestatus{ “name”: “ifname” } Dump status of given network deviceifname or all network devices if none given
    network.deviceset_state{ “name”: “ifname”, “defer”:deferred } Defer or ready the given network deviceifname, depending on the boolean valuedeferred
    network.interface.nameup{ } Bring interfacename up
    network.interface.namedown{ } Bring interfacename down
    network.interface.namestatus{ } Dump status of interfacename
    network.interface.nameprepare{ } Prepare setup of interfacename
    network.interface.nameadd_device{ “name”: “ifname” } Add network deviceifname to interfacename (e.g. for bridges:brctl addif br-nameifname)
    network.interface.nameremove_device{ “name”: “ifname” } Remove network deviceifname from interfacename (e.g. for bridges:brctl delif br-nameifname)
    network.interface.nameremove{ } Remove interfacename (?)
    network.wirelessstatus{ }

    rpcd

    Projectrpcd: OpenWrt ubus RPC daemon for backend server is a set of small plugins providing sets ofubus procedures in separated namespaces.These plugins are not strictly related to any particular software (likenetifd ordhcp) so it wasn't worth it to implement them as separated projects.rpcd and the desired plugins must be available or installed via opkg.After installing remember to enable and start the service viaservice rpcd enable andservice rpcd start .

    ubus file

    Package: rpcd

    With pluginrpcd-mod-file enabled:

    Path Procedure Signature Description
    fileread{ “path”: “String”, “base64”:Boolean } Read a file contents. The file path is encoded in Base64 if thebase64 param set to “true”
    filewrite{ “path”: “String”, “data”: “String”, “append”:Boolean, “mode”:Integer, “base64”:Boolean } Write adata to a file bypath. The file path is encoded in Base64 if thebase64 param set to “true”. If theappend param is “true” then file is not overwritten but the new content is added to the end of the file. Themode param if specified represent file permission mode.
    filelist{ “path”: “String” } ?
    filestat{ “path”: “String” } ?
    filemd5{ “path”: “String” } ?
    fileexec{ “command”: “String”, “params”: “Array”, “env”: “Table” } ?

    ubus iwinfo

    With pluginrpcd-mod-iwinfo enabled:

    Path Procedure Signature Description
    iwinfodevices{ } ?
    iwinfoinfo{ “device”: “device” } ?
    iwinfoscan{ “device”: “device” } ?
    iwinfoassoclist{ “device”: “device”, “mac”: “mac” } ?
    iwinfofreqlist{ “device”: “device” } ?
    iwinfotxpowerlist{ “device”: “device” } ?
    iwinfocountrylist{ “device”: “device” } ?
    iwinfophyname{ “section”: “device” } ?

    Always included inrpcd:

    ubus session

    Path Procedure Signature Description
    sessioncreate{ “timeout”:timeout } Create a new session and return its ID, set the session timeout totimeout in seconds (set0 for no expire)
    sessionlist{ “ubus_rpc_session”: “sid” } Dump session info specified bysid, if no ID is given, list all sessions
    sessiongrant{ “ubus_rpc_session”: “sid”, “scope”: “scope”, “objects”: [ [ “path”, “func” ], ... ] } Within the session identified bysid grant access to all specified proceduresfunc in the namespacepath listed in theobjects array
    sessionrevoke{ “ubus_rpc_session”: “sid”, “scope”: “scope”, “objects”: [ [ “path”, “func” ], ... ] } Within the session identified bysid revoke access to all specified proceduresfunc in the namespacepath listed in theobjects array. Ifobjects is unset, revoke all access
    sessionaccess{ “ubus_rpc_session”: “sid”, “scope”: “scope”, “object”: “path”, “function”: “function” } Query whether access to the specifiedfunction in the namespacepath is allowed
    sessionset{ “ubus_rpc_session”: “sid”, “values”: { “key”:value, ... } } Within the session identified bysid store the given arbitrary values under their corresponding keys specified in thevalues object
    sessionget{ “ubus_rpc_session”: “sid”, “keys”: [ “key”, ... ] } Within the session identified bysid retrieve all values associated with the given keys listed in thekeys array. If the key array is unset, dump all key/value pairs
    sessionunset{ “ubus_rpc_session”: “sid”, “keys”: [ “key”, ... ] } Within the session identified bysid unset all keys listed in thekeys array. If the key list is unset, clear all keys
    sessiondestroy{ “ubus_rpc_session”: “sid” } Terminate the session identified by the given IDsid
    sessionlogin{ “username”: “username”, “password”: “password”, “timeout”:timeout } Authenticate with rpcd and create a new session with access rights as specified in the ACLs

    Note: When using ubus overHTTP, settingubus_rpc_session isn't allowed, it's automatically set to the calling session.

    Note: Sessions are stored in memory so they will persist as long asrpcd is running

    login call description
    Example of manual session creation

    Create a session then grant access to all functions offile and to theboard object function ofsystem object.Also set a custom attributeusername toalice then check if the sid have an access tosystem.reboot function (and there is npo such access)

    root@OpenWrt:~# ubus call session create '{"timeout": 3600}'{        "ubus_rpc_session": "8c1af812b4b148fcbb92434c74cf61c1",        "timeout": 3600,        "expires": 3600,        "acls": {        },        "data": {        }}root@OpenWrt:~# ubus call session grant '{"ubus_rpc_session": "bf11e5cd01cd262ae692600a6a45ccfc", "scope": "write", "objects": [["file", "*"], ["system", "board"]]}'root@OpenWrt:~# ubus call session set '{"ubus_rpc_session": "bf11e5cd01cd262ae692600a6a45ccfc", "values": { "username": "alice" } }'root@OpenWrt:~# ubus call session list '{"ubus_rpc_session": "bf11e5cd01cd262ae692600a6a45ccfc"}'{        "ubus_rpc_session": "bf11e5cd01cd262ae692600a6a45ccfc",        "timeout": 3600,        "expires": 3600,        "acls": {                "ubus": {                        "file": [                                "*"                        ],                        "system": [                                "board"                        ]                }        },        "data": {                "username": "alice"        }}root@OpenWrt:~# ubus call session access '{ "ubus_rpc_session": "bf11e5cd01cd262ae692600a6a45ccfc", "scope": "ubus", "object": "system", "function": "reboot" }'{        "access": false}

    ubus uci

    Package: rpcd

    # ubus -v list uci'uci' @4eb774a8"configs":{}"get":{"config":"String","section":"String","option":"String","type":"String","match":"Table","ubus_rpc_session":"String"}"state":{"config":"String","section":"String","option":"String","type":"String","match":"Table","ubus_rpc_session":"String"}"add":{"config":"String","type":"String","name":"String","values":"Table","ubus_rpc_session":"String"}"set":{"config":"String","section":"String","type":"String","match":"Table","values":"Table","ubus_rpc_session":"String"}"delete":{"config":"String","section":"String","type":"String","match":"Table","option":"String","options":"Array","ubus_rpc_session":"String"}"rename":{"config":"String","section":"String","option":"String","name":"String","ubus_rpc_session":"String"}"order":{"config":"String","sections":"Array","ubus_rpc_session":"String"}"changes":{"config":"String","ubus_rpc_session":"String"}"revert":{"config":"String","ubus_rpc_session":"String"}"commit":{"config":"String","ubus_rpc_session":"String"}"apply":{"rollback":"Boolean","timeout":"Integer","ubus_rpc_session":"String"}"confirm":{"ubus_rpc_session":"String"}"rollback":{"ubus_rpc_session":"String"}"reload_config":{}
    Path Procedure Signature Description
    uciconfigs{ }

    List all available configs

    Example:

    # ubus call uci configs '{"ubus_rpc_session":"2db687f321a60414e77677bbb5dd6d6f"}'{"configs": ["dhcp","dropbear","firewall","luci","network","radius","rpcd","system","ubootenv","ucitrack","uhttpd","wireless"]}
    uciget{ “config”: “config”, “section”: “sname”, “type”: “type”, “option”: “oname” }

    Return the requested uci value(s), all arguments are optional.

    1. When called without argument or with empty object: return an array of package names in theconfigs field
    2. When called withconfig set: return an object containing all sections containing all options in a field named after the package
    3. When called withconfig andtype set: return an object containing all sections of typetype containing all options in a field named after the package
    4. When called withconfig andsname set: return an object containing all options of the section in a field named after the section
    5. When called withconfig andtype andoname set: return an object containing the value of each option namedoname within a section of typetype in a field named after the matched section
    6. When called withpackage andsname andoname set: return the result string in a field namedoname in case of options or an array of result strings in a field namedoname in case of list options

    Return messages:

    1. { “config”: { “sname1”: { “.type”: “type1”, “option1”: “value1”, “option2”: [ “value2.1”, ... ], ... }, ... } }
    2. { “config”: { “sname1”: { “.type”: “type”, “option1”: “value1”, “option2”: [ “value2.1”, ... ], ... }, ... } }
    3. { “sname”: { “.type”: “type”, “option1”: “value1”, “option2”: [ “value2.1”, ... ], ... } }
    4. { “sectionname1”: “value1”, “sectionname2”: [ “value2.1”, ... ], ... }
      1. { “oname”: “value1” }
      2. { “oname”: [ “value1.1”, ... ] }

    Example:

    # ubus call uci get '{"ubus_rpc_session":"2db687f321a60414e77677bbb5dd6d6f", "config":"wireless", "section":"wifinet2"}'{"values": {".anonymous": false,".type": "wifi-iface",".name": "wifinet2","device": "radio0","mode": "ap","ssid": "ilwf-guest","encryption": "sae-mixed","key": "XXXX","network": "lan","disabled": "0"}
    ucistate{ “config”: “config”, “section”: “sname”, “type”: “tname”, “option”: “oname” }
    uciset{ “config”: “config”, “section”: “sname”, “type”: “tname”, “values”: “array_of_values” }

    Set the given value(s), the option argument is optional.

    1. When called withconfig andsname andarray_of_values set: add a new sectionsname inconfig and set it to the type given intname
    2. When called withconfig andsname,oname andarray_of_values setarray_of_values as values insname

    The call does not produce any data, instead it returns with the following status codes:

    1. If there already is a section calledsname:UBUS_STATUS_INVALID_ARGUMENT else:UBUS_STATUS_OK
    2. If there is no sectionsname or ifvalue is neither a string nor an array:UBUS_STATUS_INVALID_ARGUMENT else:UBUS_STATUS_OK

    Example:

    # ubus call uci set '{"ubus_rpc_session":"2db687f321a60414e77677bbb5dd6d6f", "config":"wireless", "section":"wifinet2", "values":{"disabled":"1"}}'# ubus call uci get '{"ubus_rpc_session":"2db687f321a60414e77677bbb5dd6d6f", "config":"wireless", "section":"wifinet2"}'{"values": {".anonymous": false,".type": "wifi-iface",".name": "wifinet2","device": "radio0","mode": "ap","ssid": "ilwf-guest","encryption": "sae-mixed","key": "XXXXXXXX","network": "lan","disabled": "1"}}
    uciadd{ “config”: “config”, “type”: “type” }

    Add new anonymous section of given type.

    1. When called withconfig andtype set: Add a new anonymous section of typetype.

    Return message:

    1. { “section”: “sectionname” }
    ucidelete{ “config”: “config”, “section”: “sname”, “type”: “type”, “option”: “oname” }

    Delete the given value(s) or section(s), the option and type arguments are optional.

    1. When called withconfig andtype set: delete all sections of typetype inconfig
    2. When called withconfig andsname set: delete the section namedsname inconfig
    3. When called withconfig,type andoname set: delete the option namedoname within each section of typetype inpackage
    4. When called withconfig,sname andoname set: delete the option namedoname in sectionsname ofpackage

    The call does not result in any data, instead it returns the following status codes:

    1. If no section of typetype was found:UBUS_STATUS_NOT_FOUND else:UBUS_STATUS_OK
    2. If no section namedsname was found:UBUS_STATUS_NOT_FOUND else:UBUS_STATUS_OK
    3. If no options namedoname within sections of typetype where found:UBUS_STATUS_NOT_FOUND else:UBUS_STATUS_OK
    4. If the option namedoname within named sectionsname was not found:UBUS_STATUS_NOT_FOUND else:UBUS_STATUS_OK
    ucirename{“config”:“String”,“section”:“String”,“option”:“String”,“name”:“String” }
    uciorder{“config”:“String”,“sections”:“Array” }
    ucichanges{“config”:“String” }
    ucirevert{“config”:“String” }
    ucicommit{“config”:“String” }
    uciapply{“rollback”:“Boolean”,“timeout”:“Integer” }
    uciconfirm{ }
    ucirollback{ }
    ucireload_config{ }

    What's the difference between ubus vs dbus?

    Examples

    FHEM

    User mapping

    In this example we map usernameroot tofhem_acl forFHEM server.Edit/etc/config/rpcd:

    /etc/config/rpcd
    # /etc/config/rpcdconfigloginoption username'root'option password'$p$root'listread'*'listwrite'*' configloginoption username'fhem'## '$p$<username> => reference to user passowrd on /etc/shadow# '$1$<hash>' => crypt() hash, using SHA1. generate via 'uhttpd -m fhem'## password: fhem#option password'$1$$xEODf2fNSQ0ArfkJu4L2i1'## map username to rpcd acl name "fhem_acl"#        listread'fhem_acl'listwrite''

    Then reload rpcd config:

    uci commit rpcd

    User ACL

    All files under/usr/share/rpcd/acl.d/ will be merge byrpcd to one config file!!

    ubus call hostapd.wlan0 get_clientsubus call hostapd.wlan1 get_clients

    Example permissions to run ubus calls remote by fhem over http/json.

    /usr/share/rpcd/acl.d/fhem.json
    {        "fhem_acl":{                "description":"FHEM PRESENCE Module User.. https://github.com/janLo/OpenWRT-Wifi-Clients-POC",                "read":{                        "ubus":{                                "hostapd.wlan0":["get_clients"],                                "hostapd.wlan1":["get_clients"]}}}}

    FHEM Server - show all connected wireless clients:

    $ python wifi_clients.pyUsage: wifi_clients.py.orig<OpenWrt_Host><User><Pass><WiFi_1>[<WiFi2> ...]$ python wifi_clients.py 192.168.1.71 fhem fhem wlan0 wlan1c8:f6:50:e1:a9:10, 2c:f0:a2:e2:c0:15, 8c:a9:82:f1:9c:2a, 7c:c3:a1:b8:d2:1e,64:9a:be:6a:6c:13, 00:1d:63:a3:8f:4a

    Getting firmware version

    Get firmware version withJSON RPC.

    luci_rpc(){localLIB="${1}"localDATA="${2}"localURL="https://${HOST}/\cgi-bin/luci/rpc/${LIB}?auth=${TOKEN}"curl-s-k-d"${DATA}""${URL}" \| jsonfilter-e"$['result']"}HOST="localhost"USER="root"PASS=""DATA="{\"id\": 1,\"method\":\"login\",\"params\": [\"${USER}\",\"${PASS}\" ] }"TOKEN="$(luci_rpc auth "${DATA}")"DATA="{\"id\": 2,\"method\":\"exec\",\"params\": [\"ubus call system board\" ] }"VERSION="$(luci_rpc sys "${DATA}"\| jsonfilter -e "$['release']['version']")"echo"${VERSION}"

    Get firmware version with ubus RPC.

    ubus_rpc(){localDATA="${1}"localURL="https://${HOST}/ubus"curl-s-k-d"${DATA}""${URL}" \| jsonfilter-e"$['result']"}HOST="localhost"USER="root"PASS=""DATA="{ 'jsonrpc': '2.0', 'id': 1, 'method': 'call','params': [ '00000000000000000000000000000000', 'session','login', { 'username': '${USER}', 'password': '${PASS}' } ] }"SESSION="$(ubus_rpc "${DATA}"\| jsonfilter -e "$[*]['ubus_rpc_session']")"DATA="{ 'jsonrpc': '2.0', 'id': 2, 'method': 'call','params': [ '${SESSION}', 'system', 'board', {} ] }"VERSION="$(ubus_rpc "${DATA}"\| jsonfilter -e "$[*]['release']['version']")"echo"${VERSION}"
    This website uses cookies. By using the website, you agree with storing cookies on your computer. Also you acknowledge that you have read and understand our Privacy Policy. If you do not agree leave the website.More information about cookies
    • Last modified:2024/12/16 21:52
    • bystokito