Add mwan3 to v1.4 branch of package feed
authorRISCi_ATOM <bob@bobcall.me>
Sat, 27 May 2017 16:44:49 +0000 (12:44 -0400)
committerRISCi_ATOM <bob@bobcall.me>
Sat, 27 May 2017 16:44:49 +0000 (12:44 -0400)
net/mwan3/Makefile
net/mwan3/files/etc/hotplug.d/iface/15-mwan3
net/mwan3/files/etc/hotplug.d/iface/16-mwan3-user [new file with mode: 0644]
net/mwan3/files/etc/mwan3.user [new file with mode: 0644]
net/mwan3/files/lib/mwan3/mwan3.sh
net/mwan3/files/usr/libexec/rpcd/mwan3 [new file with mode: 0755]
net/mwan3/files/usr/sbin/mwan3
net/mwan3/files/usr/sbin/mwan3track

index 01f9e07f65389bd001ffeb6e745db9a8120e26d0..394a642f9a823fcc15429b4028901c4e4b93d6f0 100644 (file)
@@ -8,9 +8,9 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=mwan3
-PKG_VERSION:=2.0
-PKG_RELEASE:=3
-PKG_MAINTAINER:=Jeroen Louwes <jeroen.louwes@gmail.com>
+PKG_VERSION:=2.5.2
+PKG_RELEASE:=5
+PKG_MAINTAINER:=Florian Eckert <fe@dev.tdt.de>
 PKG_LICENSE:=GPLv2
 
 include $(INCLUDE_DIR)/package.mk
@@ -21,7 +21,7 @@ define Package/mwan3
    SUBMENU:=Routing and Redirection
    DEPENDS:=+ip +ipset +iptables +iptables-mod-conntrack-extra +iptables-mod-ipopt
    TITLE:=Multiwan hotplug script with connection tracking support
-   MAINTAINER:=Jeroen Louwes <jeroen.louwes@gmail.com>
+   MAINTAINER:=Florian Eckert <fe@dev.tdt.de>
    PKGARCH:=all
 endef
 
@@ -33,6 +33,7 @@ endef
 
 define Package/mwan3/conffiles
 /etc/config/mwan3
+/etc/mwan3.user
 endef
 
 define Build/Compile
index 86e60e1330a74909f3056ff4d7443e4bafe85e59..e3fd16cef0f27f492bb78f288e4ffdc9ef23f078 100644 (file)
@@ -4,11 +4,6 @@
 . /lib/functions/network.sh
 . /lib/mwan3/mwan3.sh
 
-config_load mwan3
-
-config_get enabled $INTERFACE enabled 0
-[ "$enabled" == "1" ] || exit 0
-
 [ "$ACTION" == "ifup" -o "$ACTION" == "ifdown" ] || exit 1
 [ -n "$INTERFACE" ] || exit 2
 
@@ -16,26 +11,35 @@ if [ "$ACTION" == "ifup" ]; then
         [ -n "$DEVICE" ] || exit 3
 fi
 
-[ -x /usr/bin/ip ] || exit 4
-[ -x /usr/sbin/ipset ] || exit 5
-[ -x /usr/sbin/iptables ] || exit 6
-[ -x /usr/sbin/ip6tables ] || exit 7
-[ -x /usr/bin/logger ] || exit 8
+mwan3_set_connected_iptables
+
+config_load mwan3
+config_get enabled $INTERFACE enabled 0
+[ "$enabled" == "1" ] || exit 0
 
-config_get family $INTERFACE family ipv4
+if [ "$ACTION" == "ifup" ]; then
+       config_get family $INTERFACE family ipv4
+       if [ "$family" = "ipv4" ]; then
+               ubus call network.interface.${INTERFACE}_4 status &>/dev/null
+               if [ "$?" -eq "0" ]; then
+                       network_get_gateway gateway ${INTERFACE}_4
+               else
+                       network_get_gateway gateway $INTERFACE
+               fi
+       elif [ "$family" = "ipv6" ]; then
+               ubus call network.interface.${INTERFACE}_6 status &>/dev/null
+               if [ "$?" -eq "0" ]; then
+                       network_get_gateway6 gateway ${INTERFACE}_6
+               else
+                       network_get_gateway6 gateway ${INTERFACE}
+               fi
+       fi
 
