*/
/*
- * $Id: ipfw2_mod.c 4671 2010-01-04 17:50:51Z luigi $
+ * $Id: ipfw2_mod.c 5797 2010-03-21 16:31:08Z luigi $
*
* The main interface to build ipfw+dummynet as a linux module.
* (and possibly as a windows module as well, though that part
#include <netinet/ipfw/ip_fw_private.h> /* ip_fw_ctl_t, ip_fw_chk_t */
#include <netinet/ip_dummynet.h> /* ip_dn_ctl_t, ip_dn_io_t */
#include <net/pfil.h> /* PFIL_IN, PFIL_OUT */
+
+#ifdef __linux__
+
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
#warning --- inet_hashtables not present on 2.4
#include <linux/tcp.h>
#else
#include <net/inet_hashtables.h> /* inet_lookup */
#endif
+#endif /* __linux__ */
+
#include <net/route.h> /* inet_iif */
/*
void (*bridge_dn_p)(struct mbuf *, struct ifnet *);
+/* Divert hooks. */
+void (*ip_divert_ptr)(struct mbuf *m, int incoming);
+
+/* ng_ipfw hooks. */
+ng_ipfw_input_t *ng_ipfw_input_p = NULL;
+
/*---
* Glue code to implement the registration of children with the parent.
* Each child should call my_mod_register() when linking, so that
my_mod_register(const char *name, int order,
struct moduledata *mod, void *init, void *uninit)
{
- struct mod_args m = { .name = name, .order = order,
- .mod = mod, .init = init, .uninit = uninit };
+ struct mod_args m;
+
+ m.name = name;
+ m.order = order;
+ m.mod = mod;
+ m.init = init;
+ m.uninit = uninit;
printf("%s %s called\n", __FUNCTION__, name);
if (mod_idx < sizeof(mods) / sizeof(mods[0]))
memset(&t, 0, sizeof(t));
s->sopt_td = &t;
- // printf("%s called with cmd %d len %d\n", __FUNCTION__, cmd, len);
+ //printf("%s called with cmd %d len %d sopt %p user %p\n", __FUNCTION__, cmd, len, s, user);
- if (cmd < IP_DUMMYNET_CONFIGURE && ip_fw_ctl_ptr)
+ if (ip_fw_ctl_ptr && cmd != IP_DUMMYNET3 && (cmd == IP_FW3 ||
+ cmd < IP_DUMMYNET_CONFIGURE))
ret = ip_fw_ctl_ptr(s);
- else if (cmd >= IP_DUMMYNET_CONFIGURE && ip_dn_ctl_ptr)
+ else if (ip_dn_ctl_ptr && (cmd == IP_DUMMYNET3 ||
+ cmd >= IP_DUMMYNET_CONFIGURE))
ret = ip_dn_ctl_ptr(s);
-
+
return -ret; /* errors are < 0 on linux */
}
-#ifdef _WIN32
-
-void
-netisr_dispatch(int __unused num, struct mbuf *m)
-{
-}
-
int
ip_output(struct mbuf *m, struct mbuf __unused *opt,
struct route __unused *ro, int __unused flags,
struct ip_moptions __unused *imo, struct inpcb __unused *inp)
{
netisr_dispatch(0, m);
- return 0;
+ return 0;
}
-#else /* this is the linux glue */
/*
* setsockopt hook has no return value other than the error code.
*/
-static int
+int
do_ipfw_set_ctl(struct sock __unused *sk, int cmd,
void __user *user, unsigned int len)
{
struct sockopt s; /* pass arguments */
-
return ipfw_ctl_h(&s, cmd, SOPT_SET, len, user);
}
/*
* getsockopt can can return a block of data in response.
*/
-static int
+int
do_ipfw_get_ctl(struct sock __unused *sk,
int cmd, void __user *user, int *len)
{
return ret;
}
+#ifdef __linux__
+
/*
* declare our [get|set]sockopt hooks
*/
}
m->m_skb = skb;
- m->m_len = skb->len; /* len in this skbuf */
+ m->m_len = skb->len; /* len from ip header to end */
m->m_pkthdr.len = skb->len; /* total packet len */
m->m_pkthdr.rcvif = info->indev;
m->queue_entry = info;
REINJECT(info, ((num == -1)?NF_DROP:NF_STOP)); /* accept but no more firewall */
}
-int
-ip_output(struct mbuf *m, struct mbuf __unused *opt,
- struct route __unused *ro, int __unused flags,
- struct ip_moptions __unused *imo, struct inpcb __unused *inp)
-{
- netisr_dispatch(0, m);
- return 0;
-}
-
/*
* socket lookup function for linux.
* This code is used to associate uid, gid, jail/xid to packets,
SET_MOD_OWNER
},
};
-#endif /* !__linux__ */
+#endif /* __linux__ */
/* descriptors for the children, until i find a way for the
* linker to produce them
*/
extern moduledata_t *moddesc_ipfw;
extern moduledata_t *moddesc_dummynet;
+extern moduledata_t *moddesc_dn_fifo;
+extern moduledata_t *moddesc_dn_wf2qp;
+extern moduledata_t *moddesc_dn_rr;
+extern moduledata_t *moddesc_dn_qfq;
+extern moduledata_t *moddesc_dn_prio;
extern void *sysinit_ipfw_init;
extern void *sysuninit_ipfw_destroy;
extern void *sysinit_vnet_ipfw_init;
/*
* Module glue - init and exit function.
*/
-static int __init
+int __init
ipfw_module_init(void)
{
int ret = 0;
-
- printf("%s in-hook %d svn id %s\n", __FUNCTION__, IPFW_HOOK_IN, "$Id: ipfw2_mod.c 4671 2010-01-04 17:50:51Z luigi $");
+#ifdef _WIN32
+ unsigned long resolution;
+#endif
rn_init(64);
-
my_mod_register("ipfw", 1, moddesc_ipfw, NULL, NULL);
my_mod_register("sy_ipfw", 2, NULL,
sysinit_ipfw_init, sysuninit_ipfw_destroy);
my_mod_register("sy_Vnet_ipfw", 3, NULL,
sysinit_vnet_ipfw_init, sysuninit_vnet_ipfw_uninit);
my_mod_register("dummynet", 4, moddesc_dummynet, NULL, NULL);
+ my_mod_register("dn_fifo", 5, moddesc_dn_fifo, NULL, NULL);
+ my_mod_register("dn_wf2qp", 6, moddesc_dn_wf2qp, NULL, NULL);
+ my_mod_register("dn_rr", 7, moddesc_dn_rr, NULL, NULL);
+ my_mod_register("dn_qfq", 8, moddesc_dn_qfq, NULL, NULL);
+ my_mod_register("dn_prio", 9, moddesc_dn_prio, NULL, NULL);
init_children();
#ifdef _WIN32
- return ret;
+ resolution = ExSetTimerResolution(1, TRUE);
+ printf("*** ExSetTimerResolution: resolution set to %d n-sec ***\n",resolution);
+#endif
+#ifdef EMULATE_SYSCTL
+ keinit_GST();
+#endif
-#else /* linux hook */
+#ifdef __linux__
/* sockopt register, in order to talk with user space */
ret = nf_register_sockopt(&ipfw_sockopts);
if (ret < 0) {
fini_children();
printf("%s error\n", __FUNCTION__);
+#endif /* __linux__ */
return ret;
-#endif /* linux */
}
/* module shutdown */
-static void __exit
+void __exit
ipfw_module_exit(void)
{
+#ifdef EMULATE_SYSCTL
+ keexit_GST();
+#endif
#ifdef _WIN32
+ ExSetTimerResolution(0,FALSE);
+
#else /* linux hook */
nf_unregister_hooks(ipfw_ops, ARRAY_SIZE(ipfw_ops));
/* maybe drain the queue before unregistering ? */
nf_unregister_queue_handler(PF_INET UNREG_QH_ARG(ipfw2_queue_handler) );
nf_unregister_sockopt(&ipfw_sockopts);
-#endif /* linux */
+#endif /* __linux__ */
fini_children();