netifd-proto.sh 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392
  1. NETIFD_MAIN_DIR="${NETIFD_MAIN_DIR:-/lib/netifd}"
  2. . /usr/share/libubox/jshn.sh
  3. . $NETIFD_MAIN_DIR/utils.sh
  4. proto_config_add_int() {
  5. config_add_int "$@"
  6. }
  7. proto_config_add_string() {
  8. config_add_string "$@"
  9. }
  10. proto_config_add_boolean() {
  11. config_add_boolean "$@"
  12. }
  13. _proto_do_teardown() {
  14. json_load "$data"
  15. eval "proto_$1_teardown \"$interface\" \"$ifname\""
  16. }
  17. _proto_do_renew() {
  18. json_load "$data"
  19. eval "proto_$1_renew \"$interface\" \"$ifname\""
  20. }
  21. _proto_do_setup() {
  22. json_load "$data"
  23. _EXPORT_VAR=0
  24. _EXPORT_VARS=
  25. eval "proto_$1_setup \"$interface\" \"$ifname\""
  26. }
  27. proto_init_update() {
  28. local ifname="$1"
  29. local up="$2"
  30. local external="$3"
  31. PROTO_KEEP=0
  32. PROTO_INIT=1
  33. PROTO_TUNNEL_OPEN=
  34. PROTO_IPADDR=
  35. PROTO_IP6ADDR=
  36. PROTO_ROUTE=
  37. PROTO_ROUTE6=
  38. PROTO_PREFIX6=
  39. PROTO_DNS=
  40. PROTO_DNS_SEARCH=
  41. json_init
  42. json_add_int action 0
  43. [ -n "$ifname" -a "*" != "$ifname" ] && json_add_string "ifname" "$ifname"
  44. json_add_boolean "link-up" "$up"
  45. [ -n "$3" ] && json_add_boolean "address-external" "$external"
  46. }
  47. proto_set_keep() {
  48. PROTO_KEEP="$1"
  49. }
  50. proto_close_nested() {
  51. [ -n "$PROTO_NESTED_OPEN" ] && json_close_object
  52. PROTO_NESTED_OPEN=
  53. }
  54. proto_add_nested() {
  55. PROTO_NESTED_OPEN=1
  56. json_add_object "$1"
  57. }
  58. proto_add_tunnel() {
  59. proto_add_nested "tunnel"
  60. }
  61. proto_close_tunnel() {
  62. proto_close_nested
  63. }
  64. proto_add_data() {
  65. proto_add_nested "data"
  66. }
  67. proto_close_data() {
  68. proto_close_nested
  69. }
  70. proto_add_dns_server() {
  71. local address="$1"
  72. append PROTO_DNS "$address"
  73. }
  74. proto_add_dns_search() {
  75. local address="$1"
  76. append PROTO_DNS_SEARCH "$address"
  77. }
  78. proto_add_ipv4_address() {
  79. local address="$1"
  80. local mask="$2"
  81. local broadcast="$3"
  82. local ptp="$4"
  83. append PROTO_IPADDR "$address/$mask/$broadcast/$ptp"
  84. }
  85. proto_add_ipv6_address() {
  86. local address="$1"
  87. local mask="$2"
  88. local preferred="$3"
  89. local valid="$4"
  90. local offlink="$5"
  91. local class="$6"
  92. append PROTO_IP6ADDR "$address/$mask/$preferred/$valid/$offlink/$class"
  93. }
  94. proto_add_ipv4_route() {
  95. local target="$1"
  96. local mask="$2"
  97. local gw="$3"
  98. append PROTO_ROUTE "$target/$mask/$gw//"
  99. }
  100. proto_add_ipv6_route() {
  101. local target="$1"
  102. local mask="$2"
  103. local gw="$3"
  104. local metric="$4"
  105. local valid="$5"
  106. local source="$6"
  107. append PROTO_ROUTE6 "$target/$mask/$gw/$metric/$valid/$source"
  108. }
  109. proto_add_ipv6_prefix() {
  110. local prefix="$1"
  111. local valid="$2"
  112. local preferred="$3"
  113. if [ -z "$valid" ]; then
  114. append PROTO_PREFIX6 "$prefix"
  115. else
  116. [ -z "$preferred" ] && preferred="$valid"
  117. append PROTO_PREFIX6 "$prefix,$valid,$preferred"
  118. fi
  119. }
  120. _proto_push_ipv4_addr() {
  121. local str="$1"
  122. local address mask broadcast ptp
  123. address="${str%%/*}"
  124. str="${str#*/}"
  125. mask="${str%%/*}"
  126. str="${str#*/}"
  127. broadcast="${str%%/*}"
  128. str="${str#*/}"
  129. ptp="$str"
  130. json_add_object ""
  131. json_add_string ipaddr "$address"
  132. [ -n "$mask" ] && json_add_string mask "$mask"
  133. [ -n "$broadcast" ] && json_add_string broadcast "$broadcast"
  134. [ -n "$ptp" ] && json_add_string ptp "$ptp"
  135. json_close_object
  136. }
  137. _proto_push_ipv6_addr() {
  138. local str="$1"
  139. local address mask preferred valid offlink
  140. address="${str%%/*}"
  141. str="${str#*/}"
  142. mask="${str%%/*}"
  143. str="${str#*/}"
  144. preferred="${str%%/*}"
  145. str="${str#*/}"
  146. valid="${str%%/*}"
  147. str="${str#*/}"
  148. offlink="${str%%/*}"
  149. str="${str#*/}"
  150. class="${str%%/*}"
  151. json_add_object ""
  152. json_add_string ipaddr "$address"
  153. [ -n "$mask" ] && json_add_string mask "$mask"
  154. [ -n "$preferred" ] && json_add_int preferred "$preferred"
  155. [ -n "$valid" ] && json_add_int valid "$valid"
  156. [ -n "$offlink" ] && json_add_boolean offlink "$offlink"
  157. [ -n "$class" ] && json_add_string class "$class"
  158. json_close_object
  159. }
  160. _proto_push_string() {
  161. json_add_string "" "$1"
  162. }
  163. _proto_push_route() {
  164. local str="$1";
  165. local target="${str%%/*}"
  166. str="${str#*/}"
  167. local mask="${str%%/*}"
  168. str="${str#*/}"
  169. local gw="${str%%/*}"
  170. str="${str#*/}"
  171. local metric="${str%%/*}"
  172. str="${str#*/}"
  173. local valid="${str%%/*}"
  174. str="${str#*/}"
  175. local source="${str}"
  176. json_add_object ""
  177. json_add_string target "$target"
  178. json_add_string netmask "$mask"
  179. [ -n "$gw" ] && json_add_string gateway "$gw"
  180. [ -n "$metric" ] && json_add_int metric "$metric"
  181. [ -n "$valid" ] && json_add_int valid "$valid"
  182. [ -n "$source" ] && json_add_string source "$source"
  183. json_close_object
  184. }
  185. _proto_push_array() {
  186. local name="$1"
  187. local val="$2"
  188. local cb="$3"
  189. [ -n "$val" ] || return 0
  190. json_add_array "$name"
  191. for item in $val; do
  192. eval "$cb \"\$item\""
  193. done
  194. json_close_array
  195. }
  196. _proto_notify() {
  197. local interface="$1"
  198. local options="$2"
  199. json_add_string "interface" "$interface"
  200. ubus $options call network.interface notify_proto "$(json_dump)"
  201. }
  202. proto_send_update() {
  203. local interface="$1"
  204. proto_close_nested
  205. json_add_boolean keep "$PROTO_KEEP"
  206. _proto_push_array "ipaddr" "$PROTO_IPADDR" _proto_push_ipv4_addr
  207. _proto_push_array "ip6addr" "$PROTO_IP6ADDR" _proto_push_ipv6_addr
  208. _proto_push_array "routes" "$PROTO_ROUTE" _proto_push_route
  209. _proto_push_array "routes6" "$PROTO_ROUTE6" _proto_push_route
  210. _proto_push_array "ip6prefix" "$PROTO_PREFIX6" _proto_push_string
  211. _proto_push_array "dns" "$PROTO_DNS" _proto_push_string
  212. _proto_push_array "dns_search" "$PROTO_DNS_SEARCH" _proto_push_string
  213. _proto_notify "$interface"
  214. }
  215. proto_export() {
  216. local var="VAR${_EXPORT_VAR}"
  217. _EXPORT_VAR="$(($_EXPORT_VAR + 1))"
  218. export -- "$var=$1"
  219. append _EXPORT_VARS "$var"
  220. }
  221. proto_run_command() {
  222. local interface="$1"; shift
  223. json_init
  224. json_add_int action 1
  225. json_add_array command
  226. while [ $# -gt 0 ]; do
  227. json_add_string "" "$1"
  228. shift
  229. done
  230. json_close_array
  231. [ -n "$_EXPORT_VARS" ] && {
  232. json_add_array env
  233. for var in $_EXPORT_VARS; do
  234. eval "json_add_string \"\" \"\${$var}\""
  235. done
  236. json_close_array
  237. }
  238. _proto_notify "$interface"
  239. }
  240. proto_kill_command() {
  241. local interface="$1"; shift
  242. json_init
  243. json_add_int action 2
  244. [ -n "$1" ] && json_add_int signal "$1"
  245. _proto_notify "$interface"
  246. }
  247. proto_notify_error() {
  248. local interface="$1"; shift
  249. json_init
  250. json_add_int action 3
  251. json_add_array error
  252. while [ $# -gt 0 ]; do
  253. json_add_string "" "$1"
  254. shift
  255. done
  256. json_close_array
  257. _proto_notify "$interface"
  258. }
  259. proto_block_restart() {
  260. local interface="$1"; shift
  261. json_init
  262. json_add_int action 4
  263. _proto_notify "$interface"
  264. }
  265. proto_set_available() {
  266. local interface="$1"
  267. local state="$2"
  268. json_init
  269. json_add_int action 5
  270. json_add_boolean available "$state"
  271. _proto_notify "$interface"
  272. }
  273. proto_add_host_dependency() {
  274. local interface="$1"
  275. local host="$2"
  276. local ifname="$3"
  277. # execute in subshell to not taint callers env
  278. # see tickets #11046, #11545, #11570
  279. (
  280. json_init
  281. json_add_int action 6
  282. json_add_string host "$host"
  283. [ -n "$ifname" ] && json_add_string ifname "$ifname"
  284. _proto_notify "$interface" -S
  285. )
  286. }
  287. proto_setup_failed() {
  288. local interface="$1"
  289. json_init
  290. json_add_int action 7
  291. _proto_notify "$interface"
  292. }
  293. init_proto() {
  294. proto="$1"; shift
  295. cmd="$1"; shift
  296. case "$cmd" in
  297. dump)
  298. add_protocol() {
  299. no_device=0
  300. available=0
  301. renew_handler=0
  302. add_default_handler "proto_$1_init_config"
  303. json_init
  304. json_add_string "name" "$1"
  305. json_add_array "config"
  306. eval "proto_$1_init_config"
  307. json_close_array
  308. json_add_boolean no-device "$no_device"
  309. json_add_boolean available "$available"
  310. json_add_boolean renew-handler "$renew_handler"
  311. json_dump
  312. }
  313. ;;
  314. setup|teardown|renew)
  315. interface="$1"; shift
  316. data="$1"; shift
  317. ifname="$1"; shift
  318. add_protocol() {
  319. [[ "$proto" == "$1" ]] || return 0
  320. case "$cmd" in
  321. setup) _proto_do_setup "$1";;
  322. teardown) _proto_do_teardown "$1" ;;
  323. renew) _proto_do_renew "$1" ;;
  324. *) return 1 ;;
  325. esac
  326. }
  327. ;;
  328. esac
  329. }