Transparently route a public subnet through shorewall

The is routed to a firewall running shorewall. Behind the firewall is an OpenStack cluster running a neutron l3 agent and known to the firewall as A parallel zone is defined as follows:

diff -r 34984beb770d hosts
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/hosts     Wed Nov 20 14:59:09 2013 +0100
@@ -0,0 +1,1 @@
+opens  eth0:
diff -r 34984beb770d policy
--- a/policy    Wed Jun 05 00:19:12 2013 +0200
+++ b/policy    Wed Nov 20 14:59:09 2013 +0100
@@ -113,6 +113,7 @@
 # If you want to force clients to access the Internet via a proxy server
 # on your firewall, change the loc to net policy to REJECT info.
 loc            net             ACCEPT
+loc            opens           ACCEPT
 loc            $FW             ACCEPT
 loc            all             REJECT          info

@@ -124,6 +125,7 @@
 # This may be useful if you run a proxy server on the firewall.
 #$FW           net             REJECT          info
 $FW            net             ACCEPT
+$FW            opens           ACCEPT
 $FW            loc             ACCEPT
 $FW            all             REJECT          info

@@ -132,6 +134,7 @@
 net            $FW             DROP            info
 net            loc             DROP            info
+net            opens           ACCEPT
 net            all             DROP            info

diff -r 34984beb770d zones
--- a/zones     Wed Jun 05 00:19:12 2013 +0200
+++ b/zones     Wed Nov 20 14:59:09 2013 +0100
@@ -115,5 +115,6 @@
 fw     firewall
 net    ipv4
 loc    ipv4
+opens  ipv4

and net incoming packets are accepted for the subnet when targeting the loc zone which contains the subnet:

ACCEPT          net             loc:

A route is added

ip r add via

A ping from the firewall will show on the destination interface

# tcpdump -i eth0 -n host
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
15:03:29.258592 IP > ICMP echo request, id 48701, seq 1, length 64

even if it timesout because the IP is not actually there

# ping -c 1
PING ( 56(84) bytes of data.
--- ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 0ms

The subnet must be excluded from the masquerading rules by setting /etc/shorewall/masq as follows:

eth1                    eth0!

which says to masquerade all but the subnet that is transparently routed. The result can then be checked from a virtual machine to which an IP has been routed with:

# wget --quiet -O - ; echo