Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 29 Jul 2008 08:41:23 -0700
From:      Jeff Kletsky <jeff+freebsd@wagsky.com>
To:        freebsd-ipfw@freebsd.org
Subject:   ipfw "bug" - recv any = not recv any
Message-ID:  <488F3A23.7070203@wagsky.com>

next in thread | raw e-mail | index | archive | help
The "recv any" = "not recv any" = noop behavior got me this weekend,
even after careful reading of the man page.

My situation is attempting to use "not recv any" to discriminate
between packets generated by the host from those being routed through
the host. It is reasonably easy to confirm that, at least in
7.0-RELEASE-p3, "recv any" and "not recv any" are both behaving as
no-ops in the ipfw syntax.

This was discussed to some extent in the post and related thread:

<http://lists.freebsd.org/mailman/htdig/freebsd-ipfw/2005-August/001969.html>;

Luigi Rizzo wrote:

 > ok, so the problem is the following: when i implemented ipfw2
 > i thought that 'recv any' or 'xmit any' were effectively NOPs
 > so the parser erroneously removes them, together with any 'not' prefix
 > (which is processed before).
 >
 > To fix this one should
 > - patch the function ipfw2.c:fill_iface()
 >   so that an argument of 'any' puts some special pattern
 >   in the ipfw_insn_if (e.g. an * in the first char of name[]
 >   should suffice as i doubt it is a legal interface name).
 >
 > [...]

While there are ways to do this (e.g., tagging, or "[not] recv *"),
I would suggest at least clarification of the documentation.

At this point, I suspect that there are enough "overly cautious" rule
writers that have included "recv any" in their now-deployed rules that
(properly for them) match both externally and internally generated
packets that changing "recv any" to only match packets that were
received would break more things than it fixes. Changing the parsing
of "not recv any" to produce the code behind "not recv *" would be
"less dangerous" and might be considered at some time.


Let me preface this by saying that I don't know the internals of ipfw2
well enough to confirm that a doc change like this matches the
operation of the code, but something along the lines of:

   recv | xmit | via {ifX | if* | ipno | * }

      Matches packets received, transmitted or going through, 
respec-           
      tively, the interface specified by exact name (ifX), by device
      name (if*), by IP address, or through some interface (*).

      The via keyword causes the interface to always be checked.  If
      recv or xmit is used instead of via, then only the receive or
      transmit interface (respectively) is checked.  By specifying
      both, it is possible to match packets based on both receive and
      transmit interface, e.g.:

         ipfw add deny ip from any to any out recv ed0 xmit ed1

      The recv interface can be tested on either incoming or outgoing
      packets, while the xmit interface can only be tested on outgoing
      packets.  So out is required (and in is invalid) whenever xmit is
      used.

      A packet may not have a receive or transmit interface: packets
      originating from the local host have no receive interface, while
      packets destined for the local host have no transmit interface.
      To match packets that have no receive interface, the construct
      "not recv *" may be used.

      The constructs "recv any" and "not recv any" are presently both
      treated equivalently as a match-all condition and both are stripped
      during parsing. This behavior, especially of the latter, is subject
      to change in future releases, and is not suggested for new rule sets.


I hope this post at least helps the next person who trips across this.
I'm very open to ideas on how to clarify and/or improve the behavior.

I haven't looked into the other "any" matches to see if they have 
similar behavior
that would benefit from additional documentation

Jeff

P.S. Thanks to Julian Elischer for suggesting "not recv *" as an approach.



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?488F3A23.7070203>