###
### The mangle chains are arranged as follows.
###
-### The PREROUTING hook simply invokes in-classify and out-classify chains as
-### subroutines. These will tail-call appropriate classification chains.
+### The INPUT and FORWARD hooks simply invoke in-classify and out-classify
+### chains as subroutines. These will tail-call appropriate classification
+### chains.
###
### The in-classify chain is responsible for both source address
### classification and verifying that the packet arrived from the correct
### goes to bad-source-address, which logs a message and drops the packet.
### The default interface is special. If no explicit matches are found, it
### dispatches to in-default which forbids a few obviously evil things and
-### finally dispatches to mark-from-untrusted.
+### finally dispatches to mark-from-DEFAULT (usually `untrusted').
###
### The out-classify is simpler because it doesn't care about the interface.
### It simply checks each network range in turn, dispatching to mark-to-CLASS
-### on a match or mark-to-DEFAULT (probably untrusted) if there is no match.
+### on a match or mark-to-DEFAULT (probably `untrusted') if there is no
+### match.
clearchain mangle:in-classify mangle:in-default mangle:out-classify
clearchain mangle:local-source
## over the loopback interface, I shouldn't see a packet from me over any
## other interface. Except that I will if I sent a broadcast or multicast.
## Allow the broadcasts, and remember not to trust them. There are no
-## broadcast addresses in IPv6 (only link-local multicast)m so we don't have
+## broadcast addresses in IPv6 (only link-local multicast) so we don't have
## to worry about that.
run iptables -t mangle -A local-source -j RETURN \
-m addrtype --dst-type BROADCAST
for entry in $ifmap; do
iface=${entry%=*} q=${entry##*=}
eval nets=\$ifnets_$q
- trace "iface $iface [$q] = $nets"
aa=!
for n in $nets; do
eval "addrs=\"\$net_inet_$n \$net_inet6_$n\""
done
eval ifaddrs_$q=\$aa
trace "iface $q = $iface; nets = $nets; addrs = $aa"
-trace "alladdrs = $alladdrs"
done
+trace "alladdrs = $alladdrs"
## Populate the `out-classify' chain, matching networks.
prepare_to () { mode=goto fail=mark-to-$net_class_default; }
-matchnets -d mark-from : prepare_to out-classify "" 0 $allnets
+matchnets -d mark-to : prepare_to out-classify "" 0 $allnets
## A `finish' hook for rejecting known address ranges arriving on a
## default-reachable interface.
## interfaces. We should match an address to a particular interface.
chains=""
for net in $nets; do
- eval hosts=\$net_hosts_$net
+ eval hosts=\$net_hosts_$net class=\$net_class_$net
for host in $hosts; do
eval ha=\$host_inet_$host ha6=\$host_inet6_$host
trace "$host : $class -> $iface"
done
## Fill in the black holes in the network. Some of these might actually be
-## known networks, so don't fill those in again.
+## known networks, so don't fill those in again. See RFC5735 and RFC4291,
+## and their successors.
for addr in \
10.0.0.0/8 172.16.0.0/12 192.168.0.0/16 \
127.0.0.0/8 \
done
for addr in \
fc00::/7 \
+ ::0:0/96 ::ffff:0:0/96 \
2001:db8::/32
do
case $alladdrs in *!$addr!*) continue ;; esac
m4_divert(92)m4_dnl
## Put the final default decision on the in-default chain, and attach the
-## classification chains to the PREROUTING hook.
+## classification chains to the INPUT and (maybe) FORWARD hooks.
for iface in $defaultifaces; do
run ip46tables -t mangle -A in-$iface -g in-default
done
-run ip46tables -t mangle -A PREROUTING -j in-classify
-run ip46tables -t mangle -A PREROUTING -j out-classify
+chains="INPUT"
+case $forward in 1) chains="$chains FORWARD" ;; esac
+for c in $chains; do
+ run ip46tables -t mangle -A $c -j in-classify
+ run ip46tables -t mangle -A $c -j out-classify
+done
## Incoming stuff to or from a link-local address is OK.
run ip46tables -t mangle -A INPUT \