<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
<article>
  <!--$Id$-->

  <articleinfo>
    <title>Issues when Upgrading to Shorewall 4.4 (Upgrading from Debian Lenny
    to Squeeze)</title>

    <authorgroup>
      <author>
        <firstname>Tom</firstname>

        <surname>Eastep</surname>
      </author>
    </authorgroup>

    <pubdate><?dbtimestamp format="Y/m/d"?></pubdate>

    <copyright>
      <year>2009</year>

      <year>2010</year>

      <holder>Thomas M. Eastep</holder>
    </copyright>

    <legalnotice>
      <para>Permission is granted to copy, distribute and/or modify this
      document under the terms of the GNU Free Documentation License, Version
      1.2 or any later version published by the Free Software Foundation; with
      no Invariant Sections, with no Front-Cover, and with no Back-Cover
      Texts. A copy of the license is included in the section entitled
      <quote><ulink url="GnuCopyright.htm">GNU Free Documentation
      License</ulink></quote>.</para>
    </legalnotice>
  </articleinfo>

  <section>
    <title>Introduction</title>

    <para>Debian Lenny includes Shorewall version 4.0.15 while Squeeze
    includes Shorewall 4.4. Because there are significant differences between
    the two product versions, some users may experience upgrade issues. This
    article outlines those issues and offers advice for dealing with
    them.</para>

    <note>
      <para>Although this article is targeted specifically at Lenny -&gt;
      Squeeze upgrades, it should be useful to any Shorewall-shell user
      upgrading to Shorewall 4.4.x. Footnotes are used to flag areas where
      non-Debian users may experience different results.</para>
    </note>
  </section>

  <section id="Packages">
    <title>Packaging Differences</title>

    <para>The first key difference between Shorewall 4.0 and Shorewall 4.4 is
    in the packaging<footnote>
        <para>Most distributions use a similar packaging structure. Note,
        however, that the 'shorewall' package in Simon Mater's RPMs for
        RedHat/Fedora/CentOS is like the Lenny shorewall-common
        package.</para>
      </footnote>. In Lenny, there are six Shorewall packages:</para>

    <orderedlist>
      <listitem>
        <para>shorewall-common — Contains the basic components needed to
        create an IPv4 firewall.</para>
      </listitem>

      <listitem>
        <para>shorewall-shell — The legacy Shorewall configuration compiler
        written in Bourne shell.</para>
      </listitem>

      <listitem>
        <para>shorewall — A transitional package that depends on
        shorewall-common and shorewall-shell. Installing this package installs
        both shorewall-common and shorewall-shell.</para>
      </listitem>

      <listitem>
        <para>shorewall-perl — A re-implementation of the Shorewall
        configuration compiler in Perl. This compiler has many advantages over
        the shell-based compiler:</para>

        <itemizedlist>
          <listitem>
            <para>The compiler is much faster</para>
          </listitem>

          <listitem>
            <para>The compiler does a much better job of validating the
            configuration, thus avoiding run-time errors.</para>
          </listitem>

          <listitem>
            <para>The compiler produces better and more consistent diagnostic
            messages.</para>
          </listitem>

          <listitem>
            <para>The compiler produces a script that runs much faster and
            that does not reject/drop connections during start/restart.</para>
          </listitem>
        </itemizedlist>
      </listitem>

      <listitem>
        <para>shorewall-lite — A small package that can run scripts generated
        by shorewall-shell or shorewall-perl. Allows centralized firewall
        administration.</para>
      </listitem>

      <listitem>
        <para>shorewall-doc — Documentation.</para>
      </listitem>
    </orderedlist>

    <para>In Squeeze, there are six slightly different packages:</para>

    <orderedlist>
      <listitem>
        <para>shorewall — Contains everything needed to create an IPv4
        firewall. It combines the former shorewall-common and shorewall-perl
        packages.</para>
      </listitem>

      <listitem>
        <para>shorewall6 — Depends on shorewall. Adds those components needed
        to create an IPv6 firewall.</para>
      </listitem>

      <listitem>
        <para>shorewall-lite — Same as in Lenny; only runs IPv4 firewall
        scripts.</para>
      </listitem>

      <listitem>
        <para>shorewall6-lite — Similar to shorewall-lite, except that it only
        runs IPv6 firewall scripts.</para>
      </listitem>

      <listitem>
        <para>shorewall-init — Allows the firewall to be closed before
        interfaces are brought up and also allows the firewall to react to
        interfaces coming up and going down.</para>
      </listitem>

      <listitem>
        <para>shorewall-doc — Documentation.</para>
      </listitem>
    </orderedlist>

    <warning>
      <para>Do not purge the old packages (shorewall-common, shorewall-shell
      and shorewall-perl) until after the new shorewall package has been
      installed.</para>
    </warning>

    <para>The key change in Squeeze that may produce upgrade issues is that
    Squeeze does not include the shell-based configuration compiler. As a
    consequence, unless you are already using Shorewall-perl on Lenny, an
    upgrade from Lenny to Squeeze will mean that you will be switching from
    the old shell-based compiler to the new Perl-based compiler<footnote>
        <para>Note that Perl is a required package on Debian. If you are
        running an embedded distribution which does not include Perl and it is
        not feasible to install Perl on your firewall, then you should
        consider installing Shorewall on another system in your network (may
        be a <trademark>Windows</trademark> system running
        <trademark>Cygwin</trademark> or an <trademark>Apple</trademark>
        <trademark>MacIntosh</trademark> running OS X) and installing
        Shorewall-lite on your firewall.</para>
      </footnote>. While the two compilers are highly compatible, there are
    some differences. Those differences are detailed in the following
    sections.</para>
  </section>

  <section id="Issues">
    <title>Issues Most Likely to Cause Problems or Concerns</title>

    <section id="conf">
      <title>shorewall.conf</title>

      <para>As always, when upgrading from one major release of Shorewall to
      another, the installer will prompt you about replacing your existing
      <filename>shorewall.conf</filename> with the updated one from the
      package. Shorewall is designed with the assumption that users will never
      replace shorewall.conf and retaining your existing file will always
      produce upward-compatible behavior.</para>

      <para>That having been said, there are a few settings that you may have
      in your shorewall.conf that will cause compilation warning or error
      messages after the upgrade.</para>

      <variablelist>
        <varlistentry>
          <term>BLACKLISTNEWONLY</term>

          <listitem>
            <para>If you have BLACKLISTNEWONLY=No together with
            FASTACCEPT=Yes, you will receive this error:</para>

            <para><emphasis role="bold">ERROR: BLACKLISTNEWONLY=No may not be
            specified with FASTACCEPT=Yes</emphasis></para>

            <para>To eliminate the error, reverse the setting of one of the
            options.</para>

            <note>
              <para>This combination never worked correctly in earlier
              versions -- to duplicate the earlier behavior, you will want to
              set BLACKLISTNEWONLY=Yes.</para>
            </note>
          </listitem>
        </varlistentry>

        <varlistentry>
          <term>BRIDGING</term>

          <listitem>
            <para>If you have set this option to Yes, you will receive the
            following error:</para>

            <para><emphasis role="bold">ERROR: BRIDGING=Yes is not supported
            by Shorewall 4.4.x</emphasis></para>

            <para>You should not be receiving this error if you are upgrading
            from Lenny since BRIDGING=Yes did not work in that release
            either<footnote>
                <para>If you are upgrading from a release using a kernel
                earlier than 2.6.20, then BRIDGING=Yes did work correctly with
                Shorewall-shell.</para>
              </footnote>. If you have a bridge configuration where you want
            to control connections through the bridge, you will want to visit
            <ulink
            url="http://www.shorewall.net/bridge-Shorewall-perl.html">http://www.shorewall.net/bridge-Shorewall-perl.html</ulink><footnote>
                <para>Kernel 2.6.20 or later is required.</para>
              </footnote>.</para>
          </listitem>
        </varlistentry>

        <varlistentry>
          <term>DELAYBLACKLISTLOAD</term>

          <listitem>
            <para>If you have set this option to Yes, you will receive the
            following warning:</para>

            <para><emphasis role="bold">WARNING: DELAYBLACKLIST=Yes is not
            supported by Shorewall 4.4.x</emphasis></para>

            <para>To eliminate the warning, set DELAYBLACKLISTLOAD=No or
            remove the setting altogether.</para>
          </listitem>
        </varlistentry>

        <varlistentry>
          <term>DYNAMIC_ZONES</term>

          <listitem>
            <para>If you have set this option to Yes, you will receive the
            following warning:</para>

            <para><emphasis role="bold">WARNING: DYNAMIC_ZONES=Yes is not
            supported by Shorewall 4.4.x</emphasis></para>

            <para>To eliminate the warning, set DYNAMIC_ZONES=No or remove the
            setting altogether. See <ulink url="Dynamic.html">this
            article</ulink> to learn how to set up Dynamic Zones under
            Shorewall 4.4.</para>
          </listitem>
        </varlistentry>

        <varlistentry id="FW">
          <term>FW</term>

          <listitem>
            <para>If a setting for FW appears in your shorewall.conf file, you
            will receive this warning:</para>

            <para><emphasis role="bold">WARNING: Unknown configuration option
            (FW) ignored.</emphasis></para>

            <para>Remove the setting from the file and modify your
            <filename>/etc/shorewall/zones</filename> file as described <link
            linkend="zones">below</link>.</para>
          </listitem>
        </varlistentry>

        <varlistentry>
          <term>IPSECFILE</term>

          <listitem>
            <para>If you have specified IPSECFILE=ipsec or IPSECFILE= or if
            you do not have a setting for IPSECFILE, then you will receive the
            following error:</para>

            <para><emphasis role="bold">ERROR: IPSECFILE=ipsec is not
            supported by Shorewall 4.4.x</emphasis></para>

            <para>To eliminate the warning, you will need to:</para>

            <orderedlist>
              <listitem>
                <para>Set IPSECFILE=zones</para>
              </listitem>

              <listitem>
                <para>Modify your <filename>/etc/shorewall/zones</filename>
                file as described <link linkend="zones">below</link>.</para>
              </listitem>
            </orderedlist>
          </listitem>
        </varlistentry>

        <varlistentry>
          <term>PKTTYPE</term>

          <listitem>
            <para>The PKTTYPE option is ignored by Shorewall-perl.
            Shorewall-perl will use Address type match if it is available;
            otherwise, it will behave as if PKTTYPE=No had been
            specified.</para>
          </listitem>
        </varlistentry>

        <varlistentry>
          <term>RFC1918_LOG_LEVEL</term>

          <listitem>
            <para>If you have specified any setting for this option, you will
            receive the following warning:</para>

            <para><emphasis role="bold">WARNING: RFC1918_LOG_LEVEL=value
            ignored. The 'norfc1918' interface/host option is no longer
            supported.</emphasis></para>

            <para>To eliminate the warning, set RFC1918_LOG_LEVEL= or simply
            remove the setting altogether.</para>
          </listitem>
        </varlistentry>

        <varlistentry>
          <term>RFC1918_STRICT</term>

          <listitem>
            <para>If you have set this option to Yes, you will receive the
            following warning:</para>

            <para><emphasis role="bold">WARNING: RFC1918_STRICT=Yes is not
            supported by Shorewall 4.4.x</emphasis></para>

            <para>To eliminate the warning, set RFC1918_STRICT=No or remove
            the setting altogether.</para>
          </listitem>
        </varlistentry>

        <varlistentry>
          <term>SAVE_IPSETS</term>

          <listitem>
            <para>Shorewall 4.4.0-4.4.5 will issue a warning if you set
            SAVE_IPSETS=Yes in <filename>shorewall.conf</filename>:</para>

            <para><emphasis role="bold">WARNING SAVE_IPSETS=Yes is not
            supported by Shorewall 4.4.x</emphasis></para>

            <para>To eliminate this message, you will need to set
            SAVE_IPSETS=No or remove the setting altogether.</para>

            <para>See <link linkend="ipsets">below</link> for additional
            information regarding ipsets in Shorewall 4.4.</para>
          </listitem>
        </varlistentry>

        <varlistentry>
          <term>SHOREWALL_COMPILER</term>

          <listitem>
            <para>If you have specified SHOREWALL_COMPILER=shell, you will
            receive the following warning message:</para>

            <para><emphasis role="bold">WARNING: SHOREWALL_COMPILER=shell
            ignored. Shorewall-shell support has been removed in this
            release</emphasis></para>

            <para>To eliminate the warning, set SHOREWALL_COMPILER=perl or
            simply remove the setting altogether.</para>
          </listitem>
        </varlistentry>

        <varlistentry>
          <term>USE_ACTIONS</term>

          <listitem>
            <para>If you have set this option to No, you will receive the
            following warning:</para>

            <para><emphasis role="bold">WARNING: USE_ACTIONS=No is not
            supported by Shorewall 4.4.x</emphasis></para>

            <para>To eliminate the warning, set USE_ACTIONS=Yes or remove the
            setting altogether.</para>
          </listitem>
        </varlistentry>
      </variablelist>
    </section>

    <section id="zones">
      <title>/etc/shorewall/zones</title>

      <para>If the column headings in your /etc/shorewall/zones file look like
      this:</para>

      <programlisting>#ZONE   DISPLAY         COMMENTS
