Discussion:
restoring sockaddr_dl size; introducing sockaddr_link
(too old to reply)
David Young
2007-08-23 00:04:22 UTC
Permalink
I have lengthened sockaddr_dl so that it can accomodate a FireWire
address. That doesn't break any user<->kernel ABI, however, a number
of people have pointed out to me that it 3rd-party programs may rely on
sockaddr_dl's size remaining the same. I am going to return sockaddr_dl
to its historical size, and introduce sockaddr_link for the kernel to use.
The address family (sa_family) of both sockaddr_dl and sockaddr_link
remain the same (AF_LINK). I am also going to introduce macros CSLADDR()
and SLADDR() whose function is analogous to CLLADDR() and LLADDR().
I will rename all of the sockaddr_dl_*() routines in the kernel to
sockaddr_link_*(). Please let me know if this is going to break your
mother's back, make your cereal soggy, or stop your WiFi from working.

Dave
--
David Young OJC Technologies
***@ojctech.com Urbana, IL * (217) 278-3933 ext 24

--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
Ignatios Souvatzis
2007-08-23 04:52:13 UTC
Permalink
Post by David Young
I have lengthened sockaddr_dl so that it can accomodate a FireWire
address. That doesn't break any user<->kernel ABI, however, a number
of people have pointed out to me that it 3rd-party programs may rely on
sockaddr_dl's size remaining the same. I am going to return sockaddr_dl
to its historical size, and introduce sockaddr_link for the kernel to use.
The address family (sa_family) of both sockaddr_dl and sockaddr_link
remain the same (AF_LINK). I am also going to introduce macros CSLADDR()
and SLADDR() whose function is analogous to CLLADDR() and LLADDR().
I will rename all of the sockaddr_dl_*() routines in the kernel to
sockaddr_link_*(). Please let me know if this is going to break your
mother's back, make your cereal soggy, or stop your WiFi from working.
You'll keep ARP working with your change? Good.

-is
--
seal your e-mail: http://www.gnupg.org/

--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
Alan Barrett
2007-08-23 07:33:29 UTC
Permalink
Post by David Young
I have lengthened sockaddr_dl so that it can accomodate a FireWire
address. That doesn't break any user<->kernel ABI, however, a number
of people have pointed out to me that it 3rd-party programs may rely on
sockaddr_dl's size remaining the same.
Could you explain this in more detail? If no ABIs are affected, then
how could already-compiled third-party programs be affected? Or if
the third-party programs are recompiled against the new definition
of struct_dl, what could go wrong? Or are we talking about broken
third-party programs that think they "know" how big a sockaddr_dl is
without having to include any headers?
Post by David Young
I am going to return sockaddr_dl to its historical size, and introduce
sockaddr_link for the kernel to use. The address family (sa_family)
of both sockaddr_dl and sockaddr_link remain the same (AF_LINK). I am
also going to introduce macros CSLADDR() and SLADDR() whose function
is analogous to CLLADDR() and LLADDR(). I will rename all of the
sockaddr_dl_*() routines in the kernel to sockaddr_link_*(). Please
let me know if this is going to break your mother's back, make your
cereal soggy, or stop your WiFi from working.
How will we avoid having to do similar renames in future, say next time
somebody invents a link layer with an even longer address format?

--apb (Alan Barrett)

--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
der Mouse
2007-08-23 21:20:40 UTC
Permalink
[...], however, a number of people have pointed out to me that it
3rd-party programs may rely on sockaddr_dl's size remaining the
same.
Could you explain this in more detail? [...]
A third-party program might abuse sockaddr_dl by embedding it into a
wire format and assuming a fixed length.
Sure. But a third-party program might also assume little-endian; does
this mean that we have to avoid big-endian hardware? No, it means such
software is broken - at least if it's intended to be general-purpose.

Similarly, software that blindly assumes that a sockaddr_dl happens to
match a wire format, even if that format was defined based on what a
sockaddr_dl happened to look like at some point, is similarly broken.

Except for a very few structs defined that way for the purpose, it is
simply _broken_ to assume that a struct looks like anything in
particular when viewed as a chunk of bytes (as when overlaying it onto
a wire octet stream). (The only examples I can think of offhand for
the "very few" are things - like struct ip - that are not really
intended for general-purpose application code.)
If you recompile the program on NetBSD, then it might not be able to
speak with a second instance of the program, if that instance was
compiled with a different/older net/if_dl.h.
Right. This means the application code needs fixing.

I can write code that won't be able to interoperate between sparc and
vax because they use different floating-point formats. Does this mean
we need to have one of them fake the other's floating-point format? No,
it means the application code is broken in that portability respect! I
believe that the brokenness you describe is a bug in the application,
and explosing it this way is doing its author(s) a favour by pointing
up their erroneous assumptions.

