ipfw initialization: SI_ORDER_ANY -> SI_ORDER_MIDDLE?

Paolo Pisati piso at freebsd.org
Sun Mar 2 07:10:13 PST 2008


On Sun, Mar 02, 2008 at 03:49:39PM +0100, Paolo Pisati wrote:
> Hi,
> 
> i just found out that depending on a KLD doesn't imply any
> initialization order, thus depending on a lock initialized in the ipfw
> init path is _really_ a bad idea from another KLD init path (see
> ip_fw_nat.c::ipfw_nat_init()).
> 
> A fix would be to move ipfw init priority from SI_ORDER_ANY to
> SI_ORDER_MIDDLE, but i guess there are side effects that i'm
> unaware in this modification...
> 
> On the other hand, if we keep ipfw at SI_ORDER_ANY, i don't know how
> to build stuff that relies on it without opening race conditions:
> see ip_fw_nat.c::flush_nat_ptrs() called in rule deletion and
> rule configuration paths.

as the problem arises only during ip_fw_nat initialization, another
viable solution would be to fix ipfw_nat_init() this way:

static void
ipfw_nat_init(void)
{

-        IPFW_WLOCK(&layer3_chain);
         /* init ipfw hooks */
-        ipfw_nat_ptr = ipfw_nat;
         ipfw_nat_cfg_ptr = ipfw_nat_cfg;
         ipfw_nat_del_ptr = ipfw_nat_del;
         ipfw_nat_get_cfg_ptr = ipfw_nat_get_cfg;
         ipfw_nat_get_log_ptr = ipfw_nat_get_log;
-        IPFW_WUNLOCK(&layer3_chain);
+	 ipfw_nat_ptr = ipfw_nat;
         ifaddr_event_tag = EVENTHANDLER_REGISTER(ifaddr_event, ifaddr_change, 
             NULL, EVENTHANDLER_PRI_ANY);
}

avoid grabbing the lock at all during init, and exploit orders of
hooks initialization: as the presence of ipfw_nat in ipfw is checked
via ipfw_nat_ptr, i can narrow/close the race window initializing
ipfw_nat_ptr at the end of the function, but can i trust the order of
variables assignment? i guess no without some sort of memory barriers,
and are memory barriers available in all archs? and are memory
barriers enough?

bye,
P.



More information about the freebsd-net mailing list