+
+void dummynet (void*);
+VOID dummynet_dpc(
+ __in struct _KDPC *Dpc,
+ __in_opt PVOID DeferredContext,
+ __in_opt PVOID SystemArgument1,
+ __in_opt PVOID SystemArgument2
+ );
+
+VOID ipfw_dpc(
+ __in struct _KDPC *Dpc,
+ __in_opt PVOID DeferredContext,
+ __in_opt PVOID SystemArgument1,
+ __in_opt PVOID SystemArgument2
+ );
+
+/* callout_reset must handle two problems:
+ * - dummynet() scheduler must be run always on the same processor
+ * because do_gettimeofday() is based on cpu performance counter, and
+ * _occasionally_ can leap backward in time if we query another cpu.
+ * typically this won't happen that much, and the cpu will almost always
+ * be the same even without the affinity restriction, but better to be sure.
+ * - ipfw_tick() does not have the granularity requirements of dummynet()
+ * but we need to pass a pointer as argument.
+ *
+ * for these reasons, if we are called for dummynet() timer,
+ * KeInitializeDpc is called only once as it should be, and the thread
+ * is forced on cpu0 (which is always present), while if we're called
+ * for ipfw_tick(), we re-initialize the DPC each time, using
+ * parameter DeferredContext to pass the needed pointer. since this
+ * timer is called only once a sec, this won't hurt that much.
+ */