forked from extern/shorewall_code
Add support for explicit routing rules
git-svn-id: https://shorewall.svn.sourceforge.net/svnroot/shorewall/trunk@3763 fbd18981-670d-0410-9b5c-8dc0c1a9a2bb
This commit is contained in:
parent
64cdda4888
commit
f39537bc90
@ -2,6 +2,8 @@ Changes in 3.2.0 Beta 4
|
||||
|
||||
1) Fix 'routeback' with bridge ports.
|
||||
|
||||
2) Add support for explicit routing rules.
|
||||
|
||||
Changes in 3.2.0 Beta 3
|
||||
|
||||
1) Correct handling of verbosity in the 'try' command.
|
||||
|
@ -693,14 +693,14 @@ get_set_flags() # $1 = set name and optional [levels], $2 = src or dst
|
||||
{
|
||||
#
|
||||
# Note: There is a lot of unnecessary evaluation in this function just so my text
|
||||
# editor doesn't get lost trying to follow the shell syntax for highlighting.
|
||||
# editor (kate) doesn't get lost trying to follow the shell syntax for highlighting.
|
||||
#
|
||||
local temp setname=$1 options=$2 firstcase='*\[[1-6]\]' secondcase='*\[*\]'
|
||||
local temp setname=$1 options=$2
|
||||
|
||||
[ -n "$IPSET_MATCH" ] || fatal_error "Your kernel and/or iptables does not include ipset match: $1"
|
||||
|
||||
case $1 in
|
||||
$firstcase)
|
||||
*\[[1-6]\])
|
||||
eval temp='${1#*\[}'
|
||||
eval temp='${temp%\]}'
|
||||
eval setname='${1%\[*}'
|
||||
@ -709,7 +709,7 @@ get_set_flags() # $1 = set name and optional [levels], $2 = src or dst
|
||||
temp=$(($temp - 1))
|
||||
done
|
||||
;;
|
||||
$secondcase)
|
||||
*\[*\])
|
||||
eval options='${1#*\[}'
|
||||
eval options='${options%\]}'
|
||||
eval setname='${1%\[*}'
|
||||
@ -1270,7 +1270,7 @@ rulenum=0
|
||||
|
||||
find_interface_addresses $interface | while read address; do
|
||||
qt ip rule del from \$address
|
||||
pref=\$((20000 + \$rulenum * 1000 + $number ))
|
||||
pref=\$((20000 + ($number - 1) * 256 + \$rulenum ))
|
||||
rulenum=\$((\$rulenum + 1))
|
||||
run_ip rule add from \$address pref \$pref table $number
|
||||
done
|
||||
@ -1287,6 +1287,56 @@ __EOF__
|
||||
fi
|
||||
}
|
||||
|
||||
verify_provider()
|
||||
{
|
||||
local p n
|
||||
|
||||
for p in $PROVIDERS; do
|
||||
[ "$p" = "$1" ] && return 0
|
||||
eval n=\$${p}_number}
|
||||
[ "$n" = "$1" ] && return 0
|
||||
done
|
||||
|
||||
fatal_error "Unknown provider $1 in rtrule \"$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"
|
||||
}
|
||||
|
||||
strip_file providers $1
|
||||
|
||||
if [ -s $TMP_DIR/providers ]; then
|
||||
@ -1333,6 +1383,20 @@ __EOF__
|
||||
\${echobin:-echo} -e "$number\t$table" >> /etc/iproute2/rt_tables
|
||||
__EOF__
|
||||
done
|
||||
|
||||
f=$(find_file rtrules)
|
||||
|
||||
if [ -f $f ]; then
|
||||
progress_message2 "$DOING $f..."
|
||||
|
||||
strip_file rtrules $f
|
||||
|
||||
while read provider priority source dest; do
|
||||
expandv priority provider source dest
|
||||
rule="$priority $provider $source $dest"
|
||||
add_an_rtrule
|
||||
done < $TMP_DIR/rtrules
|
||||
fi
|
||||
fi
|
||||
|
||||
save_command "run_ip route flush cache"
|
||||
@ -3113,6 +3177,11 @@ process_tc_rule()
|
||||
[ $chain = tcpost ] || chain=tcout
|
||||
r="$(source_ip_range ${source#*:}) "
|
||||
;;
|
||||
*:*)
|
||||
interface=${source%:*}
|
||||
verify_interface $interface || fatal_error "Unknown interface $interface in rule \"$rule\""
|
||||
r="$(match_source_dev $interface) $(source_ip_range ${source#*:}) "
|
||||
;;
|
||||
*.*.*|+*|!+*)
|
||||
r="$(source_ip_range $source) "
|
||||
;;
|
||||
@ -3160,11 +3229,17 @@ process_tc_rule()
|
||||
|
||||
if [ "x$dest" != "x-" ]; then
|
||||
case $dest in
|
||||
*:*)
|
||||
[ "$chain" = tcpre ] && fatal_error "Destination interface is not allowed in the PREROUTING chain - rule \"$rule\""
|
||||
interface=${dest%:*}
|
||||
verify_interface $interface || fatal_error "Unknown interface $interface in rule \"$rule\""
|
||||
r="$(match_dest_dev $interface) $(dest_ip_range ${dest#*:}) "
|
||||
;;
|
||||
*.*.*|+*|!+*)
|
||||
r="${r}$(dest_ip_range $dest) "
|
||||
;;
|
||||
*)
|
||||
[ "$chain" = tcpre ] && fatal_error "Destination interface is not allowed in the PREROUTING chain"
|
||||
[ "$chain" = tcpre ] && fatal_error "Destination interface is not allowed in the PREROUTING chain - rule \"$rule\""
|
||||
verify_interface $dest || fatal_error "Unknown interface $dest in rule \"$rule\""
|
||||
r="${r}$(match_dest_dev $dest) "
|
||||
;;
|
||||
|
@ -292,12 +292,12 @@ separate_list() {
|
||||
*\[*\]*)
|
||||
#
|
||||
# Where we need to embed comma-separated lists within lists, we enclose them
|
||||
# within square brackets
|
||||
# within square brackets (extra 'evals' are to keep my text editor (kate) from getting lost).
|
||||
#
|
||||
firstpart=${list%%\[*}
|
||||
lastpart=${list#*\[}
|
||||
enclosure=${lastpart%%\]*}
|
||||
lastpart=${lastpart#*\]}
|
||||
eval 'firstpart=${list%%\[*}'
|
||||
eval 'lastpart=${list#*\[}'
|
||||
eval 'enclosure=${lastpart%%\]*}'
|
||||
eval 'lastpart=${lastpart#*\]}'
|
||||
case $lastpart in
|
||||
\,*)
|
||||
case $firstpart in
|
||||
@ -593,10 +593,6 @@ strip_file() # $1 = Base Name of the file, $2 = Full Name of File (optional)
|
||||
# behavior when the shell only supports 32-bit signed arithmatic and
|
||||
# the IP address is 128.0.0.0 or 128.0.0.1.
|
||||
#
|
||||
#
|
||||
# So that emacs doesn't get lost, we use $LEFTSHIFT rather than <<
|
||||
#
|
||||
LEFTSHIFT='<<'
|
||||
|
||||
#
|
||||
# Convert an IP address in dot quad format to an integer
|
||||
@ -609,7 +605,7 @@ decodeaddr() {
|
||||
IFS=.
|
||||
|
||||
for x in $1; do
|
||||
temp=$(( $(( $temp $LEFTSHIFT 8 )) | $x ))
|
||||
temp=$(( $(( $temp << 8 )) | $x ))
|
||||
done
|
||||
|
||||
echo $temp
|
||||
@ -721,7 +717,7 @@ ip_range_explicit() {
|
||||
ip_netmask() {
|
||||
local vlsm=${1#*/}
|
||||
|
||||
[ $vlsm -eq 0 ] && echo 0 || echo $(( -1 $LEFTSHIFT $(( 32 - $vlsm )) ))
|
||||
[ $vlsm -eq 0 ] && echo 0 || echo $(( -1 << $(( 32 - $vlsm )) ))
|
||||
}
|
||||
|
||||
#
|
||||
@ -742,7 +738,7 @@ ip_network() {
|
||||
ip_broadcast() {
|
||||
local x=$(( 32 - ${1#*/} ))
|
||||
|
||||
[ $x -eq 0 ] && echo -1 || echo $(( $(( 1 $LEFTSHIFT $x )) - 1 ))
|
||||
[ $x -eq 0 ] && echo -1 || echo $(( $(( 1 << $x )) - 1 ))
|
||||
}
|
||||
|
||||
#
|
||||
@ -772,10 +768,10 @@ in_network() # $1 = IP address, $2 = CIDR network
|
||||
ip_vlsm() {
|
||||
local mask=$(decodeaddr $1)
|
||||
local vlsm=0
|
||||
local x=$(( 128 $LEFTSHIFT 24 )) # 0x80000000
|
||||
local x=$(( 128 << 24 )) # 0x80000000
|
||||
|
||||
while [ $(( $x & $mask )) -ne 0 ]; do
|
||||
[ $mask -eq $x ] && mask=0 || mask=$(( $mask $LEFTSHIFT 1 )) # Not all shells shift 0x80000000 left properly.
|
||||
[ $mask -eq $x ] && mask=0 || mask=$(( $mask << 1 )) # Not all shells shift 0x80000000 left properly.
|
||||
vlsm=$(($vlsm + 1))
|
||||
done
|
||||
|
||||
@ -838,7 +834,7 @@ if_match() # $1 = Name in interfaces file - may end in "+"
|
||||
#
|
||||
source_ip_range() # $1 = Address or Address Range
|
||||
{
|
||||
case $1 in
|
||||
[ $# -gt 0 ] && case $1 in
|
||||
*.*.*.*-*.*.*.*)
|
||||
case $1 in
|
||||
!*)
|
||||
@ -866,7 +862,7 @@ source_ip_range() # $1 = Address or Address Range
|
||||
#
|
||||
dest_ip_range() # $1 = Address or Address Range
|
||||
{
|
||||
case $1 in
|
||||
[ $# -gt 0 ] && case $1 in
|
||||
*.*.*.*-*.*.*.*)
|
||||
case $1 in
|
||||
!*)
|
||||
|
@ -38,7 +38,55 @@ Problems Corrected in 3.2.0 Beta 4
|
||||
|
||||
Other changes in 3.2.0 Beta 4
|
||||
|
||||
None.
|
||||
1) Shorewall now includes support for explicit routing rules when the
|
||||
/etc/shorewall/providers file is used. A new file, /etc/shorewall/rtrules
|
||||
can be used to add routing rules based on packet source and/or
|
||||
destination.
|
||||
|
||||
The file has the following columns:
|
||||
|
||||
PROVIDER The provider to route the traffic through.
|
||||
May be expressed either as the provider name
|
||||
or the provider number.
|
||||
|
||||
PRIORITY
|
||||
The rule's priority which determines the order
|
||||
in which the rules are processed.
|
||||
|
||||
1000-1999 Before Shorewall-generated
|
||||
'MARK' rules
|
||||
|
||||
11000- 11999 After 'MARK' rules but before
|
||||
Shorewall-generated rules for
|
||||
ISP interfaces.
|
||||
|
||||
26000-26999 After ISP interface rules but
|
||||
before 'default' rule.
|
||||
|
||||
Rules with equal priority are applied in
|
||||
the order in which they appear in the file.
|
||||
|
||||
SOURCE(optonal) An ip address (network or host) that
|
||||
matches the source IP address in a packet.
|
||||
May also be specified as an interface
|
||||
name optionally followed by ":" and an
|
||||
address. If the define 'lo' is specified,
|
||||
the packet must originate from the firewall
|
||||
itself.
|
||||
|
||||
DEST(optional) An ip address (network or host) that
|
||||
matches the destination IP address in a packet.
|
||||
|
||||
If you choose to omit either SOURCE or DEST,
|
||||
place "-" in that column (or you can simply
|
||||
leave the DEST column empty). Note that you
|
||||
may not omit both SOURCE and DEST.
|
||||
|
||||
Example: You want all traffic coming in on eth1 to be routed to the ISP1
|
||||
provider:
|
||||
|
||||
#PROVIDER PRIORITY SOURCE DEST
|
||||
ISP1 1000 eth1
|
||||
|
||||
Migration Considerations:
|
||||
|
||||
|
@ -84,10 +84,13 @@
|
||||
# SOURCE Source of the packet. A comma-separated list of
|
||||
# interface names, IP addresses, MAC addresses and/or
|
||||
# subnets for packets being routed through a common path.
|
||||
# For example, all packets for connections masqueraded
|
||||
# to eth0 from other interfaces can be matched in a
|
||||
# single rule with several alternative SOURCE criteria.
|
||||
# However, a connection whose packets gets to eth0 in a
|
||||
# List elements may also consist of an interface name
|
||||
# followed by ":" and an address
|
||||
# (e.g., eth1:192.168.1.0/24). For example, all packets
|
||||
# for connections masqueraded to eth0 from other
|
||||
# interfaces can be matched in a single rule with
|
||||
# several alternative SOURCE criteria. However, a
|
||||
# connection whose packets gets to eth0 in a
|
||||
# different way, e.g., direct from the firewall itself,
|
||||
# needs a different rule.
|
||||
#
|
||||
@ -105,8 +108,9 @@
|
||||
# DEST Destination of the packet. Comma separated list of
|
||||
# IP addresses and/or subnets. If your kernel and
|
||||
# iptables include iprange match support, IP address
|
||||
# ranges are also allowed.
|
||||
#
|
||||
# ranges are also allowed. List elements may also
|
||||
# consist of an interface name followed by ":" and an
|
||||
# address (e.g., eth1:192.168.1.0/24).
|
||||
# If the MARK column specificies a classification of
|
||||
# the form <major>:<minor> then this column may also
|
||||
# contain an interface name.
|
||||
|
Loading…
Reference in New Issue
Block a user