net     Net             The big bad net
loc     Local           The local LAN</programlisting>

      <para>then you are using the original zones file format that has been
      deprecated since Shorewall 3.0.</para>

      <para>You will need to convert to the new file format which has the
      following headings:</para>

      <programlisting>#ZONE   TYPE            OPTIONS         IN                      OUT
#                                       OPTIONS                 OPTIONS</programlisting>

      <para>You will need to add an entry for your firewall zone. The default
      name for the firewall zone is 'fw' but may have been overriden in your
      old configuration using <link linkend="FW">the FW option in
      <filename>shorewall.conf</filename></link>.</para>

      <programlisting>#ZONE   TYPE            OPTIONS         IN                      OUT
#                                       OPTIONS                 OPTIONS
fw      firewall</programlisting>

      <para>The remainder of your zones will have type 'ipv4' unless they are
      mentioned in your /etc/shorewall/ipsec file (see <link
      linkend="ipsec">below</link>).</para>

      <programlisting>#ZONE   TYPE            OPTIONS         IN                      OUT
#                                       OPTIONS                 OPTIONS
fw      firewall
net     ipv4            # The big bad net
loc     ipv4            # The local LAN</programlisting>
    </section>

    <section id="ipsec">
      <title>/etc/shorewall/ipsec</title>

      <para>This file is no longer used -- its specifications are now included
      in <filename>/etc/shorewall/zones</filename>.</para>

      <para>Take this example:</para>

      <programlisting>#ZONE   IPSEC    OPTIONS         IN              OUT
