luci.pbr 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343
  1. #!/bin/sh
  2. # Copyright 2022 Stan Grishin (stangri@melmac.ca)
  3. # shellcheck disable=SC2018,SC2019,SC2039,SC3043,SC3057,SC3060
  4. # TechRef: https://openwrt.org/docs/techref/rpcd
  5. # TESTS
  6. # ubus -v list luci.pbr
  7. # ubus -S call luci.pbr getInitList '{"name": "pbr" }'
  8. # ubus -S call luci.pbr getInitStatus '{"name": "pbr" }'
  9. # ubus -S call luci.pbr getPlatformSupport '{"name": "pbr" }'
  10. # ubus -S call luci.pbr getGateways '{"name": "pbr" }'
  11. # ubus -S call luci.pbr getInterfaces '{"name": "pbr" }'
  12. readonly luciCompat='11'
  13. readonly pbrFunctionsFile='/etc/init.d/pbr'
  14. if [ -s "$pbrFunctionsFile" ]; then
  15. # shellcheck source=../../../../../pbr/files/etc/init.d/pbr
  16. . "$pbrFunctionsFile"
  17. else
  18. print_json_string 'error' "pbr init.d file ($pbrFunctionsFile) not found!"
  19. logger -t pbr 'error' "pbr init.d file ($pbrFunctionsFile) not found!"
  20. fi
  21. # compatibility with old luci app versions
  22. is_running_iptables() { iptables -t mangle -L | grep -q PBR_PREROUTING >/dev/null 2>&1; }
  23. is_running() { is_running_iptables || is_running_nft; }
  24. check_ipset() { { [ -n "$ipset" ] && "$ipset" help hash:net; } >/dev/null 2>&1; }
  25. check_agh_ipset() {
  26. check_ipset || return 1
  27. check_agh || return 1
  28. is_greater_or_equal "$($agh --version | sed 's|AdGuard Home, version v\(.*\)|\1|' | sed 's|-.*||')" '0.107.13'
  29. }
  30. check_dnsmasq_ipset() {
  31. local o;
  32. check_ipset || return 1
  33. check_dnsmasq || return 1
  34. o="$(dnsmasq -v 2>/dev/null)"
  35. ! echo "$o" | grep -q 'no-ipset' && echo "$o" | grep -q 'ipset'
  36. }
  37. get_init_list() {
  38. local name
  39. name="$(basename "$1")"
  40. name="${name:-$packageName}"
  41. json_init
  42. json_add_object "$packageName"
  43. json_add_boolean 'enabled' "$(is_enabled "$packageName")"
  44. if is_running "$packageName"; then
  45. json_add_boolean 'running' '1'
  46. else
  47. json_add_boolean 'running' '0'
  48. fi
  49. json_close_object
  50. json_dump
  51. json_cleanup
  52. }
  53. set_init_action() {
  54. local name action="$2" cmd
  55. name="$(basename "$1")"
  56. name="${name:-$packageName}"
  57. if [ ! -f "/etc/init.d/$packageName" ]; then
  58. print_json_string 'error' 'Init script not found!'
  59. return
  60. fi
  61. case $action in
  62. enable)
  63. cmd="/etc/init.d/${name} ${action}"
  64. cmd="${cmd} && uci_set ${name} config enabled 1 && uci_commit $name"
  65. ;;
  66. disable)
  67. cmd="/etc/init.d/${name} ${action}"
  68. cmd="${cmd} && uci_set ${name} config enabled 0 && uci_commit $name"
  69. ;;
  70. start|stop|reload|restart)
  71. cmd="/etc/init.d/${name} ${action}"
  72. ;;
  73. esac
  74. if [ -n "$cmd" ] && eval "$cmd" 1>/dev/null 2>&1; then
  75. print_json_bool 'result' '1'
  76. else
  77. print_json_bool 'result' '0'
  78. fi
  79. }
  80. get_init_status() {
  81. local name
  82. name="$(basename "$1")"
  83. name="${name:-$packageName}"
  84. local gateways warnings errors
  85. gateways="$(ubus_get_status gateways | sed "s|\\\n|<br />|g;s|\(\\\033[^<]*\)|✓|g;")"
  86. warnings="$(ubus_get_status warnings)"
  87. errors="$(ubus_get_status errors)"
  88. json_init
  89. json_add_object "$packageName"
  90. json_add_boolean 'enabled' "$(is_enabled "$packageName")"
  91. if is_running "$packageName"; then
  92. json_add_boolean 'running' '1'
  93. else
  94. json_add_boolean 'running' '0'
  95. fi
  96. if is_running_iptables "$packageName"; then
  97. json_add_boolean 'running_iptables' '1'
  98. else
  99. json_add_boolean 'running_iptables' '0'
  100. fi
  101. if is_running_nft "$packageName"; then
  102. json_add_boolean 'running_nft' '1'
  103. else
  104. json_add_boolean 'running_nft' '0'
  105. fi
  106. if is_running_nft_file "$packageName"; then
  107. json_add_boolean 'running_nft_file' '1'
  108. else
  109. json_add_boolean 'running_nft_file' '0'
  110. fi
  111. json_add_string 'version' "$PKG_VERSION"
  112. json_add_string 'gateways' "$gateways"
  113. json_add_array 'errors'
  114. if [ -n "$errors" ]; then
  115. while read -r line; do
  116. if str_contains "$line" ' '; then
  117. error_id="${line% *}"
  118. error_extra="${line#* }"
  119. else
  120. error_id="$line"
  121. unset error_extra
  122. fi
  123. json_add_object
  124. json_add_string 'id' "$error_id"
  125. json_add_string 'extra' "$error_extra"
  126. json_close_object
  127. done <<EOF
  128. $(echo "$errors" | tr \# \\n)
  129. EOF
  130. fi
  131. json_close_array
  132. json_add_array 'warnings'
  133. if [ -n "$warnings" ]; then
  134. while read -r line; do
  135. if str_contains "$line" ' '; then
  136. warning_id="${line% *}"
  137. warning_extra="${line#* }"
  138. else
  139. warning_id="$line"
  140. unset warning_extra
  141. fi
  142. json_add_object
  143. json_add_string 'id' "$warning_id"
  144. json_add_string 'extra' "$warning_extra"
  145. json_close_object
  146. done <<EOF
  147. $(echo "$warnings" | tr \# \\n)
  148. EOF
  149. fi
  150. if is_greater "${packageCompat:-0}" "${luciCompat:-0}"; then
  151. json_add_object
  152. json_add_string 'id' 'warningOutdatedLuciPackage'
  153. json_close_object
  154. elif is_greater "${luciCompat:-0}" "${packageCompat:-0}"; then
  155. json_add_object
  156. json_add_string 'id' 'warningOutdatedPrincipalPackage'
  157. json_close_object
  158. fi
  159. json_close_array
  160. json_close_object
  161. json_dump
  162. json_cleanup
  163. }
  164. get_platform_support() {
  165. local name
  166. name="$(basename "$1")"
  167. name="${name:-$packageName}"
  168. json_init
  169. json_add_object "$packageName"
  170. if check_ipset; then
  171. json_add_boolean 'ipset_installed' '1'
  172. else
  173. json_add_boolean 'ipset_installed' '0'
  174. fi
  175. if check_nft; then
  176. json_add_boolean 'nft_installed' '1'
  177. else
  178. json_add_boolean 'nft_installed' '0'
  179. fi
  180. if check_agh; then
  181. json_add_boolean 'adguardhome_installed' '1'
  182. else
  183. json_add_boolean 'adguardhome_installed' '0'
  184. fi
  185. if check_dnsmasq; then
  186. json_add_boolean 'dnsmasq_installed' '1'
  187. else
  188. json_add_boolean 'dnsmasq_installed' '0'
  189. fi
  190. if check_unbound; then
  191. json_add_boolean 'unbound_installed' '1'
  192. else
  193. json_add_boolean 'unbound_installed' '0'
  194. fi
  195. if check_agh_ipset; then
  196. json_add_boolean 'adguardhome_ipset_support' '1'
  197. else
  198. json_add_boolean 'adguardhome_ipset_support' '0'
  199. fi
  200. if check_dnsmasq_ipset; then
  201. json_add_boolean 'dnsmasq_ipset_support' '1'
  202. else
  203. json_add_boolean 'dnsmasq_ipset_support' '0'
  204. fi
  205. if check_dnsmasq_nftset; then
  206. json_add_boolean 'dnsmasq_nftset_support' '1'
  207. else
  208. json_add_boolean 'dnsmasq_nftset_support' '0'
  209. fi
  210. json_close_object
  211. json_dump
  212. json_cleanup
  213. }
  214. # shellcheck disable=SC3037
  215. get_gateways() {
  216. echo -en "{\"$packageName\":{\"gateways\":"
  217. ubus_get_gateways
  218. echo -en "}}"
  219. }
  220. get_supported_interfaces() {
  221. _build_ifaces_supported() { is_supported_interface "$1" && ! str_contains "$ifacesSupported" "$1" && ifacesSupported="${ifacesSupported}${1} "; }
  222. _find_firewall_wan_zone() { [ "$(uci_get 'firewall' "$1" 'name')" = "wan" ] && firewallWanZone="$1"; }
  223. local i
  224. local firewallWanZone
  225. local ifacesSupported
  226. local webui_show_ignore_target
  227. local ignored_interface supported_interface
  228. local wanIface4 wanIface6
  229. config_load "$packageName"
  230. config_get_bool webui_show_ignore_target 'config' 'webui_show_ignore_target' '0'
  231. config_get ignored_interface 'config' 'ignored_interface'
  232. config_get supported_interface 'config' 'supported_interface'
  233. config_get procd_wan_interface 'config' 'procd_wan_interface' 'wan'
  234. config_get procd_wan6_interface 'config' 'procd_wan6_interface' 'wan6'
  235. local i
  236. wanIface4="$procd_wan_interface"
  237. wanIface6="$procd_wan6_interface"
  238. config_load 'firewall'
  239. config_foreach _find_firewall_wan_zone 'zone'
  240. for i in $(uci_get 'firewall' "$firewallWanZone" 'network'); do
  241. is_supported_interface "$i" && ! str_contains "$ifacesSupported" "$1" && ifacesSupported="${ifacesSupported}${i} "
  242. done
  243. config_load 'network'
  244. config_foreach _build_ifaces_supported 'interface'
  245. is_tor_running && ifacesSupported="$ifacesSupported tor"
  246. for i in $supported_interface; do
  247. is_xray "$i" && ifacesSupported="$ifacesSupported $i"
  248. done
  249. [ "$webui_show_ignore_target" -eq '1' ] && ifacesSupported="$ifacesSupported ignore"
  250. json_init
  251. json_add_object "$packageName"
  252. json_add_array 'interfaces'
  253. for i in $ifacesSupported; do
  254. json_add_string '' "$i"
  255. done
  256. json_close_array
  257. json_close_object
  258. json_dump
  259. json_cleanup
  260. }
  261. case "$1" in
  262. list)
  263. json_init
  264. json_add_object "getGateways"
  265. json_add_string 'name' 'name'
  266. json_close_object
  267. json_add_object "getInitList"
  268. json_add_string 'name' 'name'
  269. json_close_object
  270. json_add_object "getInitStatus"
  271. json_add_string 'name' 'name'
  272. json_close_object
  273. json_add_object "getInterfaces"
  274. json_add_string 'name' 'name'
  275. json_close_object
  276. json_add_object "getPlatformSupport"
  277. json_add_string 'name' 'name'
  278. json_close_object
  279. json_add_object "setInitAction"
  280. json_add_string 'name' 'name'
  281. json_add_string 'action' 'action'
  282. json_close_object
  283. json_dump
  284. json_cleanup
  285. ;;
  286. call)
  287. case "$2" in
  288. getGateways)
  289. read -r input
  290. json_load "$input"
  291. json_get_var name 'name'
  292. json_cleanup
  293. get_gateways "$packageName"
  294. ;;
  295. getInitList)
  296. read -r input
  297. json_load "$input"
  298. json_get_var name 'name'
  299. json_cleanup
  300. get_init_list "$packageName"
  301. ;;
  302. getInitStatus)
  303. read -r input
  304. json_load "$input"
  305. json_get_var name 'name'
  306. json_cleanup
  307. get_init_status "$packageName"
  308. ;;
  309. getInterfaces)
  310. read -r input
  311. json_load "$input"
  312. json_get_var name 'name'
  313. json_cleanup
  314. get_supported_interfaces "$packageName"
  315. ;;
  316. getPlatformSupport)
  317. read -r input
  318. json_load "$input"
  319. json_get_var name 'name'
  320. json_cleanup
  321. get_platform_support "$packageName"
  322. ;;
  323. setInitAction)
  324. read -r input
  325. json_load "$input"
  326. json_get_var name 'name'
  327. json_get_var action 'action'
  328. json_cleanup
  329. set_init_action "$packageName" "$action"
  330. ;;
  331. esac
  332. ;;
  333. esac