-
Notifications
You must be signed in to change notification settings - Fork 324
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This provides native ipv4 to clients on a network having an ipv6-only backend, relying on external plat. This allows to use clients in ipv6-only networks that would otherwise refuse to connect without a valid ipv4 route. Limitations: * External plat must be provided, for example by jool - for example by https://github.com/FreifunkMD/jool-docker.git * This implementation will break ipv4 connections when clients roam.
- Loading branch information
Showing
8 changed files
with
264 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 community 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', | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
include $(TOPDIR)/rules.mk | ||
|
||
PKG_NAME:=gluon-464xlat-clat | ||
PKG_VERSION:=1 | ||
|
||
include ../gluon.mk | ||
|
||
PKG_CONFIG_DEPENDS += $(GLUON_I18N_CONFIG) | ||
|
||
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)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
need_string(in_domain({'clat_range'})) | ||
need_string_match(in_domain({'next_node', 'ip4'}), '^%d+.%d+.%d+.%d+$', true) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
net.ipv4.conf.clat.accept_local=1 | ||
net.ipv6.conf.clat.use_oif_addrs_only=1 |
2 changes: 2 additions & 0 deletions
2
package/gluon-464xlat-clat/files/etc/sysctl.d/50-clat-sysctl.conf
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
net.ipv4.conf.clat.accept_local=1 | ||
net.ipv6.conf.clat.use_oif_addrs_only=1 |
171 changes: 171 additions & 0 deletions
171
package/gluon-464xlat-clat/files/lib/netifd/proto/xlat464clat.sh
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 changes: 39 additions & 0 deletions
39
package/gluon-464xlat-clat/luasrc/lib/gluon/upgrade/450-gluon-xlat464-clat
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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') |