#       ONLY                     OPTIONS         OPTIONS
ipsec1  Yes
ipsec2  No</programlisting>

      <para>This would translate to the following entries in
      <filename>/etc/shorewall/zones</filename>:</para>

      <programlisting>#ZONE   TYPE            OPTIONS         IN                      OUT
#                                       OPTIONS                 OPTIONS
ipsec1  ipsec4
ipsec2  ipv4</programlisting>

      <para>Any OPTIONS, IN OPTIONS and OUT OPTIONS should simply be copied
      from <filename>/etc/shorewall/ipsec</filename> to
      <filename>/etc/shorewall/zones</filename>.</para>
    </section>

    <section id="interfaces">
      <title>/etc/shorewall/interfaces</title>

      <para>The BROADCAST column is essentially unused in Squeeze. If it
      contains anything except 'detect' or '-', then you will receive this
      warning<footnote>
          <para>Users whose kernel and/or iptables do not include Address Type
          Match Support can continue to list broadcast addresses in this
          column; no warning will be issued.</para>
        </footnote>:</para>

      <blockquote>
        <para><emphasis role="bold">WARNING: Shorewall no longer uses
        broadcast addresses in rule generation when Address Type Match is
        available</emphasis></para>
      </blockquote>

      <para>To eliminate the warning, replace the contents of the BROADCAST
      column with '-' or 'detect'.</para>

      <para>The 'norfc1918' option has been removed. If you specify the
      option, you will receive the following warning:</para>

      <blockquote>
        <para><emphasis role="bold">WARNING: Support for the norfc1918
        interface option has been removed from Shorewall</emphasis></para>
      </blockquote>

      <para>To eliminate the warning, simply remove the 'norfc1918' option
      from the OPTIONS list. You may wish to consider NULL_ROUTE_RFC1918=Yes
      as a replacement (see <ulink
      url="manpages/shorewall.conf.html">shorewall.conf</ulink> (5)).</para>
    </section>

    <section id="hosts">
      <title>/etc/shorewall/hosts</title>

      <para>The 'norfc1918' option has been removed. If you specify the
      option, you will receive the following warning:</para>

      <blockquote>
        <para><emphasis role="bold">WARNING: The 'norfc1918' option is no
        longer supported</emphasis></para>
      </blockquote>

      <para>To eliminate the warning, simply remove the 'norfc1918' option
      from the OPTIONS list. You may wish to consider NULL_ROUTE_RFC1918=Yes
      as a replacement (see <ulink
      url="manpages/shorewall.conf.html">shorewall.conf</ulink> (5)).</para>
    </section>

    <section id="policy">
      <title>/etc/shorewall/policy</title>

      <para>Shorewall 4.4 detects dead policy file entries that result when an
      entry is masked by an earlier more general entry.</para>

      <para>Example:</para>

      <programlisting>#SOURCE DEST     POLICY    LOG LEVEL
