This commit fixed what6d99b602
was supposed to fix without affecting interface-bound traffic. Before6d99b602
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. Commit6d99b602
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>
179 lines
3.4 KiB
Bash
Executable file
179 lines
3.4 KiB
Bash
Executable file
#!/bin/sh
|
|
|
|
. /lib/functions.sh
|
|
. /lib/functions/network.sh
|
|
. /lib/mwan3/mwan3.sh
|
|
|
|
help()
|
|
{
|
|
cat <<EOF
|
|
Syntax: mwan3 [command]
|
|
|
|
Available commands:
|
|
start Load iptables rules, ip rules and ip routes
|
|
stop Unload iptables rules, ip rules and ip routes
|
|
restart Reload iptables rules, ip rules and ip routes
|
|
ifup <iface> Load rules and routes for specific interface
|
|
ifdown <iface> Unload rules and routes for specific interface
|
|
interfaces Show interfaces status
|
|
policies Show currently active policy
|
|
connected Show directly connected networks
|
|
rules Show active rules
|
|
status Show all status
|
|
|
|
EOF
|
|
}
|
|
|
|
ifdown()
|
|
{
|
|
if [ -z "$1" ]; then
|
|
echo "Error: Expecting interface. Usage: mwan3 ifdown <interface>" && exit 0
|
|
fi
|
|
|
|
if [ -n "$2" ]; then
|
|
echo "Error: Too many arguments. Usage: mwan3 ifdown <interface>" && exit 0
|
|
fi
|
|
|
|
ACTION=ifdown INTERFACE=$1 /sbin/hotplug-call iface
|
|
|
|
kill $(pgrep -f "mwan3track $1 $2") &> /dev/null
|
|
mwan3_track_clean $1
|
|
}
|
|
|
|
ifup()
|
|
{
|
|
local device enabled
|
|
|
|
config_load mwan3
|
|
|
|
if [ -z "$1" ]; then
|
|
echo "Expecting interface. Usage: mwan3 ifup <interface>" && exit 0
|
|
fi
|
|
|
|
if [ -n "$2" ]; then
|
|
echo "Too many arguments. Usage: mwan3 ifup <interface>" && exit 0
|
|
fi
|
|
|
|
config_get enabled "$1" enabled 0
|
|
|
|
device=$(uci -p /var/state get network.$1.ifname) &> /dev/null
|
|
|
|
if [ -n "$device" ] ; then
|
|
[ "$enabled" -eq 1 ] && ACTION=ifup INTERFACE=$1 DEVICE=$device /sbin/hotplug-call iface
|
|
fi
|
|
}
|
|
|
|
interfaces()
|
|
{
|
|
config_load mwan3
|
|
|
|
echo "Interface status:"
|
|
config_foreach mwan3_report_iface_status interface
|
|
echo -e
|
|
}
|
|
|
|
policies()
|
|
{
|
|
echo "Current ipv4 policies:"
|
|
mwan3_report_policies_v4
|
|
echo -e
|
|
echo "Current ipv6 policies:"
|
|
mwan3_report_policies_v6
|
|
echo -e
|
|
}
|
|
|
|
connected()
|
|
{
|
|
echo "Directly connected ipv4 networks:"
|
|
mwan3_report_connected_v4
|
|
echo -e
|
|
echo "Directly connected ipv6 networks:"
|
|
mwan3_report_connected_v6
|
|
echo -e
|
|
}
|
|
|
|
rules()
|
|
{
|
|
echo "Active ipv4 user rules:"
|
|
mwan3_report_rules_v4
|
|
echo -e
|
|
echo "Active ipv6 user rules:"
|
|
mwan3_report_rules_v6
|
|
echo -e
|
|
}
|
|
|
|
status()
|
|
{
|
|
interfaces
|
|
policies
|
|
connected
|
|
rules
|
|
}
|
|
|
|
start()
|
|
{
|
|
config_load mwan3
|
|
config_foreach ifup interface
|
|
}
|
|
|
|
stop()
|
|
{
|
|
local ipset route rule table IP IPT
|
|
|
|
killall mwan3track &> /dev/null
|
|
|
|
config_load mwan3
|
|
config_foreach mwan3_track_clean interface
|
|
|
|
for IP in "$IP4" "$IP6"; do
|
|
|
|
for route in $($IP route list table all | sed 's/.*table \([^ ]*\) .*/\1/' | awk '{print $1}' | awk '{for(i=1;i<=NF;i++) if($i+0>0) if($i+0<255) {print;break}}'); do
|
|
$IP route flush table $route &> /dev/null
|
|
done
|
|
|
|
for rule in $($IP rule list | egrep '^[1-2][0-9]{3}\:' | cut -d ':' -f 1); do
|
|
$IP rule del pref $rule &> /dev/null
|
|
done
|
|
done
|
|
|
|
for IPT in "$IPT4" "$IPT6"; do
|
|
|
|
$IPT -D PREROUTING -j mwan3_hook &> /dev/null
|
|
$IPT -D OUTPUT -j mwan3_hook &> /dev/null
|
|
|
|
for table in $($IPT -S | awk '{print $2}' | grep mwan3 | sort -u); do
|
|
$IPT -F $table &> /dev/null
|
|
done
|
|
|
|
for table in $($IPT -S | awk '{print $2}' | grep mwan3 | sort -u); do
|
|
$IPT -X $table &> /dev/null
|
|
done
|
|
done
|
|
|
|
for ipset in $($IPS -n list | grep mwan3_); do
|
|
$IPS -q destroy $ipset
|
|
done
|
|
|
|
for ipset in $($IPS -n list | grep mwan3 | grep -E '_v4|_v6'); do
|
|
$IPS -q destroy $ipset
|
|
done
|
|
|
|
mwan3_lock_clean
|
|
rm -rf $MWAN3_STATUS_DIR $MWAN3TRACK_STATUS_DIR
|
|
}
|
|
|
|
restart() {
|
|
stop
|
|
start
|
|
}
|
|
|
|
case "$1" in
|
|
ifup|ifdown|interfaces|policies|connected|rules|status|start|stop|restart)
|
|
$*
|
|
;;
|
|
*)
|
|
help
|
|
;;
|
|
esac
|
|
|
|
exit 0
|