-if [ "$family" == "ipv4" ]; then
-       network_get_gateway gateway $INTERFACE
-elif [ "$family" == "ipv6" ]; then
-       network_get_gateway6 gateway $INTERFACE
+       [ -n "$gateway" ] || exit 9
 fi
 
-[ -n "$gateway" ] || exit 9
-
 $LOG notice "$ACTION interface $INTERFACE (${DEVICE:-unknown})"
 
-mwan3_set_connected_iptables
-
 case "$ACTION" in
        ifup)
                mwan3_set_general_rules
@@ -46,14 +50,17 @@ case "$ACTION" in
                mwan3_track $INTERFACE $DEVICE
                mwan3_set_policies_iptables
                mwan3_set_user_rules
+               mwan3_flush_conntrack $INTERFACE $DEVICE "ifup"
        ;;
        ifdown)
                mwan3_delete_iface_rules $INTERFACE
                mwan3_delete_iface_iptables $INTERFACE
                mwan3_delete_iface_route $INTERFACE
                mwan3_delete_iface_ipset_entries $INTERFACE
+               mwan3_track_signal $INTERFACE $DEVICE
                mwan3_set_policies_iptables
                mwan3_set_user_rules
+               mwan3_flush_conntrack $INTERFACE $DEVICE "ifdown"
        ;;
 esac
 
diff --git a/net/mwan3/files/etc/hotplug.d/iface/16-mwan3-user b/net/mwan3/files/etc/hotplug.d/iface/16-mwan3-user
new file mode 100644 (file)
index 0000000..485f8de
--- /dev/null
@@ -0,0 +1,13 @@
+#!/bin/sh
+
+[ -f "/etc/mwan3.user" ] && {
+       . /lib/functions.sh
+
+       config_load mwan3
+       config_get enabled "$INTERFACE" enabled 0
+       [ "${enabled}" = "1" ] || exit 0
+       env -i ACTION="$ACTION" INTERFACE="$INTERFACE" DEVICE="$DEVICE" \
+               /bin/sh /etc/mwan3.user
+}
+
+exit 0
diff --git a/net/mwan3/files/etc/mwan3.user b/net/mwan3/files/etc/mwan3.user
new file mode 100644 (file)
index 0000000..3c1f9fb
--- /dev/null
@@ -0,0 +1,12 @@
+#!/bin/sh
+#
+# This file is interpreted as shell script.
+# Put your custom mwan3 action here, they will
+# be executed with each netifd hotplug interface event
+# on interfaces for which mwan3 is enabled.
+#
+# There are three main environment variables that are passed to this script.
+#
+# $ACTION      Either "ifup" or "ifdown"
+# $INTERFACE   Name of the interface which went up or down (e.g. "wan" or "wwan")
+# $DEVICE      Physical device name which interface went up or down (e.g. "eth0" or "wwan0")
index 1e1de969fafb957dcec19f9342784cfdc6917a5d..3798d7eb055c00e4d09a8497bdc8bcbe8618d68d 100644 (file)
@@ -1,11 +1,12 @@
 #!/bin/sh
 
