CARP as a module; followup thoughts

Will Andrews will at firepipe.net
Wed Apr 22 05:45:17 UTC 2009


Hello,

I've written a patch (against 8.0-CURRENT as of r191369) which makes
it possible to build, load, run, & unload CARP as a module, using the
GENERIC kernel.  It can be obtained from:

http://firepipe.net/patches/carp-as-module-20090421.diff

Having written this patch, I have some thoughts.  First of all, this
patch follows the same pattern of function pointers used by if_lagg,
if_vlan, ng_ether, bpf, and if_bridge.  While it works, this approach
(along with that used by the other interfaces) is a hackish way to
implement the interfaces as kernel modules.

It appears that each one needs to have its hooks inserted at a
specific point in the packet processing.  So it seems to me that a
better way to do this would be to implement a generic network protocol
interface and have everything that processes packets register its
hooks with that interface.  Which if_* seems to do to an extent, but
not enough to meet the requirements of the above-mentioned network
protocols.

More to the point, netinet/in_proto.c & netinet6/in6_proto.c use
hardcoded protocol definition structures.  Until this diff introduced
in{6,}_proto_{un,}register(), there was no way to define hooks for any
other protocols without hacking these files or compiling with
different options (like DEV_CARP).

I envision a struct ifnet_hooks array that includes hooks that can be
registered by any protocol for packet processing at any point,
including: pre-input, input, post-input, pre-output, output,
post-output, link state change, route, etc.  Then each struct ifnet
would contain a list of these pointers, to be configured in a given
order depending on the administrator's needs.  The interface would run
through the list for a given stage and run the protocol specific
function pointer to perform its processing at that stage.

Of course, that is probably a much too simplistic idea (there are a
lot of special cases it seems).  And the reality is, there is already
something in FreeBSD that makes arbitrary packet processing hook order
possible - netgraph.  So why is it FreeBSD allows these modules when
there are netgraph equivalents for all of them (currently, except
CARP)?  More to the point, why isn't netgraph used for most (if not
all) packet processing?

Has anyone tried to build a kernel without INET?  It's not pretty, and
demonstrates the biases the stack has towards IPv4 vs. other protocols
like IPv6.  In other words, there's lots of code that looks like this:

    <some IPv4 specific stuff>
#ifdef INET6
    <some IPv6 specific stuff>
#endif

It would be nice if the stack didn't assume any particular protocol
base; making all protocols optional (except as explicitly defined by
direct dependency) seems a worthy goal.

I think it also might be useful to third party developers if they
didn't have to modify anything in the base kernel to insert a new
protocol in the stack.

I'm sure most of this sounds like rambling from a crazed lunatic or
something, but I'm also sure most who understand my patch agree that
it isn't the nicest of ways to make it possible to load carp (or any
other protocol) as a module.

Regards,
--Will.


More information about the freebsd-net mailing list