Skip to content

Commit

Permalink
[feature] Added support for basic 802.11r options in OpenWRT #175
Browse files Browse the repository at this point in the history
Closes #175

Co-authored-by: Federico Capoano <f.capoano@openwisp.io>
  • Loading branch information
pandafy and nemesifier committed Mar 12, 2022
1 parent cfc388a commit 9bceb18
Show file tree
Hide file tree
Showing 4 changed files with 195 additions and 15 deletions.
87 changes: 76 additions & 11 deletions docs/source/backends/openwrt.rst
Original file line number Diff line number Diff line change
Expand Up @@ -622,17 +622,29 @@ The ``OpenWrt`` backend NetJSON extensions for wireless interfaces:

Some extensions are applicable only when ``mode`` is ``access_point``:

+---------------+---------+-------------+------------------------------------------------------+
| key name | type | default | allowed values |
+===============+=========+=============+======================================================+
| ``wmm`` | boolean | ``True`` | enables WMM (802.11e) support |
+---------------+---------+-------------+------------------------------------------------------+
| ``isolate`` | boolean | ``False`` | isolate wireless clients from one another |
+---------------+---------+-------------+------------------------------------------------------+
| ``macfilter`` | string | ``disable`` | ACL policy, accepts: "disable", "allow" and "deny" |
+---------------+---------+-------------+------------------------------------------------------+
| ``maclist`` | array | ``[]`` | mac addresses filtered according to macfilter policy |
+---------------+---------+-------------+------------------------------------------------------+
+----------------------------+---------+-------------+------------------------------------------------------+
| key name | type | default | allowed values |
+============================+=========+=============+======================================================+
| ``wmm`` | boolean | ``True`` | enables WMM (802.11e) support |
+----------------------------+---------+-------------+------------------------------------------------------+
| ``ieee80211r`` | boolean | ``False`` | enables fast BSS transition (802.11r) support |
+----------------------------+---------+-------------+------------------------------------------------------+
| ``reassociation_deadline`` | integer | ``1000`` | reassociation deadline in time units |
| | | | (TUs / 1.024 ms, 1000-65535) |
+----------------------------+---------+-------------+------------------------------------------------------+
| ``ft_psk_generate_local`` | boolean | ``False`` | whether to generate FT response locally |
| | | | for PSK networks |
+----------------------------+---------+-------------+------------------------------------------------------+
| ``ft_over_ds`` | boolean | ``True`` | whether to enable FT-over-DS |
+----------------------------+---------+-------------+------------------------------------------------------+
| ``rsn_preauth`` | boolean | ``False`` | allow pre-authentication for WPA2-EAP networks |
+----------------------------+---------+-------------+------------------------------------------------------+
| ``isolate`` | boolean | ``False`` | isolate wireless clients from one another |
+----------------------------+---------+-------------+------------------------------------------------------+
| ``macfilter`` | string | ``disable`` | ACL policy, accepts: "disable", "allow" and "deny" |
+----------------------------+---------+-------------+------------------------------------------------------+
| ``maclist`` | array | ``[]`` | mac addresses filtered according to macfilter policy |
+----------------------------+---------+-------------+------------------------------------------------------+

These extensions must be used the ``wireless`` object of a wireless interface eg:

Expand Down Expand Up @@ -852,6 +864,59 @@ UCI output::
option network 'wlan0'
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 <https://openwrt.org/docs/guide-user/network/wifi/basic#fast_bss_transition_options_80211r>`_).

In the following example we configure roaming options for a wireless access point:

.. code-block:: python
{
"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 network

config interface 'wlan0'
option ifname 'wlan0'
option proto 'none'

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
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Expand Down
19 changes: 15 additions & 4 deletions netjsonconfig/backends/openwrt/converters/wireless.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,10 +168,21 @@ def __netjson_wifi(self, wifi, interface):
return wifi

def __netjson_wifi_typecast(self, wifi):
if 'hidden' in wifi:
wifi['hidden'] = wifi['hidden'] == '1'
if 'wds' in wifi:
wifi['wds'] = wifi['wds'] == '1'
for attr in [
'hidden',
'wds',
'ft_over_ds',
'ft_psk_generate_local',
'ieee80211r',
'rsn_preauth',
]:
if attr in wifi:
wifi[attr] = wifi[attr] == '1'
if 'reassociation_deadline' in wifi:
try:
wifi['reassociation_deadline'] = int(wifi['reassociation_deadline'])
except ValueError:
del wifi['reassociation_deadline']

_encryption_keys = [
'key',
Expand Down
44 changes: 44 additions & 0 deletions netjsonconfig/backends/openwrt/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,50 @@
"format": "checkbox",
"propertyOrder": 9,
},
"ieee80211r": {
"type": "boolean",
"title": "roaming",
"description": "enables fast BSS transition (802.11r) support",
"default": False,
"format": "checkbox",
"propertyOrder": 9,
},
"reassociation_deadline": {
"type": "integer",
"title": "reassociation deadline",
"description": (
"reassociation deadline in time units "
"(TUs / 1.024 ms, 1000-65535)"
),
"default": 1000,
"minimum": 1000,
"maximum": 65535,
"propertyOrder": 9,
},
"ft_psk_generate_local": {
"type": "boolean",
"title": "FT PSK generate local",
"description": "whether to generate FT response locally for PSK networks",
"default": False,
"format": "checkbox",
"propertyOrder": 9,
},
"ft_over_ds": {
"type": "boolean",
"title": "FT-over-DS",
"description": "whether to enable FT-over-DS",
"default": True,
"format": "checkbox",
"propertyOrder": 9,
},
"rsn_preauth": {
"type": "boolean",
"title": "WPA2-EAP pre-authentication",
"description": "allow preauthentication for WPA2-EAP networks",
"default": False,
"format": "checkbox",
"propertyOrder": 9,
},
"macfilter": {
"type": "string",
"title": "MAC Filter",
Expand Down
60 changes: 60 additions & 0 deletions tests/openwrt/test_wireless.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import unittest
from copy import deepcopy

from netjsonconfig import OpenWrt
from netjsonconfig.exceptions import ValidationError
Expand Down Expand Up @@ -732,6 +733,65 @@ def test_parse_wds_bridge(self):
o = OpenWrt(native=self._wds_bridge_uci)
self.assertEqual(o.config, self._wds_bridge_netjson)

_80211r_netjson = {
"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"],
},
}
]
}
_80211r_uci = """package network
config interface 'wlan0'
option ifname 'wlan0'
option proto 'none'
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'
"""

def test_render_access_point_80211r(self):
o = OpenWrt(self._80211r_netjson)
expected = self._tabs(self._80211r_uci)
self.assertEqual(o.render(), expected)

def test_parse_access_point_80211r(self):
o = OpenWrt(native=self._80211r_uci)
self.assertEqual(o.config, self._80211r_netjson)

with self.subTest('ignore bogus reassociation_deadline'):
bogus_uci = self._80211r_uci
bogus_uci = bogus_uci.replace(
"reassociation_deadline '1000'", "reassociation_deadline 'bogus'"
)
o = OpenWrt(native=bogus_uci)
netjson_80211r = deepcopy(self._80211r_netjson)
del netjson_80211r['interfaces'][0]['wireless']['reassociation_deadline']
self.assertEqual(o.config, netjson_80211r)

_80211s_netjson = {
"interfaces": [
{
Expand Down

0 comments on commit 9bceb18

Please sign in to comment.