-IP4="/usr/bin/ip -4"
-IP6="/usr/bin/ip -6"
-IPS="/usr/sbin/ipset"
-IPT4="/usr/sbin/iptables -t mangle -w"
-IPT6="/usr/sbin/ip6tables -t mangle -w"
-LOG="/usr/bin/logger -t mwan3 -p"
+IP4="ip -4"
+IP6="ip -6"
+IPS="ipset"
+IPT4="iptables -t mangle -w"
+IPT6="ip6tables -t mangle -w"
+LOG="logger -t mwan3 -p"
+CONNTRACK_FILE="/proc/net/nf_conntrack"
 
 mwan3_get_iface_id()
 {
@@ -129,7 +130,12 @@ mwan3_create_iface_iptables()
 
        if [ "$family" == "ipv4" ]; then
 
-               network_get_ipaddr src_ip $1
+               ubus call network.interface.${1}_4 status &>/dev/null
+               if [ "$?" -eq "0" ]; then
+                       network_get_ipaddr src_ip ${1}_4
+               else
+                       network_get_ipaddr src_ip $1
+               fi
 
                $IPS -! create mwan3_connected list:set
 
@@ -165,7 +171,12 @@ mwan3_create_iface_iptables()
 
        if [ "$family" == "ipv6" ]; then
 
-               network_get_ipaddr6 src_ipv6 $1
+               ubus call network.interface.${1}_6 status &>/dev/null
+               if [ "$?" -eq "0" ]; then
+                       network_get_ipaddr6 src_ipv6 ${1}_6
+               else
+                       network_get_ipaddr6 src_ipv6 $1
+               fi
 
                $IPS -! create mwan3_connected_v6 hash:net family inet6
 
@@ -237,8 +248,13 @@ mwan3_create_iface_route()
        [ -n "$id" ] || return 0
 
        if [ "$family" == "ipv4" ]; then
+               ubus call network.interface.${1}_4 status &>/dev/null
+               if [ "$?" -eq "0" ]; then
+                       network_get_gateway route_args ${1}_4
+               else
+                       network_get_gateway route_args $1
+               fi
 
-               network_get_gateway route_args $1
                route_args="via $route_args dev $2"
 
                $IP4 route flush table $id
@@ -247,7 +263,13 @@ mwan3_create_iface_route()
 
        if [ "$family" == "ipv6" ]; then
 
-               network_get_gateway6 route_args $1
+               ubus call network.interface.${1}_6 status &>/dev/null
+               if [ "$?" -eq "0" ]; then
+                       network_get_gateway6 route_args ${1}_6
+               else
+                       network_get_gateway6 route_args $1
+               fi
+
                route_args="via $route_args dev $2"
 
                $IP6 route flush table $id
@@ -360,7 +382,7 @@ mwan3_delete_iface_ipset_entries()
 
 mwan3_track()
 {
-       local track_ip track_ips reliability count timeout interval down up
+       local track_ip track_ips
 
        mwan3_list_track_ips()
        {
@@ -368,20 +390,21 @@ mwan3_track()
        }
        config_list_foreach $1 track_ip mwan3_list_track_ips
 
-       if [ -e /var/run/mwan3track-$1.pid ] ; then
-               kill $(cat /var/run/mwan3track-$1.pid) &> /dev/null
-               rm /var/run/mwan3track-$1.pid &> /dev/null
+       kill $(pgrep -f "mwan3track $1") &> /dev/null
+       if [ -n "$track_ips" ]; then
+               [ -x /usr/sbin/mwan3track ] && /usr/sbin/mwan3track $1 $2 $track_ips &
        fi
+}
 
-       if [ -n "$track_ips" ]; then
-               config_get reliability $1 reliability 1
-               config_get count $1 count 1
-               config_get timeout $1 timeout 4
-               config_get interval $1 interval 10
-               config_get down $1 down 5
-               config_get up $1 up 5
-
-               [ -x /usr/sbin/mwan3track ] && /usr/sbin/mwan3track $1 $2 $reliability $count $timeout $interval $down $up $track_ips &
+mwan3_track_signal()
+{
+       local pid
+
+       pid="$(pgrep -f "mwan3track $1")"
+       if [ "${pid}" != "" ]; then
+               kill -USR1 "${pid}"
+       else
+               $LOG warn "Unable to send signal USR1 to mwan3track on interface $1 with pid ${pid}"
        fi
 }
 
@@ -804,3 +827,36 @@ mwan3_report_rules_v6()
                $IPT6 -L mwan3_rules -n -v 2> /dev/null | tail -n+3 | sed 's/mark.*//' | sed 's/mwan3_policy_/- /' | sed 's/mwan3_rule_/S /'
        fi
 }
