You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

214 lines
5.2 KiB

mwan3: fix interface-bound traffic when interface is offline This commit fixed what 6d99b602 was supposed to fix without affecting interface-bound traffic. Before 6d99b602 interface-bound traffic was working normally as long as at least one interface was online. However when the last interface went offline, it was impossible to ping and such state was unrecoverable. Commit 6d99b602 fixed unrecoverable offline state problem (it was possible to ping -I iface) but messed inteface-bound traffic. Traffic with interface source address was not working if the interface was in "offline" state, even if another interface was online. The problem was caused by an inconsistent "offline" interface state: iptables-related rules were kept while routing table and policy were deleted. The idea behind this commit is to: 1. Keep all the rules for each interface (iptables, routing table, policy) regardless of its state. This ensures consistency, 2. Make interface state hotplug events affect only iptables' mwan3_policy_* rules. Interface-related iptables, routing table and policy is removed only when mwan3 is manually stopped. To make such changes possible, it's necessary to change the way mwan3_policy_* rule generator keeps track of interface state hotplug events. Until now, it checked for the existence of custom interface-related routing table (table id 1, 2, 3, ...). Clearly we can no longer rely on that so each interface state is stored explicitly in file. Signed-off-by: Marcin Jurkowski <marcin1j@gmail.com>
7 years ago
mwan3: fix interface-bound traffic when interface is offline This commit fixed what 6d99b602 was supposed to fix without affecting interface-bound traffic. Before 6d99b602 interface-bound traffic was working normally as long as at least one interface was online. However when the last interface went offline, it was impossible to ping and such state was unrecoverable. Commit 6d99b602 fixed unrecoverable offline state problem (it was possible to ping -I iface) but messed inteface-bound traffic. Traffic with interface source address was not working if the interface was in "offline" state, even if another interface was online. The problem was caused by an inconsistent "offline" interface state: iptables-related rules were kept while routing table and policy were deleted. The idea behind this commit is to: 1. Keep all the rules for each interface (iptables, routing table, policy) regardless of its state. This ensures consistency, 2. Make interface state hotplug events affect only iptables' mwan3_policy_* rules. Interface-related iptables, routing table and policy is removed only when mwan3 is manually stopped. To make such changes possible, it's necessary to change the way mwan3_policy_* rule generator keeps track of interface state hotplug events. Until now, it checked for the existence of custom interface-related routing table (table id 1, 2, 3, ...). Clearly we can no longer rely on that so each interface state is stored explicitly in file. Signed-off-by: Marcin Jurkowski <marcin1j@gmail.com>
7 years ago
mwan3: fix interface-bound traffic when interface is offline This commit fixed what 6d99b602 was supposed to fix without affecting interface-bound traffic. Before 6d99b602 interface-bound traffic was working normally as long as at least one interface was online. However when the last interface went offline, it was impossible to ping and such state was unrecoverable. Commit 6d99b602 fixed unrecoverable offline state problem (it was possible to ping -I iface) but messed inteface-bound traffic. Traffic with interface source address was not working if the interface was in "offline" state, even if another interface was online. The problem was caused by an inconsistent "offline" interface state: iptables-related rules were kept while routing table and policy were deleted. The idea behind this commit is to: 1. Keep all the rules for each interface (iptables, routing table, policy) regardless of its state. This ensures consistency, 2. Make interface state hotplug events affect only iptables' mwan3_policy_* rules. Interface-related iptables, routing table and policy is removed only when mwan3 is manually stopped. To make such changes possible, it's necessary to change the way mwan3_policy_* rule generator keeps track of interface state hotplug events. Until now, it checked for the existence of custom interface-related routing table (table id 1, 2, 3, ...). Clearly we can no longer rely on that so each interface state is stored explicitly in file. Signed-off-by: Marcin Jurkowski <marcin1j@gmail.com>
7 years ago
mwan3: fix interface-bound traffic when interface is offline This commit fixed what 6d99b602 was supposed to fix without affecting interface-bound traffic. Before 6d99b602 interface-bound traffic was working normally as long as at least one interface was online. However when the last interface went offline, it was impossible to ping and such state was unrecoverable. Commit 6d99b602 fixed unrecoverable offline state problem (it was possible to ping -I iface) but messed inteface-bound traffic. Traffic with interface source address was not working if the interface was in "offline" state, even if another interface was online. The problem was caused by an inconsistent "offline" interface state: iptables-related rules were kept while routing table and policy were deleted. The idea behind this commit is to: 1. Keep all the rules for each interface (iptables, routing table, policy) regardless of its state. This ensures consistency, 2. Make interface state hotplug events affect only iptables' mwan3_policy_* rules. Interface-related iptables, routing table and policy is removed only when mwan3 is manually stopped. To make such changes possible, it's necessary to change the way mwan3_policy_* rule generator keeps track of interface state hotplug events. Until now, it checked for the existence of custom interface-related routing table (table id 1, 2, 3, ...). Clearly we can no longer rely on that so each interface state is stored explicitly in file. Signed-off-by: Marcin Jurkowski <marcin1j@gmail.com>
7 years ago
  1. #!/bin/sh
  2. . /lib/functions.sh
  3. . /lib/functions/network.sh
  4. . /usr/share/libubox/jshn.sh
  5. . /lib/mwan3/common.sh
  6. MWAN3TRACK_STATUS_DIR="/var/run/mwan3track"
  7. IPS="ipset"
  8. IPT4="iptables -t mangle -w"
  9. IPT6="ip6tables -t mangle -w"
  10. report_connected_v4() {
  11. local address
  12. if [ -n "$($IPT4 -S mwan3_connected 2> /dev/null)" ]; then
  13. for address in $($IPS -o save list mwan3_connected_v4 | grep add | cut -d " " -f 3); do
  14. json_add_string "" "${address}"
  15. done
  16. fi
  17. }
  18. report_connected_v6() {
  19. local address
  20. if [ -n "$($IPT6 -S mwan3_connected 2> /dev/null)" ]; then
  21. for address in $($IPS -o save list mwan3_connected_v6 | grep add | cut -d " " -f 3); do
  22. json_add_string "" "${address}"
  23. done
  24. fi
  25. }
  26. report_policies() {
  27. local ipt="$1"
  28. local policy="$2"
  29. local percent total_weight weight iface
  30. total_weight=$($ipt -S $policy | grep -v '.*--comment "out .*" .*$' | cut -s -d'"' -f2 | head -1 | awk '{print $3}')
  31. for iface in $($ipt -S $policy | grep -v '.*--comment "out .*" .*$' | cut -s -d'"' -f2 | awk '{print $1}'); do
  32. weight=$($ipt -S $policy | grep -v '.*--comment "out .*" .*$' | cut -s -d'"' -f2 | awk '$1 == "'$iface'"' | awk '{print $2}')
  33. percent=$(($weight*100/$total_weight))
  34. json_add_object
  35. json_add_string interface "$iface"
  36. json_add_int percent "$percent"
  37. json_close_object
  38. done
  39. }
  40. report_policies_v4() {
  41. local policy
  42. for policy in $($IPT4 -S | awk '{print $2}' | grep mwan3_policy_ | sort -u); do
  43. json_add_array "${policy##*mwan3_policy_}"
  44. report_policies "$IPT4" "$policy"
  45. json_close_array
  46. done
  47. }
  48. report_policies_v6() {
  49. local policy
  50. for policy in $($IPT6 -S | awk '{print $2}' | grep mwan3_policy_ | sort -u); do
  51. json_add_array "${policy##*mwan3_policy_}"
  52. report_policies "$IPT6" "$policy"
  53. json_close_array
  54. done
  55. }
  56. get_mwan3_status() {
  57. local iface="${1}"
  58. local iface_select="${2}"
  59. local running="0"
  60. local age=0
  61. local uptime=0
  62. local downtime=0
  63. local pid device time_p time_n time_u time_d
  64. network_get_device device $1
  65. if [ "${iface}" = "${iface_select}" ] || [ "${iface_select}" = "" ]; then
  66. pid="$(pgrep -f "mwan3track $iface $device")"
  67. if [ "${pid}" != "" ]; then
  68. running="1"
  69. fi
  70. time_p="$(cat "$MWAN3TRACK_STATUS_DIR/${iface}/TIME")"
  71. [ -z "${time_p}" ] || {
  72. time_n="$(get_uptime)"
  73. let age=time_n-time_p
  74. }
  75. time_u="$(cat "$MWAN3TRACK_STATUS_DIR/${iface}/UPTIME")"
  76. [ -z "${time_u}" ] || [ "${time_u}" = "0" ] || {
  77. time_n="$(get_uptime)"
  78. let uptime=time_n-time_u
  79. }
  80. time_d="$(cat "$MWAN3TRACK_STATUS_DIR/${iface}/DOWNTIME")"
  81. [ -z "${time_d}" ] || [ "${time_d}" = "0" ] || {
  82. time_n="$(get_uptime)"
  83. let downtime=time_n-time_d
  84. }
  85. json_add_object "${iface}"
  86. json_add_int age "$age"
  87. json_add_int uptime "${uptime}"
  88. json_add_int downtime "${downtime}"
  89. json_add_int "score" "$(cat "$MWAN3TRACK_STATUS_DIR/${iface}/SCORE")"
  90. json_add_int "lost" "$(cat "$MWAN3TRACK_STATUS_DIR/${iface}/LOST")"
  91. json_add_int "turn" "$(cat "$MWAN3TRACK_STATUS_DIR/${iface}/TURN")"
  92. json_add_string "status" "$(cat "$MWAN3TRACK_STATUS_DIR/${iface}/STATUS")"
  93. json_add_boolean "running" "${running}"
  94. json_add_array "track_ip"
  95. for file in $MWAN3TRACK_STATUS_DIR/${iface}/*; do
  96. track="${file#*/TRACK_}"
  97. if [ "${track}" != "${file}" ]; then
  98. json_add_object
  99. json_add_string ip "${track}"
  100. json_add_string status "$(cat "${file}")"
  101. json_add_int latency "$(cat "$MWAN3TRACK_STATUS_DIR/${iface}/LATENCY_${track}")"
  102. json_add_int packetloss "$(cat "$MWAN3TRACK_STATUS_DIR/${iface}/LOSS_${track}")"
  103. json_close_object
  104. fi
  105. done
  106. json_close_array
  107. json_close_object
  108. fi
  109. }
  110. main () {
  111. case "$1" in
  112. list)
  113. json_init
  114. json_add_object "status"
  115. json_add_string "section" "x"
  116. json_add_string "interface" "x"
  117. json_add_string "policies" "x"
  118. json_close_object
  119. json_dump
  120. ;;
  121. call)
  122. case "$2" in
  123. status)
  124. local section iface
  125. read input;
  126. json_load "$input"
  127. json_get_var section section
  128. json_get_var iface interface
  129. config_load mwan3
  130. json_init
  131. case "$section" in
  132. interfaces)
  133. json_add_object interfaces
  134. config_foreach get_mwan3_status interface "${iface}"
  135. json_close_object
  136. ;;
  137. connected)
  138. json_add_object connected
  139. json_add_array ipv4
  140. report_connected_v4
  141. json_close_array
  142. json_add_array ipv6
  143. report_connected_v6
  144. json_close_array
  145. json_close_object
  146. ;;
  147. policies)
  148. json_add_object policies
  149. json_add_object ipv4
  150. report_policies_v4
  151. json_close_object
  152. json_add_object ipv6
  153. report_policies_v6
  154. json_close_object
  155. json_close_object
  156. ;;
  157. *)
  158. # interfaces
  159. json_add_object interfaces
  160. config_foreach get_mwan3_status interface
  161. json_close_object
  162. # connected
  163. json_add_object connected
  164. json_add_array ipv4
  165. report_connected_v4
  166. json_close_array
  167. json_add_array ipv6
  168. report_connected_v6
  169. json_close_array
  170. json_close_object
  171. # policies
  172. json_add_object policies
  173. json_add_object ipv4
  174. report_policies_v4
  175. json_close_object
  176. json_add_object ipv6
  177. report_policies_v6
  178. json_close_object
  179. json_close_object
  180. ;;
  181. esac
  182. json_dump
  183. ;;
  184. esac
  185. ;;
  186. esac
  187. }
  188. main "$@"