Merge b6616b681d
into 1f87d15912
This commit is contained in:
commit
29ccc83da8
@ -60,6 +60,7 @@ Several Freifunk communities in Germany use Gluon as the foundation of their Fre
|
||||
:caption: Packages
|
||||
:maxdepth: 1
|
||||
|
||||
package/gluon-464xlat-clat
|
||||
package/gluon-client-bridge
|
||||
package/gluon-config-mode-domain-select
|
||||
package/gluon-ebtables-filter-multicast
|
||||
|
32
docs/package/gluon-464xlat-clat.rst
Normal file
32
docs/package/gluon-464xlat-clat.rst
Normal file
@ -0,0 +1,32 @@
|
||||
gluon-464xlat-clat
|
||||
==================
|
||||
|
||||
This package provides the kernel module and functionality required to support
|
||||
IPv4 clients on an IPv6-only backbone.
|
||||
|
||||
Assumptions
|
||||
-----------
|
||||
|
||||
* Clients will be given IPv4 addresses by a DHCP daemon that runs on each node.
|
||||
gluon-ddhcpd is a great choice for this.
|
||||
* There is a component on the network that does PLAT on the default network
|
||||
64:ff9b::/96. https://github.com/FreifunkMD/jool-docker.git can do this.
|
||||
|
||||
Limitations
|
||||
-----------
|
||||
* When roaming, clients will experience temporary loss of IPv4 connectivity
|
||||
|
||||
site.conf
|
||||
---------
|
||||
|
||||
clat_range : mandatory
|
||||
- infrastructure net (ULA) from which a /96 CLAT prefix will be generated.
|
||||
- This must be a /48 prefix.
|
||||
- This can be the same for each site and is pre-registered at https://wiki.freifunk.net/IP-Netze#IPv6 as part of fdff:ffff:ff00::/40
|
||||
|
||||
Example::
|
||||
|
||||
{
|
||||
clat_range = 'fdff:ffff:ffff::/48',
|
||||
}
|
||||
|
13
package/gluon-464xlat-clat/Makefile
Normal file
13
package/gluon-464xlat-clat/Makefile
Normal file
@ -0,0 +1,13 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=gluon-464xlat-clat
|
||||
PKG_VERSION:=1
|
||||
|
||||
include ../gluon.mk
|
||||
|
||||
define Package/gluon-464xlat-clat
|
||||
TITLE:=Support translating IPv4 addresses to IPv6 using 464xlat
|
||||
DEPENDS:=+gluon-core +kmod-nat46
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackageGluon,gluon-464xlat-clat))
|
2
package/gluon-464xlat-clat/check_site.lua
Normal file
2
package/gluon-464xlat-clat/check_site.lua
Normal file
@ -0,0 +1,2 @@
|
||||
need_string(in_domain({'clat_range'}))
|
||||
need_string_match(in_domain({'next_node', 'ip4'}), '^%d+.%d+.%d+.%d+$', true)
|
2
package/gluon-464xlat-clat/files/50-clat-sysctl.conf
Normal file
2
package/gluon-464xlat-clat/files/50-clat-sysctl.conf
Normal file
@ -0,0 +1,2 @@
|
||||
net.ipv4.conf.clat.accept_local=1
|
||||
net.ipv6.conf.clat.use_oif_addrs_only=1
|
@ -0,0 +1,2 @@
|
||||
net.ipv4.conf.clat.accept_local=1
|
||||
net.ipv6.conf.clat.use_oif_addrs_only=1
|
171
package/gluon-464xlat-clat/files/lib/netifd/proto/xlat464clat.sh
Executable file
171
package/gluon-464xlat-clat/files/lib/netifd/proto/xlat464clat.sh
Executable file
@ -0,0 +1,171 @@
|
||||
#!/bin/sh
|
||||
# Copyright 2018 Vincent Wiemann <vincent.wiemann@ironai.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License version 2
|
||||
# as published by the Free Software Foundation
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
|
||||
CTR=/proc/net/nat46/control
|
||||
|
||||
[ -n "$INCLUDE_ONLY" ] || {
|
||||
. /lib/functions.sh
|
||||
. ../netifd-proto.sh
|
||||
init_proto "$@"
|
||||
}
|
||||
|
||||
proto_464xlatclat_init_config() {
|
||||
proto_config_add_string "zone"
|
||||
proto_config_add_string "zone4"
|
||||
proto_config_add_string "local_style"
|
||||
proto_config_add_string "local_v4"
|
||||
proto_config_add_string "local_v6"
|
||||
proto_config_add_string "local_ea_len"
|
||||
proto_config_add_string "local_psid"
|
||||
proto_config_add_boolean "local_fmr_flag"
|
||||
proto_config_add_string "remote_style"
|
||||
proto_config_add_string "remote_v4"
|
||||
proto_config_add_string "remote_v6"
|
||||
proto_config_add_string "remote_ea_len"
|
||||
proto_config_add_string "remote_psid"
|
||||
proto_config_add_string "ip4table"
|
||||
proto_config_add_boolean "debug"
|
||||
available=1
|
||||
no_device=1
|
||||
}
|
||||
|
||||
proto_464xlatclat_setup() {
|
||||
local config="$1"
|
||||
local clat_cfg="config ${config}"
|
||||
local local_style
|
||||
local local_v4
|
||||
local local_v6
|
||||
local local_ea_len
|
||||
local local_psid
|
||||
local local_fmr
|
||||
local remote_style
|
||||
local remote_v4
|
||||
local remote_v6
|
||||
local remote_ea_len
|
||||
local remote_psid
|
||||
local zone
|
||||
local zone4
|
||||
local ip4table
|
||||
|
||||
config_load network
|
||||
config_get ip4table "${config}" "ip4table"
|
||||
config_get zone "${config}" "zone"
|
||||
config_get zone4 "${config}" "zone4"
|
||||
config_get_bool debug "${config}" "debug" 0
|
||||
config_get local_style "${config}" "local_style"
|
||||
config_get local_v4 "${config}" "local_v4"
|
||||
config_get local_v6 "${config}" "local_v6"
|
||||
config_get local_ea_len "${config}" "local_ea_len"
|
||||
config_get local_psid "${config}" "local_psid_offset"
|
||||
config_get_bool local_fmr "${config}" "local_fmr_flag" 0
|
||||
config_get remote_style "${config}" "remote_style"
|
||||
config_get remote_v4 "${config}" "remote_v4"
|
||||
config_get remote_v6 "${config}" "remote_v6"
|
||||
config_get remote_ea_len "${config}" "remote_ea_len"
|
||||
config_get remote_psid "${config}" "remote_psid_offset"
|
||||
config_get local_ip "${config}" "local_ip"
|
||||
|
||||
zone="${zone:-wan}"
|
||||
zone4="${zone4:-lan}"
|
||||
local_v6="${local_v6:-fd00:13:37:13:37::/96}"
|
||||
remote_v4="${remote_v4:-0.0.0.0/0}"
|
||||
|
||||
[ "$debug" -ne 0 ] && clat_cfg="$clat_cfg debug 1"
|
||||
[ "${local_fmr}" -ne 0 ] && clat_cfg="$clat_cfg local.fmr-flag 1"
|
||||
|
||||
clat_cfg="${clat_cfg} local.style ${local_style:-RFC6052} local.v4 ${local_v4:-192.168.1.0/24} local.v6 ${local_v6}"
|
||||
clat_cfg="${clat_cfg} local.ea-len ${local_ea_len:-0} local.psid-offset ${local_psid:-0}"
|
||||
clat_cfg="${clat_cfg} remote.style ${remote_style:-RFC6052} remote.v4 ${remote_v4} remote.v6 ${remote_v6:-64:ff9b::/96}"
|
||||
clat_cfg="${clat_cfg} remote.ea-len ${remote_ea_len:-0} remote.psid-offset ${remote_psid:-0}"
|
||||
|
||||
echo "add ${config}" > ${CTR}
|
||||
echo "${clat_cfg}" > ${CTR}
|
||||
|
||||
[ "${ip4table}" ] && ip -4 rule add from "${local_v4}" lookup "${ip4table}"
|
||||
|
||||
proto_init_update "${config}" 1
|
||||
|
||||
# add routes
|
||||
case "${local_v6}" in
|
||||
*:*/*)
|
||||
proto_add_ipv6_route "${local_v6%%/*}" "${local_v6##*/}"
|
||||
;;
|
||||
*:*)
|
||||
proto_add_ipv6_route "${local_v6%%/*}" "128"
|
||||
;;
|
||||
esac
|
||||
|
||||
case "${remote_v4}" in
|
||||
*.*/*)
|
||||
proto_add_ipv4_route "${remote_v4%%/*}" "${remote_v4##*/}" "" "" 2048
|
||||
;;
|
||||
*.*)
|
||||
proto_add_ipv4_route "${remote_v4%%/*}" "32" "" "" 2048
|
||||
;;
|
||||
esac
|
||||
|
||||
proto_add_data
|
||||
[ "${zone}" != "-" ] && json_add_string zone "${zone}"
|
||||
|
||||
json_add_array firewall
|
||||
# if forwarding within "zone" and between zone<->zone4 is allowed you can set zone = "-"
|
||||
if [ "${zone}" != "-" ]; then
|
||||
json_add_object ""
|
||||
json_add_string type rule
|
||||
json_add_string family inet6
|
||||
json_add_string proto all
|
||||
json_add_string direction in
|
||||
json_add_string dest "${zone}"
|
||||
json_add_string src "${zone}"
|
||||
json_add_string src_ip "$local_v6"
|
||||
json_add_string target ACCEPT
|
||||
json_close_object
|
||||
# if a forwarding between zone and zone4 exists (e.g. lan<->wan) you can set zone4 = "-"
|
||||
if [ "${zone4}" != "-" ]; then
|
||||
json_add_object ""
|
||||
json_add_string type rule
|
||||
json_add_string family inet
|
||||
json_add_string proto all
|
||||
json_add_string direction out
|
||||
json_add_string dest "${zone}"
|
||||
[ "$remote_v4" != "0.0.0.0/0" ] && json_add_string dest_ip "$remote_v4"
|
||||
json_add_string src "${zone4}"
|
||||
json_add_string src_ip "$local_v4"
|
||||
json_add_string target ACCEPT
|
||||
json_close_object
|
||||
fi
|
||||
fi
|
||||
|
||||
json_close_array
|
||||
|
||||
proto_close_data
|
||||
|
||||
proto_send_update "$config"
|
||||
|
||||
# this rule relies on the ll-address being set. This rule will set the
|
||||
# src-address for icmp packets to the ipv4 next-node address
|
||||
clat_ll_ip="$(ip -o a s dev clat |cut -d" " -f7|cut -d"/" -f1)/128"
|
||||
clat_cfg="insert $config local.v4 ${local_ip} local.v6 :: local.style NONE"
|
||||
clat_cfg="${clat_cfg} local.ea-len 0 local.psid-offset 0"
|
||||
clat_cfg="${clat_cfg} remote.v4 ${local_ip} remote.v6 $clat_ll_ip"
|
||||
clat_cfg="${clat_cfg} remote.style NONE remote.ea-len 0 remote.psid-offset 0"
|
||||
echo "${clat_cfg}" > ${CTR}
|
||||
}
|
||||
|
||||
proto_464xlatclat_teardown() {
|
||||
local config="$1"
|
||||
echo "del ${config}" > ${CTR}
|
||||
}
|
||||
|
||||
[ -n "$INCLUDE_ONLY" ] || {
|
||||
add_protocol 464xlatclat
|
||||
}
|
39
package/gluon-464xlat-clat/luasrc/lib/gluon/upgrade/450-gluon-xlat464-clat
Executable file
39
package/gluon-464xlat-clat/luasrc/lib/gluon/upgrade/450-gluon-xlat464-clat
Executable file
@ -0,0 +1,39 @@
|
||||
#!/usr/bin/lua
|
||||
local site = require 'gluon.site'
|
||||
local sysconfig = require 'gluon.sysconfig'
|
||||
local uci = require('simple-uci').cursor()
|
||||
|
||||
local f = io.open("/etc/iproute2/rt_tables", "r")
|
||||
if f then
|
||||
if not f:read("*a"):find("10\tclat") then
|
||||
f:close()
|
||||
f = io.open("/etc/iproute2/rt_tables", "a")
|
||||
if f then
|
||||
f:write("\n10\tclat\n")
|
||||
end
|
||||
end
|
||||
f:close()
|
||||
end
|
||||
|
||||
local plat_prefix = uci:get('network', 'plat', 'local_v6') or "64:ff9b::/96"
|
||||
|
||||
uci:set('network', 'local_node', 'ip4table', 'clat')
|
||||
|
||||
local appendix = sysconfig.primary_mac:gsub('%:', '')
|
||||
appendix = string.format('%x:%x:%x', tonumber(appendix:sub(1, 4), 16),
|
||||
tonumber(appendix:sub(5, 8), 16),
|
||||
tonumber(appendix:sub(9, 12), 16))
|
||||
local clat_prefix = string.format('%s%s::/96', site.clat_range():gsub(':/.+', ''), appendix)
|
||||
|
||||
uci:delete('network', 'clat')
|
||||
uci:section('network', 'interface', 'clat', {
|
||||
proto = '464xlatclat',
|
||||
local_v4 = site.prefix4(),
|
||||
local_v6 = clat_prefix,
|
||||
remote_v6 = plat_prefix,
|
||||
zone = "local_client",
|
||||
zone4 = "local_client",
|
||||
ip4table = "clat",
|
||||
local_ip = site.next_node.ip4() .. '/32'
|
||||
})
|
||||
uci:save('network')
|
13
package/gluon-ddhcpd/Makefile
Normal file
13
package/gluon-ddhcpd/Makefile
Normal file
@ -0,0 +1,13 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=gluon-ddhcpd
|
||||
PKG_VERSION:=1
|
||||
|
||||
include ../gluon.mk
|
||||
|
||||
define Package/gluon-ddhcpd
|
||||
TITLE:=Distributed DHCP Daemon for Gluon
|
||||
DEPENDS:=+gluon-core +ddhcpd
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackageGluon,gluon-ddhcpd))
|
2
package/gluon-ddhcpd/check_site.lua
Normal file
2
package/gluon-ddhcpd/check_site.lua
Normal file
@ -0,0 +1,2 @@
|
||||
|
||||
need_string_match(in_domain({'next_node', 'ip4'}), '^%d+.%d+.%d+.%d+$', true)
|
6
package/gluon-ddhcpd/files/etc/ddhcp-hook.sh
Executable file
6
package/gluon-ddhcpd/files/etc/ddhcp-hook.sh
Executable file
@ -0,0 +1,6 @@
|
||||
#!/bin/sh
|
||||
|
||||
for i in /etc/ddhcpd.d/*
|
||||
do
|
||||
$i "$@"
|
||||
done
|
53
package/gluon-ddhcpd/files/etc/init.d/gluon-ddhcpd
Executable file
53
package/gluon-ddhcpd/files/etc/init.d/gluon-ddhcpd
Executable file
@ -0,0 +1,53 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
|
||||
START=90
|
||||
USE_PROCD=1
|
||||
NAME=ddhcpd
|
||||
DAEMON=/usr/sbin/ddhcpd
|
||||
MAXDELAY=10
|
||||
|
||||
validate_section_ddhcpd() {
|
||||
uci_validate_section "$NAME" ddhcpd settings \
|
||||
'dhcp_interface:string:br-client' \
|
||||
'server_interface:string:br-client' \
|
||||
'block_size_pow:uinteger:2' \
|
||||
'spare_blocks:uinteger:1' \
|
||||
'timeout:uinteger:30' \
|
||||
'block_network:cidr4' \
|
||||
'dhcp_lease_time:uinteger:300'
|
||||
server_interface=$(ubus call network.interface dump | jsonfilter -e "@.interface[@.interface='$(cat /lib/gluon/respondd/client.dev 2>/dev/null)' && @.up=true].device")
|
||||
}
|
||||
|
||||
start_service() {
|
||||
[ -x /lib/gluon/ddhcpd/arguments ] || exit 1
|
||||
|
||||
procd_open_instance
|
||||
procd_set_param command $DAEMON -D
|
||||
|
||||
config_load "${NAME}"
|
||||
|
||||
validate_section_ddhcpd || {
|
||||
echo "validation failed"
|
||||
return 1
|
||||
}
|
||||
|
||||
procd_append_param command -s "$spare_blocks"
|
||||
procd_append_param command -b "$block_size_pow"
|
||||
procd_append_param command -c "$dhcp_interface"
|
||||
procd_append_param command -i "$server_interface"
|
||||
procd_append_param command -N "$block_network"
|
||||
procd_append_param command -o "51:4:0.0.1.44"
|
||||
procd_append_param command -o "3:4:$(lua -e 'print(require("gluon.site").next_node.ip4())')"
|
||||
procd_append_param command -o "6:4:$(lua -e 'print(require("gluon.site").next_node.ip4())')"
|
||||
procd_append_param command $(/lib/gluon/ddhcpd/arguments)
|
||||
procd_set_param respawn
|
||||
procd_set_param netdev "$dhcp_interface"
|
||||
[ "$dhcp_interface" == "$server_interface" ] || procd_append_param netdev "$server_interface"
|
||||
procd_set_param stderr 1
|
||||
procd_close_instance
|
||||
}
|
||||
|
||||
service_triggers() {
|
||||
procd_add_config_trigger "config.change" "ddhcpd" /etc/init.d/ddhcpd restart
|
||||
procd_add_interface_trigger "interface.*" "$server_interface" /etc/init.d/ddhcpd restart
|
||||
}
|
0
package/gluon-ddhcpd/files/lib/gluon/ddhcpd/arguments
Executable file
0
package/gluon-ddhcpd/files/lib/gluon/ddhcpd/arguments
Executable file
22
package/gluon-ddhcpd/luasrc/lib/gluon/upgrade/315-dhcp-config-firewall
Executable file
22
package/gluon-ddhcpd/luasrc/lib/gluon/upgrade/315-dhcp-config-firewall
Executable file
@ -0,0 +1,22 @@
|
||||
#!/usr/bin/lua
|
||||
|
||||
local uci = require('simple-uci').cursor()
|
||||
|
||||
uci:section('firewall', 'rule', 'local_node_dhcp', {
|
||||
src = 'local_client',
|
||||
name = 'allow_dhcp_local_client',
|
||||
dest_port = '67',
|
||||
proto = 'udp',
|
||||
target = 'ACCEPT',
|
||||
})
|
||||
|
||||
uci:section('firewall', 'rule', 'ddhcpd_mmfd', {
|
||||
dest_port = '1234',
|
||||
src = 'mmfd',
|
||||
src_ip = 'fe80::/64',
|
||||
name = 'allow_ddhcp_to_reserve_blocks',
|
||||
proto = 'udp',
|
||||
target = 'ACCEPT',
|
||||
})
|
||||
|
||||
uci:save('firewall')
|
10
package/gluon-ddhcpd/luasrc/lib/gluon/upgrade/316-ddhcp
Executable file
10
package/gluon-ddhcpd/luasrc/lib/gluon/upgrade/316-ddhcp
Executable file
@ -0,0 +1,10 @@
|
||||
#!/usr/bin/lua
|
||||
|
||||
local site = require 'gluon.site'
|
||||
|
||||
local uci = require('simple-uci').cursor()
|
||||
|
||||
uci:set('ddhcpd', 'settings', 'enabled', false)
|
||||
uci:set('ddhcpd', 'settings', 'block_network', site.prefix4())
|
||||
|
||||
uci:save('ddhcpd')
|
5
package/gluon-l3roamd/files/etc/ddhcpd.d/l3roamd
Executable file
5
package/gluon-l3roamd/files/etc/ddhcpd.d/l3roamd
Executable file
@ -0,0 +1,5 @@
|
||||
#!/bin/sh
|
||||
if [ "$1" = "lease" ]
|
||||
then
|
||||
echo add_address "$2" "$3" | uc /var/run/l3roamd.sock
|
||||
fi
|
@ -1,6 +1,8 @@
|
||||
need_string_match(in_domain({'node_prefix6'}), '^[%x:]+/64$')
|
||||
need_string_match(in_domain({'node_client_prefix6'}), '^[%x:]+/64$')
|
||||
|
||||
need_string_match(in_domain({'clat_range'}), '^[%x:]+/48$', false)
|
||||
|
||||
need_string_match(in_domain({'next_node', 'ip6'}), '^[%x:]+$', false)
|
||||
need_string_match(in_domain({'next_node', 'ip4'}), '^%d+.%d+.%d+.%d+$', false)
|
||||
|
||||
|
@ -17,6 +17,10 @@ file:write("redistribute ip " .. site.prefix6() .. " eq 128 allow\n")
|
||||
file:write("redistribute ip " .. site.node_client_prefix6() .. " eq 128 allow\n")
|
||||
file:write("redistribute ip " .. site.node_prefix6() .. " eq 128 allow\n")
|
||||
file:write("redistribute ip 2000::/3 allow\n")
|
||||
|
||||
if site.clat_range() ~= nil and site.clat_range() ~= '' then
|
||||
file:write("redistribute ip " .. site.clat_range() .. " eq 96 allow\n")
|
||||
end
|
||||
file:write("redistribute local if br-wan deny\n")
|
||||
file:write("redistribute local ip 0.0.0.0/0 deny\n")
|
||||
file:write("install pref-src " .. nodeip .."\n")
|
||||
|
Loading…
Reference in New Issue
Block a user