+
+mwan3_flush_conntrack()
+{
+       local flush_conntrack
+
+       config_get flush_conntrack $1 flush_conntrack never
+
+       if [ -e "$CONNTRACK_FILE" ]; then
+               case $flush_conntrack in
+                       ifup)
+                               [ "$3" = "ifup" ] && {
+                                       echo f > ${CONNTRACK_FILE}
+                                       $LOG info "connection tracking flushed on interface $1 ($2) $3"
+                               }
+                               ;;
+                       ifdown)
+                               [ "$3" = "ifdown" ] && {
+                                       echo f > ${CONNTRACK_FILE}
+                                       $LOG info "connection tracking flushed on interface $1 ($2) $3"
+                               }
+                               ;;
+                       always)
+                               echo f > ${CONNTRACK_FILE}
+                               $LOG info "connection tracking flushed on interface $1 ($2) $3"
+                               ;;
+                       never)
+                               $LOG info "connection tracking not flushed on interface $1 ($2) $3"
+                               ;;
+               esac
+       else
+               $LOG warning "connection tracking not enabled"
+       fi
+}
diff --git a/net/mwan3/files/usr/libexec/rpcd/mwan3 b/net/mwan3/files/usr/libexec/rpcd/mwan3
new file mode 100755 (executable)
index 0000000..bbc570f
--- /dev/null
@@ -0,0 +1,122 @@
+#!/bin/sh
+
+. /lib/functions.sh
+. /usr/share/libubox/jshn.sh
+
+MWAN3_STATUS_DIR="/var/run/mwan3track"
+MWAN3_PID_FILE="/var/run/mwan3track"
+
+IPS="ipset"
+IPT4="iptables -t mangle -w"
+IPT6="ip6tables -t mangle -w"
+
+report_connected_v4() {
+       local address
+
+       if [ -n "$($IPT4 -S mwan3_connected 2> /dev/null)" ]; then
+               for address in $($IPS list mwan3_connected_v4 | tail -n +8); do
+                       json_add_string "" "${address}"
+               done
+       fi
+}
+
+report_connected_v6() {
+       local address
+
+       if [ -n "$($IPT6 -S mwan3_connected 2> /dev/null)" ]; then
+               for address in $($IPS list mwan3_connected_v6 | tail -n +8); do
+                       json_add_string "" "${address}"
+               done
+       fi
+}
+
+get_mwan3_status() {
+       local iface="${1}"
+       local iface_select="${2}"
+       local running="0"
+       local pid
+
+       if [ "${iface}" = "${iface_select}" ] || [ "${iface_select}" = "" ]; then
+               pid="$(pgrep -f "mwan3track $iface_selected")"
+               if [ "${pid}" != "" ]; then
+                       running="1"
+               fi
+
+               json_add_object "${iface}"
+               json_add_string "score" "$(cat "$MWAN3_STATUS_DIR/${iface}/SCORE")"
+               json_add_string "lost" "$(cat "$MWAN3_STATUS_DIR/${iface}/LOST")"
+               json_add_string "turn" "$(cat "$MWAN3_STATUS_DIR/${iface}/TURN")"
+               json_add_string "status" "$(cat "$MWAN3_STATUS_DIR/${iface}/STATUS")"
+               json_add_boolean "running" "${running}"
+               json_add_array "track_ip"
+               for file in $MWAN3_STATUS_DIR/${iface}/*; do
+                       track="${file#*/TRACK_}"
+                       if [ "${track}" != "${file}" ]; then
+                               json_add_object
+                               json_add_string ip "${track}"
+                               json_add_string status "$(cat "${file}")"
+                               json_close_object
+                       fi
+               done
+               json_close_array
+               json_close_object
+       fi
+}
+
+case "$1" in
+       list)
+               json_init
+               json_add_object "status"
+               json_add_string "section" "x"
+               json_add_string "interface" "x"
+               json_close_object
+               json_dump
+               ;;
+       call)
+               case "$2" in
+               status)
+                       local section iface
+                       read input;
+                       json_load "$input"
+                       json_get_var section section
+                       json_get_var iface interface
+
+                       config_load mwan3
+                       json_init
+                       case "$section" in
+                               interfaces)
+                                       json_add_object interfaces
+                                       config_foreach get_mwan3_status interface "${iface}"
+                                       json_close_object
+                                       ;;
+                               connected)
+                                       json_add_object connected
+                                       json_add_array ipv4
+                                       report_connected_v4
+                                       json_close_array
+                                       json_add_array ipv6
+                                       report_connected_v6
+                                       json_close_array
+                                       json_close_object
+                                       ;;
+                               *)
+                                       # interfaces
+                                       json_add_object interfaces
+                                       config_foreach get_mwan3_status interface
+                                       json_close_object
+                                       # connected
+                                       json_add_object connected
+                                       json_add_array ipv4
+                                       report_connected_v4
+                                       json_close_array
+                                       json_add_array ipv6
+                                       report_connected_v6
+                                       json_close_array
+                                       json_close_object
+                                       ;;
+                       esac
+                       json_dump
+                       ;;
+               esac
+               ;;
+esac
index 405cd43f3fdf5c019c802c31691a1dfac5474a62..f23d2e71b72c468c871feb454d6842b5e2e7b020 100755 (executable)
@@ -1,11 +1,5 @@
 #!/bin/sh
 
