summaryrefslogtreecommitdiffstats
path: root/net/external-protocol/files/external.sh
blob: 532615950d2b1a13e9a2547e73adac5e1b6121f7 (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
#!/bin/sh

[ -n "$INCLUDE_ONLY" ] || {
	. /lib/functions.sh
	. ../netifd-proto.sh
	init_proto "$@"
}

proto_external_init_config() {
	no_device=0
	available=0

	proto_config_add_string "device:device"
	proto_config_add_string "searchdomain"
	proto_config_add_int "delay"
}

proto_external_setup() {
	local cfg="$1"
	local iface="$2"
	local device searchdomain delay

	json_get_vars device searchdomain delay

	[ -n "$device" ] || {
		echo "External protocol interface is not specified"
		proto_notify_error "$cfg" NO_DEVICE
		proto_set_available "$cfg" 0
		return 1
	}

	[ -n "$delay" ] && sleep "$delay"

	[ -L "/sys/class/net/${iface}" ] || {
		echo "External protocol interface $iface is not present"
		proto_notify_error "$cfg" NO_DEVICE
		proto_set_available "$cfg" 0
		return 1
	}

	IP4ADDRS=
	IP6ADDRS=

	local addresses="$(ip -json address list dev "$iface")"
	json_init
	json_load "{\"addresses\":${addresses}}"

	if json_is_a addresses array; then
		json_select addresses
		json_select 1

		if json_is_a addr_info array; then
			json_select addr_info

			local i=1
			while json_is_a ${i} object; do
				json_select ${i}
				json_get_vars scope family local prefixlen broadcast

				if [ "${scope}" == "global" ]; then
					case "${family}" in
						inet)
							append IP4ADDRS "$local/$prefixlen/$broadcast/"
							;;

						inet6)
							append IP6ADDRS "$local/$prefixlen/$broadcast///"
							;;
					esac
				fi

				json_select ..
				i=$(( i + 1 ))
			done
		fi
	fi

	IP4ROUTES=
	IP6ROUTES=

	local routes="$(ip -json route list dev "$iface")"
	json_init
	json_load "{\"routes\":${routes}}"

	if json_is_a routes array;then
		json_select routes

		local i=1
		while json_is_a ${i} object; do
			json_select ${i}
			json_get_vars dst gateway metric prefsrc

			case "${dst}" in
				*:*/*)
					append IP6ROUTES "$dst/$gateway/$metric///$prefsrc"
					;;
				*.*/*)
					append IP4ROUTES "$dst/$gateway/$metric///$prefsrc"
					;;
				*:*)
					append IP6ROUTES "$dst/128/$gateway/$metric///$prefsrc"
					;;
				*.*)
					append IP4ROUTES "$dst/32/$gateway/$metric///$prefsrc"
					;;
			esac

			json_select ..
			i=$(( i + 1 ))
		done
	fi

	[ -z "${IP4ADDRS}" -a -z "${IP6ADDRS}" ] && {
		echo "interface $iface does not have ip address"
		proto_notify_error "$cfg" NO_IPADDRESS
		return 1
	}

	proto_init_update "$iface" 1

	PROTO_IPADDR="${IP4ADDRS}"
	PROTO_IP6ADDR="${IP6ADDRS}"

	PROTO_ROUTE="${IP4ROUTES}"
	PROTO_ROUTE6="${IP6ROUTES}"

	[ -n "$searchdomain" ] && proto_add_dns_search "$searchdomain"

	echo "$iface is up"

	proto_send_update "$cfg"
}

proto_external_teardown() {
	local cfg="$1"
	return 0
}

[ -n "$INCLUDE_ONLY" ] || {
	add_protocol external
}