Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 3 Jun 2011 06:10:11 GMT
From:      "Alexander V. Chernikov" <melifaro@ipfw.ru>
To:        freebsd-ipfw@FreeBSD.org
Subject:   Re: kern/122109: [ipfw] ipfw nat traceroute problem
Message-ID:  <201106030610.p536ABfN064049@freefall.freebsd.org>

Next in thread | Raw E-Mail | Index | Archive | Help
The following reply was made to PR kern/122109; it has been noted by GNATS.

From: "Alexander V. Chernikov" <melifaro@ipfw.ru>
To: bug-followup@FreeBSD.org, m.dyadchenko@211.ru, ae@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



Want to link to this message? Use this URL: <http://docs.FreeBSD.org/cgi/mid.cgi?201106030610.p536ABfN064049>