In freebsd-questions Digest, Vol 585, Issue 3, Message: 9
On Wed, 19 Aug 2015 00:41:35 +0200 andreas scherrer <[email protected]> wrote:

<snip>

  > When I run a quick test, sending one ICMP echo request from
  > 192.168.32.10 to 192.168.38.17 (two devices communicating via the box
  > that has the "count" rules listed below configured), I get the following
  > result:

A good set of tests for all combinations.  Something else I saw recently
made me doubt that my own understanding of this was correct, and your
tests seem to confirm that I've been misadvising people for, oh, the
best part of 10 years .. here's the code, which I've checked hasn't
functionally changed at all since 2012, and little from 2002 with
Luigi's first ip_fw2.c (tabs lost):

                 case O_RECV:
                         match = iface_match(m->m_pkthdr.rcvif,
                             (ipfw_insn_if *)cmd, chain, &tablearg);
                         break;

                 case O_XMIT:
                         match = iface_match(oif, (ipfw_insn_if *)cmd,
                             chain, &tablearg);
                         break;

                 case O_VIA:
                         match = iface_match(oif ? oif :
                             m->m_pkthdr.rcvif, (ipfw_insn_if *)cmd,
                             chain, &tablearg);
                         break;

iface_match() (qv) does the test vs iface name or IP address, returning
1 on a match, but begins by returning 0 if the passed interface is NULL.
In the case of O_VIA, if the outside iface is specified then that iface
(only) is tested; the rcvif is only checked if there's NO out iface.

This directly contradicts what I've been telling myself and others for
years :( I guess what's amazing is that nobody who'd know better ever
pulled me up on such statements, increasing confidence in wrongness :)

  > -----
  > When 192.168.38.17 does not answer the ping:
  > 00350     2     168 count icmp from 192.168.32.10 to 192.168.38.17 recv 
re0.32
  > 00350     0       0 count icmp from 192.168.38.17 to 192.168.32.10 recv 
re0.38
  > 00351     1      84 count icmp from 192.168.32.10 to 192.168.38.17 in recv 
re0.32
  > 00351     0       0 count icmp from 192.168.38.17 to 192.168.32.10 in recv 
re0.38
  > 00352     1      84 count icmp from 192.168.32.10 to 192.168.38.17 out recv 
re0.32
  > 00352     0       0 count icmp from 192.168.38.17 to 192.168.32.10 out recv 
re0.38
  > 00355     1      84 count icmp from 192.168.32.10 to 192.168.38.17 via 
re0.32
  > 00355     0       0 count icmp from 192.168.38.17 to 192.168.32.10 via 
re0.38
  > 00356     1      84 count icmp from 192.168.32.10 to 192.168.38.17 in via 
re0.32
  > 00356     0       0 count icmp from 192.168.38.17 to 192.168.32.10 in via 
re0.38
  > 00357     0       0 count icmp from 192.168.32.10 to 192.168.38.17 out via 
re0.32
  > 00357     0       0 count icmp from 192.168.38.17 to 192.168.32.10 out via 
re0.38
  > 00358     1      84 count icmp from 192.168.32.10 to 192.168.38.17 out recv 
re0.32 xmit re0.38
  > 00358     0       0 count icmp from 192.168.38.17 to 192.168.32.10 out recv 
re0.38 xmit re0.32
  >
  > When 192.168.38.17 does answer the ping:
  > 00350     2     168 count icmp from 192.168.32.10 to 192.168.38.17 recv 
re0.32
  > 00350     2     168 count icmp from 192.168.38.17 to 192.168.32.10 recv 
re0.38
  > 00351     1      84 count icmp from 192.168.32.10 to 192.168.38.17 in recv 
re0.32
  > 00351     1      84 count icmp from 192.168.38.17 to 192.168.32.10 in recv 
re0.38
  > 00352     1      84 count icmp from 192.168.32.10 to 192.168.38.17 out recv 
re0.32
  > 00352     1      84 count icmp from 192.168.38.17 to 192.168.32.10 out recv 
re0.38
  > 00355     1      84 count icmp from 192.168.32.10 to 192.168.38.17 via 
re0.32
  > 00355     1      84 count icmp from 192.168.38.17 to 192.168.32.10 via 
re0.38
  > 00356     1      84 count icmp from 192.168.32.10 to 192.168.38.17 in via 
re0.32
  > 00356     1      84 count icmp from 192.168.38.17 to 192.168.32.10 in via 
re0.38
  > 00357     0       0 count icmp from 192.168.32.10 to 192.168.38.17 out via 
re0.32
  > 00357     0       0 count icmp from 192.168.38.17 to 192.168.32.10 out via 
re0.38
  > 00358     1      84 count icmp from 192.168.32.10 to 192.168.38.17 out recv 
re0.32 xmit re0.38
  > 00358     1      84 count icmp from 192.168.38.17 to 192.168.32.10 out recv 
re0.38 xmit re0.32
  > -----
  >
  > According to the statement in [4] I would expect rule 357 to match...

Yes; [4] is clearly wrong in this respect.  'out via' does NOT check the
receive interface if the transmit interface is known.

Thank you for your effort! I finally understand what I am doing here! Awesome! To be honest I was looking for the code you pasted but was not able to find it. Now I know where to look.

In summary I think it would be reasonable to advise people to *not* use "via" in combination with "in" or "out".

"in via $if" => "in recv $if"
"out via $if" => "out xmit $if"

Unless there can be outgoing packets without an xmit interface; but I don't see what those would be good for.

Still looking for a use case for "via" (there must be a reason it exists, right?) "via" seems to make more sense when used *without* "in"/"out".

"via $if" matches packets that are either incoming on $if or outgoing on $if. The most prominent use case that comes to my mind for that would be NAT (hiding an RFC 1918 network):

nat X ip4 from any to any via $if

Assuming the above is correct and that I wanted to tackle the issue of rewriting the ipfw handbook section: how would I do that (i.e. how to submit a new version)?


Best regards
andreas
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-ipfw
To unsubscribe, send any mail to "[email protected]"

Reply via email to