-[ -x /usr/bin/ip ] || exit 4
-[ -x /usr/sbin/ipset ] || exit 5
-[ -x /usr/sbin/iptables ] || exit 6
-[ -x /usr/sbin/ip6tables ] || exit 7
-[ -x /usr/bin/logger ] || exit 8
-
 . /lib/functions.sh
 . /lib/functions/network.sh
 . /lib/mwan3/mwan3.sh
@@ -42,10 +36,7 @@ ifdown()
 
        ACTION=ifdown INTERFACE=$1 /sbin/hotplug-call iface
 
-       if [ -e /var/run/mwan3track-$1.pid ] ; then
-               kill $(cat /var/run/mwan3track-$1.pid)
-               rm /var/run/mwan3track-$1.pid
-       fi
+       kill $(pgrep -f "mwan3track $1") &> /dev/null
 }
 
 ifup()
@@ -129,7 +120,6 @@ stop()
        local ipset route rule table IP IPT
 
        killall mwan3track &> /dev/null
-       rm /var/run/mwan3track-* &> /dev/null
 
        for IP in "$IP4" "$IP6"; do
 
index 35f97fe0d50f0124497f63640d6ccc903f3a0202..8afe9012939b91cd13ba0b6efb9508b37e1fd0eb 100755 (executable)
 #!/bin/sh
 
-[ -z "$9" ] && echo "Error: should not be started manually" && exit 0
+. /lib/functions.sh
 
-if [ -e /var/run/mwan3track-$1.pid ] ; then
-       kill $(cat /var/run/mwan3track-$1.pid) &> /dev/null
-       rm /var/run/mwan3track-$1.pid &> /dev/null
-fi
+LOG="logger -t $(basename "$0")[$$] -p"
+INTERFACE=""
+DEVICE=""
 
-echo "$$" > /var/run/mwan3track-$1.pid
+IFDOWN_EVENT=0
 