all     all      REJECT    info
loc     net      ACCEPT</programlisting>

      <para>Shorewall-shell silently accepted the above even though the
      loc-&gt;net policy is useless. Shorewall-perl generates a fatal
      compilation error:</para>

      <blockquote>
        <para><emphasis role="bold">ERROR: Policy "loc net ACCEPT" duplicates
        earlier policy "all all REJECT"</emphasis></para>
      </blockquote>
    </section>

    <section id="masq">
      <title>/etc/shorewall/masq</title>

      <para>There is a long tradition of specifying an interface name in the
      SOURCE column of this file.</para>

      <para>Masquerading/SNAT occurs in the Netfilter POSTROUTING chain where
      an incoming interface may not be specified in iptables rules.
      Consequently, while processing the <command>shorewall start</command>
      and <command>shorewall restart</command> commands, the generated script
      must examine the firewall's main routing table to determine those
      networks that are routed out of the interface; the script then adds a
      MASQUERADE/SNAT rule for connections from each of those networks. This
      additional processing requires the named interface to be up and
      configured when Shorewall starts or restarts.</para>

      <para>Users often complain that Shorewall fails to start at boot time
      because a VPN interface that is named as a masq SOURCE isn't up and
      configured during boot.</para>

      <para>To emphasize this restriction, if an interface is named in the
      SOURCE column of one or more entries, a single warning is issued as
      follows:</para>

      <blockquote>
        <para><emphasis role="bold">WARNING: Using an interface as the masq
        SOURCE requires the interface to be up and configured when Shorewall
        starts/restarts</emphasis></para>
      </blockquote>

      <para>To suppress this warning, replace the interface name with the list
      of networks that are routed out of the interface.</para>

      <para>Example.</para>

      <para>Existing entry:</para>

      <programlisting>#INTERFACE              SOURCE          ADDRESS         PROTO   PORT(S) IPSEC   MARK    USER/
