X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=dummynet2%2Fipfw2_mod.c;fp=dummynet2%2Fipfw2_mod.c;h=1ea6e5718b6511bf184ccf8c27074636152592fa;hb=40445faa1db58b90083115bc315d095e7eb2fe51;hp=f59a37c178421cde9d2df1de0573b6dbebf1d494;hpb=fccf30d4bf6b00b317756a9ff9d2135b361d2599;p=ipfw.git diff --git a/dummynet2/ipfw2_mod.c b/dummynet2/ipfw2_mod.c index f59a37c..1ea6e57 100644 --- a/dummynet2/ipfw2_mod.c +++ b/dummynet2/ipfw2_mod.c @@ -24,7 +24,7 @@ */ /* - * $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 @@ -70,6 +70,9 @@ #include /* ip_fw_ctl_t, ip_fw_chk_t */ #include /* ip_dn_ctl_t, ip_dn_io_t */ #include /* PFIL_IN, PFIL_OUT */ + +#ifdef __linux__ + #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) #warning --- inet_hashtables not present on 2.4 #include @@ -83,6 +86,8 @@ static inline int inet_iif(const struct sk_buff *skb) #else #include /* inet_lookup */ #endif +#endif /* __linux__ */ + #include /* inet_iif */ /* @@ -98,6 +103,12 @@ ip_fw_chk_t *ip_fw_chk_ptr; 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 @@ -130,8 +141,13 @@ int 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])) @@ -199,49 +215,42 @@ ipfw_ctl_h(struct sockopt *s, int cmd, int dir, int len, void __user *user) 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) { @@ -252,6 +261,8 @@ do_ipfw_get_ctl(struct sock __unused *sk, return ret; } +#ifdef __linux__ + /* * declare our [get|set]sockopt hooks */ @@ -405,7 +416,7 @@ ipfw2_queue_handler(QH_ARGS) } 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; @@ -463,15 +474,6 @@ netisr_dispatch(int num, struct mbuf *m) 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, @@ -674,13 +676,18 @@ static struct nf_hook_ops ipfw_ops[] __read_mostly = { 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; @@ -689,27 +696,37 @@ extern void *sysuninit_vnet_ipfw_uninit; /* * 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) { @@ -740,21 +757,26 @@ clean_modules: 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();