-score=$(($7+$8))
-track_ips=$(echo $* | cut -d ' ' -f 9-99)
-host_up_count=0
-lost=0
-
-while true; do
-
-       for track_ip in $track_ips; do
-               ping -I $2 -c $4 -W $5 -q $track_ip &> /dev/null
-               if [ $? -eq 0 ]; then
-                       let host_up_count++
+clean_up() {
+       $LOG notice "Stopping mwan3track for interface \"${INTERFACE}\""
+       if [ "$(pgrep -f "mwan3track ${INTERFACE}")" = "" ]; then
+               rm -rf "/var/run/mwan3track/${INTERFACE}" &> /dev/null
+       fi
+       if [ -z "$(ls -A "/var/run/mwan3track")" ]; then
+               rm -rf "/var/run/mwan3track"
+       fi
+       exit 0
+}
+
+if_down() {
+       $LOG info "Detect ifdown event on interface ${INTERFACE} (${DEVICE})"
+       IFDOWN_EVENT=1
+}
+
+main() {
+       local reliability count timeout interval failure_interval
+       local recovery_interval down up size
+
+       [ -z "$3" ] && echo "Error: should not be started manually" && exit 0
+
+       INTERFACE=$1
+       DEVICE=$2
+       mkdir -p /var/run/mwan3track/$1
+       trap clean_up SIGINT SIGTERM
+       trap if_down SIGUSR1
+
+       config_load mwan3
+       config_get reliability $1 reliability 1
+       config_get count $1 count 1
+       config_get timeout $1 timeout 4
+       config_get interval $1 interval 10
+       config_get down $1 down 5
+       config_get up $1 up 5
+       config_get size $1 size 56
+       config_get failure_interval $1 failure_interval $interval
+       config_get recovery_interval $1 recovery_interval $interval
+
+       local score=$(($down+$up))
+       local track_ips=$(echo $* | cut -d ' ' -f 3-99)
+       local host_up_count=0
+       local lost=0
+       local sleep_time=0
+       local turn=0
+
+       echo "offline" > /var/run/mwan3track/$1/STATUS
+       while true; do
+
+               sleep_time=$interval
+
+               for track_ip in $track_ips; do
+                       ping -I $2 -c $count -W $timeout -s $size -q $track_ip &> /dev/null
+                       if [ $? -eq 0 ]; then
+                               let host_up_count++
+                               echo "up" > /var/run/mwan3track/$1/TRACK_${track_ip}
+                       else
+                               let lost++
+                               echo "down" > /var/run/mwan3track/$1/TRACK_${track_ip}
+                       fi
+               done
+
+               if [ $host_up_count -lt $reliability ]; then
+                       let score--
+
+                       if [ $score -lt $up ]; then
+                               score=0
+                       else
+                               sleep_time=$failure_interval
+                       fi
+
+                       if [ $score -eq $up ]; then
+                               echo "offline" > /var/run/mwan3track/$1/STATUS
+                               $LOG notice "Interface $1 ($2) is offline"
+                               env -i ACTION=ifdown INTERFACE=$1 DEVICE=$2 /sbin/hotplug-call iface
+                               score=0
+                       fi
                else
-                       let lost++
+                       if [ $score -lt $(($down+$up)) ] && [ $lost -gt 0 ]; then
+                               $LOG info "Lost $(($lost*$count)) ping(s) on interface $1 ($2)"
+                       fi
+
+                       let score++
+                       lost=0
+
+                       if [ $score -gt $up ]; then
+                               echo "online" > /var/run/mwan3track/$1/STATUS
+                               score=$(($down+$up))
+                       elif [ $score -le $up ]; then
+                               sleep_time=$recovery_interval
+                       fi
+
+                       if [ $score -eq $up ]; then
+                               $LOG notice "Interface $1 ($2) is online"
+                               env -i ACTION=ifup INTERFACE=$1 DEVICE=$2 /sbin/hotplug-call iface
+                               rm -rf "/var/run/mwan3track/${1}" &> /dev/null
+                               exit 0
+                       fi
                fi
-       done
 
-       if [ $host_up_count -lt $3 ]; then
-               let score--
+               let turn++
+               mkdir -p "/var/run/mwan3track/${1}"
+               echo "${lost}" > /var/run/mwan3track/$1/LOST
+               echo "${score}" > /var/run/mwan3track/$1/SCORE
+               echo "${turn}" > /var/run/mwan3track/$1/TURN
 
-               if [ $score -lt $8 ]; then score=0 ; fi
-               if [ $score -eq $8 ]; then
+               host_up_count=0
+               sleep "${sleep_time}" &
+               wait
 
-                       logger -t mwan3track -p notice "Interface $1 ($2) is offline"
-                       env -i ACTION=ifdown INTERFACE=$1 DEVICE=$2 /sbin/hotplug-call iface
+               if [ "${IFDOWN_EVENT}" -eq 1 ]; then
                        score=0
-
-               fi
-
-       else
-
-               if [ $score -lt $(($7+$8)) ] && [ $lost -gt 0 ]; then
-
-                       logger -t mwan3track -p info "Lost $(($lost*$4)) ping(s) on interface $1 ($2)"
-
+                       echo "offline" > /var/run/mwan3track/$1/STATUS
+                       IFDOWN_EVENT=0
                fi
+       done
+}
 
-               let score++
-               lost=0
-
-               if [ $score -gt $8 ]; then score=$(($7+$8)); fi
-               if [ $score -eq $8 ]; then
-
-                       logger -t mwan3track -p notice "Interface $1 ($2) is online"
-                       env -i ACTION=ifup INTERFACE=$1 DEVICE=$2 /sbin/hotplug-call iface
-                       rm /var/run/mwan3track-$1.pid
-                       exit 0
-               fi
-       fi
-
-       host_up_count=0
-       sleep $6
-done
-
-exit 1
+main "$@"