#                                                                                       GROUP
eth0                    eth1</programlisting>

      <para>Current routing configuration:</para>

      <programlisting>gateway:~# ip route ls dev eth1
<emphasis role="bold">172.20.1.0/24</emphasis>  proto kernel  scope link  src 172.20.1.254 
224.0.0.0/4  scope link 
gateway:~# 
</programlisting>

      <para>Replacement entry:</para>

      <programlisting>#INTERFACE              SOURCE          ADDRESS         PROTO   PORT(S) IPSEC   MARK    USER/
#                                                                                       GROUP
eth0                    <emphasis role="bold">172.20.1.0/24</emphasis></programlisting>

      <para>Note that no entry is included for 224.0.0.0/4 since that is the
      multicast IP range and there should never be any packets with a SOURCE
      IP address in that network.</para>
    </section>

    <section id="rules">
      <title>/etc/shorewall/rules</title>

      <para>If you include a destination zone in a 'nonat' rule, Shorewall
      issues the following warning:</para>

      <blockquote>
        <para><emphasis role="bold">WARNING: Destination zone (zonename)
        ignored.</emphasis></para>
      </blockquote>

      <para>Nonat rules include:</para>

      <blockquote>
        <simplelist>
          <member>DNAT-</member>

          <member>REDIRECT-</member>

          <member>NONAT</member>
        </simplelist>
      </blockquote>

      <para>To eliminate the warning, remove the DEST zone.</para>

      <para>Example.</para>

      <para>Before:</para>

      <programlisting>#ACTION         SOURCE          DEST            PROTO   DEST    SOURCE          ORIGINAL        RATE            USER/   MARK    CONNLIMIT       TIME
