OpenWrt Backend
The OpenWrt
backend allows to generate OpenWrt compatible
configurations.
Note
This backend purposely generates only named UCI blocks.
UCI stands for Unified Configuration Interface and it is the default configuration system installed on OpenWrt.
Important
OpenWrt introduced a new syntax for defining interfaces in OpenWrt 21.
By default, the netjsonconfig library generates configuration in the
new syntax. If you want to generate configuration in the legacy syntax
(OpenWrt <=19), then set dsa=False
while instantiating object of
netjsonconfig.OpenWrt
class.
from netjsonconfig import OpenWrt
o = OpenWrt(
config={
"interfaces": [
{
"name": "eth0",
"type": "ethernet",
"addresses": [{"proto": "dhcp", "family": "ipv4"}],
}
]
},
dsa=False, # This will generate configuration in legacy syntax
)
The examples present in this documentation only demonstrates configuration in new syntax. Refer older documentation versions to check examples of old syntax.
Initialization
- OpenWrt.__init__(config=None, native=None, templates=None, context=None, dsa=True)[source]
- Parameters:
config –
dict
containing a valid NetJSON configuration dictionarynative –
str
or file object representing a native configuration that will be parsed and converted to a NetJSON configuration dictionarytemplates –
list
containing NetJSON configuration dictionaries that will be used as a base for the main configcontext –
dict
containing configuration variablesdsa –
bool
flag to switch between OpenWrt configuration syntax.True
generates configuration in OpenWrt >21 syntax.False
generates configuration in OpenWrt <= 19 syntax.
- Raises:
TypeError – raised if
config
is not of typedict
or iftemplates
is not of typelist
If you are unsure about the meaning of the initalization parameters, read about the following basic concepts:
Initialization example (forward conversion):
from netjsonconfig import OpenWrt
router = OpenWrt({"general": {"hostname": "HomeRouter"}})
Initialization example (backward conversion):
from netjsonconfig import OpenWrt
router = OpenWrt(native=open("./openwrt-config.tar.gz"))
Render method
- OpenWrt.render(files=True)
Converts the configuration dictionary into the corresponding configuration format
- Parameters:
files – whether to include “additional files” in the output or not; defaults to
True
- Returns:
string with output
Code example:
from netjsonconfig import OpenWrt
o = OpenWrt(
{
"interfaces": [
{
"name": "eth0.1",
"type": "ethernet",
"addresses": [
{
"address": "192.168.1.2",
"gateway": "192.168.1.1",
"mask": 24,
"proto": "static",
"family": "ipv4",
},
{
"address": "192.168.2.1",
"mask": 24,
"proto": "static",
"family": "ipv4",
},
{
"address": "fd87::2",
"gateway": "fd87::1",
"mask": 64,
"proto": "static",
"family": "ipv6",
},
],
}
]
}
)
print(o.render())
Will return the following output:
package network
config interface 'eth0_1'
option gateway '192.168.1.1'
option ifname 'eth0.1'
option ip6addr 'fd87::2/64'
option ip6gw 'fd87::1'
list ipaddr '192.168.1.2/24'
list ipaddr '192.168.2.1/24'
option proto 'static'
Generate method
- OpenWrt.generate()
Returns a
BytesIO
instance representing an in-memory tar.gz archive containing the native router configuration.- Returns:
in-memory tar.gz archive, instance of
BytesIO
Example:
import tarfile
from netjsonconfig import OpenWrt
o = OpenWrt(
{
"interfaces": [
{
"name": "eth0",
"type": "ethernet",
"addresses": [{"proto": "dhcp", "family": "ipv4"}],
}
]
}
)
stream = o.generate()
print(stream)
# <_io.BytesIO object at 0x7fd2287fb410>
tar = tarfile.open(fileobj=stream, mode="r:gz")
print(tar.getmembers())
# [<TarInfo 'etc/config/network' at 0x7fd228790250>]
As you can see from this example, the generate
method does not write
to disk, but returns an instance of io.BytesIO
which contains a tar.gz
file object with the following file structure:
/etc/config/network
The configuration archive can then be written to disk, served via HTTP or
uploaded directly on the OpenWrt router where it can be finally “restored”
with sysupgrade
:
sysupgrade -r <archive>
Note that sysupgrade -r
does not apply the configuration, to do this
you have to reload the services manually or reboot the router.
Note
the generate
method intentionally sets the timestamp of the tar.gz
archive and its members to 0
in order to facilitate comparing two
different archives: setting the timestamp would infact cause the
checksum to be different each time even when contents of the archive
are identical.
Write method
- OpenWrt.write(name, path='./')
Like
generate
but writes to disk.- Parameters:
name – file name, the tar.gz extension will be added automatically
path – directory where the file will be written to, defaults to
./
- Returns:
None
Example:
import tarfile
from netjsonconfig import OpenWrt
o = OpenWrt(
{
"interfaces": [
{
"name": "eth0",
"type": "ethernet",
"addresses": [{"proto": "dhcp", "family": "ipv4"}],
}
]
}
)
o.write("dhcp-router", path="/tmp/")
Will write the configuration archive in /tmp/dhcp-router.tar.gz
.
Parse method
- OpenWrt.parse(native)
Parses a native configuration and converts it to a NetJSON configuration dictionary
This method is automatically called when initializing the backend with the
native
argument:
from netjsonconfig import OpenWrt
router = OpenWrt(native=open("./openwrt-config.tar.gz"))
The argument passed to native
can be a string containing a dump
obtained via uci export
, or a file object (real file or BytesIO
instance) representing a configuration archive in tar.gz format typically
used in OpenWrt.
JSON method
- OpenWrt.json(validate=True, *args, **kwargs)
returns a string formatted as NetJSON DeviceConfiguration; performs validation before returning output;
*args
and*kwargs
will be passed tojson.dumps
;- Returns:
string
Code example:
from netjsonconfig import OpenWrt
router = OpenWrt({"general": {"hostname": "HomeRouter"}})
print(router.json(indent=4))
# {
# "type": "DeviceConfiguration",
# "general": {
# "hostname": "HomeRouter"
# }
# }
General settings
The general settings reside in the general
key of the configuration
dictionary, which follows the NetJSON General object definition (see the link for the
detailed specification).
Currently only the hostname
option is processed by this backend.
General object extensions
In addition to the default NetJSON General object options, the
OpenWrt
backend also supports the following custom options:
key name |
type |
function |
---|---|---|
|
string |
one of the allowed timezone values (first element of each tuple) |
General settings example
The following configuration dictionary:
{
"general": {
"hostname": "routerA",
"timezone": "UTC",
"ula_prefix": "fd8e:f40a:6701::/48",
}
}
Will be rendered as follows:
package system
config system 'system'
option hostname 'routerA'
option timezone 'UTC'
option zonename 'UTC'
package network
config globals 'globals'
option ula_prefix 'fd8e:f40a:6701::/48'
Network interfaces
The network interface settings reside in the interfaces
key of the
configuration dictionary, which must contain a list of NetJSON
interface objects (see the
link for the detailed specification).
There are 4 main types of interfaces:
network interfaces: may be of type
ethernet
,virtual
,loopback
orother
wireless interfaces: must be of type
wireless
bridge interfaces: must be of type
bridge
dialup interfaces: must be of type
dialup
modem manager interfaces: must be of type
modem-manager
Interface object extensions
In addition to the default NetJSON Interface object options, the
OpenWrt
backend also supports the following custom options for every
type of interface:
key name |
type |
allowed values |
---|---|---|
|
string |
logical interface name (UCI specific) |
Important
OpenWrt introduced a new syntax for defining interfaces in OpenWrt 21.
By default, the netjsonconfig library generates configuration in the
new syntax. If you want to generate configuration in the legacy syntax
(OpenWrt <=19), then set dsa=False
while instantiating object of
netjsonconfig.OpenWrt
class.
from netjsonconfig import OpenWrt
o = OpenWrt(
config={
"interfaces": [
{
"name": "eth0",
"type": "ethernet",
"addresses": [{"proto": "dhcp", "family": "ipv4"}],
}
]
},
dsa=False, # This will generate configuration in legacy syntax
)
The examples present in this documentation only demonstrates configuration in new syntax. Refer older documentation versions to check examples of old syntax.
In the following sections some examples of the most common use cases are shown.
Loopback interface example
The following configuration dictionary:
{
"interfaces": [
{
"name": "lo",
"type": "loopback",
"addresses": [
{
"address": "127.0.0.1",
"mask": 8,
"proto": "static",
"family": "ipv4",
}
],
}
]
}
Will be rendered as follows:
package network
config interface 'lo'
option device 'lo'
option ipaddr '127.0.0.1'
option netmask '255.0.0.0'
option proto 'static'
Dualstack (IPv4 & IPv6)
The following configuration dictionary:
{
"interfaces": [
{
"name": "eth0",
"type": "ethernet",
"addresses": [
{
"family": "ipv4",
"proto": "static",
"address": "10.27.251.1",
"mask": 24,
},
{
"family": "ipv6",
"proto": "static",
"address": "fdb4:5f35:e8fd::1",
"mask": 48,
},
],
}
]
}
Will be rendered as follows:
package network
config interface 'eth0'
option device 'eth0'
option ip6addr 'fdb4:5f35:e8fd::1/48'
option ipaddr '10.27.251.1'
option netmask '255.255.255.0'
option proto 'static'
DNS servers and search domains
DNS servers can be set using dns_servers
, while search domains can be
set using dns_search
.
If specified, these values will be automatically added in every interface
which has at least one static ip address; interfaces which have no ip
address configured or are using dynamic ip address configuration won’t get
the dns
option in the UCI output, eg:
{
"dns_servers": ["10.11.12.13", "8.8.8.8"],
"dns_search": ["openwisp.org", "netjson.org"],
"interfaces": [
{
"name": "eth0",
"type": "ethernet",
"addresses": [
{
"address": "192.168.1.1",
"mask": 24,
"proto": "static",
"family": "ipv4",
}
],
},
# the following interface has DHCP enabled
# and it won't contain the dns setting
{
"name": "eth1",
"type": "ethernet",
"addresses": [{"proto": "dhcp", "family": "ipv4"}],
},
# the following VLAN interface won't get
# the dns nor the dns_search settings
{"name": "eth1.31", "type": "ethernet"},
],
}
Will return the following UCI output:
package network
config interface 'eth0'
option dns '10.11.12.13 8.8.8.8'
option dns_search 'openwisp.org netjson.org'
option device 'eth0'
option ipaddr '192.168.1.1'
option netmask '255.255.255.0'
option proto 'static'
config interface 'eth1'
option dns_search 'openwisp.org netjson.org'
option device 'eth1'
option proto 'dhcp'
config interface 'eth1_31'
option device 'eth1.31'
option proto 'none'
DHCP ipv6 ethernet interface
The following configuration dictionary:
{
"interfaces": [
{
"name": "eth0",
"network": "lan",
"type": "ethernet",
"addresses": [{"proto": "dhcp", "family": "ipv6"}],
}
]
}
Will be rendered as follows:
package network
config interface 'lan'
option device 'eth0'
option proto 'dchpv6'
Using different protocols
OpenWrt supports many protocols (pppoe, pppoa, pptp, l2tp, ecc) and the list of supported protocols evolves over time.
OpenWISP and netjsonconfig try to stay out of your way by leaving you
maximum flexibility to use any protocol and any configuration option you
may need, just set type
to other
, then proceed by setting proto
and any other configuration option according to your needs, see the
example below.
PPPoE proto example
The following configuration dictionary:
{
"interfaces": [
{
"type": "other",
"name": "eth0",
"network": "wan",
"proto": "pppoe",
"username": "<username>",
"password": "<password>",
}
]
}
Will be rendered as follows:
package network
config interface 'wan'
option ifname 'eth0'
option password '<password>'
option proto 'ppoe'
option username '<username>'
Bridge settings
Interfaces of type bridge
contains options that are specific for
network bridges.
The OpenWrt
backend NetJSON extensions for bridge interfaces:
key name |
type |
default |
allowed values |
---|---|---|---|
|
list |
|
list of interface names for creating bridge |
|
boolean |
|
sets the
|
|
boolean |
|
enables the bridge as a multicast querier |
|
integer |
|
time interval in centiseconds between multicast general queries |
|
integer |
|
the max response time in centiseconds inserted into the periodic general queries |
|
integer |
|
the maximum response time in centiseconds inserted into group-specific queries sent in response to leave group messages. |
|
integer |
|
size of kernel multicast hash table |
|
integer |
|
sets Startup Query Count and Last Member Count |
|
boolean |
|
enables the spanning tree protocol |
|
integer |
|
time in seconds to spend in listening and learning states (range between 2-30) |
|
integer |
|
time interval in seconds for STP hello packets (range 1-10) |
|
integer |
|
sets the STP bridge priority (range 0-65535) |
|
integer |
|
expiration time in seconds for dynamic MAC entries in the filtering DB” (range 10-1000000) |
|
integer |
|
timeout in seconds until topology updates on link loss |
|
list |
|
a list of Refer to the VLAN options table below for a list of available options. |
VLAN options:
key name |
type |
allowed values |
||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
integer |
VLAN ID |
||||||||||||
|
list |
A list of
|
Bridge interface example
The following configuration dictionary:
{
"interfaces": [
{"name": "eth0.1", "network": "lan", "type": "ethernet"},
{"name": "eth0.2", "network": "wan", "type": "ethernet"},
{
"name": "br-lan",
"type": "bridge",
"stp": True, # enable spanning tree protocol
"igmp_snooping": True, # enable imgp snooping
"bridge_members": ["eth0.1", "eth0.2"],
"addresses": [
{
"address": "172.17.0.2",
"mask": 24,
"proto": "static",
"family": "ipv4",
}
],
},
]
}
Will be rendered as follows:
package network
config interface 'lan'
option device 'eth0.1'
option proto 'none'
config interface 'wan'
option device 'eth0.2'
option proto 'none'
config device 'device_br_lan'
option igmp_snooping '1'
option name 'br-lan'
list ports 'eth0.1'
list ports 'eth0.2'
option stp '1'
option type 'bridge'
config interface 'br_lan'
option device 'br-lan'
option ipaddr '172.17.0.2'
option netmask '255.255.255.0'
option proto 'static'
Using VLAN Filtering on a Bridge
The following configuration dictionary:
{
"interfaces": [
{
"type": "bridge",
"bridge_members": ["lan1", "lan2", "lan3"],
"name": "br-lan",
"vlan_filtering": [
{
"vlan": 1,
"ports": [
{
"ifname": "lan1",
"tagging": "t",
"primary_vid": True,
},
{"ifname": "lan2", "tagging": "t"},
],
},
{
"vlan": 2,
"ports": [
{
"ifname": "lan1",
"tagging": "t",
"primary_vid": False,
},
{
"ifname": "lan3",
"tagging": "u",
"primary_vid": True,
},
],
},
],
}
]
}
Will be rendered as follows:
package network
config device 'device_br_lan'
option name 'br-lan'
list ports 'lan1'
list ports 'lan2'
list ports 'lan3'
option type 'bridge'
option vlan_filtering '1'
config bridge-vlan 'vlan_br_lan_1'
option device 'br-lan'
list ports 'lan1:t*'
list ports 'lan2:t'
option vlan '1'
config bridge-vlan 'vlan_br_lan_2'
option device 'br-lan'
list ports 'lan1:t'
list ports 'lan3:u*'
option vlan '2'
config interface 'vlan_br_lan_1'
option device 'br-lan.1'
option proto 'none'
config interface 'vlan_br_lan_2'
option device 'br-lan.2'
option proto 'none'
config interface 'br_lan'
option device 'br-lan'
option proto 'none'
Wireless settings
Interfaces of type wireless
may contain a lot of different combination
of settings to configure wireless connectivity: from simple access points,
to 802.1x authentication, 802.11s mesh networks, adhoc mesh networks, WDS
repeaters and much more.
The OpenWrt
backend NetJSON extensions for wireless interfaces:
key name |
type |
default |
allowed values |
---|---|---|---|
|
array |
|
attached networks; if left blank will be automatically determined |
Some extensions are applicable only when mode
is access_point
:
key name |
type |
default |
allowed values |
---|---|---|---|
|
boolean |
|
enables WMM (802.11e) support |
|
boolean |
|
enables fast BSS transition (802.11r) support |
|
integer |
|
reassociation deadline in time units (TUs / 1.024 ms, 1000-65535) |
|
boolean |
|
whether to generate FT response locally for PSK networks |
|
boolean |
|
whether to enable FT-over-DS |
|
boolean |
|
allow pre-authentication for WPA2-EAP networks |
|
boolean |
|
isolate wireless clients from one another |
|
string |
|
ACL policy, accepts: “disable”, “allow” and “deny” |
|
array |
|
mac addresses filtered according to macfilter policy |
These extensions must be used the wireless
object of a wireless
interface eg:
{
"interfaces": [
{
"name": "wlan0",
"type": "wireless",
"wireless": {
"radio": "radio0",
"mode": "access_point",
"ssid": "myWiFi",
# OpenWrt backend NetJSON extensions
"wmm": True,
"isolate": True,
},
}
]
}
The same applies for custom configuration options not included in the
OpenWrt
backend schema:
{
"interfaces": [
{
"name": "wlan0",
"type": "wireless",
"wireless": {
"radio": "radio0",
"mode": "access_point",
"ssid": "myWiFi",
# custom configuration options not defined
# in the OpenWrt backend schema
"beacon_int": 200,
"noscan": True,
"custom1": "made-up-for-example-purposes",
},
}
]
}
In the following sections some examples of the most common use cases are shown.
Wireless access point
The following configuration dictionary represent one of the most common wireless access point configuration:
{
"interfaces": [
{
"name": "wlan0",
"type": "wireless",
"wireless": {
"radio": "radio0",
"mode": "access_point",
"ssid": "myWiFi",
"wmm": True, # 802.11e
"isolate": True, # client isolation
},
}
]
}
UCI output:
package wireless
config wifi-iface 'wifi_wlan0'
option device 'radio0'
option ifname 'wlan0'
option isolate '1'
option mode 'ap'
option ssid 'myWiFi'
option wmm '1'
Note
the network
option of the wifi-iface
directive is filled in
automatically but can be overridden if needed by setting the
network
option in the wireless
section of the configuration
dictionary. The next example shows how to do this.
Wireless attached to a different network
In most cases you want to bridge a wireless interface to a different network, usually the LAN bridge:
{
"interfaces": [
{"name": "eth0", "type": "ethernet"},
{
"name": "wlan0",
"type": "wireless",
"wireless": {
"radio": "radio0",
"mode": "access_point",
"ssid": "wifi service",
# "network": ["lan"] this property can be omitted
# but may be overridden if needed
},
},
{
"name": "lan", # the bridge will be named br-lan by OpenWrt
"type": "bridge",
"bridge_members": ["eth0", "wlan0"],
"addresses": [{"proto": "dhcp", "family": "ipv4"}],
},
]
}
Will be rendered as follows:
package network
config interface 'eth0'
option device 'eth0'
option proto 'none'
config device 'device_lan'
option name 'br-lan'
list ports 'eth0'
list ports 'wlan0'
option type 'bridge'
config interface 'lan'
option device 'br-lan'
option proto 'dhcp'
package wireless
config wifi-iface 'wifi_wlan0'
option device 'radio0'
option ifname 'wlan0'
option mode 'ap'
option network 'lan'
option ssid 'wifi service'
Wireless access point with macfilter ACL
The OpenWrt
backend supports a custom NetJSON extension for wireless
access point interfaces: macfilter
(read more about macfilter
and
maclist
on the OpenWrt documentation for Wireless configuration).
In the following example we ban two mac addresses from connecting to a wireless access point:
{
"interfaces": [
{
"name": "wlan0",
"type": "wireless",
"wireless": {
"radio": "radio0",
"mode": "access_point",
"ssid": "MyWifiAP",
"macfilter": "deny",
"maclist": ["E8:94:F6:33:8C:1D", "42:6c:8f:95:0f:00"],
},
}
]
}
UCI output:
package wireless
config wifi-iface 'wifi_wlan0'
option device 'radio0'
option ifname 'wlan0'
option macfilter 'deny'
list maclist 'E8:94:F6:33:8C:1D'
list maclist '42:6c:8f:95:0f:00'
option mode 'ap'
option ssid 'MyWifiAP'
Wireless access point with roaming (802.11r)
The OpenWrt
backend supports custom NetJSON extensions to support
(802.11r) in wireless access point interfaces (refer “Fast BSS transition
options” section in the OpenWrt documentation for Wireless configuration).
In the following example we configure roaming options for a wireless access point:
{
"interfaces": [
{
"name": "wlan0",
"type": "wireless",
"wireless": {
"radio": "radio0",
"mode": "access_point",
"ssid": "MyWifiAP",
"ieee80211r": True,
"ft_over_ds": False,
"ft_psk_generate_local": True,
"rsn_preauth": True,
"reassociation_deadline": 1000,
"network": ["lan"],
},
}
]
}
UCI output:
package wireless
config wifi-iface 'wifi_wlan0'
option device 'radio0'
option ft_over_ds '0'
option ft_psk_generate_local '1'
option ieee80211r '1'
option ifname 'wlan0'
option mode 'ap'
option network 'lan'
option reassociation_deadline '1000'
option rsn_preauth '1'
option ssid 'MyWifiAP'
Wireless mesh (802.11s) example
Setting up 802.11s interfaces is fairly simple, in the following
example we bridge eth0
with mesh0
, the latter being a layer2
802.11s wireless interface.
Note
in 802.11s mesh mode the ssid
property is not required, while
mesh_id
is mandatory.
{
"interfaces": [
{"name": "eth0", "type": "ethernet"},
{
"name": "mesh0",
"type": "wireless",
"wireless": {
"radio": "radio0",
"mode": "802.11s",
"mesh_id": "ninux",
"network": ["lan"],
},
},
{
"name": "lan",
"type": "bridge",
"bridge_members": ["eth0", "mesh0"],
"addresses": [
{
"address": "192.168.0.1",
"mask": 24,
"proto": "static",
"family": "ipv4",
}
],
},
]
}
UCI output:
package network
config interface 'eth0'
option device 'eth0'
option proto 'none'
config device 'device_lan'
option name 'br-lan'
list ports 'eth0'
list ports 'mesh0'
option type 'bridge'
config interface 'lan'
option device 'br-lan'
option ipaddr '192.168.0.1'
option netmask '255.255.255.0'
option proto 'static'
package wireless
config wifi-iface 'wifi_mesh0'
option device 'radio0'
option ifname 'mesh0'
option mesh_id 'ninux'
option mode 'mesh'
option network 'lan'
Wireless mesh (adhoc) example
In wireless adhoc mode, the bssid
property is required.
The following example:
{
"interfaces": [
{
"name": "wlan0",
"type": "wireless",
"wireless": {
"radio": "radio0",
"ssid": "freifunk",
"mode": "adhoc",
"bssid": "02:b8:c0:00:00:00",
},
}
]
}
Will result in:
package wireless
config wifi-iface 'wifi_wlan0'
option bssid '02:b8:c0:00:00:00'
option device 'radio0'
option ifname 'wlan0'
option mode 'adhoc'
option ssid 'freifunk'
WDS repeater example
In the following example we show how to configure a WDS station and repeat the signal:
{
"interfaces": [
# client
{
"name": "wlan0",
"type": "wireless",
"wireless": {
"mode": "station",
"radio": "radio0",
"network": ["wds_bridge"],
"ssid": "FreeRomaWifi",
"bssid": "C0:4A:00:2D:05:FD",
"wds": True,
},
},
# repeater access point
{
"name": "wlan1",
"type": "wireless",
"wireless": {
"mode": "access_point",
"radio": "radio1",
"network": ["wds_bridge"],
"ssid": "FreeRomaWifi",
},
},
# WDS bridge
{
"name": "br-wds",
"network": "wds_bridge",
"type": "bridge",
"addresses": [{"proto": "dhcp", "family": "ipv4"}],
"bridge_members": [
"wlan0",
"wlan1",
],
},
]
}
Will result in:
package network
config device 'device_wds_bridge'
option name 'br-wds'
list ports 'wlan0'
list ports 'wlan1'
option type 'bridge'
config interface 'wds_bridge'
option device 'br-wds'
option proto 'dhcp'
package wireless
config wifi-iface 'wifi_wlan0'
option bssid 'C0:4A:00:2D:05:FD'
option device 'radio0'
option ifname 'wlan0'
option mode 'sta'
option network 'wds_bridge'
option ssid 'FreeRomaWifi'
option wds '1'
config wifi-iface 'wifi_wlan1'
option device 'radio1'
option ifname 'wlan1'
option mode 'ap'
option network 'wds_bridge'
option ssid 'FreeRomaWifi'
WPA2 Enterprise (802.1x) ap
The following example shows a typical wireless access point using WPA2 Enterprise (802.1x) security on OpenWrt, you can use this type of configuration for networks like eduroam:
{
"interfaces": [
{
"name": "wlan0",
"type": "wireless",
"wireless": {
"radio": "radio0",
"mode": "access_point",
"ssid": "eduroam",
"encryption": {
"protocol": "wpa2_enterprise",
"cipher": "auto",
"key": "radius_secret",
"server": "192.168.0.1",
"port": 1812,
"acct_server": "192.168.0.2",
"acct_port": 1813,
"nasid": "hostname",
},
},
}
]
}
UCI Output:
package wireless
config wifi-iface 'wifi_wlan0'
option acct_port '1813'
option acct_secret 'radius_secret'
option acct_server '192.168.0.2'
option auth_port '1812'
option auth_secret 'radius_secret'
option auth_server '192.168.0.1'
option device 'radio0'
option encryption 'wpa2'
option ifname 'wlan0'
option key 'radius_secret'
option mode 'ap'
option nasid 'hostname'
option port '1812'
option server '192.168.0.1'
option ssid 'eduroam'
WPA2 Enterprise (802.1x) client
WPA2 Enterprise (802.1x) client with EAP-TLS example:
{
"interfaces": [
{
"name": "wlan0",
"type": "wireless",
"wireless": {
"radio": "radio0",
"mode": "station",
"ssid": "enterprise-client",
"bssid": "00:26:b9:20:5f:09",
"encryption": {
"protocol": "wpa2_enterprise",
"cipher": "auto",
"eap_type": "tls",
"anonymous_identity": "anonymous",
"identity": "test-identity",
"password": "test-password",
"ca_cert_usesystem": True,
"subject_match": "CN = wifi.openwisp.io",
"altsubject_match": ["DNS Name: wifi.openwisp.io"],
"domain_match": ["wifi.openwisp.io"],
},
},
}
]
}
UCI Output:
package wireless
config wifi-iface 'wifi_wlan0'
list altsubject_match 'DNS Name: wifi.openwisp.io'
option anonymous_identity 'anonymous'
option bssid '00:26:b9:20:5f:09'
option ca_cert_usesystem '1'
option device 'radio0'
list domain_match 'wifi.openwisp.io'
option eap_type 'tls'
option encryption 'wpa2'
option identity 'test-identity'
option ifname 'wlan0'
option mode 'sta'
option password 'test-password'
option ssid 'enterprise-client'
option subject_match 'CN = wifi.openwisp.io'
WPA3 Personal (Simultaneous Authentication of Equals)
The following example shows a typical wireless access point using WPA3 Personal (SAE) encryption:
{
"interfaces": [
{
"name": "wlan0",
"type": "wireless",
"wireless": {
"radio": "radio0",
"mode": "access_point",
"ssid": "wpa3-personal",
"encryption": {
"protocol": "wpa3_personal",
# WPA3 only supports ccmp
"cipher": "ccmp",
"key": "passphrase012345",
# Management Frame Protection is required for WPA3
"ieee80211w": "2",
},
},
}
]
}
UCI output:
package wireless
config wifi-iface 'wifi_wlan0'
option device 'radio0'
option encryption 'sae+ccmp'
option ieee80211w '2'
option ifname 'wlan0'
option key 'passphrase012345'
option mode 'ap'
option ssid 'wpa3-personal'
WPA3 Enterprise (802.1x) AP
The following example shows a typical wireless access point using WPA3 Enterprise (802.1x) security on OpenWrt, you can use this type of configuration for networks like eduroam:
{
"interfaces": [
{
"name": "wlan0",
"type": "wireless",
"wireless": {
"radio": "radio0",
"mode": "access_point",
"ssid": "eduroam",
"encryption": {
"protocol": "wpa3_enterprise",
# WPA3 only supports ccmp
"cipher": "ccmp",
"key": "radius_secret",
"server": "192.168.0.1",
"port": 1812,
"acct_server": "192.168.0.2",
"acct_port": 1813,
"nasid": "hostname",
"ieee80211w": "2",
},
},
}
]
}
UCI Output:
package wireless
config wifi-iface 'wifi_wlan0'
option acct_port '1813'
option acct_secret 'radius_secret'
option acct_server '192.168.0.2'
option auth_port '1812'
option auth_secret 'radius_secret'
option auth_server '192.168.0.1'
option device 'radio0'
option encryption 'wpa3+ccmp'
option ieee80211w '2'
option ifname 'wlan0'
option key 'radius_secret'
option mode 'ap'
option nasid 'hostname'
option port '1812'
option server '192.168.0.1'
option ssid 'eduroam'
WPA3 Enterprise (802.1x) client
WPA3 Enterprise (802.1x) client example:
{
"interfaces": [
{
"name": "wlan0",
"type": "wireless",
"wireless": {
"radio": "radio0",
"mode": "station",
"ssid": "enterprise-client",
"bssid": "00:26:b9:20:5f:09",
"encryption": {
"protocol": "wpa3_enterprise",
# WPA3 only supports ccmp
"cipher": "ccmp",
"eap_type": "tls",
"identity": "test-identity",
"password": "test-password",
"ieee80211w": "2",
},
},
}
]
}
UCI Output:
package wireless
config wifi-iface 'wifi_wlan0'
option bssid '00:26:b9:20:5f:09'
option device 'radio0'
option eap_type 'tls'
option encryption 'wpa3+ccmp'
option identity 'test-identity'
option ieee80211w '2'
option ifname 'wlan0'
option mode 'sta'
option password 'test-password'
option ssid 'enterprise-client'
WPA2 Enterprise (802.1x) client with EAP-TTLS example:
{
"interfaces": [
{
"name": "wlan0",
"type": "wireless",
"wireless": {
"radio": "radio0",
"mode": "station",
"ssid": "enterprise-client",
"bssid": "00:26:b9:20:5f:09",
"encryption": {
"protocol": "wpa2_enterprise",
"cipher": "auto",
"eap_type": "ttls",
"auth": "MSCHAPV2",
"identity": "test-identity",
"password": "test-password",
},
},
}
]
}
UCI Output:
package wireless
config wifi-iface 'wifi_wlan0'
option auth 'MSCHAPV2'
option bssid '00:26:b9:20:5f:09'
option device 'radio0'
option eap_type 'ttls'
option encryption 'wpa2'
option identity 'test-identity'
option ifname 'wlan0'
option mode 'sta'
option password 'test-password'
option ssid 'enterprise-client'
WPA2 Enterprise (802.1x) client with EAP-PEAP example:
{
"interfaces": [
{
"name": "wlan0",
"type": "wireless",
"wireless": {
"radio": "radio0",
"mode": "station",
"ssid": "enterprise-client",
"bssid": "00:26:b9:20:5f:09",
"encryption": {
"protocol": "wpa2_enterprise",
"cipher": "auto",
"eap_type": "peap",
"auth": "EAP-MSCHAPV2",
"identity": "test-identity",
"password": "test-password",
},
},
}
]
}
UCI Output:
package wireless
config wifi-iface 'wifi_wlan0'
option auth 'EAP-MSCHAPV2'
option bssid '00:26:b9:20:5f:09'
option device 'radio0'
option eap_type 'peap'
option encryption 'wpa2'
option identity 'test-identity'
option ifname 'wlan0'
option mode 'sta'
option password 'test-password'
option ssid 'enterprise-client'
Dialup settings
Interfaces of type dialup
contain a few options that are specific to
dialup connections.
The OpenWrt
backend NetJSON extensions for dialup interfaces:
key name |
type |
default |
allowed values |
---|---|---|---|
|
string |
|
|
|
string |
|
|
|
string |
|
Dialup interface example
The following configuration dictionary:
{
"interfaces": [
{
"name": "dsl0",
"network": "xdsl",
"type": "dialup",
"proto": "pppoe",
"password": "jf93nf82o023$",
"username": "dsluser",
"mtu": 1448,
}
]
}
Will be rendered as follows:
package network
config interface 'xdsl'
option ifname 'dsl0'
option mtu '1448'
option password 'jf93nf82o023$'
option proto 'pppoe'
option username 'dsluser'
Modem Manager settings
Interfaces of type modem-manager
contain a few options that are
specific to modem-manager interfaces (2G, 3G, 4G, LTE, etc).
These are the OpenWrt
backend NetJSON extensions for Modem Manager
interfaces:
key name |
type |
default |
allowed values |
---|---|---|---|
|
string |
|
|
|
string |
empty |
APN, can be left blank |
|
string |
empty |
PIN code, can be left blank |
|
string |
empty |
path to device (see note below) |
|
string |
empty |
password, can be left blank |
|
string |
empty |
username, can be left blank |
|
integer |
|
metric, can be left blank |
|
string |
|
One of |
|
boolean |
|
low power mode |
|
integer |
singal refresh rate in seconds |
Note
device
is a required property but can be left empty so that the
default value supplied by the hardware itself and already present on
the device can be left untouched by merging the configuration
generated with netjsonconfig (instead of fully overwriting it).
Modem Manager interface example
The following configuration dictionary:
{
"interfaces": [
{
"type": "modem-manager",
"apn": "apn.operator.com",
"pin": "1234",
"device": "/sys/devices/platform/ahb/1b000000.usb/usb1/1-1",
"username": "user123",
"password": "pwd123456",
"metric": 50,
"lowpower": False,
"name": "modem0",
"mtu": 1500,
"signalrate": 5,
"loglevel": "ERR",
"force_link": True,
}
]
}
Will be rendered as follows:
package network
config device 'device_modem0'
option mtu '1500'
option name 'modem0'
config interface 'modem0'
option apn 'apn.operator.com'
option device '/sys/devices/platform/ahb/1b000000.usb/usb1/1-1'
option force_link '1'
option loglevel 'ERR'
option lowpower '0'
option metric '50'
option password 'pwd123456'
option pincode '1234'
option proto 'modemmanager'
option signalrate '5'
option username 'user123'
VLAN 802.1q / VLAN 802.1ad settings
Note
The configuration setting for VLAN 802.1q and VLAN 802.1ad are
exactly same, except the type
setting. Hence, the documentation
only explains VLAN 802.1q.
Interfaces of type vlan_8021q
contain a few options that are specific
to VLAN 802.1q interfaces.
These are the OpenWrt
backend NetJSON extensions for VLAN 802.1q
interfaces:
key name |
type |
default |
allowed values |
---|---|---|---|
|
string |
|
type of interface
( |
|
integer |
empty |
VLAN ID |
|
string |
empty |
Defines a mapping of VLAN header priority to the Linux internal packet priority on incoming frames |
|
string |
empty |
Defines a mapping of Linux internal packet priority to VLAN header priority but for outgoing frames |
VLAN 802.1q example
The following configuration dictionary:
{
"interfaces": [
{
"type": "8021q",
"vid": 1,
"name": "br-lan",
"mac": "E8:6A:64:3E:4A:3A",
"mtu": 1500,
"ingress_qos_mapping": ["1:1"],
"egress_qos_mapping": ["2:2"],
}
]
}
Will be rendered as follows:
package network
config device 'device_br_lan_1'
list egress_qos_mapping '2:2'
option ifname 'br-lan'
list ingress_qos_mapping '1:1'
option macaddr 'E8:6A:64:3E:4A:3A'
option mtu '1500'
option name 'br-lan.1'
option type '8021q'
option vid '1'
config interface 'vlan_br_lan_1'
option device 'br-lan.1'
option proto 'none'
VLAN 802.1ad example
The following configuration dictionary:
{
"interfaces": [
{
"type": "8021ad",
"vid": 6,
"name": "eth0",
}
]
}
Will be rendered as follows:
package network
config device 'device_eth0_6'
option ifname 'eth0'
option name 'eth0.6'
option type '8021ad'
option vid '6'
config interface 'vlan_eth0_6'
option device 'eth0.6'
option proto 'none'
Radio settings
The radio settings reside in the radio
key of the configuration
dictionary, which must contain a list of NetJSON radio objects (see the link for the detailed
specification).
Radio object extensions
In addition to the default NetJSON Radio object options, the OpenWrt
backend also requires setting the following additional options for each
radio in the list:
key name |
type |
allowed values |
---|---|---|
|
string |
mac80211, atheros, ath5k, ath9k, broadcom |
|
string |
802.11a, 802.11b, 802.11g, 802.11n, 802.11ac, 802.11ax |
Radio example
The following configuration dictionary:
{
"radios": [
{
"name": "radio0",
"phy": "phy0",
"driver": "mac80211",
"protocol": "802.11n",
"channel": 11,
"channel_width": 20,
"tx_power": 5,
"country": "IT",
},
{
"name": "radio1",
"phy": "phy1",
"driver": "mac80211",
"protocol": "802.11n",
"channel": 36,
"channel_width": 20,
"tx_power": 4,
"country": "IT",
},
]
}
Will be rendered as follows:
package wireless
config wifi-device 'radio0'
option band '2g'
option channel '11'
option country 'IT'
option htmode 'HT20'
option phy 'phy0'
option txpower '5'
option type 'mac80211'
config wifi-device 'radio1'
option band '5g'
option channel '36'
option country 'IT'
option htmode 'HT20'
option phy 'phy1'
option txpower '4'
option type 'mac80211'
Automatic channel selection example
If you need to use the “automatic channel selection” feature of OpenWrt,
you must set the channel to 0
. You must also set the band
property
to tell OpenWrt which band to use (2g
for 2.4 Ghz, 5g
for 5 GHz,
6g
for 6 GHz, 60g
for 60 GHz).
The following example sets “automatic channel selection” for two radios, the first radio uses 802.11n in the 2.4 GHz band, while the second uses 802.11ac in the 5 GHz band.
{
"radios": [
{
"name": "radio0",
"phy": "phy0",
"driver": "mac80211",
"protocol": "802.11n",
"channel": 0, # 0 stands for auto
"band": "2g", # must set this explicitly, 2g means 2.4 GHz band
"channel_width": 20,
},
{
"name": "radio1",
"phy": "phy1",
"driver": "mac80211",
"protocol": "802.11ac",
"channel": 0, # 0 stands for auto
"band": "5g", # must set this explicitly, 5g means 5 GHz band,
# but this is optional for "802.11ac" because it only
# support 5 GHz band.
"channel_width": 80,
},
]
}
UCI output:
package wireless
config wifi-device 'radio0'
option band '2g'
option channel 'auto'
option htmode 'HT20'
option phy 'phy0'
option type 'mac80211'
config wifi-device 'radio1'
option band '5g'
option channel 'auto'
option htmode 'VHT80'
option phy 'phy1'
option type 'mac80211'
802.11ac example
In the following example we show how to configure an 802.11ac capable radio:
{
"radios": [
{
"name": "radio0",
"phy": "phy0",
"driver": "mac80211",
"protocol": "802.11ac",
"channel": 36,
"channel_width": 80,
}
]
}
UCI output:
package wireless
config wifi-device 'radio0'
option band '5g'
option channel '36'
option htmode 'VHT80'
option phy 'phy0'
option type 'mac80211'
802.11ax example
In the following example we show how to configure an 802.11ax capable radio:
{
"radios": [
{
"name": "radio0",
"phy": "phy0",
"driver": "mac80211",
"protocol": "802.11ax",
"channel": 36,
"channel_width": 80,
}
]
}
UCI output:
package wireless
config wifi-device 'radio0'
option band '5g'
option channel '36'
option htmode 'HE80'
option phy 'phy0'
option type 'mac80211'
Static Routes
The static routes settings reside in the routes
key of the
configuration dictionary, which must contain a list of NetJSON Static
Route objects (see the link for
the detailed specification).
Static route object extensions
In addition to the default NetJSON Route object options, the OpenWrt
backend also allows to define the following optional settings:
key name |
type |
default |
description |
---|---|---|---|
|
string |
|
unicast, local, broadcast, multicast, unreachable prohibit, blackhole, anycast |
|
string |
|
MTU for route, only numbers are allowed |
|
string |
|
Routing table id, only numbers are allowed |
|
boolean |
|
When enabled, gateway is on link even if the gateway does not match any interface prefix |
Static route example
The following configuration dictionary:
{
"routes": [
{
"device": "eth1",
"destination": "192.168.4.1/24",
"next": "192.168.2.2",
"cost": 2,
"source": "192.168.1.10",
"table": "2",
"onlink": True,
"mtu": "1450",
},
{
"device": "eth1",
"destination": "fd89::1/128",
"next": "fd88::1",
"cost": 0,
},
]
}
Will be rendered as follows:
package network
config route 'route1'
option gateway '192.168.2.2'
option interface 'eth1'
option metric '2'
option mtu '1450'
option netmask '255.255.255.0'
option onlink '1'
option source '192.168.1.10'
option table '2'
option target '192.168.4.1'
config route6 'route2'
option gateway 'fd88::1'
option interface 'eth1'
option metric '0'
option target 'fd89::1/128'
Policy routing
The policy routing settings reside in the ip_rule
key of the
configuration dictionary, which is a custom NetJSON extension not
present in the original NetJSON RFC.
The ip_rule
key must contain a list of rules, each rule allows the
following options:
key name |
type |
---|---|
|
string |
|
string |
|
string |
|
string |
|
string |
|
boolean |
|
string |
|
integer |
|
string |
For the function and meaning of each key consult the relevant OpenWrt documentation about rule directives.
Policy routing example
The following configuration dictionary:
{
"ip_rules": [
{
"in": "eth0",
"out": "eth1",
"src": "192.168.1.0/24",
"dest": "192.168.2.0/24",
"tos": 2,
"mark": "0x0/0x1",
"invert": True,
"lookup": "0",
"action": "blackhole",
},
{"src": "192.168.1.0/24", "dest": "192.168.3.0/24", "goto": 0},
{"in": "vpn", "dest": "fdca:1234::/64", "action": "prohibit"},
{"in": "vpn", "src": "fdca:1235::/64", "action": "prohibit"},
]
}
Will be rendered as follows:
package network
config rule 'rule1'
option action 'blackhole'
option dest '192.168.2.0/24'
option in 'eth0'
option invert '1'
option lookup '0'
option mark '0x0/0x1'
option out 'eth1'
option src '192.168.1.0/24'
option tos '2'
config rule 'rule2'
option dest '192.168.3.0/24'
option goto '0'
option src '192.168.1.0/24'
config rule6 'rule3'
option action 'prohibit'
option dest 'fdca:1234::/64'
option in 'vpn'
config rule6 'rule4'
option action 'prohibit'
option in 'vpn'
option src 'fdca:1235::/64'
Programmable switch settings
The programmable switch settings reside in the switch
key of the
configuration dictionary, which is a custom NetJSON extension not
present in the original NetJSON RFC.
The switch
key must contain a list of dictionaries, all the following
keys are required:
key name |
type |
---|---|
|
string |
|
boolean |
|
boolean |
|
list |
The elements of the vlan
list must be dictionaries, all the following
keys are required:
key name |
type |
---|---|
|
string |
|
boolean |
|
integer |
|
string |
For the function and meaning of each key consult the relevant OpenWrt documentation about switch directives.
Switch example
The following configuration dictionary:
{
"switch": [
{
"name": "switch0",
"reset": True,
"enable_vlan": True,
"vlan": [
{"device": "switch0", "vlan": 1, "ports": "0t 2 3 4 5"},
{"device": "switch0", "vlan": 2, "ports": "0t 1"},
],
}
]
}
Will be rendered as follows:
package network
config switch 'switch0'
option enable_vlan '1'
option name 'switch0'
option reset '1'
config switch_vlan 'switch0_vlan1'
option device 'switch0'
option ports '0t 2 3 4 5'
option vid '1'
option vlan '1'
config switch_vlan 'switch0_vlan2'
option device 'switch0'
option ports '0t 1'
option vid '2'
option vlan '2'
Overriding or disabling vid
UCI option
The OpenWrt UCI vid
option of switch_vlan
sections is
automatically inferred from the vlan
number, although it’s possible to
override it or disable it if needed:
{
"switch": [
{
"name": "switch0",
"reset": True,
"enable_vlan": True,
"vlan": [
{
"device": "switch0",
"vlan": 1,
"vid": 110, # manual override
"ports": "0t 2 3 4 5",
},
{
"device": "switch0",
"vlan": 2,
# ``None`` or empty string will remove
# ``vid`` output from the UCI result
"vid": None,
"ports": "0t 1",
},
],
}
]
}
Will be rendered as follows:
package network
config switch 'switch0'
option enable_vlan '1'
option name 'switch0'
option reset '1'
config switch_vlan 'switch0_vlan1'
option device 'switch0'
option ports '0t 2 3 4 5'
option vid '110'
option vlan '1'
config switch_vlan 'switch0_vlan2'
option device 'switch0'
option ports '0t 1'
option vlan '2'
NTP settings
The Network Time Protocol settings reside in the ntp
key of the
configuration dictionary, which is a custom NetJSON extension not
present in the original NetJSON RFC.
The ntp
key must contain a dictionary, the allowed options are:
key name |
type |
function |
---|---|---|
|
boolean |
ntp client enabled |
|
boolean |
ntp server enabled |
|
list |
list of ntp servers |
NTP settings example
The following configuration dictionary:
{
"ntp": {
"enabled": True,
"enable_server": False,
"server": [
"0.openwrt.pool.ntp.org",
"1.openwrt.pool.ntp.org",
"2.openwrt.pool.ntp.org",
"3.openwrt.pool.ntp.org",
],
}
}
Will be rendered as follows:
package system
config timeserver 'ntp'
list server '0.openwrt.pool.ntp.org'
list server '1.openwrt.pool.ntp.org'
list server '2.openwrt.pool.ntp.org'
list server '3.openwrt.pool.ntp.org'
option enable_server '0'
option enabled '1'
LED settings
The led settings reside in the led
key of the configuration
dictionary, which is a custom NetJSON extension not present in the
original NetJSON RFC.
The led
key must contain a list of dictionaries, the allowed options
are:
key name |
type |
---|---|
|
string |
|
boolean |
|
string |
|
string |
|
string |
|
integer |
|
integer |
|
integer |
|
string |
|
string |
The required keys are:
name
sysfs
trigger
For the function and meaning of each key consult the relevant OpenWrt documentation about led directives.
LED settings example
The following configuration dictionary:
{
"led": [
{
"name": "USB1",
"sysfs": "tp-link:green:usb1",
"trigger": "usbdev",
"dev": "1-1.1",
"interval": 50,
},
{
"name": "USB2",
"sysfs": "tp-link:green:usb2",
"trigger": "usbdev",
"dev": "1-1.2",
"interval": 50,
},
{
"name": "WLAN2G",
"sysfs": "tp-link:blue:wlan2g",
"trigger": "phy0tpt",
},
]
}
Will be rendered as follows:
package system
config led 'led_usb1'
option dev '1-1.1'
option interval '50'
option name 'USB1'
option sysfs 'tp-link:green:usb1'
option trigger 'usbdev'
config led 'led_usb2'
option dev '1-1.2'
option interval '50'
option name 'USB2'
option sysfs 'tp-link:green:usb2'
option trigger 'usbdev'
config led 'led_wlan2g'
option name 'WLAN2G'
option sysfs 'tp-link:blue:wlan2g'
option trigger 'phy0tpt'
Including custom options
It is very easy to add configuration options that are not explicitly
defined in the schema of the OpenWrt
backend.
For example, in some cases you may need to define a “ppp” interface, which can use quite a few properties that are not defined in the schema:
from netjsonconfig import OpenWrt
o = OpenWrt(
{
"interfaces": [
{
"name": "ppp0",
"type": "other",
"proto": "ppp",
"device": "/dev/usb/modem1",
"username": "user1",
"password": "pwd0123",
"keepalive": 3,
"ipv6": True,
}
]
}
)
print(o.render())
UCI output:
package network
config interface 'ppp0'
option device '/dev/usb/modem1'
option ifname 'ppp0'
option ipv6 '1'
option keepalive '3'
option password 'pwd0123'
option proto 'ppp'
option username 'user1'
Including custom lists
Under specific circumstances, OpenWrt allows adding configuration options
in the form of lists. Many of these UCI options are not defined in the
JSON-Schema of the OpenWrt
backend, but the schema allows adding
custom properties.
The OpenWrt
backend recognizes list options for the following
sections:
interface settings
ip address settings
wireless settings
radio settings
Interface list setting example
The following example shows how to set a list of ip6class
options:
o = OpenWrt(
{
"interfaces": [
{
"name": "eth0",
"type": "ethernet",
"ip6class": ["wan6", "backbone"],
}
]
}
)
print(o.render())
UCI Output:
package network
config interface 'eth0'
option ifname 'eth0'
list ip6class 'wan6'
list ip6class 'backbone'
option proto 'none'
Address list setting example
The following example shows how to set a list of dhcp reqopts
settings:
o = OpenWrt(
{
"interfaces": [
{
"name": "eth0",
"type": "ethernet",
"addresses": [
{
"proto": "dhcp",
"family": "ipv4",
"reqopts": ["43", "54"],
}
],
}
]
}
)
print(o.render())
UCI Output:
package network
config interface 'eth0'
option ifname 'eth0'
option proto 'dhcp'
list reqopts '43'
list reqopts '54'
Radio list setting example
The following example shows how to set a list of advanced capabilities
supported by the radio using ht_capab
:
o = OpenWrt(
{
"radios": [
{
"name": "radio0",
"phy": "phy0",
"driver": "mac80211",
"protocol": "802.11n",
"channel": 1,
"channel_width": 20,
"ht_capab": ["SMPS-STATIC", "SHORT-GI-20"],
}
]
}
)
print(o.render())
UCI output:
package wireless
config wifi-device 'radio0'
option channel '1'
list ht_capab 'SMPS-STATIC'
list ht_capab 'SHORT-GI-20'
option htmode 'HT20'
option band '2g'
option phy 'phy0'
option type 'mac80211'
Wireless list setting example
The following example shows how to set the supported basic rates of a
wireless interface using basic_rate
:
o = OpenWrt(
{
"interfaces": [
{
"name": "wlan0",
"type": "wireless",
"wireless": {
"radio": "radio0",
"mode": "access_point",
"ssid": "open",
"basic_rate": ["6000", "9000"],
},
}
]
}
)
print(o.render())
UCI output:
package network
config interface 'wlan0'
option ifname 'wlan0'
option proto 'none'
package wireless
config wifi-iface 'wifi_wlan0'
list basic_rate '6000'
list basic_rate '9000'
option device 'radio0'
option ifname 'wlan0'
option mode 'ap'
option network 'wlan0'
option ssid 'open'
Including additional files
The OpenWrt
backend supports inclusion of arbitrary plain text files
through the files
key of the configuration dictionary. The value of
the files
key must be a list in which each item is a dictionary
representing a file, each dictionary is structured as follows:
key name |
type |
required |
function |
---|---|---|---|
|
string |
yes |
filesystem path, will be encoded in the tar.gz archive |
|
string |
yes |
plain text contents of the file, new lines
must be encoded as |
|
string |
yes |
filesystem permissions, defaults to |
The files
key of the configuration dictionary is a custom NetJSON
extension not present in the original NetJSON RFC.
Warning
The files are included in the output of the render
method unless
you pass files=False
, eg: openwrt.render(files=False)
Plain file example
The following example code will generate an archive with one file in
/etc/crontabs/root
:
from netjsonconfig import OpenWrt
o = OpenWrt(
{
"files": [
{
"path": "/etc/crontabs/root",
"mode": "0644",
# new lines must be escaped with ``\n``
"contents": '* * * * * echo "test" > /etc/testfile\n'
'* * * * * echo "test2" > /etc/testfile2',
}
]
}
)
o.generate()
Executable script file example
The following example will create an executable shell script:
o = OpenWrt(
{
"files": [
{
"path": "/bin/hello_world",
"mode": "0755",
"contents": "#!/bin/sh\n" "echo 'Hello world'",
}
]
}
)
o.generate()
OpenVPN
This backend includes the schema of the OpenVpn
backend, inheriting
its features.
For details regarding the OpenVPN schema please see OpenVPN backend schema.
Schema additions
The OpenWrt
backend adds a few properties to the OpenVPN schema, see
below.
key name |
type |
default |
allowed values |
---|---|---|---|
|
boolean |
|
OpenVPN example
The following configuration dictionary:
{
"openvpn": [
{
"ca": "ca.pem",
"cert": "cert.pem",
"dev": "tap0",
"dev_type": "tap",
"dh": "dh.pem",
"disabled": False,
"key": "key.pem",
"mode": "server",
"name": "test-vpn-server",
"proto": "udp",
"tls_server": True,
}
]
}
Will be rendered as follows:
package openvpn
config openvpn 'test_vpn_server'
option ca 'ca.pem'
option cert 'cert.pem'
option dev 'tap0'
option dev_type 'tap'
option dh 'dh.pem'
option enabled '1'
option key 'key.pem'
option mode 'server'
option proto 'udp'
option tls_server '1'
WireGuard
This backend includes the schema of the Wireguard
backend, inheriting
its features.
For details regarding the WireGuard schema please see WireGuard backend schema.
Schema additions
The OpenWrt
backend adds a few properties to the WireGuard schema, see
below.
key name |
type |
default |
description |
---|---|---|---|
|
string |
|
logical interface name (UCI specific), 2 to 15 alphanumeric characters, dashes and underscores |
|
boolean |
|
do not add routes to ensure the tunnel endpoints are routed via non-tunnel device |
|
string |
|
firewall mark to apply to tunnel endpoint packets |
|
list |
|
IPv6 prefixes to delegate to other interfaces |
|
list |
|
list of unique IPv4 or IPv6 addresses |
The OpenWrt
backend also adds wireguard_peers
option for
sepecifying a list of WireGuard Peers. It add the following properties to
the wireguard_peers
property of WireGuard schema.
key name |
type |
default |
description |
---|---|---|---|
|
string |
|
name of the wireguard interface, 2 to 15 alphanumeric characters, dashes and underscores |
|
boolean |
|
automatically create a route for each of the Allowed IPs for this peer |
WireGuard example
The following configuration dictionary:
{
"interfaces": [
{
"name": "wg",
"type": "wireguard",
"private_key": "QFdbnuYr7rrF4eONCAs7FhZwP7BXX/jD/jq2LXCpaXI=",
"port": 51820,
"mtu": 1420,
"nohostroute": False,
"fwmark": "",
"ip6prefix": [],
"addresses": [
{
"proto": "static",
"family": "ipv4",
"address": "10.0.0.5/32",
"mask": 32,
}
],
"network": "",
}
],
"wireguard_peers": [
{
"interface": "wg",
"public_key": "94a+MnZSdzHCzOy5y2K+0+Xe7lQzaa4v7lEiBZ7elVE=",
"allowed_ips": ["10.0.0.1/32"],
"endpoint_host": "wireguard.test.com",
"endpoint_port": 51820,
"preshared_key": "",
"persistent_keepalive": 60,
"route_allowed_ips": True,
}
],
}
Will be rendered as follows:
package network
config interface 'wg'
list addresses '10.0.0.5/32/32'
option listen_port '51820'
option mtu '1420'
option nohostroute '0'
option private_key 'QFdbnuYr7rrF4eONCAs7FhZwP7BXX/jD/jq2LXCpaXI='
option proto 'wireguard'
config wireguard_wg 'wgpeer'
list allowed_ips '10.0.0.1/32'
option endpoint_host 'wireguard.test.com'
option endpoint_port '51820'
option persistent_keepalive '60'
option public_key '94a+MnZSdzHCzOy5y2K+0+Xe7lQzaa4v7lEiBZ7elVE='
option route_allowed_ips '1'
VXLAN
OpenWrt
backend includes the schema requied for generating VXLAN
interface configouration. This is useful of setting up layer 2 tunnels.
VXLAN Settings
key name |
type |
default |
description |
---|---|---|---|
|
string |
|
name of interface, 2 to 15 alphanumeric characters, dashes and underscores |
|
string |
|
VXLAN tunnel endpoint |
|
integer |
|
port for VXLAN connection |
|
integer or string |
|
VXLAN Network Identifier |
|
list |
|
interface to which the VXLAN tunnel will be bound |
|
boolean |
|
use checksum validation in RX direction |
|
boolean |
|
use checksum validation in TX direction |
|
integer |
|
MTU for route, only numbers are allowed |
|
integer |
|
TTL of the encapsulation packets |
VXLAN example
The following configuration dictionary:
{
"interfaces": [
{
"name": "vxlan",
"type": "vxlan",
"vtep": "10.0.0.1",
"port": 4789,
"vni": 1,
"tunlink": "",
"rxcsum": True,
"txcsum": True,
"mtu": 1280,
"ttl": 64,
"mac": "",
"disabled": False,
"network": "",
},
]
}
Will be rendered as follows:
package network
config interface 'vxlan'
option enabled '0'
option ifname 'vxlan'
option mtu '1280'
option peeraddr '10.0.0.1'
option port '4789'
option proto 'vxlan'
option rxcsum '1'
option ttl '64'
option txcsum '1'
option vid '1'
VXLAN over WireGuard example
Since a layer 2 tunnel can be encapsulated in a layer 3 tunnel, here is an example configuration for setting up a VXLAN tunnel over WireGuard.
The following configuration dictionary:
{
"interfaces": [
{
"name": "wgvxlan",
"type": "wireguard",
"private_key": "QFdbnuYr7rrF4eONCAs7FhZwP7BXX/jD/jq2LXCpaXI=",
"port": 51820,
"mtu": 1420,
"nohostroute": False,
"fwmark": "",
"ip6prefix": [],
"addresses": [
{
"proto": "static",
"family": "ipv4",
"address": "10.0.0.5/32",
"mask": 32,
}
],
"network": "",
},
{
"name": "vxlan",
"type": "vxlan",
"vtep": "10.0.0.1",
"port": 4789,
"vni": 1,
"tunlink": "wgvxlan",
"rxcsum": True,
"txcsum": True,
"mtu": 1280,
"ttl": 64,
"mac": "",
"disabled": False,
"network": "",
},
],
"wireguard_peers": [
{
"interface": "wgvxlan",
"public_key": "94a+MnZSdzHCzOy5y2K+0+Xe7lQzaa4v7lEiBZ7elVE=",
"allowed_ips": ["10.0.0.1/32"],
"endpoint_host": "wireguard.test.com",
"endpoint_port": 51820,
"preshared_key": "",
"persistent_keepalive": 60,
"route_allowed_ips": True,
}
],
}
Will be rendered as follows:
package network
config interface 'wgvxlan'
list addresses '10.0.0.5/32/32'
option listen_port '51820'
option mtu '1420'
option nohostroute '0'
option private_key 'QFdbnuYr7rrF4eONCAs7FhZwP7BXX/jD/jq2LXCpaXI='
option proto 'wireguard'
config interface 'vxlan'
option enabled '1'
option ifname 'vxlan'
option mtu '1280'
option peeraddr '10.0.0.1'
option port '4789'
option proto 'vxlan'
option rxcsum '1'
option ttl '64'
option tunlink 'wgvxlan'
option txcsum '1'
option vid '1'
config wireguard_wgvxlan 'wgpeer'
list allowed_ips '10.0.0.1/32'
option endpoint_host 'wireguard.test.com'
option endpoint_port '51820'
option persistent_keepalive '60'
option public_key '94a+MnZSdzHCzOy5y2K+0+Xe7lQzaa4v7lEiBZ7elVE='
option route_allowed_ips '1'
All the other settings
Do you need to include some configuration directives that are not defined
in the NetJSON spec nor in the schema of the OpenWrt
backend? Don’t
panic!
Because netjsonconfig aims to be very flexible, it ships code that will try to render extra parts of the configuration dictionary into meaningful UCI output.
In order to accomplish this, you must add extra keys to the configuration dictionary which have to meet the following requirements:
the name of the key must be the name of the package that needs to be configured
the value of the key must be a
list
each element in the list must be a
dict
each
dict
MUST contain a key namedconfig_name
each
dict
MAY contain a key namedconfig_value
This feature is best explained with a few examples.
Dropbear example
The following configuration dictionary:
{
"dropbear": [
{
"config_name": "dropbear",
"config_value": "dropbear_1",
"PasswordAuth": "on",
"RootPasswordAuth": "on",
"Port": 22,
}
]
}
Will be rendered as follows:
package dropbear
config dropbear 'dropbear_1'
option PasswordAuth 'on'
option Port '22'
option RootPasswordAuth 'on'
OLSRd2 example
The following configuration dictionary:
{
"olsrd2": [
{
"config_name": "global",
"config_value": "global",
"pidfile": "/var/run/olsrd2.pid",
"lockfile": "/var/lock/olsrd2",
},
{
"config_name": "log",
"config_value": "log",
"syslog": "true",
"stderr": "true",
"file": "/var/log/olsrd2.log",
},
{
"config_name": "interface",
"config_value": "olsr2_common",
"ifname": ["loopback", "wlan0", "wlan1"],
},
]
}
Will be rendered as follows:
package olsrd2
config global 'global'
option lockfile '/var/lock/olsrd2'
option pidfile '/var/run/olsrd2.pid'
config log 'log'
option file '/var/log/olsrd2.log'
option stderr 'true'
option syslog 'true'
config interface 'olsr2_common'
list ifname 'loopback'
list ifname 'wlan0'
list ifname 'wlan1'