add chaos_calmer branch
[15.05/openwrt.git] / package / network / ipv6 / map / files / map.sh
1 #!/bin/sh
2 # map.sh - IPv4-in-IPv6 tunnel backend
3 #
4 # Author: Steven Barth <cyrus@openwrt.org>
5 # Copyright (c) 2014 cisco Systems, Inc.
6 #
7 # This program is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License version 2
9 # as published by the Free Software Foundation
10 #
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 # GNU General Public License for more details.
15
16 [ -n "$INCLUDE_ONLY" ] || {
17         . /lib/functions.sh
18         . /lib/functions/network.sh
19         . ../netifd-proto.sh
20         init_proto "$@"
21 }
22
23 proto_map_setup() {
24         local cfg="$1"
25         local iface="$2"
26         local link="map-$cfg"
27
28         # uncomment for legacy MAP0 mode
29         #export LEGACY=1
30
31         local type mtu ttl tunlink zone
32         local rule ipaddr ip4prefixlen ip6prefix ip6prefixlen peeraddr ealen psidlen psid offset
33         json_get_vars type mtu ttl tunlink zone
34         json_get_vars rule ipaddr ip4prefixlen ip6prefix ip6prefixlen peeraddr ealen psidlen psid offset
35
36         [ -z "$zone" ] && zone="wan"
37         [ -z "$type" ] && type="map-e"
38         [ -z "$ip4prefixlen" ] && ip4prefixlen=32
39
40         ( proto_add_host_dependency "$cfg" "::" "$tunlink" )
41
42         # fixme: handle RA/DHCPv6 address race for LW
43         [ "$type" = lw4o6 ] && sleep 5
44
45         if [ -z "$rule" ]; then
46                 rule="type=$type,ipv6prefix=$ip6prefix,prefix6len=$ip6prefixlen,ipv4prefix=$ipaddr,prefix4len=$ip4prefixlen"
47                 [ -n "$psid" ] && rule="$rule,psid=$psid"
48                 [ -n "$psidlen" ] && rule="$rule,psidlen=$psidlen"
49                 [ -n "$offset" ] && rule="$rule,offset=$offset"
50                 [ -n "$ealen" ] && rule="$rule,ealen=$ealen"
51                 if [ "$type" = "map-t" ]; then
52                         rule="$rule,dmr=$peeraddr"
53                 else
54                         rule="$rule,br=$peeraddr"
55                 fi
56         fi
57
58         echo "rule=$rule" > /tmp/map-$cfg.rules
59         RULE_DATA=$(mapcalc ${tunlink:-\*} $rule)
60         if [ "$?" != 0 ]; then
61                 proto_notify_error "$cfg" "INVALID_MAP_RULE"
62                 proto_block_restart "$cfg"
63                 return
64         fi
65
66         echo "$RULE_DATA" >> /tmp/map-$cfg.rules
67         eval $RULE_DATA
68
69         if [ -z "$RULE_BMR" ]; then
70                 proto_notify_error "$cfg" "NO_MATCHING_PD"
71                 proto_block_restart "$cfg"
72                 return
73         fi
74
75         k=$RULE_BMR
76         if [ "$type" = "lw4o6" -o "$type" = "map-e" ]; then
77                 proto_init_update "$link" 1
78                 proto_add_ipv4_address $(eval "echo \$RULE_${k}_IPV4ADDR") "" "" ""
79
80                 proto_add_tunnel
81                 json_add_string mode ipip6
82                 json_add_int mtu "${mtu:-1280}"
83                 json_add_int ttl "${ttl:-64}"
84                 json_add_string local $(eval "echo \$RULE_${k}_IPV6ADDR")
85                 json_add_string remote $(eval "echo \$RULE_${k}_BR")
86                 json_add_string link $(eval "echo \$RULE_${k}_PD6IFACE")
87
88                 if [ "$type" = "map-e" ]; then
89                         json_add_array "fmrs"
90                                 for i in $(seq $RULE_COUNT); do
91                                         [ "$(eval "echo \$RULE_${i}_FMR")" != 1 ] && continue
92                                         fmr="$(eval "echo \$RULE_${i}_IPV6PREFIX")/$(eval "echo \$RULE_${i}_PREFIX6LEN")"
93                                         fmr="$fmr,$(eval "echo \$RULE_${i}_IPV4PREFIX")/$(eval "echo \$RULE_${i}_PREFIX4LEN")"
94                                         fmr="$fmr,$(eval "echo \$RULE_${i}_EALEN"),$(eval "echo \$RULE_${i}_OFFSET")"
95                                         json_add_string "" "$fmr"
96                                 done
97                         json_close_array
98                 fi
99
100                 proto_close_tunnel
101         elif [ "$type" = "map-t" -a -f "/proc/net/nat46/control" ]; then
102                 proto_init_update "$link" 1
103                 local style="MAP"
104                 [ "$LEGACY" = 1 ] && style="MAP0"
105
106                 echo add $link > /proc/net/nat46/control
107                 local cfgstr="local.style $style local.v4 $(eval "echo \$RULE_${k}_IPV4PREFIX")/$(eval "echo \$RULE_${k}_PREFIX4LEN")"
108                 cfgstr="$cfgstr local.v6 $(eval "echo \$RULE_${k}_IPV6PREFIX")/$(eval "echo \$RULE_${k}_PREFIX6LEN")"
109                 cfgstr="$cfgstr local.ea-len $(eval "echo \$RULE_${k}_EALEN") local.psid-offset $(eval "echo \$RULE_${k}_OFFSET")"
110                 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"
111                 echo config $link $cfgstr > /proc/net/nat46/control
112
113                 for i in $(seq $RULE_COUNT); do
114                         [ "$(eval "echo \$RULE_${i}_FMR")" != 1 ] && continue
115                         local cfgstr="remote.style $style remote.v4 $(eval "echo \$RULE_${i}_IPV4PREFIX")/$(eval "echo \$RULE_${i}_PREFIX4LEN")"
116                         cfgstr="$cfgstr remote.v6 $(eval "echo \$RULE_${i}_IPV6PREFIX")/$(eval "echo \$RULE_${i}_PREFIX6LEN")"
117                         cfgstr="$cfgstr remote.ea-len $(eval "echo \$RULE_${i}_EALEN") remote.psid-offset $(eval "echo \$RULE_${i}_OFFSET")"
118                         echo insert $link $cfgstr > /proc/net/nat46/control
119                 done
120         else
121                 proto_notify_error "$cfg" "UNSUPPORTED_TYPE"
122                 proto_block_restart "$cfg"
123         fi
124
125         proto_add_ipv4_route "0.0.0.0" 0
126         proto_add_data
127         [ "$zone" != "-" ] && json_add_string zone "$zone"
128
129         json_add_array firewall
130           if [ -z "$(eval "echo \$RULE_${k}_PORTSETS")" ]; then
131             json_add_object ""
132               json_add_string type nat
133               json_add_string target SNAT
134               json_add_string family inet
135               json_add_string snat_ip $(eval "echo \$RULE_${k}_IPV4ADDR")
136             json_close_object
137           else
138             for portset in $(eval "echo \$RULE_${k}_PORTSETS"); do
139               for proto in icmp tcp udp; do
140                 json_add_object ""
141                   json_add_string type nat
142                   json_add_string target SNAT
143                   json_add_string family inet
144                   json_add_string proto "$proto"
145                   json_add_boolean connlimit_ports 1
146                   json_add_string snat_ip $(eval "echo \$RULE_${k}_IPV4ADDR")
147                   json_add_string snat_port "$portset"
148                 json_close_object
149               done
150             done
151           fi
152           if [ "$type" = "map-t" ]; then
153                 json_add_object ""
154                         json_add_string type rule
155                         json_add_string family inet6
156                         json_add_string proto all
157                         json_add_string direction in
158                         json_add_string dest "$zone"
159                         json_add_string src "$zone"
160                         json_add_string src_ip $(eval "echo \$RULE_${k}_IPV6ADDR")
161                         json_add_string target ACCEPT
162                 json_close_object
163                 json_add_object ""
164                         json_add_string type rule
165                         json_add_string family inet6
166                         json_add_string proto all
167                         json_add_string direction out
168                         json_add_string dest "$zone"
169                         json_add_string src "$zone"
170                         json_add_string dest_ip $(eval "echo \$RULE_${k}_IPV6ADDR")
171                         json_add_string target ACCEPT
172                 json_close_object
173                 proto_add_ipv6_route $(eval "echo \$RULE_${k}_IPV6ADDR") 128
174           fi
175         json_close_array
176         proto_close_data
177
178         proto_send_update "$cfg"
179
180         if [ "$type" = "lw4o6" -o "$type" = "map-e" ]; then
181                 json_init
182                 json_add_string name "${cfg}_"
183                 json_add_string ifname "@$(eval "echo \$RULE_${k}_PD6IFACE")"
184                 json_add_string proto "static"
185                 json_add_array ip6addr
186                 json_add_string "" "$(eval "echo \$RULE_${k}_IPV6ADDR")"
187                 json_close_array
188                 json_close_object
189                 ubus call network add_dynamic "$(json_dump)"
190         fi
191 }
192
193 proto_map_teardown() {
194         local cfg="$1"
195         ifdown "${cfg}_"
196         rm -f /tmp/map-$cfg.rules
197 }
198
199 proto_map_init_config() {
200         no_device=1
201         available=1
202
203         proto_config_add_string "rule"
204         proto_config_add_string "ipaddr"
205         proto_config_add_int "ip4prefixlen"
206         proto_config_add_string "ip6prefix"
207         proto_config_add_int "ip6prefixlen"
208         proto_config_add_string "peeraddr"
209         proto_config_add_int "psidlen"
210         proto_config_add_int "psid"
211         proto_config_add_int "offset"
212
213         proto_config_add_string "tunlink"
214         proto_config_add_int "mtu"
215         proto_config_add_int "ttl"
216         proto_config_add_string "zone"
217 }
218
219 [ -n "$INCLUDE_ONLY" ] || {
220         add_protocol map
221 }