mirror of
https://gitlab.com/shorewall/code.git
synced 2024-11-23 16:13:18 +01:00
Modularize Multi-ISP
git-svn-id: https://shorewall.svn.sourceforge.net/svnroot/shorewall/trunk@4452 fbd18981-670d-0410-9b5c-8dc0c1a9a2bb
This commit is contained in:
parent
97218564ae
commit
f6cb3ecd77
@ -411,365 +411,6 @@ deletechain() # $1 = name of chain
|
||||
save_command "qt $IPTABLES -L $1 -n && qt $IPTABLES -F $1 && qt $IPTABLES -X $1"
|
||||
}
|
||||
|
||||
#
|
||||
# Process the providers file
|
||||
#
|
||||
setup_providers()
|
||||
{
|
||||
local table number mark duplicate interface gateway options provider address copy route loose addresses rulenum rulebase echobin=$(mywhich echo) balance save_indent="$INDENT" mask= first=Yes save_indent1=
|
||||
|
||||
copy_table() {
|
||||
indent >&3 << __EOF__
|
||||
ip route show table $duplicate | while read net route; do
|
||||
case \$net in
|
||||
default|nexthop)
|
||||
;;
|
||||
*)
|
||||
run_ip route add table $number \$net \$route
|
||||
;;
|
||||
esac
|
||||
done
|
||||
__EOF__
|
||||
}
|
||||
|
||||
copy_and_edit_table() {
|
||||
indent >&3 << __EOF__
|
||||
ip route show table $duplicate | while read net route; do
|
||||
case \$net in
|
||||
default|nexthop)
|
||||
;;
|
||||
*)
|
||||
case \$(find_device \$route) in
|
||||
`echo $copy\) | sed 's/ /|/g'`
|
||||
run_ip route add table $number \$net \$route
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
__EOF__
|
||||
}
|
||||
|
||||
balance_default_route() # $1 = weight
|
||||
{
|
||||
balance=yes
|
||||
|
||||
save_command
|
||||
if [ -n "$first" ]; then
|
||||
if [ -n "$gateway" ] ; then
|
||||
save_command "DEFAULT_ROUTE=\"nexthop via $gateway dev $interface weight $1\""
|
||||
else
|
||||
save_command "DEFAULT_ROUTE=\"nexthop dev $interface weight $1\""
|
||||
fi
|
||||
|
||||
first=
|
||||
else
|
||||
if [ -n "$gateway" ] ; then
|
||||
save_command "DEFAULT_ROUTE=\"\$DEFAULT_ROUTE nexthop via $gateway dev $interface weight $1\""
|
||||
else
|
||||
save_command "DEFAULT_ROUTE=\"\$DEFAULT_ROUTE nexthop dev $interface weight $1\""
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
add_a_provider() {
|
||||
local t n iface option optional=
|
||||
|
||||
[ -n "$MANGLE_ENABLED" ] || fatal_error "Providers require mangle support in your kernel and iptables"
|
||||
|
||||
for t in $PROVIDERS local main default unspec; do
|
||||
if [ "$t" = "$table" ]; then
|
||||
fatal_error "Duplicate Provider: $table, provider: \"$provider\""
|
||||
fi
|
||||
|
||||
eval n=\$${t}_number
|
||||
#
|
||||
# The following is because the %$#@ shell doesn't accept hex numbers in '-eq' tests
|
||||
#
|
||||
if [ $(($n)) -eq $(($number)) ]; then
|
||||
fatal_error "Duplicate Provider number: $number, provider: \"$provider\""
|
||||
fi
|
||||
done
|
||||
|
||||
eval ${table}_number=$number
|
||||
|
||||
indent >&3 << __EOF__
|
||||
#
|
||||
# Add Provider $table ($number)
|
||||
#
|
||||
__EOF__
|
||||
save_command "if interface_is_up $interface && [ \"\$(find_first_interface_address_if_any $interface)\" != 0.0.0.0 ]; then"
|
||||
save_indent1="$INDENT"
|
||||
INDENT="$INDENT "
|
||||
|
||||
iface=$(chain_base $interface)
|
||||
|
||||
save_command "${iface}_up=Yes"
|
||||
|
||||
save_command "qt ip route flush table $number"
|
||||
|
||||
if [ "x${duplicate:=-}" != x- ]; then
|
||||
if [ "x${copy:=-}" != "x-" ]; then
|
||||
if [ "x${copy}" = xnone ]; then
|
||||
copy=$interface
|
||||
else
|
||||
copy="$interface $(separate_list $copy)"
|
||||
fi
|
||||
copy_and_edit_table
|
||||
else
|
||||
copy_table
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "x$gateway" = xdetect ] ; then
|
||||
gateway='$gateway'
|
||||
indent >&3 << __EOF__
|
||||
gateway=\$(detect_gateway $interface)
|
||||
|
||||
if [ -n "\$gateway" ]; then
|
||||
run_ip route replace \$gateway src \$(find_first_interface_address $interface) dev $interface table $number
|
||||
run_ip route add default via \$gateway dev $interface table $number
|
||||
else
|
||||
fatal_error "Unable to detect the gateway through interface $interface"
|
||||
fi
|
||||
|
||||
__EOF__
|
||||
elif [ "x$gateway" != "x-" -a -n "$gateway" ]; then
|
||||
indent >&3 << __EOF__
|
||||
run_ip route replace $gateway src \$(find_first_interface_address $interface) dev $interface table $number
|
||||
run_ip route add default via $gateway dev $interface table $number
|
||||
__EOF__
|
||||
else
|
||||
gateway=
|
||||
save_command "run_ip route add default dev $interface table $number"
|
||||
fi
|
||||
|
||||
if [ x${mark} != x- ]; then
|
||||
verify_mark $mark
|
||||
|
||||
if [ $(($mark)) -lt 256 ]; then
|
||||
if [ -n "$HIGH_ROUTE_MARKS" ]; then
|
||||
fatal_error "Invalid Mark Value ($mark) with HIGH_ROUTE_MARKS=Yes"
|
||||
fi
|
||||
elif [ -z "$HIGH_ROUTE_MARKS" ]; then
|
||||
fatal_error "Invalid Mark Value ($mark) with HIGH_ROUTE_MARKS=No"
|
||||
fi
|
||||
|
||||
eval ${table}_mark=$mark
|
||||
|
||||
save_command "qt ip rule del fwmark $mark"
|
||||
save_command "run_ip rule add fwmark $mark pref $((10000 + $mark)) table $number"
|
||||
fi
|
||||
|
||||
loose=
|
||||
|
||||
for option in $(separate_list $options); do
|
||||
case $option in
|
||||
-)
|
||||
;;
|
||||
track)
|
||||
list_search $interface $ROUTEMARK_INTERFACES && \
|
||||
fatal_error "Interface $interface is tracked through an earlier provider"
|
||||
[ x${mark} = x- ] && fatal_error "The 'track' option requires a numeric value in the MARK column - Provider \"$provider\""
|
||||
eval ${iface}_routemark=$mark
|
||||
ROUTEMARK_INTERFACES="$ROUTEMARK_INTERFACES $interface"
|
||||
;;
|
||||
balance=*)
|
||||
balance_default_route ${option#*=}
|
||||
;;
|
||||
balance)
|
||||
balance_default_route 1
|
||||
;;
|
||||
loose)
|
||||
loose=Yes
|
||||
;;
|
||||
optional)
|
||||
optional=Yes
|
||||
;;
|
||||
*)
|
||||
error_message "WARNING: Invalid option ($option) ignored in provider \"$provider\""
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
rulenum=0
|
||||
|
||||
if [ -z "$loose" ]; then
|
||||
rulebase=$(( 20000 + ( 256 * ($number-1) ) ))
|
||||
indent >&3 << __EOF__
|
||||
|
||||
rulenum=0
|
||||
|
||||
find_interface_addresses $interface | while read address; do
|
||||
qt ip rule del from \$address
|
||||
run_ip rule add from \$address pref \$(( $rulebase + \$rulenum )) table $number
|
||||
rulenum=\$((\$rulenum + 1))
|
||||
done
|
||||
__EOF__
|
||||
else
|
||||
indent >&3 << __EOF__
|
||||
|
||||
find_interface_addresses $interface | while read address; do
|
||||
qt ip rule del from \$address
|
||||
done
|
||||
__EOF__
|
||||
fi
|
||||
|
||||
indent >&3 << __EOF__
|
||||
|
||||
progress_message " Provider $table ($number) Added"
|
||||
|
||||
__EOF__
|
||||
|
||||
INDENT="$save_indent1"
|
||||
save_command else
|
||||
|
||||
if [ -n "$optional" ]; then
|
||||
save_command " error_message \"WARNING: Interface $interface is not configured -- Provider $table ($number) not Added\""
|
||||
save_command " ${iface}_up="
|
||||
else
|
||||
save_command " fatal_error \"ERROR: Interface $interface is not configured -- Provider $table ($number) Cannot be Added\""
|
||||
fi
|
||||
|
||||
save_command fi
|
||||
save_command
|
||||
|
||||
}
|
||||
|
||||
verify_provider()
|
||||
{
|
||||
local p n
|
||||
|
||||
for p in $PROVIDERS main; do
|
||||
[ "$p" = "$1" ] && return 0
|
||||
eval n=\$${p}_number}
|
||||
[ "$n" = "$1" ] && return 0
|
||||
done
|
||||
|
||||
fatal_error "Unknown provider $1 in route rule \"$rule\""
|
||||
}
|
||||
|
||||
add_an_rtrule()
|
||||
{
|
||||
verify_provider $provider
|
||||
|
||||
[ "x$source" = x- ] && source=
|
||||
[ "x$dest" = x- ] && dest= || dest="to $dest"
|
||||
|
||||
[ -n "${source}${dest}" ] || fatal_error "You must specify either the source or destination in an rt rule: \"$rule\""
|
||||
|
||||
[ -n "$source" ] && case $source in
|
||||
*:*)
|
||||
source="iif ${source%:*} from ${source#*:}"
|
||||
;;
|
||||
*.*.*)
|
||||
source="from $source"
|
||||
;;
|
||||
*)
|
||||
source="iif $source"
|
||||
;;
|
||||
esac
|
||||
|
||||
case "$priority" in
|
||||
[0-9][0-9][0-9][0-9]|[0-9][0-9][0-9][0-9][0-9])
|
||||
;;
|
||||
*)
|
||||
fatal_error "Invalid priority ($priority) in rule \"$rule\""
|
||||
;;
|
||||
esac
|
||||
|
||||
priority="priority $priority"
|
||||
|
||||
save_command "qt ip rule del $source $dest $priority"
|
||||
save_command "run_ip rule add $source $dest $priority table $provider"
|
||||
|
||||
progress_message "Routing rule \"$rule\" $DONE"
|
||||
}
|
||||
|
||||
local_number=255
|
||||
main_number=254
|
||||
default_number=253
|
||||
unspec_number=0
|
||||
|
||||
strip_file providers $1
|
||||
|
||||
if [ -s $TMP_DIR/providers ]; then
|
||||
balance=
|
||||
|
||||
progress_message2 "$DOING $1..."
|
||||
save_command
|
||||
save_command "if [ -z \"\$NOROUTES\" ]; then"
|
||||
INDENT="$INDENT "
|
||||
save_progress_message "Adding Providers..."
|
||||
save_command "DEFAULT_ROUTE="
|
||||
|
||||
while read table number mark duplicate interface gateway options copy; do
|
||||
expandv table number mark duplicate interface gateway options copy
|
||||
provider="$table $number $mark $duplicate $interface $gateway $options $copy"
|
||||
add_a_provider
|
||||
PROVIDERS="$PROVIDERS $table"
|
||||
progress_message "Provider $provider $DONE"
|
||||
done < $TMP_DIR/providers
|
||||
|
||||
if [ -n "$PROVIDERS" ]; then
|
||||
if [ -n "$balance" ]; then
|
||||
save_command "if [ -n \"\$DEFAULT_ROUTE\" ]; then"
|
||||
save_command " run_ip route replace default scope global \$DEFAULT_ROUTE"
|
||||
save_command " progress_message \"Default route '\$(echo \$DEFAULT_ROUTE | sed 's/\$\\s*//')' Added\""
|
||||
save_command "else"
|
||||
save_command " error_message \"WARNING: No Default route added (all 'balance' providers are down)\""
|
||||
save_command "fi"
|
||||
save_command
|
||||
fi
|
||||
|
||||
cat >&3 << __EOF__
|
||||
${INDENT}cat > /etc/iproute2/rt_tables <<EOF
|
||||
#
|
||||
# reserved values
|
||||
#
|
||||
255 local
|
||||
254 main
|
||||
253 default
|
||||
0 unspec
|
||||
#
|
||||
# local
|
||||
#
|
||||
EOF
|
||||
__EOF__
|
||||
for table in $PROVIDERS; do
|
||||
eval number=\$${table}_number
|
||||
indent >&3 << __EOF__
|
||||
\${echobin:-echo} -e "$number\t$table" >> /etc/iproute2/rt_tables
|
||||
__EOF__
|
||||
done
|
||||
|
||||
f=$(find_file route_rules)
|
||||
|
||||
if [ -f $f ]; then
|
||||
strip_file route_rules $f
|
||||
|
||||
if [ -s $TMP_DIR/route_rules ]; then
|
||||
progress_message2 "$DOING $f..."
|
||||
|
||||
save_command
|
||||
|
||||
while read source dest provider priority; do
|
||||
expandv source dest provider priority
|
||||
rule="$source $dest $priority $provider"
|
||||
add_an_rtrule
|
||||
done < $TMP_DIR/route_rules
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
save_command "run_ip route flush cache"
|
||||
INDENT="$save_indent"
|
||||
save_command "fi"
|
||||
save_command
|
||||
fi
|
||||
}
|
||||
|
||||
#
|
||||
# validate the policy file
|
||||
#
|
||||
@ -2261,8 +1902,7 @@ setup_tc1() {
|
||||
append_file $TC_SCRIPT
|
||||
elif [ -n "$TC_ENABLED" ]; then
|
||||
strip_file_and_lib_load tcdevices tc
|
||||
strip_file_and_lib_load tcclasses tc
|
||||
setup_traffic_shaping
|
||||
strip_file_and_lib_load tcclasses tc && setup_traffic_shaping
|
||||
fi
|
||||
}
|
||||
|
||||
@ -2397,235 +2037,6 @@ compile_refresh_firewall()
|
||||
|
||||
}
|
||||
|
||||
#
|
||||
# Process a record from the accounting file
|
||||
#
|
||||
process_accounting_rule() {
|
||||
rule=
|
||||
rule2=
|
||||
jumpchain=
|
||||
user1=
|
||||
|
||||
accounting_error() {
|
||||
error_message "WARNING: Invalid Accounting rule" $action $chain $source $dest $proto $port $sport $user
|
||||
}
|
||||
|
||||
accounting_interface_error() {
|
||||
error_message "WARNING: Unknown interface $1 in " $action $chain $source $dest $proto $port $sport $user
|
||||
}
|
||||
|
||||
accounting_interface_verify() {
|
||||
verify_interface $1 || accounting_interface_error $1
|
||||
}
|
||||
|
||||
jump_to_chain() {
|
||||
if ! havechain $jumpchain; then
|
||||
if ! createchain2 $jumpchain No; then
|
||||
accounting_error
|
||||
return 2
|
||||
fi
|
||||
fi
|
||||
|
||||
rule="$rule -j $jumpchain"
|
||||
}
|
||||
|
||||
do_ipp2p() {
|
||||
[ -n "$IPP2P_MATCH" ] || fatal_error "Your kernel and/or iptables does not have IPP2P match support"
|
||||
case $proto in
|
||||
*:*)
|
||||
proto=${proto#*:}
|
||||
;;
|
||||
*)
|
||||
proto=tcp
|
||||
;;
|
||||
esac
|
||||
|
||||
rule="$rule -p $proto -m ipp2p --${port:-ipp2p}"
|
||||
}
|
||||
|
||||
case $source in
|
||||
*:*)
|
||||
accounting_interface_verify ${source%:*}
|
||||
rule="$(source_ip_range ${source#*:}) $(match_source_dev ${source%:*})"
|
||||
;;
|
||||
*.*.*.*|+*|!+*)
|
||||
rule="$(source_ip_range $source)"
|
||||
;;
|
||||
-|all|any)
|
||||
;;
|
||||
*)
|
||||
if [ -n "$source" ]; then
|
||||
accounting_interface_verify $source
|
||||
rule="$(match_source_dev $source)"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
[ -n "$dest" ] && case $dest in
|
||||
*:*)
|
||||
accounting_interface_verify ${dest%:*}
|
||||
rule="$rule $(dest_ip_range ${dest#*:}) $(match_dest_dev ${dest%:*})"
|
||||
;;
|
||||
*.*.*.*|+*|!*)
|
||||
rule="$rule $(dest_ip_range $dest)"
|
||||
;;
|
||||
-|all|any)
|
||||
;;
|
||||
*)
|
||||
accounting_interface_verify $dest
|
||||
rule="$rule $(match_dest_dev $dest)"
|
||||
;;
|
||||
esac
|
||||
|
||||
[ -n "$proto" ] && case $proto in
|
||||
-|any|all)
|
||||
;;
|
||||
ipp2p|IPP2P|ipp2p:*|IPP2P:*)
|
||||
do_ipp2p
|
||||
;;
|
||||
*)
|
||||
rule="$rule -p $proto"
|
||||
;;
|
||||
esac
|
||||
|
||||
multiport=
|
||||
|
||||
[ -n "$port" ] && case $port in
|
||||
-|any|all)
|
||||
;;
|
||||
*)
|
||||
if [ -n "$MULTIPORT" ]; then
|
||||
rule="$rule -m multiport --dports $port"
|
||||
multiport=Yes
|
||||
else
|
||||
rule="$rule --dport $port"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
[ -n "$sport" ] && case $sport in
|
||||
-|any|all)
|
||||
;;
|
||||
*)
|
||||
if [ -n "$MULTIPORT" ]; then
|
||||
[ -n "$multiport" ] && rule="$rule --sports $sport" || rule="$rule -m multiport --sports $sport"
|
||||
else
|
||||
rule="$rule --sport $sport"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
[ -n "$user" ] && case $user in
|
||||
-|any|all)
|
||||
;;
|
||||
*)
|
||||
[ "$chain" != OUTPUT ] && \
|
||||
fatal_error "Invalid use of a user/group: chain is not OUTPUT but $chain"
|
||||
rule="$rule -m owner"
|
||||
user1="$user"
|
||||
|
||||
case "$user" in
|
||||
!*+*)
|
||||
if [ -n "${user#*+}" ]; then
|
||||
rule="$rule ! --cmd-owner ${user#*+} "
|
||||
fi
|
||||
user1=${user%+*}
|
||||
;;
|
||||
*+*)
|
||||
if [ -n "${user#*+}" ]; then
|
||||
rule="$rule --cmd-owner ${user#*+} "
|
||||
fi
|
||||
user1=${user%+*}
|
||||
;;
|
||||
esac
|
||||
|
||||
case "$user1" in
|
||||
!*:*)
|
||||
if [ "$user1" != "!:" ]; then
|
||||
temp="${user1#!}"
|
||||
temp="${temp%:*}"
|
||||
[ -n "$temp" ] && rule="$rule ! --uid-owner $temp "
|
||||
temp="${user1#*:}"
|
||||
[ -n "$temp" ] && rule="$rule ! --gid-owner $temp "
|
||||
fi
|
||||
;;
|
||||
*:*)
|
||||
if [ "$user1" != ":" ]; then
|
||||
temp="${user1%:*}"
|
||||
[ -n "$temp" ] && rule="$rule --uid-owner $temp "
|
||||
temp="${user1#*:}"
|
||||
[ -n "$temp" ] && rule="$rule --gid-owner $temp "
|
||||
fi
|
||||
;;
|
||||
!*)
|
||||
[ "$user1" != "!" ] && rule="$rule ! --uid-owner ${user1#!} "
|
||||
;;
|
||||
*)
|
||||
[ -n "$user1" ] && rule="$rule --uid-owner $user1 "
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
||||
case $action in
|
||||
COUNT)
|
||||
;;
|
||||
DONE)
|
||||
rule="$rule -j RETURN"
|
||||
;;
|
||||
*:COUNT)
|
||||
rule2="$rule"
|
||||
jumpchain=${action%:*}
|
||||
jump_to_chain || return
|
||||
;;
|
||||
JUMP:*)
|
||||
jumpchain=${action#*:}
|
||||
jump_to_chain || return
|
||||
;;
|
||||
*)
|
||||
jumpchain=$action
|
||||
jump_to_chain || return
|
||||
;;
|
||||
esac
|
||||
|
||||
[ "x${chain:=accounting}" = "x-" ] && chain=accounting
|
||||
|
||||
ensurechain1 $chain
|
||||
|
||||
if do_iptables -A $chain $(fix_bang $rule) ; then
|
||||
[ -n "$rule2" ] && run_iptables2 -A $jumpchain $rule2
|
||||
progress_message " Accounting rule \"$action $chain $source $dest $proto $port $sport $user\" $DONE"
|
||||
save_progress_message_short " Accounting rule \\\"$action $chain $source $dest $proto $port $sport $user\\\" Added"
|
||||
else
|
||||
accounting_error
|
||||
fi
|
||||
}
|
||||
|
||||
#
|
||||
# Set up Accounting
|
||||
#
|
||||
setup_accounting() # $1 = Name of accounting file
|
||||
{
|
||||
|
||||
progress_message2 "$DOING Accounting..."
|
||||
|
||||
save_progress_message "Setting up Accounting..."
|
||||
|
||||
strip_file accounting $1
|
||||
|
||||
while read action chain source dest proto port sport user ; do
|
||||
expandv action chain source dest proto port sport user
|
||||
process_accounting_rule
|
||||
done < $TMP_DIR/accounting
|
||||
|
||||
if havechain accounting; then
|
||||
for chain in INPUT FORWARD OUTPUT; do
|
||||
run_iptables -I $chain -j accounting
|
||||
done
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
#
|
||||
# Add one Filter Rule from an action -- Helper function for the action file processor
|
||||
#
|
||||
@ -5469,40 +4880,6 @@ rules_chain() # $1 = source zone, $2 = destination zone
|
||||
fi
|
||||
}
|
||||
|
||||
#
|
||||
# Set up Routing
|
||||
#
|
||||
setup_routes()
|
||||
{
|
||||
local mask=0xFF mark_op="--set-mark" save_indent="$INDENT"
|
||||
|
||||
[ -n "$HIGH_ROUTE_MARKS" ] && mask=0xFF00 && mark_op="--or-mark"
|
||||
|
||||
run_iptables -t mangle -A PREROUTING -m connmark ! --mark 0/$mask -j CONNMARK --restore-mark --mask $mask
|
||||
run_iptables -t mangle -A OUTPUT -m connmark ! --mark 0/$mask -j CONNMARK --restore-mark --mask $mask
|
||||
createmanglechain routemark
|
||||
|
||||
if [ -n "$ROUTEMARK_INTERFACES" ]; then
|
||||
for interface in $ROUTEMARK_INTERFACES ; do
|
||||
iface=$(chain_base $interface)
|
||||
eval mark_value=\$${iface}_routemark
|
||||
|
||||
save_command
|
||||
save_command "if [ -n \"\$${iface}_up\" ]; then"
|
||||
INDENT="$INDENT "
|
||||
run_iptables -t mangle -A PREROUTING -i $interface -m mark --mark 0/$mask -j routemark
|
||||
run_iptables -t mangle -A routemark -i $interface -j MARK $mark_op $mark_value
|
||||
INDENT="$save_indent"
|
||||
save_command "fi"
|
||||
done
|
||||
|
||||
save_command
|
||||
fi
|
||||
|
||||
run_iptables -t mangle -A routemark -m mark ! --mark 0/$mask -j CONNMARK --save-mark --mask $mask
|
||||
|
||||
}
|
||||
|
||||
#
|
||||
# Set up Source NAT (including masquerading)
|
||||
#
|
||||
@ -6303,10 +5680,8 @@ initialize_netfilter () {
|
||||
run_iptables -A $chain -p udp --dport 53 -j ACCEPT
|
||||
done
|
||||
|
||||
accounting_file=$(find_file accounting)
|
||||
|
||||
[ -f $accounting_file ] && setup_accounting $accounting_file
|
||||
|
||||
strip_file_and_lib_load accounting accounting && setup_accounting $(find_file accounting)
|
||||
|
||||
createchain reject no
|
||||
createchain dynamic no
|
||||
createchain logdrop no
|
||||
@ -7800,8 +7175,10 @@ __EOF__
|
||||
#
|
||||
# [re]-Establish routing
|
||||
#
|
||||
setup_providers $(find_file providers)
|
||||
[ -n "$ROUTEMARK_INTERFACES" ] && setup_routes
|
||||
if strip_file_and_lib_load providers providers; then
|
||||
setup_providers $(find_file providers)
|
||||
[ -n "$ROUTEMARK_INTERFACES" ] && setup_routes
|
||||
fi
|
||||
|
||||
progress_message2 "$DOING NAT..."; setup_nat
|
||||
progress_message2 "$DOING NETMAP..."; setup_netmap
|
||||
|
410
Shorewall/lib.providers
Normal file
410
Shorewall/lib.providers
Normal file
@ -0,0 +1,410 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Shorewall 3.2 -- /usr/share/shorewall/lib.providers
|
||||
#
|
||||
# This program is under GPL [http://www.gnu.org/copyleft/gpl.htm]
|
||||
#
|
||||
# (c) 1999,2000,2001,2002,2003,2004,2005,2006 - Tom Eastep (teastep@shorewall.net)
|
||||
#
|
||||
# Complete documentation is available at http://shorewall.net
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of Version 2 of the GNU General Public License
|
||||
# as published by the Free Software Foundation.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
|
||||
|
||||
#
|
||||
# Process the providers file
|
||||
#
|
||||
setup_providers()
|
||||
{
|
||||
local table number mark duplicate interface gateway options provider address copy route loose addresses rulenum rulebase echobin=$(mywhich echo) balance save_indent="$INDENT" mask= first=Yes save_indent1=
|
||||
|
||||
copy_table() {
|
||||
indent >&3 << __EOF__
|
||||
ip route show table $duplicate | while read net route; do
|
||||
case \$net in
|
||||
default|nexthop)
|
||||
;;
|
||||
*)
|
||||
run_ip route add table $number \$net \$route
|
||||
;;
|
||||
esac
|
||||
done
|
||||
__EOF__
|
||||
}
|
||||
|
||||
copy_and_edit_table() {
|
||||
indent >&3 << __EOF__
|
||||
ip route show table $duplicate | while read net route; do
|
||||
case \$net in
|
||||
default|nexthop)
|
||||
;;
|
||||
*)
|
||||
case \$(find_device \$route) in
|
||||
`echo $copy\) | sed 's/ /|/g'`
|
||||
run_ip route add table $number \$net \$route
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
__EOF__
|
||||
}
|
||||
|
||||
balance_default_route() # $1 = weight
|
||||
{
|
||||
balance=yes
|
||||
|
||||
save_command
|
||||
if [ -n "$first" ]; then
|
||||
if [ -n "$gateway" ] ; then
|
||||
save_command "DEFAULT_ROUTE=\"nexthop via $gateway dev $interface weight $1\""
|
||||
else
|
||||
save_command "DEFAULT_ROUTE=\"nexthop dev $interface weight $1\""
|
||||
fi
|
||||
|
||||
first=
|
||||
else
|
||||
if [ -n "$gateway" ] ; then
|
||||
save_command "DEFAULT_ROUTE=\"\$DEFAULT_ROUTE nexthop via $gateway dev $interface weight $1\""
|
||||
else
|
||||
save_command "DEFAULT_ROUTE=\"\$DEFAULT_ROUTE nexthop dev $interface weight $1\""
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
add_a_provider() {
|
||||
local t n iface option optional=
|
||||
|
||||
[ -n "$MANGLE_ENABLED" ] || fatal_error "Providers require mangle support in your kernel and iptables"
|
||||
|
||||
for t in $PROVIDERS local main default unspec; do
|
||||
if [ "$t" = "$table" ]; then
|
||||
fatal_error "Duplicate Provider: $table, provider: \"$provider\""
|
||||
fi
|
||||
|
||||
eval n=\$${t}_number
|
||||
#
|
||||
# The following is because the %$#@ shell doesn't accept hex numbers in '-eq' tests
|
||||
#
|
||||
if [ $(($n)) -eq $(($number)) ]; then
|
||||
fatal_error "Duplicate Provider number: $number, provider: \"$provider\""
|
||||
fi
|
||||
done
|
||||
|
||||
eval ${table}_number=$number
|
||||
|
||||
indent >&3 << __EOF__
|
||||
#
|
||||
# Add Provider $table ($number)
|
||||
#
|
||||
__EOF__
|
||||
save_command "if interface_is_up $interface && [ \"\$(find_first_interface_address_if_any $interface)\" != 0.0.0.0 ]; then"
|
||||
save_indent1="$INDENT"
|
||||
INDENT="$INDENT "
|
||||
|
||||
iface=$(chain_base $interface)
|
||||
|
||||
save_command "${iface}_up=Yes"
|
||||
|
||||
save_command "qt ip route flush table $number"
|
||||
|
||||
if [ "x${duplicate:=-}" != x- ]; then
|
||||
if [ "x${copy:=-}" != "x-" ]; then
|
||||
if [ "x${copy}" = xnone ]; then
|
||||
copy=$interface
|
||||
else
|
||||
copy="$interface $(separate_list $copy)"
|
||||
fi
|
||||
copy_and_edit_table
|
||||
else
|
||||
copy_table
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "x$gateway" = xdetect ] ; then
|
||||
gateway='$gateway'
|
||||
indent >&3 << __EOF__
|
||||
gateway=\$(detect_gateway $interface)
|
||||
|
||||
if [ -n "\$gateway" ]; then
|
||||
run_ip route replace \$gateway src \$(find_first_interface_address $interface) dev $interface table $number
|
||||
run_ip route add default via \$gateway dev $interface table $number
|
||||
else
|
||||
fatal_error "Unable to detect the gateway through interface $interface"
|
||||
fi
|
||||
|
||||
__EOF__
|
||||
elif [ "x$gateway" != "x-" -a -n "$gateway" ]; then
|
||||
indent >&3 << __EOF__
|
||||
run_ip route replace $gateway src \$(find_first_interface_address $interface) dev $interface table $number
|
||||
run_ip route add default via $gateway dev $interface table $number
|
||||
__EOF__
|
||||
else
|
||||
gateway=
|
||||
save_command "run_ip route add default dev $interface table $number"
|
||||
fi
|
||||
|
||||
if [ x${mark} != x- ]; then
|
||||
verify_mark $mark
|
||||
|
||||
if [ $(($mark)) -lt 256 ]; then
|
||||
if [ -n "$HIGH_ROUTE_MARKS" ]; then
|
||||
fatal_error "Invalid Mark Value ($mark) with HIGH_ROUTE_MARKS=Yes"
|
||||
fi
|
||||
elif [ -z "$HIGH_ROUTE_MARKS" ]; then
|
||||
fatal_error "Invalid Mark Value ($mark) with HIGH_ROUTE_MARKS=No"
|
||||
fi
|
||||
|
||||
eval ${table}_mark=$mark
|
||||
|
||||
save_command "qt ip rule del fwmark $mark"
|
||||
save_command "run_ip rule add fwmark $mark pref $((10000 + $mark)) table $number"
|
||||
fi
|
||||
|
||||
loose=
|
||||
|
||||
for option in $(separate_list $options); do
|
||||
case $option in
|
||||
-)
|
||||
;;
|
||||
track)
|
||||
list_search $interface $ROUTEMARK_INTERFACES && \
|
||||
fatal_error "Interface $interface is tracked through an earlier provider"
|
||||
[ x${mark} = x- ] && fatal_error "The 'track' option requires a numeric value in the MARK column - Provider \"$provider\""
|
||||
eval ${iface}_routemark=$mark
|
||||
ROUTEMARK_INTERFACES="$ROUTEMARK_INTERFACES $interface"
|
||||
;;
|
||||
balance=*)
|
||||
balance_default_route ${option#*=}
|
||||
;;
|
||||
balance)
|
||||
balance_default_route 1
|
||||
;;
|
||||
loose)
|
||||
loose=Yes
|
||||
;;
|
||||
optional)
|
||||
optional=Yes
|
||||
;;
|
||||
*)
|
||||
error_message "WARNING: Invalid option ($option) ignored in provider \"$provider\""
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
rulenum=0
|
||||
|
||||
if [ -z "$loose" ]; then
|
||||
rulebase=$(( 20000 + ( 256 * ($number-1) ) ))
|
||||
indent >&3 << __EOF__
|
||||
|
||||
rulenum=0
|
||||
|
||||
find_interface_addresses $interface | while read address; do
|
||||
qt ip rule del from \$address
|
||||
run_ip rule add from \$address pref \$(( $rulebase + \$rulenum )) table $number
|
||||
rulenum=\$((\$rulenum + 1))
|
||||
done
|
||||
__EOF__
|
||||
else
|
||||
indent >&3 << __EOF__
|
||||
|
||||
find_interface_addresses $interface | while read address; do
|
||||
qt ip rule del from \$address
|
||||
done
|
||||
__EOF__
|
||||
fi
|
||||
|
||||
indent >&3 << __EOF__
|
||||
|
||||
progress_message " Provider $table ($number) Added"
|
||||
|
||||
__EOF__
|
||||
|
||||
INDENT="$save_indent1"
|
||||
save_command else
|
||||
|
||||
if [ -n "$optional" ]; then
|
||||
save_command " error_message \"WARNING: Interface $interface is not configured -- Provider $table ($number) not Added\""
|
||||
save_command " ${iface}_up="
|
||||
else
|
||||
save_command " fatal_error \"ERROR: Interface $interface is not configured -- Provider $table ($number) Cannot be Added\""
|
||||
fi
|
||||
|
||||
save_command fi
|
||||
save_command
|
||||
|
||||
}
|
||||
|
||||
verify_provider()
|
||||
{
|
||||
local p n
|
||||
|
||||
for p in $PROVIDERS main; do
|
||||
[ "$p" = "$1" ] && return 0
|
||||
eval n=\$${p}_number}
|
||||
[ "$n" = "$1" ] && return 0
|
||||
done
|
||||
|
||||
fatal_error "Unknown provider $1 in route rule \"$rule\""
|
||||
}
|
||||
|
||||
add_an_rtrule()
|
||||
{
|
||||
verify_provider $provider
|
||||
|
||||
[ "x$source" = x- ] && source=
|
||||
[ "x$dest" = x- ] && dest= || dest="to $dest"
|
||||
|
||||
[ -n "${source}${dest}" ] || fatal_error "You must specify either the source or destination in an rt rule: \"$rule\""
|
||||
|
||||
[ -n "$source" ] && case $source in
|
||||
*:*)
|
||||
source="iif ${source%:*} from ${source#*:}"
|
||||
;;
|
||||
*.*.*)
|
||||
source="from $source"
|
||||
;;
|
||||
*)
|
||||
source="iif $source"
|
||||
;;
|
||||
esac
|
||||
|
||||
case "$priority" in
|
||||
[0-9][0-9][0-9][0-9]|[0-9][0-9][0-9][0-9][0-9])
|
||||
;;
|
||||
*)
|
||||
fatal_error "Invalid priority ($priority) in rule \"$rule\""
|
||||
;;
|
||||
esac
|
||||
|
||||
priority="priority $priority"
|
||||
|
||||
save_command "qt ip rule del $source $dest $priority"
|
||||
save_command "run_ip rule add $source $dest $priority table $provider"
|
||||
|
||||
progress_message "Routing rule \"$rule\" $DONE"
|
||||
}
|
||||
|
||||
local_number=255
|
||||
main_number=254
|
||||
default_number=253
|
||||
unspec_number=0
|
||||
balance=
|
||||
|
||||
progress_message2 "$DOING $1..."
|
||||
save_command
|
||||
save_command "if [ -z \"\$NOROUTES\" ]; then"
|
||||
INDENT="$INDENT "
|
||||
save_progress_message "Adding Providers..."
|
||||
save_command "DEFAULT_ROUTE="
|
||||
|
||||
while read table number mark duplicate interface gateway options copy; do
|
||||
expandv table number mark duplicate interface gateway options copy
|
||||
provider="$table $number $mark $duplicate $interface $gateway $options $copy"
|
||||
add_a_provider
|
||||
PROVIDERS="$PROVIDERS $table"
|
||||
progress_message "Provider $provider $DONE"
|
||||
done < $TMP_DIR/providers
|
||||
|
||||
if [ -n "$PROVIDERS" ]; then
|
||||
if [ -n "$balance" ]; then
|
||||
save_command "if [ -n \"\$DEFAULT_ROUTE\" ]; then"
|
||||
save_command " run_ip route replace default scope global \$DEFAULT_ROUTE"
|
||||
save_command " progress_message \"Default route '\$(echo \$DEFAULT_ROUTE | sed 's/\$\\s*//')' Added\""
|
||||
save_command "else"
|
||||
save_command " error_message \"WARNING: No Default route added (all 'balance' providers are down)\""
|
||||
save_command "fi"
|
||||
save_command
|
||||
fi
|
||||
|
||||
cat >&3 << __EOF__
|
||||
${INDENT}cat > /etc/iproute2/rt_tables <<EOF
|
||||
#
|
||||
# reserved values
|
||||
#
|
||||
255 local
|
||||
254 main
|
||||
253 default
|
||||
0 unspec
|
||||
#
|
||||
# local
|
||||
#
|
||||
EOF
|
||||
__EOF__
|
||||
for table in $PROVIDERS; do
|
||||
eval number=\$${table}_number
|
||||
indent >&3 << __EOF__
|
||||
\${echobin:-echo} -e "$number\t$table" >> /etc/iproute2/rt_tables
|
||||
__EOF__
|
||||
done
|
||||
|
||||
f=$(find_file route_rules)
|
||||
|
||||
if [ -f $f ]; then
|
||||
strip_file route_rules $f
|
||||
|
||||
if [ -s $TMP_DIR/route_rules ]; then
|
||||
progress_message2 "$DOING $f..."
|
||||
|
||||
save_command
|
||||
|
||||
while read source dest provider priority; do
|
||||
expandv source dest provider priority
|
||||
rule="$source $dest $priority $provider"
|
||||
add_an_rtrule
|
||||
done < $TMP_DIR/route_rules
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
save_command "run_ip route flush cache"
|
||||
INDENT="$save_indent"
|
||||
save_command "fi"
|
||||
save_command
|
||||
}
|
||||
|
||||
#
|
||||
# Set up Routing
|
||||
#
|
||||
setup_routes()
|
||||
{
|
||||
local mask=0xFF mark_op="--set-mark" save_indent="$INDENT"
|
||||
|
||||
[ -n "$HIGH_ROUTE_MARKS" ] && mask=0xFF00 && mark_op="--or-mark"
|
||||
|
||||
run_iptables -t mangle -A PREROUTING -m connmark ! --mark 0/$mask -j CONNMARK --restore-mark --mask $mask
|
||||
run_iptables -t mangle -A OUTPUT -m connmark ! --mark 0/$mask -j CONNMARK --restore-mark --mask $mask
|
||||
createmanglechain routemark
|
||||
|
||||
if [ -n "$ROUTEMARK_INTERFACES" ]; then
|
||||
for interface in $ROUTEMARK_INTERFACES ; do
|
||||
iface=$(chain_base $interface)
|
||||
eval mark_value=\$${iface}_routemark
|
||||
|
||||
save_command
|
||||
save_command "if [ -n \"\$${iface}_up\" ]; then"
|
||||
INDENT="$INDENT "
|
||||
run_iptables -t mangle -A PREROUTING -i $interface -m mark --mark 0/$mask -j routemark
|
||||
run_iptables -t mangle -A routemark -i $interface -j MARK $mark_op $mark_value
|
||||
INDENT="$save_indent"
|
||||
save_command "fi"
|
||||
done
|
||||
|
||||
save_command
|
||||
fi
|
||||
|
||||
run_iptables -t mangle -A routemark -m mark ! --mark 0/$mask -j CONNMARK --save-mark --mask $mask
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user