I once ran into a wire protocol that depended on the exact layout of
the internal key schedules used by a particular DES library. Does this
mean that another DES library has to use the same key schedules? No,
it means there's a portability bug in the protocol design!
A hypothetical 3rd-party program that reads/writes AF_LINK sockaddrs
from/to the kernel, today, and that assumes AF_LINK sockaddrs of
fixed length, has always been broken. It will remain broken.
However, a hypothetical 3rd-party program that sends/receives AF_LINK
sockaddrs of fixed length to/from instances of itself will not break,
because we will not change the length of sockaddr_dl.
Such code has always been broken and will remain broken; I don't see
why it's a good thing to conceal this brokenness. There's no guarantee
our sockaddr_dl matches anyone else's; indeed, if sdl_index values not
multiples of 257 are used, our sockaddr_dl is not compatible between
arches of different endianness right now. As long ago as 1.4T,
sdl_data was already commented as "can be larger; contains both if name
and ll address". We cannot protect idiot code authors from all the
ways they can be idiots, and I believe it is no favour to them to try.

Do you know of any non-hypothetical examples? I suspect that such code
is rare enough that, quite aside from the principles I outlined above,
it's not unreasonable to not care about it.

/~\ The ASCII der Mouse
\ / Ribbon Campaign
X Against HTML ***@rodents.montreal.qc.ca
/ \ Email! 7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B

--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
David Young
2007-08-23 22:10:07 UTC
Permalink
Post by der Mouse
[...], however, a number of people have pointed out to me that it
3rd-party programs may rely on sockaddr_dl's size remaining the
same.
Could you explain this in more detail? [...]
A third-party program might abuse sockaddr_dl by embedding it into a
wire format and assuming a fixed length.
Sure. But a third-party program might also assume little-endian; does
this mean that we have to avoid big-endian hardware? No, it means such
software is broken - at least if it's intended to be general-purpose.
Similarly, software that blindly assumes that a sockaddr_dl happens to
match a wire format, even if that format was defined based on what a
sockaddr_dl happened to look like at some point, is similarly broken.
Except for a very few structs defined that way for the purpose, it is
simply _broken_ to assume that a struct looks like anything in
particular when viewed as a chunk of bytes (as when overlaying it onto
a wire octet stream). (The only examples I can think of offhand for
the "very few" are things - like struct ip - that are not really
intended for general-purpose application code.)
This is an important perspective. It sounds to me like we agree that
if a 3rd-party program depends on an AF_LINK sockaddr of fixed size,
then it is abusing sockaddr_dl. However, enough developers have told me
their concern that changing the size of sockaddr_dl will have unforeseen
consequences on 3rd-party programs, that I feel that I must respond.
And besides, even if 3rd-party software is not written to NetBSD's
standards, our users will not forgive us when it stops working.
Post by der Mouse
Do you know of any non-hypothetical examples? I suspect that such code
is rare enough that, quite aside from the principles I outlined above,
it's not unreasonable to not care about it.
I have the Quagga sources right before me, and it looks as if Quagga
embeds a sockaddr_dl in a wire-protocol packet. In quagga/lib/zclient.c,
zebra_interface_add_read(), I have found some sockaddr_dl abuse:

#ifdef HAVE_SOCKADDR_DL
stream_get (&ifp->sdl, s, sizeof (ifp->sdl));
#else
ifp->hw_addr_len = stream_getl (s);
if (ifp->hw_addr_len)
stream_get (ifp->hw_addr, s, ifp->hw_addr_len);
#endif /* HAVE_SOCKADDR_DL */

Elsewhere in Quagga, it looks as if someone intended to abuse sockaddr_dl
some more, but they did not finish.

Dave
--
David Young OJC Technologies
***@ojctech.com Urbana, IL * (217) 278-3933 ext 24

--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
Greg Troxel
2007-08-23 22:58:06 UTC
Permalink
Post by David Young
I have the Quagga sources right before me, and it looks as if Quagga
embeds a sockaddr_dl in a wire-protocol packet. In quagga/lib/zclient.c,
#ifdef HAVE_SOCKADDR_DL
stream_get (&ifp->sdl, s, sizeof (ifp->sdl));
#else
ifp->hw_addr_len = stream_getl (s);
if (ifp->hw_addr_len)
stream_get (ifp->hw_addr, s, ifp->hw_addr_len);
#endif /* HAVE_SOCKADDR_DL */
That's abuse in a 'wire protocol', but that seems to be in the
zebra/routing-daemon interface that's a) on machine and b) semi private
within quagga. It's not clear that changing the size will lead to
problems, assuming consistent compilation between zebra and e.g. ospfd.

Granted, this is gross on quagga's part, but I'm not sure it's a good
reason for workarounds.

--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
Loading...