Date: Tue, 21 Apr 2009 23:16:58 -0600 From: Will Andrews <will@firepipe.net> To: freebsd-net@freebsd.org Subject: CARP as a module; followup thoughts Message-ID: <2aada3410904212216o128e1fdfx8c299b3531adc694@mail.gmail.com>
next in thread | raw e-mail | index | archive | help
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.
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?2aada3410904212216o128e1fdfx8c299b3531adc694>