#                                                       PORT(S) PORT(S)         DEST            LIMIT           GROUP
NONAT           loc             net             tcp     80</programlisting>

      <para>After:</para>

      <programlisting>#ACTION         SOURCE          DEST            PROTO   DEST    SOURCE          ORIGINAL        RATE            USER/   MARK    CONNLIMIT       TIME
#                                                       PORT(S) PORT(S)         DEST            LIMIT           GROUP
NONAT           loc             -               tcp     80</programlisting>

      <para>Shorewall 4.4 versions prior to 4.4.19 do not support icmp type
      lists in the DEST PORT(S) column. Only a single ICMP type may be listed.
      If you have a shell variable with a list of ICMP types that you use in a
      rule, you can work around this limitation as follows. Replace this
      rule:</para>

      <programlisting>#ACTION         SOURCE          DEST            PROTO   DEST    SOURCE          ORIGINAL        RATE            USER/   MARK    CONNLIMIT       TIME
#                                                       PORT(S) PORT(S)         DEST            LIMIT           GROUP
ACCEPT          z1              z2              icmp    $ITYPES</programlisting>

      <para>with:</para>

      <programlisting>#ACTION         SOURCE          DEST            PROTO   DEST    SOURCE          ORIGINAL        RATE            USER/   MARK    CONNLIMIT       TIME
#                                                       PORT(S) PORT(S)         DEST            LIMIT           GROUP

BEGIN SHELL
for type in $ITYPES; do
ACCEPT          z1              z2              icmp    $type
done
END SHELL</programlisting>
    </section>

    <section id="routestopped">
      <title>/etc/shorewall/routestopped</title>

      <para>The 'critical' option is no longer needed and hence is no longer
      supported. If you have critical hosts defined, you will receive this
      warning:</para>

      <blockquote>
        <para><emphasis role="bold">WARNING: The 'critical' option is no
        longer supported (or needed)</emphasis></para>
      </blockquote>

      <para>To suppress the warning, simply remove the option.</para>

      <para>Shorewall 4.4 also treats the <filename>routestopped</filename>
      file differently from earlier releases. Previously, the
      <filename>routestopped</filename> file was parsed during
      <command>shorewall stop</command> processing so that changes made to the
      file while Shorewall was running would be applied at the next
      <command>stop</command>. This is no longer the case -- the
      <filename>routestopped</filename> file is processed during compilation
      just like the rest of the configuration files so that when
      <command>shorewall stop</command> is issued, the firewall will pass
      traffic based on the contents of the <filename>routestopped</filename>
      file at the last <command>start</command> or
      <command>restart</command>.</para>

      <para>If you change the <filename>routestopped</filename> file and now
      want to stop the firewall, you can run this sequence of commands:</para>

      <programlisting><command>shorewall compile
