Date: Mon, 24 Aug 2015 23:29:19 +0200 From: andreas scherrer <ascherrer@gmail.com> To: freebsd-questions@freebsd.org Cc: Ian Smith <smithi@nimnet.asn.au>, freebsd-ipfw@freebsd.org Subject: Re: ipfw's "via" rule option/match pattern Message-ID: <55DB8CAF.8040608@gmail.com> In-Reply-To: <20150821013137.E8515@sola.nimnet.asn.au> References: <20150821013137.E8515@sola.nimnet.asn.au>
next in thread | previous in thread | raw e-mail | index | archive | help
> In freebsd-questions Digest, Vol 585, Issue 3, Message: 9 > On Wed, 19 Aug 2015 00:41:35 +0200 andreas scherrer <ascherrer@gmail.com> 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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?55DB8CAF.8040608>