Explorar el Código

gluon-mesh-babel: HACK: basic, experimental babel config

Nils Schneider hace 8 años
padre
commit
3247ca0e4a

+ 36 - 0
package/gluon-mesh-babel/Makefile

@@ -0,0 +1,36 @@
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=gluon-mesh-babel
+PKG_VERSION:=1
+
+PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
+
+include $(GLUONDIR)/include/package.mk
+
+define Package/gluon-mesh-babel
+  SECTION:=gluon
+  CATEGORY:=Gluon
+  TITLE:=Babel mesh
+  DEPENDS:=+gluon-core +babeld
+endef
+
+define Build/Prepare
+	mkdir -p $(PKG_BUILD_DIR)
+endef
+
+define Build/Configure
+endef
+
+define Build/Compile
+endef
+
+define Package/gluon-mesh-babel/install
+	$(CP) ./files/* $(1)/
+endef
+
+define Package/gluon-mesh-babel/postinst
+#!/bin/sh
+$(call GluonCheckSite,check_site.lua)
+endef
+
+$(eval $(call BuildPackage,gluon-mesh-babel))

+ 2 - 0
package/gluon-mesh-babel/check_site.lua

@@ -0,0 +1,2 @@
+need_string_match('babel_mesh.prefix', '^[%x:]+/64$')
+need_boolean('mesh_on_wan', false)

+ 27 - 0
package/gluon-mesh-babel/files/lib/gluon/upgrade/300-gluon-mesh-babel-firewall

@@ -0,0 +1,27 @@
+#!/usr/bin/lua
+
+local uci = require('luci.model.uci').cursor()
+
+uci:section('firewall', 'rule', 'wan_babel',
+  {
+    name = 'wan_babel',
+    src = 'wan',
+    src_ip = 'fe80::/64',
+    dest_port = '6696',
+    proto = 'udp',
+    target = 'ACCEPT',
+  }
+)
+
+uci:section('firewall', 'zone', 'mesh_babel',
+  {
+    name = 'mesh_babel',
+    input = 'ACCEPT',
+    output = 'ACCEPT',
+    forward = 'ACCEPT',
+  }
+)
+
+uci:save('firewall')
+uci:commit('firewall')
+

+ 104 - 0
package/gluon-mesh-babel/files/lib/gluon/upgrade/300-gluon-mesh-babel-ip6

@@ -0,0 +1,104 @@
+#!/usr/bin/lua
+
+local nixio = require 'nixio'
+local sysconfig = require 'gluon.sysconfig'
+local uci = require('luci.model.uci').cursor()
+local site = require 'gluon.site_config'
+
+
+function IPv6(address)
+--[[
+(c) 2008 Jo-Philipp Wich <xm@leipzig.freifunk.net>
+(c) 2008 Steven Barth <steven@midlink.org>
+
+Licensed under the Apache License, Version 2.0 (the "License").
+You may obtain a copy of the License at
+
+	        http://www.apache.org/licenses/LICENSE-2.0
+]]--
+	local data = {}
+
+	local borderl = address:sub(1, 1) == ":" and 2 or 1
+	local borderh, zeroh, chunk, block
+
+	if #address > 45 then return nil end
+
+	repeat
+		borderh = address:find(":", borderl, true)
+		if not borderh then break end
+
+		block = tonumber(address:sub(borderl, borderh - 1), 16)
+		if block and block <= 0xFFFF then
+			data[#data+1] = block
+		else
+			if zeroh or borderh - borderl > 1 then return nil end
+			zeroh = #data + 1
+		end
+
+		borderl = borderh + 1
+	until #data == 7
+
+	chunk = address:sub(borderl)
+	if #chunk > 0 and #chunk <= 4 then
+		block = tonumber(chunk, 16)
+		if not block or block > 0xFFFF then return nil end
+
+		data[#data+1] = block
+	elseif #chunk > 4 then
+		if #data == 7 or #chunk > 15 then return nil end
+		borderl = 1
+		for i=1, 4 do
+			borderh = chunk:find(".", borderl, true)
+			if not borderh and i < 4 then return nil end
+			borderh = borderh and borderh - 1
+
+			block = tonumber(chunk:sub(borderl, borderh))
+			if not block or block > 255 then return nil end
+
+			if i == 1 or i == 3 then
+				data[#data+1] = block * 256
+			else
+				data[#data] = data[#data] + block
+			end
+
+			borderl = borderh and borderh + 2
+		end
+	end
+
+	if zeroh then
+		if #data == 8 then return nil end
+		while #data < 8 do
+			table.insert(data, zeroh, 0)
+		end
+	end
+
+	if #data == 8 then
+		return data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8]
+	end
+end
+
+function mac_to_ip(prefix, mac)
+  local m1, m2, m3, m6, m7, m8 = string.match(mac, '(%x%x):(%x%x):(%x%x):(%x%x):(%x%x):(%x%x)')
+  local m4 = 0xff
+  local m5 = 0xfe
+  m1 = nixio.bit.bxor(tonumber(m1, 16), 0x02)
+
+  local h1 = 0x100 * m1 + tonumber(m2, 16)
+  local h2 = 0x100 * tonumber(m3, 16) + m4
+  local h3 = 0x100 * m5 + tonumber(m6, 16)
+  local h4 = 0x100 * tonumber(m7, 16) + tonumber(m8, 16)
+
+  local prefix, plen = string.match(prefix, '(.*)/(%d+)')
+  plen = tonumber(plen, 10)
+
+  local p1, p2, p3, p4, p5, p6, p7, p8 = IPv6(prefix)
+
+  return string.format("%x:%x:%x:%x:%x:%x:%x:%x/%d", p1, p2, p3, p4, h1, h2, h3, h4, 128)
+end
+
+local ip = mac_to_ip(site.babel_mesh.prefix, sysconfig.primary_mac)
+
+uci:set('network', 'loopback', 'ip6addr', ip)
+uci:save('network')
+uci:commit('network')
+

+ 34 - 0
package/gluon-mesh-babel/files/lib/gluon/upgrade/300-gluon-mesh-babel-tables

@@ -0,0 +1,34 @@
+#!/usr/bin/lua
+
+local uci = require('luci.model.uci').cursor()
+local site = require 'gluon.site_config'
+
+uci:section('babeld', 'general', 'gluon',
+  {
+    export_table = 10,
+    import_table = {
+      255,
+      11,
+    },
+  }
+)
+
+uci:section('network', 'rule6', 'babel_import_lookup',
+  {
+    lookup = 11,
+    priority = 64000,
+  }
+)
+
+uci:section('network', 'rule6', 'babel_export_lookup',
+  {
+    lookup = 10,
+    priority = 64100,
+  }
+)
+
+uci:save('babeld')
+uci:save('network')
+uci:commit('babeld')
+uci:commit('network')
+

+ 52 - 0
package/gluon-mesh-babel/files/lib/gluon/upgrade/310-gluon-mesh-babel-filters

@@ -0,0 +1,52 @@
+#!/usr/bin/lua
+
+local uci = require('luci.model.uci').cursor()
+local site = require 'gluon.site_config'
+
+uci:section('babeld', 'filter', 'mesh_prefix',
+  {
+    type = 'redistribute',
+    ip = site.babel_mesh.prefix,
+    eq = 128,
+    action = 'allow',
+  }
+)
+
+uci:section('babeld', 'filter', 'client_prefix',
+  {
+    type = 'redistribute',
+    ip = site.prefix6,
+    eq = 128,
+    action = 'allow',
+  }
+)
+
+uci:section('babeld', 'filter', 'client_prefix',
+  {
+    type = 'redistribute',
+    ip = site.prefix6,
+    eq = 128,
+    action = 'allow',
+  }
+)
+
+uci:section('babeld', 'filter', 'local_deny',
+  {
+    type = 'redistribute',
+    ['local'] = 1, -- local is a keyword
+    action = 'deny',
+  }
+)
+
+uci:section('babeld', 'filter', 'defaultroute',
+  {
+    type = 'redistribute',
+    ip = '::/0',
+    eq = 0,
+    action = 'allow',
+  }
+)
+
+uci:save('babeld')
+uci:commit('babeld')
+

+ 79 - 0
package/gluon-mesh-babel/files/lib/gluon/upgrade/320-gluon-mesh-babel-wireless

@@ -0,0 +1,79 @@
+#!/usr/bin/lua
+
+local site = require 'gluon.site_config'
+local util = require 'gluon.util'
+
+local uci = require('luci.model.uci').cursor()
+
+
+local function is_disabled(config, name)
+  local disabled = config and config.disabled
+  if uci:get('wireless', name) then
+    disabled = uci:get_bool('wireless', name, 'disabled')
+  end
+
+  return disabled and 1 or 0
+end
+
+local function configure_mesh(config, radio, index, suffix)
+  local name = 'mesh_' .. radio
+  local disabled = is_disabled(config, name)
+
+  uci:delete('network', name)
+  uci:delete('wireless', name)
+  uci:delete('babeld', name)
+
+  if config then
+    uci:section('network', 'interface', name,
+      {
+        proto = 'none',
+      }
+    )
+
+    local ifname = 'mesh' .. suffix
+
+    uci:section('wireless', 'wifi-iface', name,
+      {
+        device = radio,
+        network = name,
+        mode = 'mesh',
+        mesh_id = config.id,
+        mesh_fwding = 0,
+        mcast_rate = config.mcast_rate,
+        ifname = ifname,
+        disabled = disabled,
+      }
+    )
+
+    uci:section('babeld', 'interface', name,
+      {
+        ifname = ifname,
+      }
+    )
+
+    local networks = uci:get_list('firewall', 'mesh_babel', 'network')
+    local set = {}
+    for _, l in ipairs(networks) do set[l] = true end
+    set[name] = true
+    networks = {}
+    for k, _ in pairs(set) do table.insert(networks, k) end
+    uci:set_list('firewall', 'mesh_babel', 'network', networks)
+  end
+end
+
+local function configure_radio(radio, index, config)
+  local suffix = radio:match('^radio(%d+)$')
+
+  configure_mesh(config.mesh, radio, index, suffix)
+end
+
+util.iterate_radios(configure_radio)
+
+uci:save('wireless')
+uci:save('network')
+uci:save('babeld')
+uci:save('firewall')
+uci:commit('wireless')
+uci:commit('network')
+uci:commit('babeld')
+uci:commit('firewall')

+ 23 - 0
package/gluon-mesh-babel/files/lib/gluon/upgrade/330-gluon-mesh-babel-interfaces

@@ -0,0 +1,23 @@
+#!/usr/bin/lua
+
+local uci = require('luci.model.uci').cursor()
+local site = require 'gluon.site_config'
+
+if site.mesh_on_wan then
+  uci:section('babeld', 'interface', 'mesh_wan',
+    {
+      ifname = 'br-wan',
+    }
+  )
+
+  uci:add_to_set('firewall', 'mesh_babel', 'network', 'wan')
+end
+
+uci:add_to_set('firewall', 'mesh_babel', 'network', 'client')
+uci:add_to_set('firewall', 'mesh_babel', 'network', 'local_node4')
+uci:add_to_set('firewall', 'mesh_babel', 'network', 'local_node6')
+
+uci:save('babeld')
+uci:save('firewall')
+uci:commit('babeld')
+uci:commit('firewall')