kern/122109: [ipfw] ipfw nat traceroute problem

Alexander V. Chernikov melifaro at ipfw.ru
Fri Jun 3 06:10:12 UTC 2011


The following reply was made to PR kern/122109; it has been noted by GNATS.

From: "Alexander V. Chernikov" <melifaro at ipfw.ru>
To: bug-followup at FreeBSD.org, m.dyadchenko at 211.ru, ae at FreeBSD.org
Cc:  
Subject: Re: kern/122109: [ipfw] ipfw nat traceroute problem
Date: Fri, 03 Jun 2011 10:08:13 +0400

 Problem is actually a bit deeper.
 
 Before libalias-based kernel nat appears natd uses PKT_ALIAS_IGNORE
 retrun code to drop packets iff PKT_ALIAS_DENY_INCOMING flag is set:
 
                status = LibAliasIn (mla, buf, IP_MAXPACKET);
                 if (status == PKT_ALIAS_IGNORED &&
                     mip->dropIgnoredIncoming) {
 
                         if (verbose)
                                 printf (" dropped.\n");
 
 
 Current ipfw nat (and ng_nat) implementation simply drops every packet
 with PKT_ALIAS_IGNORE return code:
 
        if (retval != PKT_ALIAS_OK &&
            retval != PKT_ALIAS_FOUND_HEADER_FRAGMENT) {
                 /* XXX - should i add some logging? */
                 m_free(mcl);
 
 Most of PKT_ALIAS_IGNORED are returned in case of no state is found (the
 rest are some (possibly) very rare unknown errors/handlers error).
 
 Libalias automatically create new state for every packet not found in
 aliasing database if it reasonable to do so (TCP/UDP packets is
 definitely reasonable since they represent logical sessions, icmp
 req/reply is reasonable too, etc..). On the opposite, there is no reason
 for creating state for packets signaling some existing session errors
 (icmp unreach, etc..) since such packets are rare/unidirectional and no
 reply is needed.
 
 The only 2 places states are not created (not mentioning
 PKT_ALIAS_PROXY_ONLY and PKT_ALIAS_DENY_INCOMING modes) are
 IcmpAliasIn2()|IcmpAliasOut2() functions.
 
 Those function dispatches various ICMP notification and tries to map
 those notification to existing states using original packet header
 within ICMP message. If such session is not found (PR case, since
 usually locally-originated packets are not passed to libalias and no
 replies are transmitted due to traceroute specific) return code is set
 to PKT_ALIAS_IGNORED.
 
 As a result: restoring original behavior should not break anything.
 
 This patch seems to fix the problem:
 
 Index: ip_fw_nat.c
 ===================================================================
 --- ip_fw_nat.c (revision 221263)
 +++ ip_fw_nat.c (working copy)
 @@ -267,8 +267,9 @@
                 m->m_flags |= M_SKIP_FIREWALL;
                 retval = PKT_ALIAS_OK;
         }
 -       if (retval != PKT_ALIAS_OK &&
 -           retval != PKT_ALIAS_FOUND_HEADER_FRAGMENT) {
 +       if (retval == PKT_ALIAS_ERROR || retval ==
 PKT_ALIAS_UNRESOLVED_FRAGMENT ||
 +               (retval == PKT_ALIAS_IGNORED &&
 +                (t->lib->packetAliasMode & PKT_ALIAS_DENY_INCOMING))) {
                 /* XXX - should i add some logging? */
                 m_free(mcl);
                 args->m = NULL;
 
 
 Something similar should be applied to ng_nat.c


More information about the freebsd-ipfw mailing list