shorewall stop</command></programlisting>
    </section>

    <section id="tos">
      <title>/etc/shorewall/tos</title>

      <para>The <filename>/etc/shorewall/tos</filename> file now has
      zone-independent SOURCE and DEST columns as do all other files except
      the rules and policy files.</para>

      <para>The SOURCE column may be one of the following:</para>

      <simplelist>
        <member>[<command>all</command>:]&lt;<replaceable>address</replaceable>&gt;[,...]</member>

        <member>[<command>all</command>:]&lt;<replaceable>interface</replaceable>&gt;[:&lt;<replaceable>address</replaceable>&gt;[,...]]</member>

        <member><command>$FW</command>[:&lt;<replaceable>address</replaceable>&gt;[,...]]</member>
      </simplelist>

      <para>The DEST column may be one of the following:</para>

      <simplelist>
        <member>[<command>all</command>:]&lt;<replaceable>address</replaceable>&gt;[,...]</member>

        <member>[<command>all</command>:]&lt;<replaceable>interface</replaceable>&gt;[:&lt;<replaceable>address</replaceable>&gt;[,...]]</member>
      </simplelist>

      <para>This is a permanent change. The old zone-based rules have never
      worked right and this is a good time to replace them. We have tried to
      make the new syntax cover the most common cases without requiring change
      to existing files. In particular, it will handle the
      <filename>tos</filename> file released with Shorewall 1.4 and
      earlier.</para>
    </section>

    <section id="extension">
      <title>Extension Scripts</title>

      <para>With the shell-based compiler, all extension scripts were copied
      into the compiled script and executed at run-time. In some cases, this
      approach doesn't work with Shorewall Perl because (almost) the entire
      rule set is built by the compiler. As a result, Shorewall-perl runs some
      extension scripts at compile-time rather than at run-time. Because the
      compiler is written in Perl, these extension scripts from earlier
      versions will no longer work.</para>

      <para>The following table summarizes when the various extension scripts
      are run:<informaltable align="left" frame="none">
          <tgroup cols="3">
            <tbody>
              <row>
                <entry><emphasis role="bold">Compile-time (Must be written in
                Perl)</emphasis></entry>

                <entry><emphasis role="bold">Run-time</emphasis></entry>

                <entry><emphasis role="bold">Eliminated</emphasis></entry>
              </row>

              <row>
                <entry>initdone</entry>

                <entry>clear</entry>

                <entry>continue</entry>
              </row>

              <row>
                <entry>maclog</entry>

                <entry>init</entry>

                <entry></entry>
              </row>

              <row>
                <entry>Per-chain (including those associated with
                actions)</entry>

                <entry>start</entry>

                <entry></entry>
              </row>

              <row>
                <entry></entry>

                <entry>started</entry>

                <entry></entry>
              </row>

              <row>
                <entry></entry>

                <entry>stop</entry>

                <entry></entry>
              </row>

              <row>
                <entry></entry>

                <entry>stopped</entry>

                <entry></entry>
              </row>

              <row>
                <entry></entry>

                <entry>tcclear</entry>

                <entry></entry>
              </row>
            </tbody>
          </tgroup>
        </informaltable></para>

      <para>Compile-time extension scripts are executed using the Perl 'eval
      `cat &lt;file&gt;`' mechanism. Be sure that each script returns a 'true'
      value; otherwise, the Shorewall-perl compiler will assume that the
      script failed and will abort the compilation.</para>

      <para>When a script is invoked, the <emphasis
      role="bold">$chainref</emphasis> scalar variable will usually hold a
      reference to a chain table entry.</para>

      <simplelist>
        <member><emphasis role="bold">$chainref-&gt;{name}</emphasis> contains
        the name of the chain</member>

        <member><emphasis role="bold">$chainref-&gt;{table}</emphasis> holds
        the table name</member>
      </simplelist>

      <para>To add a rule to the chain:</para>

      <simplelist>
        <member>add_rule $chainref,
        <replaceable>the-rule</replaceable></member>
      </simplelist>

      <para>Where</para>

      <simplelist>
        <member><replaceable>the rule</replaceable> is a scalar argument
        holding the rule text. Do not include "-A
        <replaceable>chain-name</replaceable>"</member>
      </simplelist>

      <para>Example:</para>

      <simplelist>
        <member>add_rule $chainref, '-j ACCEPT';</member>
      </simplelist>

      <para>To insert a rule into the chain:</para>

      <simplelist>
        <member>insert_rule $chainref, <replaceable>rulenum</replaceable>,
        <replaceable>the-rule</replaceable></member>
      </simplelist>

      <para>The log_rule_limit function works like it does in the shell
      compiler with three exceptions:</para>

      <itemizedlist>
        <listitem>
          <para>You pass the chain reference rather than the name of the
          chain.</para>
        </listitem>

        <listitem>
          <para>The commands are 'add' and 'insert' rather than '-A' and
          '-I'.</para>
        </listitem>

        <listitem>
          <para>There is only a single "pass as-is to iptables" argument (so
          you must quote that part</para>
        </listitem>
      </itemizedlist>

      <para>Example:</para>

      <programlisting>    log_rule_limit
              'info' , 
              $chainref , 
              $chainref-&gt;{name},
              'DROP' , 
              '',    #Limit
              '' ,   #Log tag
              'add'
              '-p tcp ';         </programlisting>

      <para>Here is an example of an actual initdone script used with
      Shorewall 3.4:<programlisting>run_iptables -t mangle -I PREROUTING -p esp -j MARK --set-mark 0x50
run_iptables -t filter -I INPUT -p udp --dport 1701 -m mark --mark 0x50 -j ACCEPT
run_iptables -t filter -I OUTPUT -p udp --sport 1701 -j ACCEPT
</programlisting></para>

      <para>Here is the corresponding script used with Shorewall
      4.4:<programlisting>use Shorewall::Chains;

insert_rule $mangle_table-&gt;{PREROUTING}, 1, "-p esp -j MARK --set-mark 0x50";
insert_rule $filter_table-&gt;{INPUT},      1, "-p udp --dport 1701 -m mark --mark 0x50 -j ACCEPT";
insert_rule $filter_table-&gt;{OUTPUT},     1, "-p udp --sport 1701 -j ACCEPT";

1;</programlisting></para>

      <para>The initdone script is unique because the $chainref variable is
      not set before the script is called. The above script illustrates how
      the $mangle_table, $filter_table, and $nat_table references can be used
      to add or insert rules in arbitrary chains.</para>
    </section>

    <section id="ipsets">
      <title>Ipsets</title>

      <para>Shorewall 4.4 insists that ipset names begin with a letter and be
      composed of alphanumeric characters, underscores (_) and dashes (-).
      When used in a Shorewall configuration file, the name must be preceded
      by a plus sign (+) as with the shell-based compiler.</para>

      <para>Shorewall 4.4.6 re-introduced SAVE_IPSETS=Yes with slightly
      different semantics:</para>

      <itemizedlist>
        <listitem>
          <para>The contents of the ipsets are saved during processing of the
          <command>stop</command> command in addition to during processing of
          the <command>save</command> command.</para>
        </listitem>

        <listitem>
          <para>The contents of the ipsets are restored during processing of
          the <command>start</command> command in addition to during
          processing of the <command>restore</command> command. When
          <command>restore</command> is being run when Shorewall is not in the
          stopped state (such as when it is run to recover from a failed
          <command>start</command>, <command>restart</command> or
          <command>refresh</command>) ipsets are not restored.</para>
        </listitem>

        <listitem>
          <para>Specifying an ipset in <ulink
          url="manpages/shorewall-routestopped.html">shorewall-routestopped
          </ulink>(5) is prohibited when SAVE_IPSETS=Yes.</para>
        </listitem>
      </itemizedlist>
    </section>

    <section id="SimpleTC">
      <title>Simple Traffic Shaping</title>

      <para>If you find that output bandwidth is extremely limited, it is
      likely due to TCP Segmentation Offload (TSO) and/or Generic Segmentation
      Offload (GSO) being enabled in the network adapter. To verify that,
      install the <firstterm>ethtool</firstterm> package and use the -k
      command:</para>

      <programlisting>root@gateway:~# ethtool -k eth1
Offload parameters for eth1:
rx-checksumming: on
tx-checksumming: on
scatter-gather: on
tcp-segmentation-offload: <emphasis role="bold">on</emphasis>
udp-fragmentation-offload: off
generic-segmentation-offload: <emphasis role="bold">on</emphasis>
generic-receive-offload: off
large-receive-offload: off
ntuple-filters: off
receive-hashing: off
root@gateway:~#</programlisting>

      <para>If that is the case, you can correct the problem by adjusting the
      <replaceable>minburst</replaceable> setting in
      /etc/shorewall/tcinterfaces. We suggest starting at 10-12kb and adjust
      as necessary. Example:</para>

      <programlisting>#INTERFACE	TYPE		IN-BANDWIDTH			OUT-BANDWIDTH
eth0		External	50mbit:200kb			5.0mbit:100kb:200ms:100mbit:<emphasis
          role="bold">10kb</emphasis>
</programlisting>

      <para>Alternatively, you can turn off TSO and GSO using this command in
      <filename>/etc/shorewall/init</filename>:</para>

      <programlisting><emphasis role="bold">ethtool -k eth<emphasis>N</emphasis> tso off gso off</emphasis></programlisting>
    </section>
  </section>

  <section id="Additional">
    <title>Additional Sources of Information</title>

    <para>The following articles provide additional information.</para>

    <itemizedlist>
      <listitem>
        <para><ulink url="Shorewall-perl.html#Incompatibilities">Shorewall
        Perl Incompatibilities</ulink></para>
      </listitem>

      <listitem>
        <para><ulink url="upgrade_issues.htm">Upgrade Issues</ulink></para>
      </listitem>
    </itemizedlist>
  </section>
</article>