NetBSD-current pfil_hooksとpf

ip_flowに関する調査の続き。

pfil_hooksは複数のフィルタフレームワークを切り替えて使う為の機構だと思われる。

pfil_add_hook()/pfil_remove_hook()でフック関数を追加・削除、
pfil_run_hooks()でプロトコルスタック内からフック関数群を実行する。

フック関数はフラグによって以下のような種類分けがされている:

/*
 * pfil_add_hook() adds a function to the packet filter hook.  the
 * flags are:
 *	PFIL_IN		call me on incoming packets
 *	PFIL_OUT	call me on outgoing packets
 *	PFIL_ALL	call me on all of the above
 *	PFIL_IFADDR  	call me on interface reconfig (mbuf ** is ioctl #)
 *	PFIL_IFNET  	call me on interface attach/detach
 *			(mbuf ** is PFIL_IFNET_*)
 *	PFIL_WAITOK	OK to call malloc with M_WAITOK.
 */

ether_input()で指定しているフラグは

#ifdef PFIL_HOOKS
	if ((error = pfil_run_hooks(&ifp->if_pfil, &m, ifp, PFIL_OUT)) != 0)
		return (error);
	if (m == NULL)
		return (0);
#endif

なのでPFIL_OUTである。

一方、dist/pf以下を調べてみると、以下のようなhookが登録されている:

--
dist/pf/net/pf_ioctl.c:         error = pfil_add_hook((void
*)pfil4_wrapper, NULL,
dist/pf/net/pf_ioctl.c-             PFIL_IN|PFIL_OUT, ph_inet);
--
dist/pf/net/pf_ioctl.c:         error = pfil_add_hook((void
*)pfil6_wrapper, NULL,
dist/pf/net/pf_ioctl.c-             PFIL_IN|PFIL_OUT, ph_inet6);
--
dist/pf/net/pf_if.c:    pfil_add_hook(pfil_ifnet_wrapper, NULL,
PFIL_IFNET, &if_pfil);
dist/pf/net/pf_if.c:    pfil_add_hook(pfil_ifaddr_wrapper, NULL,
PFIL_IFADDR, &if_pfil);
dist/pf/net/pf_if.c-#endif /* __NetBSD__ */

という訳で、ether_input()からはpfil4_wrapper, pfil6_wrapperが呼ばれるものと思われる。

pfil4_wrapper()をみてみると、以下のような事をやっている:
・mbuf関連の処理
チェックサム関連の処理
・pf_test()を呼ぶ(多分これがpfのフィルタ部分)
・mbufのフラグからM_CANFASTFWDを外す

最後の部分については、we're not compatible with fast-forward.と明記されている。
つまり、pfが有効な限りはfast-forwardされることはない。