Skip to content

Commit

Permalink
Added support for basic bridges #6
Browse files Browse the repository at this point in the history
  • Loading branch information
nemesifier committed Sep 24, 2015
1 parent afd2bc8 commit b492ec8
Show file tree
Hide file tree
Showing 4 changed files with 164 additions and 6 deletions.
7 changes: 4 additions & 3 deletions netjsonconfig/backends/base.py
Expand Up @@ -4,9 +4,10 @@ class BaseRenderer(object):
"""
block_name = None

def __init__(self, config, env):
self.config = config
self.env = env
def __init__(self, backend):
self.config = backend.config
self.env = backend.env
self.backend = backend

def cleanup(self, output):
"""
Expand Down
28 changes: 27 additions & 1 deletion netjsonconfig/backends/openwrt/openwrt.py
Expand Up @@ -22,12 +22,13 @@ def __init__(self, config):
self.config = config
self.env = Environment(loader=PackageLoader('netjsonconfig.backends.openwrt', 'templates'),
trim_blocks=True)
self.__find_bridges()

def render(self):
self.validate()
output = ''
for renderer_class in self.renderers:
renderer = renderer_class(self.config, self.env)
renderer = renderer_class(self)
additional_output = renderer.render()
# add an additional new line
# to separate blocks
Expand All @@ -45,3 +46,28 @@ def validate(self):
def json(self, *args, **kwargs):
self.validate()
return json.dumps(self.config, *args, **kwargs)

def __find_bridges(self):
"""
OpenWRT declare bridges in /etc/config/network
but wireless interfaces are attached to ethernet ones
with declarations that go in /etc/config/wireless
this method
"""
wifi = {}
bridges = {}
net_bridges = {}
for interface in self.config.get('interfaces', []):
if interface.get('type') == 'wireless':
wifi[interface['name']] = interface
elif interface.get('type') == 'bridge':
bridges[interface['name']] = interface['bridge_members']
for bridge_members in bridges.values():
# determine bridges that will go in /etc/config/network
net_names = [name for name in bridge_members if name not in wifi.keys()]
net_bridges[net_names[0]] = net_names
# openwrt deals with wifi bridges differently
for name in bridge_members:
if name in wifi.keys():
wifi[name]['_attached'] = net_names
self._net_bridges = net_bridges
22 changes: 20 additions & 2 deletions netjsonconfig/backends/openwrt/renderers.py
Expand Up @@ -35,7 +35,8 @@ def _get_interfaces(self):
del uci_interface['type']
if uci_interface.get('wireless'):
del uci_interface['wireless']

if uci_interface.get('_attached'):
del uci_interface['_attached']
# default values
address_key = None
address_value = None
Expand All @@ -62,6 +63,14 @@ def _get_interfaces(self):
# add address if any (with correct option name)
if address_key and address_value:
uci_interface[address_key] = address_value
# determine if must be type bridge
bridges = self.backend._net_bridges.copy()
if interface['name'] in list(bridges.keys()):
bridge_members = bridges[interface['name']]
uci_interface['type'] = 'bridge'
uci_interface['ifname'] = ' '.join(bridge_members)
# ensure type "bridge" is only given to one logical interface
del bridges[interface['name']]
# append to interface list
uci_interfaces.append(sorted_dict(uci_interface))
counter += 1
Expand Down Expand Up @@ -198,7 +207,16 @@ def _get_wifi_interfaces(self):
'802.11s': 'mesh'
}
uci_wifi['mode'] = modes[wireless['mode']]
uci_wifi['network'] = wifi_interface['name']
# wifi interface will be attached
# to the relative section in /etc/config/network
# but might be also attached to other interfaces
# indicated in "_attached", which is populated
# in OpenWrt.__find_bridges method
network = [wifi_interface['name']]
if wifi_interface.get('_attached'):
network += wifi_interface['_attached']
uci_wifi['network'] = ' '.join(network)
# determine encryption for wifi
if uci_wifi.get('encryption'):
del uci_wifi['encryption']
uci_encryption = self.__get_encryption(wireless)
Expand Down
113 changes: 113 additions & 0 deletions tests/test_openwrt.py
Expand Up @@ -941,5 +941,118 @@ def test_multiple_ssid(self):
option mode 'adhoc'
option network 'wlan0'
option ssid 'adhoc-ssid'
""")
self.assertEqual(o.render(), expected)

def test_wifi_bridge(self):
o = OpenWrt({
"type": "DeviceConfiguration",
"interfaces": [
{
"name": "eth0",
"type": "ethernet",
"addresses": [
{
"address": "192.168.1.1",
"mask": 24,
"proto": "static",
"family": "ipv4"
}
]
},
{
"name": "wlan0",
"type": "wireless",
"addresses": [
{
"proto": "dhcp"
}
],
"wireless": [
{
"radio": "radio0",
"mode": "access_point",
"ssid": "open"
}
]
},
{
"name": "br-eth0",
"type": "bridge",
"bridge_members": [
"eth0",
"wlan0"
]
}
]
})
expected = self._tabs("""package network
config interface 'eth0'
option ifname 'eth0'
option ipaddr '192.168.1.1/24'
option proto 'static'
option type 'bridge'
config interface 'wlan0'
option ifname 'wlan0'
option proto 'dhcp'
package wireless
config wifi-iface
option device 'radio0'
option mode 'ap'
option network 'wlan0 eth0'
option ssid 'open'
""")
self.assertEqual(o.render(), expected)

def test_eth_bridge(self):
o = OpenWrt({
"type": "DeviceConfiguration",
"interfaces": [
{
"name": "eth0",
"type": "ethernet",
"addresses": [
{
"address": "192.168.1.1",
"mask": 24,
"proto": "static",
"family": "ipv4"
}
]
},
{
"name": "eth1",
"type": "ethernet",
"addresses": [
{
"proto": "dhcp"
}
]
},
{
"name": "br-eth0",
"type": "bridge",
"bridge_members": [
"eth0",
"eth1"
]
}
]
})
expected = self._tabs("""package network
config interface 'eth0'
option ifname 'eth0 eth1'
option ipaddr '192.168.1.1/24'
option proto 'static'
option type 'bridge'
config interface 'eth1'
option ifname 'eth1'
option proto 'dhcp'
""")
self.assertEqual(o.render(), expected)

0 comments on commit b492ec8

Please sign in to comment.