[package] ipv6: add tayga
authorFlorian Fainelli <florian@openwrt.org>
Tue, 16 Aug 2011 20:34:12 +0000 (20:34 +0000)
committerFlorian Fainelli <florian@openwrt.org>
Tue, 16 Aug 2011 20:34:12 +0000 (20:34 +0000)
TAYGA is an out-of-kernel stateless NAT64 implementation for
Linux.  It uses the TUN driver to exchange packets with the
kernel, which is the same driver used by OpenVPN and QEMU/KVM.

Signed-off-by: Alexey I. Froloff <raorn@altlinux.org>
SVN-Revision: 28013

ipv6/tayga/Makefile [new file with mode: 0644]
ipv6/tayga/files/tayga.hotplug [new file with mode: 0644]
ipv6/tayga/files/tayga.sh [new file with mode: 0644]

diff --git a/ipv6/tayga/Makefile b/ipv6/tayga/Makefile
new file mode 100644 (file)
index 0000000..c109a92
--- /dev/null
@@ -0,0 +1,39 @@
+# $Id: Makefile 5624 2006-11-23 00:29:07Z nbd $
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=tayga
+PKG_VERSION:=0.9.2
+PKG_RELEASE:=1
+
+PKG_SOURCE:=tayga-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:=http://www.litech.org/tayga/
+PKG_MD5SUM:=7a7b24165ce008df772f398d86fa280e
+PKG_CAT:=bzcat
+
+PKG_BUILD_DIR:=$(BUILD_DIR)/tayga-$(PKG_VERSION)
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/tayga
+  SECTION:=ipv6
+  CATEGORY:=IPv6
+  DEPENDS:=+ip +kmod-ipv6 +kmod-tun
+  TITLE:=Out-of-kernel stateless NAT64 implementation for Linux
+  URL:=http://www.litech.org/tayga/
+endef
+
+define Package/tayga/description
+  TAYGA is an out-of-kernel stateless NAT64 implementation for
+  Linux.  It uses the TUN driver to exchange packets with the
+  kernel, which is the same driver used by OpenVPN and QEMU/KVM.
+endef
+
+define Package/tayga/install
+       $(INSTALL_DIR) $(1)/usr/sbin $(1)/lib/network $(1)/etc/hotplug.d/iface
+       $(INSTALL_BIN) $(PKG_BUILD_DIR)/tayga $(1)/usr/sbin/
+       $(INSTALL_DATA) ./files/tayga.sh $(1)/lib/network/tayga.sh
+       $(INSTALL_DATA) ./files/tayga.hotplug $(1)/etc/hotplug.d/iface/95-tayga
+endef
+
+$(eval $(call BuildPackage,tayga))
diff --git a/ipv6/tayga/files/tayga.hotplug b/ipv6/tayga/files/tayga.hotplug
new file mode 100644 (file)
index 0000000..2539f09
--- /dev/null
@@ -0,0 +1,37 @@
+#!/bin/sh
+
+if [ "$ACTION" = ifup ]; then
+       . /etc/functions.sh
+
+       include /lib/network
+       scan_interfaces
+
+       update_tunnel() {
+               local cfg="$1"
+
+               local proto
+               config_get proto "$cfg" proto
+               [ "$proto" = tayga ] || return 0
+
+               local wandev4
+               config_get wandev4 "$cfg" wan4_device "$(find_tayga_wanif4)"
+
+               local wandev6
+               config_get wandev6 "$cfg" wan6_device "$(find_tayga_wanif6)"
+
+               [ "$wandev4" = "$DEVICE" ] || [ "$wandev6" = "$DEVICE" ] || return 0
+
+               local wanip4=$(find_tayga_wanip4 "$wandev4")
+               local wanip6=$(find_tayga_wanip6 "$wandev6")
+
+               [ -n "$wanip4" ] && [ -n "$wanip6" ] && {
+                       uci_set_state network "$cfg" ipv4addr "$wanip4"
+                       uci_set_state network "$cfg" ipv6addr "$wanip6"
+
+                       logger -t tayga-update "Re-establishing tayga NAT64 due to change on $INTERFACE ($DEVICE)"
+                       ifup "$cfg" &
+               }
+       }
+
+       config_foreach update_tunnel interface
+fi
diff --git a/ipv6/tayga/files/tayga.sh b/ipv6/tayga/files/tayga.sh
new file mode 100644 (file)
index 0000000..9f515c6
--- /dev/null
@@ -0,0 +1,139 @@
+# tayga.sh - NAT64 backend
+
+find_tayga_wanif4() {
+       local if=$(ip -4 r l e 0.0.0.0/0); if="${if#default* dev }"; if="${if%% *}"
+       [ -n "$if" ] && grep -qs "^ *$if:" /proc/net/dev && echo "$if"
+}
+
+find_tayga_wanip4() {
+       local ip=$(ip -4 a s dev "$1"); ip="${ip#*inet }"
+       echo "${ip%%[^0-9.]*}"
+}
+
+find_tayga_wanif6() {
+       local if=$(ip -6 r l e ::/0); if="${if#default* dev }"; if="${if%% *}"
+       [ -n "$if" ] && grep -qs "^ *$if:" /proc/net/dev && echo "$if"
+}
+
+find_tayga_wanip6() {
+       local ip=$(ip -6 a s dev "$1"); ip="${ip#*inet6 }"
+       echo "${ip%%[^0-9A-Fa-f:]*}"
+}
+
+# Hook into scan_interfaces() to synthesize a .device option
+# This is needed for /sbin/ifup to properly dispatch control
+# to setup_interface_tayga() even if no .ifname is set in
+# the configuration.
+scan_tayga() {
+       config_set "$1" device "tayga-$1"
+}
+
+coldplug_interface_tayga() {
+       setup_interface_tayga "tayga-$1" "$1"
+}
+
+conf_rule_add() {
+       local cfg="$1"
+       local tmpconf="$2"
+       local ipv4_addr ipv6_addr
+       config_get ipv4_addr "$cfg" ipv4_addr ""
+       config_get ipv6_addr "$cfg" ipv6_addr ""
+       [ -n "$ipv4_addr" ] && [ -n "$ipv6_addr" ] &&
+               echo "map $ipv4_addr $ipv6_addr" >>$tmpconf
+}
+
+setup_interface_tayga() {
+       local iface="$1"
+       local cfg="$2"
+       local link="tayga-$cfg"
+
+       local ipv4_addr ipv6_addr prefix dynamic_pool
+
+       config_get ipv4_addr "$cfg" ipv4_addr
+       config_get ipv6_addr "$cfg" ipv6_addr
+       config_get prefix "$cfg" prefix
+       config_get dynamic_pool "$cfg" dynamic_pool
+
+       local args
+
+       include /lib/network
+       scan_interfaces
+
+       local wanip4=$(uci_get network "$cfg" ipv4addr)
+       local wanip6=$(uci_get network "$cfg" ipv6addr)
+
+       local wanif4=$(find_tayga_wanif4)
+       local wanif6=$(find_tayga_wanif6)
+
+       [ -z "$wanip4" ] && {
+               [ -n "$wanif4" ] && {
+                       wanip4=$(find_tayga_wanip4 "$wanif4")
+                       uci_set_state network "$cfg" wan4_device "$wanif4"
+               }
+       }
+
+       [ -z "$wanip6" ] && {
+               [ -n "$wanif6" ] && {
+                       wanip6=$(find_tayga_wanip6 "$wanif6")
+                       uci_set_state network "$cfg" wan6_device "$wanif6"
+               }
+       }
+
+       [ -n "$wanip4" ] && [ -n "$wanip6" ] || {
+               echo "Cannot determine local IPv4 and IPv6 addressed for tayga NAT64 $cfg - skipping"
+               return
+       }
+
+       local tmpconf="/var/etc/tayga-$cfg.conf"
+       args="-c $tmpconf"
+       mkdir -p /var/etc
+       mkdir -p /var/run/tayga/$cfg
+
+       echo "tun-device $link" >$tmpconf
+       echo "ipv4-addr $ipv4_addr" >>$tmpconf
+       [ -n "$ipv6_addr" ] &&
+               echo "ipv6-addr $ipv6_addr" >>$tmpconf
+       [ -n "$prefix" ] &&
+               echo "prefix $prefix" >>$tmpconf
+
+       config_foreach conf_rule_add map_rule "$tmpconf"
+
+       [ -n "$dynamic_pool" ] &&
+               echo "dynamic-pool $dynamic_pool" >>$tmpconf
+       echo "data-dir /var/run/tayga/$cfg" >>$tmpconf
+
+       # creating the tunnel below will trigger a net subsystem event
+       # prevent it from touching or iface by disabling .auto here
+       uci_set_state network "$cfg" ifname $link
+       uci_set_state network "$cfg" auto 0
+
+       tayga $args --mktun
+       ip link set "$link" up
+
+       ip addr add "$wanip4" dev "$link"
+       ip addr add "$wanip6" dev "$link"
+
+       [ -n "$dynamic_pool" ] &&
+               ip -4 route add "$dynamic_pool" dev "$link"
+       [ -n "$prefix" ] &&
+               ip -6 route add "$prefix" dev "$link"
+
+       start-stop-daemon -S -x tayga -- $args -p /var/run/$link.pid
+
+       env -i ACTION="ifup" DEVICE="$link" INTERFACE="$cfg" PROTO="tayga" \
+               /sbin/hotplug-call iface
+}
+
+stop_interface_tayga() {
+       local cfg="$1"
+       local link="tayga-$cfg"
+
+       env -i ACTION="ifdown" DEVICE="$link" INTERFACE="$cfg" PROTO="tayga" \
+               /sbin/hotplug-call iface
+
+       service_kill tayga "/var/run/$link.pid"
+
+       ip link set "$link" down
+       ip addr flush dev "$link"
+       ip route flush dev "$link"
+}