netifd-proto.sh 8.3 KB

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