Skip site navigation (1)Skip section navigation (2)
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>