Here’s a quick quiz. Let’s say that you have a Linux kernel module, built against the same version of the kernel that you’re running but with one slightly different configuration option, and you try to load it. It will:

  1. Work correctly.
  2. Fail to load, because it is recognized as being incompatible.
  3. Load but fail to function, producing some error messages that explain the problem.
  4. Crash your system in an utterly non-obvious way.

The answer, of course, is D. It shouldn’t be, but it is, at least if what you’re loading is a network driver and the configuration option is netfilters. The reason is simply bad software engineering, similar to another example I wrote about seven years ago. Both of the examples I mention there have been fixed, by the way; I guess that senior developer I mentioned managed to put his new knowledge about pointers and caches into context enough to do the right thing (or allow someone else to) at some point. Without getting too far into the technical details, because that’s not the point I want to make, the problem in this case is that turning on netfilters in your kernel adds fields to the sk_buff structure – one universally needed by any networking code – and adds them in the middle. Thus, inline functions in network drivers try to modify some common fields and actually end up trashing the structure. I thought everyone knew that, at the very least, new or optional fields should be added at the end of a structure. Better still would be to put these special-purpose fields in a separate structure, allocated along with the sk_buff itself or hidden in an skb_reserve area (as is done in some similar cases). Structure versions would be nice too, so at least a mismatch could fail gracefully instead of messily.

Of course, some Linux hackers will say such things are just aesthetic, because you have the source and should always build against the exact same kernel you’re using anyway. Bull. For one thing, this doesn’t affect only developers but users as well. I might have the source, but Joe User might not. If I therefore have to provide Joe with binaries, I now need to provide exactly the right binaries for every possible configuration Joe might be using, and that’s a logistical nightmare. If anyone wants people like Joe to use Linux, they should consider what makes life easier for people like Joe, and this kind of silliness definitely doesn’t. Incompatibilities involving an integral part of an API that’s used by hundreds of packages maintained by thousands of different people should simply be handled better, and not introduced spuriously just because someone wants a few new fields for their own use and Linux-kernel politics preclude adding them the right way. If Linux is a private toy for a closed community you can do that. If it’s something you expect to gain broad acceptance you can’t.