aboutsummaryrefslogtreecommitdiff
path: root/ipv6/tayga/files/tayga.sh
blob: a9edb6d0b10335e9af04a12e283e64236fa968db (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# 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"
}

tayga_add_static_mappings() {
	local tmpconf="$1"

	(
		. /lib/functions.sh
		config_load firewall

		tayga_map_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
		}

		config_foreach tayga_map_rule_add nat64 "$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 1
	}

	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

	tayga_add_static_mappings "$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

	# here we create TUN device and check configuration
	tayga $args --mktun || return 1

	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"
}