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