aboutsummaryrefslogtreecommitdiffstats
path: root/package/network/ipv6/map/files/map.sh
diff options
context:
space:
mode:
Diffstat (limited to 'package/network/ipv6/map/files/map.sh')
-rwxr-xr-xpackage/network/ipv6/map/files/map.sh221
1 files changed, 221 insertions, 0 deletions
diff --git a/package/network/ipv6/map/files/map.sh b/package/network/ipv6/map/files/map.sh
new file mode 100755
index 0000000..98a493d
--- /dev/null
+++ b/package/network/ipv6/map/files/map.sh
@@ -0,0 +1,221 @@
+#!/bin/sh
+# map.sh - IPv4-in-IPv6 tunnel backend
+#
+# Author: Steven Barth <cyrus@openwrt.org>
+# Copyright (c) 2014 cisco Systems, Inc.
+#
+# 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.
+
+[ -n "$INCLUDE_ONLY" ] || {
+ . /lib/functions.sh
+ . /lib/functions/network.sh
+ . ../netifd-proto.sh
+ init_proto "$@"
+}
+
+proto_map_setup() {
+ local cfg="$1"
+ local iface="$2"
+ local link="map-$cfg"
+
+ # uncomment for legacy MAP0 mode
+ #export LEGACY=1
+
+ local type mtu ttl tunlink zone
+ local rule ipaddr ip4prefixlen ip6prefix ip6prefixlen peeraddr ealen psidlen psid offset
+ json_get_vars type mtu ttl tunlink zone
+ json_get_vars rule ipaddr ip4prefixlen ip6prefix ip6prefixlen peeraddr ealen psidlen psid offset
+
+ [ -z "$zone" ] && zone="wan"
+ [ -z "$type" ] && type="map-e"
+ [ -z "$ip4prefixlen" ] && ip4prefixlen=32
+
+ ( proto_add_host_dependency "$cfg" "::" "$tunlink" )
+
+ # fixme: handle RA/DHCPv6 address race for LW
+ [ "$type" = lw4o6 ] && sleep 5
+
+ if [ -z "$rule" ]; then
+ rule="type=$type,ipv6prefix=$ip6prefix,prefix6len=$ip6prefixlen,ipv4prefix=$ipaddr,prefix4len=$ip4prefixlen"
+ [ -n "$psid" ] && rule="$rule,psid=$psid"
+ [ -n "$psidlen" ] && rule="$rule,psidlen=$psidlen"
+ [ -n "$offset" ] && rule="$rule,offset=$offset"
+ [ -n "$ealen" ] && rule="$rule,ealen=$ealen"
+ if [ "$type" = "map-t" ]; then
+ rule="$rule,dmr=$peeraddr"
+ else
+ rule="$rule,br=$peeraddr"
+ fi
+ fi
+
+ echo "rule=$rule" > /tmp/map-$cfg.rules
+ RULE_DATA=$(mapcalc ${tunlink:-\*} $rule)
+ if [ "$?" != 0 ]; then
+ proto_notify_error "$cfg" "INVALID_MAP_RULE"
+ proto_block_restart "$cfg"
+ return
+ fi
+
+ echo "$RULE_DATA" >> /tmp/map-$cfg.rules
+ eval $RULE_DATA
+
+ if [ -z "$RULE_BMR" ]; then
+ proto_notify_error "$cfg" "NO_MATCHING_PD"
+ proto_block_restart "$cfg"
+ return
+ fi
+
+ k=$RULE_BMR
+ if [ "$type" = "lw4o6" -o "$type" = "map-e" ]; then
+ proto_init_update "$link" 1
+ proto_add_ipv4_address $(eval "echo \$RULE_${k}_IPV4ADDR") "" "" ""
+
+ proto_add_tunnel
+ json_add_string mode ipip6
+ json_add_int mtu "${mtu:-1280}"
+ json_add_int ttl "${ttl:-64}"
+ json_add_string local $(eval "echo \$RULE_${k}_IPV6ADDR")
+ json_add_string remote $(eval "echo \$RULE_${k}_BR")
+ json_add_string link $(eval "echo \$RULE_${k}_PD6IFACE")
+
+ if [ "$type" = "map-e" ]; then
+ json_add_array "fmrs"
+ for i in $(seq $RULE_COUNT); do
+ [ "$(eval "echo \$RULE_${i}_FMR")" != 1 ] && continue
+ fmr="$(eval "echo \$RULE_${i}_IPV6PREFIX")/$(eval "echo \$RULE_${i}_PREFIX6LEN")"
+ fmr="$fmr,$(eval "echo \$RULE_${i}_IPV4PREFIX")/$(eval "echo \$RULE_${i}_PREFIX4LEN")"
+ fmr="$fmr,$(eval "echo \$RULE_${i}_EALEN"),$(eval "echo \$RULE_${i}_OFFSET")"
+ json_add_string "" "$fmr"
+ done
+ json_close_array
+ fi
+
+ proto_close_tunnel
+ elif [ "$type" = "map-t" -a -f "/proc/net/nat46/control" ]; then
+ proto_init_update "$link" 1
+ local style="MAP"
+ [ "$LEGACY" = 1 ] && style="MAP0"
+
+ echo add $link > /proc/net/nat46/control
+ local cfgstr="local.style $style local.v4 $(eval "echo \$RULE_${k}_IPV4PREFIX")/$(eval "echo \$RULE_${k}_PREFIX4LEN")"
+ cfgstr="$cfgstr local.v6 $(eval "echo \$RULE_${k}_IPV6PREFIX")/$(eval "echo \$RULE_${k}_PREFIX6LEN")"
+ cfgstr="$cfgstr local.ea-len $(eval "echo \$RULE_${k}_EALEN") local.psid-offset $(eval "echo \$RULE_${k}_OFFSET")"
+ cfgstr="$cfgstr remote.v4 0.0.0.0/0 remote.v6 $(eval "echo \$RULE_${k}_DMR") remote.style RFC6052 remote.ea-len 0 remote.psid-offset 0"
+ echo config $link $cfgstr > /proc/net/nat46/control
+
+ for i in $(seq $RULE_COUNT); do
+ [ "$(eval "echo \$RULE_${i}_FMR")" != 1 ] && continue
+ local cfgstr="remote.style $style remote.v4 $(eval "echo \$RULE_${i}_IPV4PREFIX")/$(eval "echo \$RULE_${i}_PREFIX4LEN")"
+ cfgstr="$cfgstr remote.v6 $(eval "echo \$RULE_${i}_IPV6PREFIX")/$(eval "echo \$RULE_${i}_PREFIX6LEN")"
+ cfgstr="$cfgstr remote.ea-len $(eval "echo \$RULE_${i}_EALEN") remote.psid-offset $(eval "echo \$RULE_${i}_OFFSET")"
+ echo insert $link $cfgstr > /proc/net/nat46/control
+ done
+ else
+ proto_notify_error "$cfg" "UNSUPPORTED_TYPE"
+ proto_block_restart "$cfg"
+ fi
+
+ proto_add_ipv4_route "0.0.0.0" 0
+ proto_add_data
+ [ "$zone" != "-" ] && json_add_string zone "$zone"
+
+ json_add_array firewall
+ if [ -z "$(eval "echo \$RULE_${k}_PORTSETS")" ]; then
+ json_add_object ""
+ json_add_string type nat
+ json_add_string target SNAT
+ json_add_string family inet
+ json_add_string snat_ip $(eval "echo \$RULE_${k}_IPV4ADDR")
+ json_close_object
+ else
+ for portset in $(eval "echo \$RULE_${k}_PORTSETS"); do
+ for proto in icmp tcp udp; do
+ json_add_object ""
+ json_add_string type nat
+ json_add_string target SNAT
+ json_add_string family inet
+ json_add_string proto "$proto"
+ json_add_boolean connlimit_ports 1
+ json_add_string snat_ip $(eval "echo \$RULE_${k}_IPV4ADDR")
+ json_add_string snat_port "$portset"
+ json_close_object
+ done
+ done
+ fi
+ if [ "$type" = "map-t" ]; 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 $(eval "echo \$RULE_${k}_IPV6ADDR")
+ json_add_string target ACCEPT
+ json_close_object
+ json_add_object ""
+ json_add_string type rule
+ json_add_string family inet6
+ json_add_string proto all
+ json_add_string direction out
+ json_add_string dest "$zone"
+ json_add_string src "$zone"
+ json_add_string dest_ip $(eval "echo \$RULE_${k}_IPV6ADDR")
+ json_add_string target ACCEPT
+ json_close_object
+ proto_add_ipv6_route $(eval "echo \$RULE_${k}_IPV6ADDR") 128
+ fi
+ json_close_array
+ proto_close_data
+
+ proto_send_update "$cfg"
+
+ if [ "$type" = "lw4o6" -o "$type" = "map-e" ]; then
+ json_init
+ json_add_string name "${cfg}_"
+ json_add_string ifname "@$(eval "echo \$RULE_${k}_PD6IFACE")"
+ json_add_string proto "static"
+ json_add_array ip6addr
+ json_add_string "" "$(eval "echo \$RULE_${k}_IPV6ADDR")"
+ json_close_array
+ json_close_object
+ ubus call network add_dynamic "$(json_dump)"
+ fi
+}
+
+proto_map_teardown() {
+ local cfg="$1"
+ ifdown "${cfg}_"
+ rm -f /tmp/map-$cfg.rules
+}
+
+proto_map_init_config() {
+ no_device=1
+ available=1
+
+ proto_config_add_string "rule"
+ proto_config_add_string "ipaddr"
+ proto_config_add_int "ip4prefixlen"
+ proto_config_add_string "ip6prefix"
+ proto_config_add_int "ip6prefixlen"
+ proto_config_add_string "peeraddr"
+ proto_config_add_int "psidlen"
+ proto_config_add_int "psid"
+ proto_config_add_int "offset"
+
+ proto_config_add_string "tunlink"
+ proto_config_add_int "mtu"
+ proto_config_add_int "ttl"
+ proto_config_add_string "zone"
+}
+
+[ -n "$INCLUDE_ONLY" ] || {
+ add_protocol map
+}