netifd-proto.sh 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478
  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. PROTO_NEIGHBOR=
  56. PROTO_NEIGHBOR6=
  57. json_init
  58. json_add_int action 0
  59. [ -n "$ifname" -a "*" != "$ifname" ] && json_add_string "ifname" "$ifname"
  60. json_add_boolean "link-up" "$up"
  61. [ -n "$3" ] && json_add_boolean "address-external" "$external"
  62. }
  63. proto_set_keep() {
  64. PROTO_KEEP="$1"
  65. }
  66. proto_close_nested() {
  67. [ -n "$PROTO_NESTED_OPEN" ] && json_close_object
  68. PROTO_NESTED_OPEN=
  69. }
  70. proto_add_nested() {
  71. PROTO_NESTED_OPEN=1
  72. json_add_object "$1"
  73. }
  74. proto_add_tunnel() {
  75. proto_add_nested "tunnel"
  76. }
  77. proto_close_tunnel() {
  78. proto_close_nested
  79. }
  80. proto_add_data() {
  81. proto_add_nested "data"
  82. }
  83. proto_close_data() {
  84. proto_close_nested
  85. }
  86. proto_add_dns_server() {
  87. local address="$1"
  88. append PROTO_DNS "$address"
  89. }
  90. proto_add_dns_search() {
  91. local address="$1"
  92. append PROTO_DNS_SEARCH "$address"
  93. }
  94. proto_add_ipv4_address() {
  95. local address="$1"
  96. local mask="$2"
  97. local broadcast="$3"
  98. local ptp="$4"
  99. append PROTO_IPADDR "$address/$mask/$broadcast/$ptp"
  100. }
  101. proto_add_ipv6_address() {
  102. local address="$1"
  103. local mask="$2"
  104. local preferred="$3"
  105. local valid="$4"
  106. local offlink="$5"
  107. local class="$6"
  108. append PROTO_IP6ADDR "$address/$mask/$preferred/$valid/$offlink/$class"
  109. }
  110. proto_add_ipv4_neighbor(){
  111. local address="$1"
  112. local mac="$2"
  113. local proxy="$3"
  114. append PROTO_NEIGHBOR "$address/$mac/$proxy"
  115. }
  116. proto_add_ipv6_neighbor(){
  117. local address="$1"
  118. local mac="$2"
  119. local proxy="$3"
  120. local router="$4"
  121. append PROTO_NEIGHBOR6 "$address/$mac/$proxy/$router"
  122. }
  123. proto_add_ipv4_route() {
  124. local target="$1"
  125. local mask="$2"
  126. local gw="$3"
  127. local source="$4"
  128. local metric="$5"
  129. append PROTO_ROUTE "$target/$mask/$gw/$metric///$source"
  130. }
  131. proto_add_ipv6_route() {
  132. local target="$1"
  133. local mask="$2"
  134. local gw="$3"
  135. local metric="$4"
  136. local valid="$5"
  137. local source="$6"
  138. local table="$7"
  139. append PROTO_ROUTE6 "$target/$mask/$gw/$metric/$valid/$table/$source"
  140. }
  141. proto_add_ipv6_prefix() {
  142. local prefix="$1"
  143. local valid="$2"
  144. local preferred="$3"
  145. if [ -z "$valid" ]; then
  146. append PROTO_PREFIX6 "$prefix"
  147. else
  148. [ -z "$preferred" ] && preferred="$valid"
  149. append PROTO_PREFIX6 "$prefix,$valid,$preferred"
  150. fi
  151. }
  152. _proto_push_ipv4_addr() {
  153. local str="$1"
  154. local address mask broadcast ptp
  155. address="${str%%/*}"
  156. str="${str#*/}"
  157. mask="${str%%/*}"
  158. str="${str#*/}"
  159. broadcast="${str%%/*}"
  160. str="${str#*/}"
  161. ptp="$str"
  162. json_add_object ""
  163. json_add_string ipaddr "$address"
  164. [ -n "$mask" ] && json_add_string mask "$mask"
  165. [ -n "$broadcast" ] && json_add_string broadcast "$broadcast"
  166. [ -n "$ptp" ] && json_add_string ptp "$ptp"
  167. json_close_object
  168. }
  169. _proto_push_ipv6_addr() {
  170. local str="$1"
  171. local address mask preferred valid offlink
  172. address="${str%%/*}"
  173. str="${str#*/}"
  174. mask="${str%%/*}"
  175. str="${str#*/}"
  176. preferred="${str%%/*}"
  177. str="${str#*/}"
  178. valid="${str%%/*}"
  179. str="${str#*/}"
  180. offlink="${str%%/*}"
  181. str="${str#*/}"
  182. class="${str%%/*}"
  183. json_add_object ""
  184. json_add_string ipaddr "$address"
  185. [ -n "$mask" ] && json_add_string mask "$mask"
  186. [ -n "$preferred" ] && json_add_int preferred "$preferred"
  187. [ -n "$valid" ] && json_add_int valid "$valid"
  188. [ -n "$offlink" ] && json_add_boolean offlink "$offlink"
  189. [ -n "$class" ] && json_add_string class "$class"
  190. json_close_object
  191. }
  192. _proto_push_string() {
  193. json_add_string "" "$1"
  194. }
  195. _proto_push_ipv4_neighbor(){
  196. local str="$1"
  197. local address mac proxy
  198. address="${str%%/*}"
  199. str="${str#*/}"
  200. mac="${str%%/*}"
  201. str="${str#*/}"
  202. proxy="${str%%/*}"
  203. json_add_object ""
  204. json_add_string ipaddr "$address"
  205. [ -n "$mac" ] && json_add_string mac "$mac"
  206. [ -n "$proxy" ] && json_add_boolean proxy "$proxy"
  207. json_close_object
  208. }
  209. _proto_push_ipv6_neighbor(){
  210. local str="$1"
  211. local address mac proxy router
  212. address="${str%%/*}"
  213. str="${str#*/}"
  214. mac="${str%%/*}"
  215. str="${str#*/}"
  216. proxy="${str%%/*}"
  217. str="${str#*/}"
  218. router="${str%%/*}"
  219. json_add_object ""
  220. json_add_string ipaddr "$address"
  221. [ -n "$mac" ] && json_add_string mac "$mac"
  222. [ -n "$proxy" ] && json_add_boolean proxy "$proxy"
  223. [ -n "$router" ] && json_add_boolean router "$router"
  224. json_close_object
  225. }
  226. _proto_push_route() {
  227. local str="$1";
  228. local target="${str%%/*}"
  229. str="${str#*/}"
  230. local mask="${str%%/*}"
  231. str="${str#*/}"
  232. local gw="${str%%/*}"
  233. str="${str#*/}"
  234. local metric="${str%%/*}"
  235. str="${str#*/}"
  236. local valid="${str%%/*}"
  237. str="${str#*/}"
  238. local table="${str%%/*}"
  239. str="${str#*/}"
  240. local source="${str}"
  241. json_add_object ""
  242. json_add_string target "$target"
  243. json_add_string netmask "$mask"
  244. [ -n "$gw" ] && json_add_string gateway "$gw"
  245. [ -n "$metric" ] && json_add_int metric "$metric"
  246. [ -n "$valid" ] && json_add_int valid "$valid"
  247. [ -n "$source" ] && json_add_string source "$source"
  248. [ -n "$table" ] && json_add_string table "$table"
  249. json_close_object
  250. }
  251. _proto_push_array() {
  252. local name="$1"
  253. local val="$2"
  254. local cb="$3"
  255. [ -n "$val" ] || return 0
  256. json_add_array "$name"
  257. for item in $val; do
  258. eval "$cb \"\$item\""
  259. done
  260. json_close_array
  261. }
  262. _proto_notify() {
  263. local interface="$1"
  264. local options="$2"
  265. json_add_string "interface" "$interface"
  266. ubus $options call network.interface notify_proto "$(json_dump)"
  267. }
  268. proto_send_update() {
  269. local interface="$1"
  270. proto_close_nested
  271. json_add_boolean keep "$PROTO_KEEP"
  272. _proto_push_array "ipaddr" "$PROTO_IPADDR" _proto_push_ipv4_addr
  273. _proto_push_array "ip6addr" "$PROTO_IP6ADDR" _proto_push_ipv6_addr
  274. _proto_push_array "routes" "$PROTO_ROUTE" _proto_push_route
  275. _proto_push_array "routes6" "$PROTO_ROUTE6" _proto_push_route
  276. _proto_push_array "ip6prefix" "$PROTO_PREFIX6" _proto_push_string
  277. _proto_push_array "dns" "$PROTO_DNS" _proto_push_string
  278. _proto_push_array "dns_search" "$PROTO_DNS_SEARCH" _proto_push_string
  279. _proto_push_array "neighbor" "$PROTO_NEIGHBOR" _proto_push_ipv4_neighbor
  280. _proto_push_array "neighbor6" "$PROTO_NEIGHBOR6" _proto_push_ipv6_neighbor
  281. _proto_notify "$interface"
  282. }
  283. proto_export() {
  284. local var="VAR${_EXPORT_VAR}"
  285. _EXPORT_VAR="$(($_EXPORT_VAR + 1))"
  286. export -- "$var=$1"
  287. append _EXPORT_VARS "$var"
  288. }
  289. proto_run_command() {
  290. local interface="$1"; shift
  291. json_init
  292. json_add_int action 1
  293. json_add_array command
  294. while [ $# -gt 0 ]; do
  295. json_add_string "" "$1"
  296. shift
  297. done
  298. json_close_array
  299. [ -n "$_EXPORT_VARS" ] && {
  300. json_add_array env
  301. for var in $_EXPORT_VARS; do
  302. eval "json_add_string \"\" \"\${$var}\""
  303. done
  304. json_close_array
  305. }
  306. _proto_notify "$interface"
  307. }
  308. proto_kill_command() {
  309. local interface="$1"; shift
  310. json_init
  311. json_add_int action 2
  312. [ -n "$1" ] && json_add_int signal "$1"
  313. _proto_notify "$interface"
  314. }
  315. proto_notify_error() {
  316. local interface="$1"; shift
  317. json_init
  318. json_add_int action 3
  319. json_add_array error
  320. while [ $# -gt 0 ]; do
  321. json_add_string "" "$1"
  322. shift
  323. done
  324. json_close_array
  325. _proto_notify "$interface"
  326. }
  327. proto_block_restart() {
  328. local interface="$1"; shift
  329. json_init
  330. json_add_int action 4
  331. _proto_notify "$interface"
  332. }
  333. proto_set_available() {
  334. local interface="$1"
  335. local state="$2"
  336. json_init
  337. json_add_int action 5
  338. json_add_boolean available "$state"
  339. _proto_notify "$interface"
  340. }
  341. proto_add_host_dependency() {
  342. local interface="$1"
  343. local host="$2"
  344. local ifname="$3"
  345. # execute in subshell to not taint callers env
  346. # see tickets #11046, #11545, #11570
  347. (
  348. json_init
  349. json_add_int action 6
  350. json_add_string host "$host"
  351. [ -n "$ifname" ] && json_add_string ifname "$ifname"
  352. _proto_notify "$interface" -S
  353. )
  354. }
  355. proto_setup_failed() {
  356. local interface="$1"
  357. json_init
  358. json_add_int action 7
  359. _proto_notify "$interface"
  360. }
  361. init_proto() {
  362. proto="$1"; shift
  363. cmd="$1"; shift
  364. case "$cmd" in
  365. dump)
  366. add_protocol() {
  367. no_device=0
  368. no_proto_task=0
  369. available=0
  370. renew_handler=0
  371. teardown_on_l3_link_down=0
  372. add_default_handler "proto_$1_init_config"
  373. json_init
  374. json_add_string "name" "$1"
  375. json_add_array "config"
  376. eval "proto_$1_init_config"
  377. json_close_array
  378. json_add_boolean no-device "$no_device"
  379. json_add_boolean no-proto-task "$no_proto_task"
  380. json_add_boolean available "$available"
  381. json_add_boolean renew-handler "$renew_handler"
  382. json_add_boolean lasterror "$lasterror"
  383. json_add_boolean teardown-on-l3-link-down "$teardown_on_l3_link_down"
  384. json_dump
  385. }
  386. ;;
  387. setup|teardown|renew)
  388. interface="$1"; shift
  389. data="$1"; shift
  390. ifname="$1"; shift
  391. add_protocol() {
  392. [[ "$proto" == "$1" ]] || return 0
  393. case "$cmd" in
  394. setup) _proto_do_setup "$1";;
  395. teardown) _proto_do_teardown "$1" ;;
  396. renew) _proto_do_renew "$1" ;;
  397. *) return 1 ;;
  398. esac
  399. }
  400. ;;
  401. esac
  402. }