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:
teastep 2006-04-02 15:17:41 +00:00
parent 64cdda4888
commit f39537bc90
5 changed files with 154 additions and 29 deletions

View File

@ -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.

View File

@ -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) "
;;

View File

@ -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
!*)

View File

@ -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:

View File

@ -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.