Date: Sun, 30 Sep 2007 22:32:52 +0100 From: Tom Judge <tom@tomjudge.com> To: Oleg Bulyzhin <oleg@freebsd.org> Cc: freebsd-net@freebsd.org Subject: Re: new mbuf flag proposal Message-ID: <47001604.6030504@tomjudge.com> In-Reply-To: <20070926060241.GA3945@lath.rinet.ru> References: <20070926060241.GA3945@lath.rinet.ru>
next in thread | previous in thread | raw e-mail | index | archive | help
Oleg Bulyzhin wrote: > Hi all. > > Recently, i discovered following problem (though it was already discussed, see > http://freebsd.rambler.ru/bsdmail/freebsd-ipfw_2006/msg00491.html): > pfil handlers (like ipfw or pf) sometime need to create packets (like tcp rst > or icmp errors). In order to avoid loops M_SKIP_FIREWALL flag is used. > Unfortunately, this behaviour is not always correct. > There are configurations when you need to reinject such packets into pfil(4) > handlers (in order to translate them using NAT or apply routing policy > or divert them somewhere, etc). In my case i had to modify kernel > in order to translate tcp keepalive packets(generated by ipfw) using pfnat. > > I have a proposal how to solve this: > 1) Introduce new mbuf flag, something like M_PFIL_CREATED, which should be > used to mark packets created by pfil handler. If packet is not supposed > to reenter pfil handlers M_SKIP_FIREWALL can be used instead. > 2) When pfil handler generate packet it should be marked either with > M_SKIP_FIREWALL or M_PFIL_CREATED. In latter case, pfil handler should add > mbuf_tag for distinguishing source of M_PFIL_CREATED flag. > I only really have one comment, surely all packets created in pfil handlers should have M_PFIL_CREATED set, and those that should not pass through the firewall should have M_SKIP_FIREWALL set in addition? Just my 2p Tom > So, for packet creation code should be like this: > > m->m_flags |= M_PFIL_CREATED; > mtag = m_tag_alloc(MTAG_PFIL_CREATED, PFIL_IPFW, 0, M_NOWAIT); > if (mtag) { > m_tag_prepend(m, mtag); > } else { > goto drop_pkt; > } > > at the beginning of pfil handler we should have something like this: > > int dont_emit_pkt = 0; > > if (m->m_flags & M_PFIL_CREATED) { > dont_emit_pkt = 1; > mtag = m_tag_locate(m, MTAG_PFIL_CREATED, PFIL_IPFW, NULL); > if (mtag) { /* pkt was created by myself */ > /* my own packet, handle it with care. */ > goto specal_handler; > } else { /* pkt was created by other pfil(4) handler */ > > /* do normal processing but do not emit new packets. */ > goto normal_handler; > } > } > > This functionality can be archived with mbuf_tag only (without new mbuf flag), > but it would be ineffective: > calling m_tag_locate() (unsuccessful most of the time!) for every packet is > rather expensive. > > What do you think about this? >
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?47001604.6030504>