Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 26 Sep 2007 10:02:41 +0400
From:      Oleg Bulyzhin <oleg@freebsd.org>
To:        freebsd-net@freebsd.org
Subject:   new mbuf flag proposal
Message-ID:  <20070926060241.GA3945@lath.rinet.ru>

next in thread | raw e-mail | index | archive | help

--7JfCtLOvnd9MIVvH
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable


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 r=
st
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=20
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 a=
dd
   mbuf_tag for distinguishing source of M_PFIL_CREATED flag.

So, for packet creation code should be like this:

	m->m_flags |=3D M_PFIL_CREATED;
	mtag =3D 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 =3D 0;

	if (m->m_flags & M_PFIL_CREATED) {
		dont_emit_pkt =3D 1;
		mtag =3D 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 fla=
g),
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?

--=20
Oleg.

=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
=3D=3D=3D Oleg Bulyzhin -- OBUL-RIPN -- OBUL-RIPE -- oleg@rinet.ru =3D=3D=3D
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D


--7JfCtLOvnd9MIVvH
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.7 (FreeBSD)

iD8DBQFG+fYAryLc73jOEF8RAjuEAJ0Q6RaGDeGRNc4a3dCCE+JdjZUbUwCfYScz
mtdSZTHAVlLXO7ckiQIiIrU=
=EaIm
-----END PGP SIGNATURE-----

--7JfCtLOvnd9MIVvH--



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