O.K., I have taken the gre-tun.c code and learned how to use the
tun device. Then, I thought, I would simply build an RFC 1933
IP over IP(v4) tunnel daemon (iptund). This was all very simple
and worked using any kind of protocol, except -- BUMMER -- I
can't open a raw IP socket with the IPPROTO_IPIP (#4). Of course,
as we read in /sys/netinet/ip_encap.c, there are many things that
want to use protocols 4 and 41 and so we need -- again (!) --
a filter based on src and dst fields, etc. This ip_encap code
acts, once again, like ipfilter, ipfw, the ALTQ classifyer, or
bpf. The only problem with this mechanism is that I can't
seem to find a way to participate in the game from userspace.
So, an IPIP tun daemon doesn't seem possible without hacking
kernel.
I was almost going to do just that. My plan was to
a) find where I get the "protocol not supported" error upon
calling socket as raw ip with IPPROTO_IPIP;
b) to disable this error exit;
c) to provide hooks in the form of either setsockopt(2) or
connect(2) so that any userland client can hook itself into the
encaptab list.
Does this sound very unreasonable?
However, I also contemplated my course of action on my way home
from work and I found now that the gif device, while still not
supporting ALTQ, is supposed to work in ECN mode if IFF_LINK1
is set. At least this is what the man pages say and what the
code intends. It didn't work, though, when I tried it. And a
quick look into the sourcecode reveals why it doesn't work. See
for yourself.
in_gif.c,v 1.52 says:
> in_gif_output(ifp, family, m, rt)
> ...
> if (ifp->if_flags & IFF_LINK1)
> ip_ecn_ingress(ECN_ALLOWED, &iphdr.ip_tos, &tos);
> ...
But in ip_ecn.c,v 1.9 we read:
> /*
> * modify outer ECN (TOS) field on ingress operation (tunnel encapsulation).
> * call it after you've done the default initialization/copy for the outer.
> */
> void
> ip_ecn_ingress(mode, outer, inner)
> int mode;
> u_int8_t *outer;
> u_int8_t *inner;
> {
> if (!outer || !inner)
> panic("NULL pointer passed to ip_ecn_ingress");
>
> switch (mode) {
> case ECN_ALLOWED: /* ECN allowed */
> *outer &= ~IPTOS_CE;
> break;
> case ECN_FORBIDDEN: /* ECN forbidden */
> *outer &= ~(IPTOS_ECT | IPTOS_CE);
> break;
> case ECN_NOCARE: /* no consideration to ECN */
> break;
> }
> }
That is, ip_ecn_ingress exposes the formal argument "inner", that
is never used. It says -- in the comment -- that it expects that
the *outer = *inner assignment has already been made. And yet,
in_gif_output never makes that assignment. It's confusing and
easy to make such mistake. I will fix this problem in one of
two ways, either in in_gif_output to say:
> in_gif_output(ifp, family, m, rt)
> ...
> if (ifp->if_flags & IFF_LINK1) {
> iphdr.ip_tos = tos;
> ip_ecn_ingress(ECN_ALLOWED, &iphdr.ip_tos, &tos);
> }
> ...
or in ip_ecn_ingress to add a line
> *outer = *inner
before the case switch. I checked the latest CVS repository and
the revisions I refer to here are current (and unchanged for
a long while.) I guess noone has actually tried using the ECN
feature of the gif device. I would appreciate some advice on
which change to apply, since someone must have thought something
by putting the "inner" argument into the in_gif_output and then
not using it.
Anyway, once I fixed this tomorrow, I can dump my iptund code
and use gif tunnels with ECN and ALTQ classifying on the tos
bits as set by that video conferencing application I need to
accomodate.
regards,
-Gunther
PS: I did submit a formal bug report for this @ kame.net.
TODO:
- ip_encap should llow for userspace processes to hook in
handlers for flows on protocols 4 and 41.
- ALTQ should support the gif tunnel device as it does
support the tun device.
--
Gunther Schadow, M.D., Ph.D. [EMAIL PROTECTED]
Medical Information Scientist Regenstrief Institute for Health Care
Adjunct Assistent Professor Indiana University School of Medicine
tel:1(317)630-7960 http://aurora.regenstrief.org
To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-net" in the body of the message