├── ChangeLog.txt ├── Changelog_iptables.txt ├── Credits.txt ├── License.txt ├── README.md ├── SECURITY.md ├── iptables ├── iptables-1.2.5-imq.diff ├── iptables-1.2.6a-imq.diff ├── iptables-1.2.9-imq1.diff ├── iptables-1.3.0-imq1.diff ├── iptables-1.3.6-imq.diff ├── iptables-1.4.0-imq.diff ├── iptables-1.4.1-imq.diff ├── iptables-1.4.10-imq.diff ├── iptables-1.4.12-imq.diff ├── iptables-1.4.13-imq.diff ├── iptables-1.4.3.2-imq_xt.diff ├── iptables-1.4.4-imq.diff ├── iptables-1.4.6-imq.diff └── iptables-1.6.0-imq.diff └── kernel ├── v2.4 ├── debian │ ├── imq-combo-debian-2.4.22.diff │ ├── imq-combo-debian.diff │ └── linux-2.4.24-imq-combo-debian.diff ├── linux-2.4.18-imq.diff ├── linux-2.4.21-imq-1.diff ├── linux-2.4.24-imq.diff ├── linux-2.4.26-imq.diff └── linux-2.4.28-imq2.diff ├── v2.6-multiqueue ├── README ├── linux-2.6.35-imq.diff ├── linux-2.6.37-imq.diff ├── linux-2.6.38-imq.diff ├── linux-2.6.39-imq-fixqueuemapping.diff ├── linux-2.6.39-imq.diff └── load-imq-multiqueue.sh ├── v2.6 ├── linux-2.6.0-imq.diff ├── linux-2.6.1-imq.diff ├── linux-2.6.13-imq.diff ├── linux-2.6.14-imq.diff ├── linux-2.6.16-imq.diff ├── linux-2.6.17-imq.diff ├── linux-2.6.18-imq-2.diff ├── linux-2.6.18-imq.diff ├── linux-2.6.19-imq.diff ├── linux-2.6.2-imq.diff ├── linux-2.6.2-rc1-imq.diff ├── linux-2.6.20-imq.diff ├── linux-2.6.21-imq-2.diff ├── linux-2.6.21-imq.diff ├── linux-2.6.22-imq.diff ├── linux-2.6.23-imq.diff ├── linux-2.6.24-imq.diff ├── linux-2.6.25-imq.diff ├── linux-2.6.26-imq.diff ├── linux-2.6.26.8-imq.diff ├── linux-2.6.27.21-imq.diff ├── linux-2.6.28.9-imq.diff ├── linux-2.6.29.1-imq.diff ├── linux-2.6.30.8-imq.diff ├── linux-2.6.31.6-imq.diff ├── linux-2.6.32-imq.diff ├── linux-2.6.33-imq.diff ├── linux-2.6.33.4-imq.diff ├── linux-2.6.34-imq.diff ├── linux-2.6.35-imq.diff ├── linux-2.6.7-imq.diff ├── linux-2.6.8-imq-2.diff ├── linux-2.6.8-imq.diff └── linux-2.6.9-imq.diff ├── v3.x ├── README ├── gentoo │ └── linux-3.13.10_hardened_gentoo.diff ├── linux-3.0-imq.diff ├── linux-3.1-imq.diff ├── linux-3.10-imq.diff ├── linux-3.10.27-imq.diff ├── linux-3.11-imq.diff ├── linux-3.12-imq.diff ├── linux-3.12.4-imq.diff ├── linux-3.13-imq.diff ├── linux-3.14-imq.diff ├── linux-3.18-imq.diff ├── linux-3.2-imq.diff ├── linux-3.3-imq.diff ├── linux-3.5.x-imq.diff ├── linux-3.7-imq.diff └── linux-3.9.x-imq.diff ├── v4.x ├── README ├── linux-4.0-imq.diff ├── linux-4.1-imq.diff ├── linux-4.10-imq.diff ├── linux-4.11-imq.diff ├── linux-4.12-imq.diff ├── linux-4.13-imq.diff ├── linux-4.14-imq.diff ├── linux-4.16-imq.diff ├── linux-4.19-imq.diff ├── linux-4.2-imq.diff ├── linux-4.20-imq.diff ├── linux-4.3-imq.diff ├── linux-4.4-imq.diff ├── linux-4.4.32-imq.diff ├── linux-4.4.5-imq.diff ├── linux-4.5-imq.diff ├── linux-4.6-imq.diff ├── linux-4.7-imq.diff ├── linux-4.8-imq.diff ├── linux-4.8.8-imq.diff └── linux-4.9-imq.diff ├── v5.x ├── linux-5.0-imq.patch ├── linux-5.1-imq.patch ├── linux-5.10-imq.patch ├── linux-5.2-imq.patch ├── linux-5.3-imq.patch ├── linux-5.4-imq.patch └── linux-5.9-imq.patch └── v6.x ├── linux-6.1-imq.patch └── linux-6.11.x-imq.patch /ChangeLog.txt: -------------------------------------------------------------------------------- 1 | IMQ changelog: 2 | -------------- 3 | 2024-08-18 4 | ----------- 5 | Patch for kernel 6.11 6 | 7 | 2023-05-12 8 | ----------- 9 | 10 | Sven-Haegar Koch 11 | Sometimes skb->dev->real_num_tx_queues can be zero, perhaps while 12 | updating the shaping queues. 13 | If this happens take the safe route and clear the queue mapping 14 | instead of crashing the kernel. 15 | Patch for kernel 6.x 16 | 17 | 2020-01-15 18 | ----------- 19 | Removed unsed locks 20 | changed net/core/skbuff.c to "spin_lock_irqsave(&skb_cb_store_lock, flags)" 21 | 22 | 2019-11-26 23 | ---------- 24 | Patch for kernel 5.4 25 | 26 | 2019-09-17 27 | ---------- 28 | Patch for kernel 5.3 29 | 30 | 2019-07-08 31 | ---------- 32 | Patch for kernel 5.2 33 | 34 | 2019-05-07 35 | ---------- 36 | Patch for kernel 5.1 37 | 38 | 2019-03-04 39 | ---------- 40 | Patch for kernel 5.0 41 | 42 | 2018-12-28 43 | ---------- 44 | Patch for kernel 4.20 45 | 46 | 2018-04-01 47 | ---------- 48 | Patch for kernel 4.16 49 | 50 | 2017-12-06 51 | ---------- 52 | Removed unused directories from the repo. 53 | 54 | 2017-11-20 55 | ---------- 56 | Patch for kernel 4.14 57 | 58 | 2017-09-04 59 | ---------- 60 | Patch for kernel 4.13 61 | 62 | 2017-07-04 63 | ---------- 64 | Patch for kernel 4.12 65 | 66 | 2017-05-01 67 | ---------- 68 | Patch for kernel 4.11 69 | 70 | 2017-02-28 71 | ---------- 72 | Patch for kernel 4.10 73 | 74 | 2017-01-17 75 | ---------- 76 | Patch for kernel 4.9 77 | 78 | 2016-12-04 79 | ---------- 80 | Patch for kernel 4.4.32 81 | 82 | 2016-11-17 83 | ---------- 84 | Patch for kernel 4.8.8 85 | 86 | 2016-10-03 87 | ---------- 88 | Patch for kernel 4.8 89 | 90 | 2016-07-26 91 | ---------- 92 | Patch for kernel 4.7 93 | 94 | 2016-06-12 95 | ---------- 96 | Patch for kernel 4.6 97 | 98 | 2016-03-30 99 | ---------- 100 | Patch for kernel 4.4 and 4.4.5 101 | 102 | 2015-12-26 103 | ---------- 104 | Patch for kernel 4.4 105 | 106 | 2015-09-29 107 | ---------- 108 | Patch for kernel 4.3 109 | 110 | 2015-08-12 111 | ---------- 112 | Patch for kernel 4.2 113 | 114 | 2015-06-25 115 | ---------- 116 | Feng Gao add one new parameter of IMQ module(3.18,4.0,and 4.1), imq_dev_accurate_stats (default is 1). 117 | It is used to notify if IMQ get the accurate stats. 118 | When imq_dev_accurate_stats is 0, it could avoid one spin to enhance the performance. 119 | 120 | 2015-06-24 121 | ---------- 122 | Feng Gao removed usless skb_cb_store_lock of 4.0 patch. It will be merged into other patches if it is ok. 123 | Fixed malformed linux-3.2-imq.diff, linux-3.10-imq.diff, linux-3.12-imq.diff 124 | 125 | 2015-06-23 126 | ---------- 127 | Feng Gao fix one hang issue caused by IPv6 and shutdown interfaces before remove IMQ rule of IPv6 128 | 129 | 2015-06-20 130 | ---------- 131 | Feng Gao support for kernel 4.1 132 | 133 | 2015-06-19 134 | ---------- 135 | Feng Gao support for kernel 4.0 and fix the hang issue and crash issue by the performance enhancement. 136 | 137 | 2015-06-17 138 | ---------- 139 | Feng Gao support for kernel 3.18 and 3.14; 140 | And make one enhancement for IMQ performance. It could enhance IMQ Performance about 20%. 141 | 142 | 2014-02-24 143 | ---------- 144 | patch for kernel 3.13.x 145 | 146 | 2014-01-21 147 | ---------- 148 | Please don't use patch from 3.11.x on 3.12.4+ Kernels because you will get a warning message in the logs: 149 | 150 | skbuff: IMQ: kfree_skb: skb->nf_queue_entry != NULL 151 | 152 | 2013-10-06 153 | ---------- 154 | Jussi Kivilinna support kernel 3.11.x 155 | 2013-09-24 156 | ---------- 157 | Support Kernel 3.9.10 158 | 159 | 2013-07-20 160 | ---------- 161 | Support Kernel 3.9.1. It should work on 3.9.x also. 162 | 2012/12/23: 163 | ----------- 164 | Support Kernel 3.7 165 | 166 | 2012/09/25: 167 | ----------- 168 | Minor change in net/netfilter/Makefile. 169 | Patch for 3.3.x also works for 3.4.x 170 | 2012/03/19: 171 | ----------- 172 | Jussi Kivilinna : 173 | - Port to 3.3 174 | 175 | 2012/01/05: 176 | ----------- 177 | Jussi Kivilinna : 178 | - Port to 3.2 179 | 180 | 2011/11/04: 181 | ----------- 182 | Jussi Kivilinna : 183 | - Port to 3.1 184 | - Clean-up, move 'get imq device pointer by imqX name' to 185 | separate function from imq_nf_queue(). 186 | 187 | 2011/11/03: 188 | ----------- 189 | Germano Michel : 190 | - Fix IMQ for net namespaces 191 | 192 | 193 | 2011/08/16: 194 | ----------- 195 | Jussi Kivilinna: 196 | - Clear IFF_TX_SKB_SHARING flag that was added for linux 3.0.2 197 | 198 | 2011/07/26: 199 | ----------- 200 | Jussi Kivilinna: 201 | - Add queue mapping checks for packets exiting IMQ. 202 | - Port to 3.0 203 | 204 | 2011/07/12: 205 | ----------- 206 | syoder89@gmail.com: 207 | - Crash fix that happens when the receiving interface has more 208 | than one queue (add missing skb_set_queue_mapping in 209 | imq_select_queue). 210 | 211 | 2011/03/18: 212 | ----------- 213 | Jussi Kivilinna: 214 | - Port to 2.6.38 215 | 216 | 2010/08/15: 217 | ----------- 218 | Jussi Kivilinna: 219 | - Port to 2.6.35 220 | - Simplify hook registration by using nf_register_hooks. 221 | - nf_reinject doesn't need spinlock around it, therefore remove 222 | imq_nf_reinject function. Other nf_reinject users protect 223 | their own data with spinlock. With IMQ however all data is 224 | needed is stored per skbuff, so no locking is needed. 225 | - Changed IMQ to use 'separate' NF_IMQ_QUEUE instead of 226 | NF_QUEUE, this allows working coexistance of IMQ and other 227 | NF_QUEUE users. 228 | - Make IMQ multi-queue. Number of IMQ device queues can be 229 | increased with 'numqueues' module parameters. Default number 230 | of queues is 1, in other words by default IMQ works as 231 | single-queue device. Multi-queue selection is based on 232 | IFB multi-queue patch by Changli Gao . 233 | 234 | 235 | 2010/02/25: 236 | ----------- 237 | Jussi Kivilinna: 238 | - Port to 2.6.33 239 | 240 | 2009/12/08: 241 | ----------- 242 | Jussi Kivilinna: 243 | - Port to 2.6.32 244 | - Add check for skb->nf_queue_entry==NULL in imq_dev_xmit() 245 | - Also add better error checking for skb->nf_queue_entry usage 246 | 247 | 248 | 2009/09/26: 249 | ----------- 250 | Jussi Kivilinna: 251 | - Add imq_nf_reinject_lockless to fix deadlock with 252 | imq_nf_queue/imq_nf_reinject. 253 | 254 | 255 | 2009/04/20: 256 | ----------- 257 | Jussi Kivilinna: 258 | - Use netdevice feature flags to avoid extra packet handling 259 | by core networking layer and possibly increase performance. 260 | 261 | 262 | 2009/04/12: 263 | ----------- 264 | Jussi Kivilinna: 265 | - 2.6.27 and newer overwrite control buffer. 266 | - Add skb_save_cb/skb_restore_cb helper functions for backuping 267 | control buffer. This is needed because qdisc-layer on kernels 268 | - Add better locking for IMQ device. Hopefully this will solve SMP issues. 269 | - Port to 2.6.27 270 | - Port to 2.6.28 271 | - Port to 2.6.29 + fix rmmod not working 272 | 273 | 274 | 2008/08/06: 275 | ----------- 276 | 2.6.26 - (JK) 277 | - Replaced tasklet with 'netif_schedule()'. 278 | - Cleaned up and added comments for imq_nf_queue(). 279 | 280 | 281 | 2008/06/17: 282 | ----------- 283 | 2.6.25 - Changed imq.c to use qdisc_run() instead of qdisc_restart() and moved 284 | qdisc_run() to tasklet to avoid recursive locking. 285 | New initialization routines to fix 'rmmod' not working anymore. Used code from ifb.c. (Jussi Kivilinna) 286 | 287 | 288 | 2005/12/16: 289 | ----------- 290 | IMQ versions between 2.6.7 and 2.6.13 were released with almost no problems. 291 | 2.6.14-x was released with some important changes: nfcache was removed. 292 | After some weeks of trouble we figured out that some IMQ fields in skb were missing 293 | in skbuff.c - skb_clone and copy_skb_header. 294 | These functions are correctly patched by this new patch version. 295 | Thanks for all who helped to figure out all the problems with 296 | 2.6.14.x: 297 | - Patrick McHardy, Rune Kock, VeNoMouS, Max CtRiX, Kevin Shanahan, Richard Lucassen, 298 | Valery Dachev (hopefully I didn't forget anybody). I apologize again for my lack of time. 299 | 300 | 301 | 2004/06/30: 302 | ----------- 303 | New version of IMQ patch to kernels <=2.6.7 including the following changes: 304 | - Correction of ipv6 support "+"s issue (Hasso Tepper) 305 | - Correction of imq_init_devs() issue that resulted in kernel OOPS unloading IMQ as module (Norbert Buchmuller) 306 | - Addition of functionality to choose number of IMQ devices during kernel config (Andre Correa) 307 | - Addition of functionality to choose how IMQ hooks on PRE and POSTROUTING (after or before NAT) (Andre Correa) 308 | - Cosmetic corrections (Norbert Buchmuller) (Andre Correa) 309 | -------------------------------------------------------------------------------- /Changelog_iptables.txt: -------------------------------------------------------------------------------- 1 | IPTABLES changelog: 2 | ------------------- 3 | Patch for iptables 1.6.0 (2016-05-17) 4 | Patch for iptables 1.4.13.x, 1.4.14.x and 1.4.15.x 5 | Patch for iptables 1.4.12.x (by Adrian Ban) 6 | Patch for iptables 1.4.10 (by Adrian Ban) 7 | Patch for iptables 1.4.6 (by Adrian Ban) 8 | Patch for iptables 1.4.4 (by Zabavschi Vlad, thanks to Jussi Kivilinna) 9 | Patch for iptables 1.4.3.2 (by Zabavschi Vlad, thanks to Jussi Kivilinna) 10 | Patch for iptables 1.4.1 (2008-07-19 by Danny Rawlins) 11 | Patch for iptables 1.4.0 12 | Patch for iptables 1.3.6 up to 1.3.8 13 | Patch for iptables 1.3.0 up to 1.3.5 14 | Patch for iptables up to 1.2.11 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /Credits.txt: -------------------------------------------------------------------------------- 1 | 2 | Jan Rafaj 3 | - Update patch to 2.4.21 4 | 5 | Sebastian Strollo 6 | - Fix "Dead-loop on netdevice imq"-issue 7 | 8 | Marcel Sebek 9 | - Update to 2.6.2-rc1 10 | 11 | 2004/06/30 - New version of IMQ patch to kernels <=2.6.7 including the following changes: 12 | 13 | - Correction of ipv6 support "+"s issue (Hasso Tepper) 14 | - Correction of imq_init_devs() issue that resulted in kernel OOPS unloading IMQ as module (Norbert Buchmuller) 15 | - Addition of functionality to choose number of IMQ devices during kernel config (Andre Correa) 16 | - Addition of functionality to choose how IMQ hooks on PRE and POSTROUTING (after or before NAT) (Andre Correa) 17 | - Cosmetic corrections (Norbert Buchmuller) (Andre Correa) 18 | 19 | 20 | 2005/12/16 - IMQ versions between 2.6.7 and 2.6.13 were released with almost no problems. 2.6.14-x was released 21 | with some important changes: nfcache was removed. 22 | After some weeks of trouble we figured out that some IMQ fields in skb were missing in skbuff.c - skb_clone and copy_skb_header. 23 | These functions are correctly patched by this new patch version. 24 | 25 | Thanks for all who helped to figure out all the problems with 2.6.14.x: Patrick McHardy, Rune Kock, VeNoMouS, Max CtRiX, 26 | Kevin Shanahan, Richard Lucassen, Valery Dachev (hopefully I didn't forget anybody). I apologize again for my lack of time. 27 | 28 | 29 | 2008/06/17 - 2.6.25 - Changed imq.c to use qdisc_run() instead of qdisc_restart() and moved qdisc_run() to tasklet to avoid 30 | recursive locking. New initialization routines to fix 'rmmod' not working anymore. Used code from ifb.c. (Jussi Kivilinna) 31 | 32 | 2008/08/06 - 2.6.26 - (JK) 33 | - Replaced tasklet with 'netif_schedule()'. 34 | - Cleaned up and added comments for imq_nf_queue(). 35 | 36 | 2009/04/12 37 | - Add skb_save_cb/skb_restore_cb helper functions for backuping control buffer. 38 | This is needed because qdisc-layer on kernels 2.6.27 and newer overwrite control buffer. (Jussi Kivilinna) 39 | - Add better locking for IMQ device. Hopefully this will solve SMP issues. (Jussi Kivilinna) 40 | - Port to 2.6.27 41 | - Port to 2.6.28 42 | - Port to 2.6.29 + fix rmmod not working 43 | 44 | 2009/04/20 - (Jussi Kivilinna) 45 | - Use netdevice feature flags to avoid extra packet handling by core networking layer and possibly increase performance. 46 | 47 | 2009/09/26 - (Jussi Kivilinna) 48 | - Add imq_nf_reinject_lockless to fix deadlock with imq_nf_queue/imq_nf_reinject. 49 | 50 | 2009/12/08 - (Jussi Kivilinna) 51 | - Port to 2.6.32 52 | - Add check for skb->nf_queue_entry==NULL in imq_dev_xmit() 53 | - Also add better error checking for skb->nf_queue_entry usage 54 | 55 | 2010/02/25 - (Jussi Kivilinna) 56 | - Port to 2.6.33 57 | 58 | 2010/08/15 - (Jussi Kivilinna) 59 | - Port to 2.6.35 60 | - Simplify hook registration by using nf_register_hooks. 61 | - nf_reinject doesn't need spinlock around it, therefore remove imq_nf_reinject function. Other nf_reinject users protect 62 | their own data with spinlock. With IMQ however all data is needed is stored per skbuff, so no locking is needed. 63 | - Changed IMQ to use 'separate' NF_IMQ_QUEUE instead of NF_QUEUE, this allows working coexistance of IMQ and other NF_QUEUE users. 64 | - Make IMQ multi-queue. Number of IMQ device queues can be increased with 'numqueues' module parameters. Default number 65 | of queues is 1, in other words by default IMQ works as single-queue device. Multi-queue selection is based on IFB multi-queue patch by Changli Gao . 66 | 67 | 2011/03/18 - (Jussi Kivilinna) 68 | - Port to 2.6.38 69 | 70 | 2011/07/12 - (syoder89@gmail.com) 71 | - Crash fix that happens when the receiving interface has more than one queue (add missing skb_set_queue_mapping in imq_select_queue). 72 | 73 | 2011/07/26 - (Jussi Kivilinna) 74 | - Add queue mapping checks for packets exiting IMQ. 75 | - Port to 3.0 76 | 77 | 2011/08/16 - (Jussi Kivilinna) 78 | - Clear IFF_TX_SKB_SHARING flag that was added for linux 3.0.2 79 | 80 | 2011/11/03 - Germano Michel 81 | - Fix IMQ for net namespaces 82 | 83 | 2011/11/04 - Jussi Kivilinna 84 | - Port to 3.1 85 | - Clean-up, move 'get imq device pointer by imqX name' to separate function from imq_nf_queue(). 86 | 87 | 2012/01/05 - Jussi Kivilinna 88 | - Port to 3.2 89 | 90 | 2012/03/19 - Jussi Kivilinna 91 | - Port to 3.3 92 | 93 | 2012/12/12 - Jussi Kivilinna 94 | - Port to 3.7 95 | - Fix checkpatch.pl warnings 96 | 97 | 2013/09/10 - Jussi Kivilinna 98 | - Fixed GSO handling for 3.10, see imq_nf_queue() for comments. 99 | - Don't copy skb->cb_next when copying or cloning skbuffs. 100 | 101 | 2013/09/16 - Jussi Kivilinna 102 | - Port to 3.11 103 | 104 | 2013/11/12 - Jussi Kivilinna 105 | - Port to 3.12 106 | 107 | 2015/06/15 - Feng Gao 108 | - Port to 3.14 109 | - Pop and send one packet when push one packet into the IMQ queue. 110 | It could enhance the IMQ performance about 20%. 111 | 112 | 2015/06/18 - Feng Gao 113 | - Port to 3.18 114 | 115 | 2015/06/18 - Feng Gao 116 | - Fix the hang issue caused by the imq rule exists in the localout hook in process context 117 | - Fix the crash issue caused by that shutdown the interfaces before remove imq rules 118 | 119 | 2015/06/19 - Feng Gao 120 | - Port to 4.0 121 | 122 | Also, many thanks to pablo Sebastian Greco for making the initial patch and to those who helped the testing. 123 | -------------------------------------------------------------------------------- /License.txt: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | 294 | Copyright (C) 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | , 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Pseudo-driver for the intermediate queue device. (IMQ) 2 | ------------------------------------------------------ 3 | 4 | ### Contents: 5 | 1. [What is IMQ ?](https://github.com/imq/linuximq/wiki/WhatIs) 6 | 2. [How to use IMQ](https://github.com/imq/linuximq/wiki/UsingIMQ) 7 | 3. [Patching Kernel/IPTABLES](https://github.com/imq/linuximq/wiki/PatchingKernel) 8 | 4. [IMQ Traveling Diagram](https://github.com/imq/linuximq/wiki/IMQ-traversal) 9 | 5. [Kernel Packet Traveling Diagram](https://github.com/imq/linuximq/wiki/Kernel-Packet-Traveling-Diagram) 10 | 6. [The Intermediate queueing device (IMQ)](https://github.com/imq/linuximq/wiki/The-Intermediate-queueing-device) 11 | 7. [Intermediate Functional Block - IFB interface (IMQ replacement)](https://wiki.linuxfoundation.org/networking/ifb) 12 | 8. [Dummy interface - (IMQ replacement)](http://lwn.net/Articles/121407/) 13 | 9. [FAQ](https://github.com/imq/linuximq/wiki/FAQ) 14 | 15 | 16 | 17 | 18 | This program is free software. 19 | 20 | You can redistribute it and/or modify it under the terms of the GNU General Public License 21 | as published by the Free Software Foundation either version 2 of the License, or (at your option) any later version. 22 | 23 | 24 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Reporting Security Vulnerabilities 2 | 3 | We value the independent security research community and believes that responsible disclosure of security vulnerabilities helps us ensure the security and privacy of all our users. 4 | 5 | Non-vulnerability related security issues such as new great new ideas for security features are welcome on GitHub Issues. 6 | 7 | If you discover a security vulnerability, please open an issue with label type: security. 8 | 9 | ## Supported Versions 10 | 11 | | Version | Supported | 12 | | ------- | ------------------ | 13 | | 6.x.x | :white_check_mark: | 14 | | 5.15.x | :white_check_mark: | 15 | | 5.10.x | :white_check_mark: | 16 | | 5.4.x | :white_check_mark: | 17 | | 4.19.x | :white_check_mark: | 18 | | 4.14.x | :white_check_mark: | 19 | | < 3.x | :x: | 20 | -------------------------------------------------------------------------------- /iptables/iptables-1.2.5-imq.diff: -------------------------------------------------------------------------------- 1 | diff -urN iptables-1.2.5-clean/extensions/.IMQ-test iptables-1.2.5-imq/extensions/.IMQ-test 2 | --- iptables-1.2.5-clean/extensions/.IMQ-test Thu Jan 1 01:00:00 1970 3 | +++ iptables-1.2.5-imq/extensions/.IMQ-test Mon Apr 29 01:43:37 2002 4 | @@ -0,0 +1,3 @@ 5 | +#!/bin/sh 6 | +# True if IMQ target patch is applied. 7 | +[ -f $KERNEL_DIR/net/ipv4/netfilter/ipt_IMQ.c ] && echo IMQ 8 | diff -urN iptables-1.2.5-clean/extensions/.IMQ-test6 iptables-1.2.5-imq/extensions/.IMQ-test6 9 | --- iptables-1.2.5-clean/extensions/.IMQ-test6 Thu Jan 1 01:00:00 1970 10 | +++ iptables-1.2.5-imq/extensions/.IMQ-test6 Mon Apr 29 01:43:37 2002 11 | @@ -0,0 +1,3 @@ 12 | +#!/bin/sh 13 | +# True if IMQ target patch is applied. 14 | +[ -f $KERNEL_DIR/net/ipv6/netfilter/ip6t_IMQ.c ] && echo IMQ 15 | diff -urN iptables-1.2.5-clean/extensions/libip6t_IMQ.c iptables-1.2.5-imq/extensions/libip6t_IMQ.c 16 | --- iptables-1.2.5-clean/extensions/libip6t_IMQ.c Thu Jan 1 01:00:00 1970 17 | +++ iptables-1.2.5-imq/extensions/libip6t_IMQ.c Mon Apr 29 01:44:11 2002 18 | @@ -0,0 +1,102 @@ 19 | +/* Shared library add-on to iptables to add IMQ target support. */ 20 | +#include 21 | +#include 22 | +#include 23 | +#include 24 | + 25 | +#include 26 | +#include 27 | +#include 28 | + 29 | +/* Function which prints out usage message. */ 30 | +static void 31 | +help(void) 32 | +{ 33 | + printf( 34 | +"IMQ target v%s options:\n" 35 | +" --todev enqueue to imq, defaults to 0\n", 36 | +NETFILTER_VERSION); 37 | +} 38 | + 39 | +static struct option opts[] = { 40 | + { "todev", 1, 0, '1' }, 41 | + { 0 } 42 | +}; 43 | + 44 | +/* Initialize the target. */ 45 | +static void 46 | +init(struct ip6t_entry_target *t, unsigned int *nfcache) 47 | +{ 48 | + struct ip6t_imq_info *mr = (struct ip6t_imq_info*)t->data; 49 | + 50 | + mr->todev = 0; 51 | + *nfcache |= NFC_UNKNOWN; 52 | +} 53 | + 54 | +/* Function which parses command options; returns true if it 55 | + ate an option */ 56 | +static int 57 | +parse(int c, char **argv, int invert, unsigned int *flags, 58 | + const struct ip6t_entry *entry, 59 | + struct ip6t_entry_target **target) 60 | +{ 61 | + struct ip6t_imq_info *mr = (struct ip6t_imq_info*)(*target)->data; 62 | + 63 | + switch(c) { 64 | + case '1': 65 | + if (check_inverse(optarg, &invert)) 66 | + exit_error(PARAMETER_PROBLEM, 67 | + "Unexpected `!' after --todev"); 68 | + mr->todev=atoi(optarg); 69 | + break; 70 | + default: 71 | + return 0; 72 | + } 73 | + return 1; 74 | +} 75 | + 76 | +static void 77 | +final_check(unsigned int flags) 78 | +{ 79 | +} 80 | + 81 | +/* Prints out the targinfo. */ 82 | +static void 83 | +print(const struct ip6t_ip6 *ip, 84 | + const struct ip6t_entry_target *target, 85 | + int numeric) 86 | +{ 87 | + struct ip6t_imq_info *mr = (struct ip6t_imq_info*)target->data; 88 | + 89 | + printf("IMQ: todev %u ", mr->todev); 90 | +} 91 | + 92 | +/* Saves the union ipt_targinfo in parsable form to stdout. */ 93 | +static void 94 | +save(const struct ip6t_ip6 *ip, const struct ip6t_entry_target *target) 95 | +{ 96 | + struct ip6t_imq_info *mr = (struct ip6t_imq_info*)target->data; 97 | + 98 | + printf("--todev %u", mr->todev); 99 | +} 100 | + 101 | +static 102 | +struct ip6tables_target imq 103 | += { NULL, 104 | + "IMQ", 105 | + NETFILTER_VERSION, 106 | + IP6T_ALIGN(sizeof(struct ip6t_imq_info)), 107 | + IP6T_ALIGN(sizeof(struct ip6t_imq_info)), 108 | + &help, 109 | + &init, 110 | + &parse, 111 | + &final_check, 112 | + &print, 113 | + &save, 114 | + opts 115 | +}; 116 | + 117 | +void _init(void) 118 | +{ 119 | + register_target6(&imq); 120 | +} 121 | diff -urN iptables-1.2.5-clean/extensions/libipt_IMQ.c iptables-1.2.5-imq/extensions/libipt_IMQ.c 122 | --- iptables-1.2.5-clean/extensions/libipt_IMQ.c Thu Jan 1 01:00:00 1970 123 | +++ iptables-1.2.5-imq/extensions/libipt_IMQ.c Mon Apr 29 01:44:23 2002 124 | @@ -0,0 +1,102 @@ 125 | +/* Shared library add-on to iptables to add IMQ target support. */ 126 | +#include 127 | +#include 128 | +#include 129 | +#include 130 | + 131 | +#include 132 | +#include 133 | +#include 134 | + 135 | +/* Function which prints out usage message. */ 136 | +static void 137 | +help(void) 138 | +{ 139 | + printf( 140 | +"IMQ target v%s options:\n" 141 | +" --todev enqueue to imq, defaults to 0\n", 142 | +NETFILTER_VERSION); 143 | +} 144 | + 145 | +static struct option opts[] = { 146 | + { "todev", 1, 0, '1' }, 147 | + { 0 } 148 | +}; 149 | + 150 | +/* Initialize the target. */ 151 | +static void 152 | +init(struct ipt_entry_target *t, unsigned int *nfcache) 153 | +{ 154 | + struct ipt_imq_info *mr = (struct ipt_imq_info*)t->data; 155 | + 156 | + mr->todev = 0; 157 | + *nfcache |= NFC_UNKNOWN; 158 | +} 159 | + 160 | +/* Function which parses command options; returns true if it 161 | + ate an option */ 162 | +static int 163 | +parse(int c, char **argv, int invert, unsigned int *flags, 164 | + const struct ipt_entry *entry, 165 | + struct ipt_entry_target **target) 166 | +{ 167 | + struct ipt_imq_info *mr = (struct ipt_imq_info*)(*target)->data; 168 | + 169 | + switch(c) { 170 | + case '1': 171 | + if (check_inverse(optarg, &invert)) 172 | + exit_error(PARAMETER_PROBLEM, 173 | + "Unexpected `!' after --todev"); 174 | + mr->todev=atoi(optarg); 175 | + break; 176 | + default: 177 | + return 0; 178 | + } 179 | + return 1; 180 | +} 181 | + 182 | +static void 183 | +final_check(unsigned int flags) 184 | +{ 185 | +} 186 | + 187 | +/* Prints out the targinfo. */ 188 | +static void 189 | +print(const struct ipt_ip *ip, 190 | + const struct ipt_entry_target *target, 191 | + int numeric) 192 | +{ 193 | + struct ipt_imq_info *mr = (struct ipt_imq_info*)target->data; 194 | + 195 | + printf("IMQ: todev %u ", mr->todev); 196 | +} 197 | + 198 | +/* Saves the union ipt_targinfo in parsable form to stdout. */ 199 | +static void 200 | +save(const struct ipt_ip *ip, const struct ipt_entry_target *target) 201 | +{ 202 | + struct ipt_imq_info *mr = (struct ipt_imq_info*)target->data; 203 | + 204 | + printf("--todev %u", mr->todev); 205 | +} 206 | + 207 | +static 208 | +struct iptables_target imq 209 | += { NULL, 210 | + "IMQ", 211 | + NETFILTER_VERSION, 212 | + IPT_ALIGN(sizeof(struct ipt_imq_info)), 213 | + IPT_ALIGN(sizeof(struct ipt_imq_info)), 214 | + &help, 215 | + &init, 216 | + &parse, 217 | + &final_check, 218 | + &print, 219 | + &save, 220 | + opts 221 | +}; 222 | + 223 | +void _init(void) 224 | +{ 225 | + register_target(&imq); 226 | +} 227 | diff -urN iptables-1.2.5-clean/patch-o-matic/extra/IMQ.patch iptables-1.2.5-imq/patch-o-matic/extra/IMQ.patch 228 | --- iptables-1.2.5-clean/patch-o-matic/extra/IMQ.patch Thu Jan 1 01:00:00 1970 229 | +++ iptables-1.2.5-imq/patch-o-matic/extra/IMQ.patch Mon Apr 29 01:43:37 2002 230 | @@ -0,0 +1,94 @@ 231 | +diff -urN linux-2.4.18-clean/include/linux/netfilter_ipv4/ipt_IMQ.h linux-2.4.18-imq-nf/include/linux/netfilter_ipv4/ipt_IMQ.h 232 | +--- linux-2.4.18-clean/include/linux/netfilter_ipv4/ipt_IMQ.h Thu Jan 1 01:00:00 1970 233 | ++++ linux-2.4.18-imq-nf/include/linux/netfilter_ipv4/ipt_IMQ.h Tue Apr 2 21:35:20 2002 234 | +@@ -0,0 +1,8 @@ 235 | ++#ifndef _IPT_IMQ_H 236 | ++#define _IPT_IMQ_H 237 | ++ 238 | ++struct ipt_imq_info { 239 | ++ unsigned int todev; /* target imq device */ 240 | ++}; 241 | ++ 242 | ++#endif /* _IPT_IMQ_H */ 243 | +diff -urN linux-2.4.18-clean/net/ipv4/netfilter/ipt_IMQ.c linux-2.4.18-imq-nf/net/ipv4/netfilter/ipt_IMQ.c 244 | +--- linux-2.4.18-clean/net/ipv4/netfilter/ipt_IMQ.c Thu Jan 1 01:00:00 1970 245 | ++++ linux-2.4.18-imq-nf/net/ipv4/netfilter/ipt_IMQ.c Tue Apr 2 21:34:15 2002 246 | +@@ -0,0 +1,78 @@ 247 | ++/* This target marks packets to be enqueued to an imq device */ 248 | ++#include 249 | ++#include 250 | ++#include 251 | ++#include 252 | ++#include 253 | ++ 254 | ++static unsigned int imq_target(struct sk_buff **pskb, 255 | ++ unsigned int hooknum, 256 | ++ const struct net_device *in, 257 | ++ const struct net_device *out, 258 | ++ const void *targinfo, 259 | ++ void *userinfo) 260 | ++{ 261 | ++ struct ipt_imq_info *mr = (struct ipt_imq_info*)targinfo; 262 | ++ 263 | ++ (*pskb)->imq_flags = mr->todev | IMQ_F_ENQUEUE; 264 | ++ (*pskb)->nfcache |= NFC_ALTERED; 265 | ++ 266 | ++ return IPT_CONTINUE; 267 | ++} 268 | ++ 269 | ++static int imq_checkentry(const char *tablename, 270 | ++ const struct ipt_entry *e, 271 | ++ void *targinfo, 272 | ++ unsigned int targinfosize, 273 | ++ unsigned int hook_mask) 274 | ++{ 275 | ++ struct ipt_imq_info *mr; 276 | ++ 277 | ++ if (targinfosize != IPT_ALIGN(sizeof(struct ipt_imq_info))) { 278 | ++ printk(KERN_WARNING "IMQ: invalid targinfosize\n"); 279 | ++ return 0; 280 | ++ } 281 | ++ mr = (struct ipt_imq_info*)targinfo; 282 | ++ 283 | ++ if (strcmp(tablename, "mangle") != 0) { 284 | ++ printk(KERN_WARNING 285 | ++ "IMQ: IMQ can only be called from \"mangle\" table, not \"%s\"\n", 286 | ++ tablename); 287 | ++ return 0; 288 | ++ } 289 | ++ 290 | ++ if (mr->todev > IMQ_MAX_DEVS) { 291 | ++ printk(KERN_WARNING 292 | ++ "IMQ: invalid device specified, highest is %u\n", 293 | ++ IMQ_MAX_DEVS); 294 | ++ return 0; 295 | ++ } 296 | ++ 297 | ++ return 1; 298 | ++} 299 | ++ 300 | ++static struct ipt_target ipt_imq_reg = { 301 | ++ { NULL, NULL}, 302 | ++ "IMQ", 303 | ++ imq_target, 304 | ++ imq_checkentry, 305 | ++ NULL, 306 | ++ THIS_MODULE 307 | ++}; 308 | ++ 309 | ++static int __init init(void) 310 | ++{ 311 | ++ if (ipt_register_target(&ipt_imq_reg)) 312 | ++ return -EINVAL; 313 | ++ 314 | ++ return 0; 315 | ++} 316 | ++ 317 | ++static void __exit fini(void) 318 | ++{ 319 | ++ ipt_unregister_target(&ipt_imq_reg); 320 | ++} 321 | ++ 322 | ++module_init(init); 323 | ++module_exit(fini); 324 | ++MODULE_LICENSE("GPL"); 325 | diff -urN iptables-1.2.5-clean/patch-o-matic/extra/IMQ.patch.config.in iptables-1.2.5-imq/patch-o-matic/extra/IMQ.patch.config.in 326 | --- iptables-1.2.5-clean/patch-o-matic/extra/IMQ.patch.config.in Thu Jan 1 01:00:00 1970 327 | +++ iptables-1.2.5-imq/patch-o-matic/extra/IMQ.patch.config.in Mon Apr 29 01:43:37 2002 328 | @@ -0,0 +1,2 @@ 329 | + dep_tristate ' MARK target support' CONFIG_IP_NF_TARGET_MARK $CONFIG_IP_NF_MANGLE 330 | + dep_tristate ' IMQ target support' CONFIG_IP_NF_TARGET_IMQ $CONFIG_IP_NF_MANGLE 331 | diff -urN iptables-1.2.5-clean/patch-o-matic/extra/IMQ.patch.configure.help iptables-1.2.5-imq/patch-o-matic/extra/IMQ.patch.configure.help 332 | --- iptables-1.2.5-clean/patch-o-matic/extra/IMQ.patch.configure.help Thu Jan 1 01:00:00 1970 333 | +++ iptables-1.2.5-imq/patch-o-matic/extra/IMQ.patch.configure.help Mon Apr 29 01:43:37 2002 334 | @@ -0,0 +1,8 @@ 335 | +CONFIG_IP_NF_TARGET_MARK 336 | +IMQ target support 337 | +CONFIG_IP_NF_TARGET_IMQ 338 | + This option adds a `IMQ' target which is used to specify if and 339 | + to which imq device packets should get enqueued/dequeued. 340 | + 341 | + If you want to compile it as a module, say M here and read 342 | + . If unsure, say `N'. 343 | diff -urN iptables-1.2.5-clean/patch-o-matic/extra/IMQ.patch.help iptables-1.2.5-imq/patch-o-matic/extra/IMQ.patch.help 344 | --- iptables-1.2.5-clean/patch-o-matic/extra/IMQ.patch.help Thu Jan 1 01:00:00 1970 345 | +++ iptables-1.2.5-imq/patch-o-matic/extra/IMQ.patch.help Mon Apr 29 01:43:37 2002 346 | @@ -0,0 +1,5 @@ 347 | +Author: Patrick McHardy 348 | +Status: Working 349 | + 350 | + This patch adds a new target 'IMQ' which is required 351 | + to direct packets through an imq device. 352 | diff -urN iptables-1.2.5-clean/patch-o-matic/extra/IMQ.patch.ipv6 iptables-1.2.5-imq/patch-o-matic/extra/IMQ.patch.ipv6 353 | --- iptables-1.2.5-clean/patch-o-matic/extra/IMQ.patch.ipv6 Thu Jan 1 01:00:00 1970 354 | +++ iptables-1.2.5-imq/patch-o-matic/extra/IMQ.patch.ipv6 Mon Apr 29 01:43:37 2002 355 | @@ -0,0 +1,94 @@ 356 | +diff -urN linux-2.4.18-clean/include/linux/netfilter_ipv6/ip6t_IMQ.h linux-2.4.18-imq/include/linux/netfilter_ipv6/ip6t_IMQ.h 357 | +--- linux-2.4.18-clean/include/linux/netfilter_ipv6/ip6t_IMQ.h Thu Jan 1 01:00:00 1970 358 | ++++ linux-2.4.18-imq/include/linux/netfilter_ipv6/ip6t_IMQ.h Sun Apr 28 23:34:53 2002 359 | +@@ -0,0 +1,8 @@ 360 | ++#ifndef _IP6T_IMQ_H 361 | ++#define _IP6T_IMQ_H 362 | ++ 363 | ++struct ip6t_imq_info { 364 | ++ unsigned int todev; /* target imq device */ 365 | ++}; 366 | ++ 367 | ++#endif /* _IP6T_IMQ_H */ 368 | +diff -urN linux-2.4.18-clean/net/ipv6/netfilter/ip6t_IMQ.c linux-2.4.18-imq/net/ipv6/netfilter/ip6t_IMQ.c 369 | +--- linux-2.4.18-clean/net/ipv6/netfilter/ip6t_IMQ.c Thu Jan 1 01:00:00 1970 370 | ++++ linux-2.4.18-imq/net/ipv6/netfilter/ip6t_IMQ.c Sun Apr 28 23:34:11 2002 371 | +@@ -0,0 +1,78 @@ 372 | ++/* This target marks packets to be enqueued to an imq device */ 373 | ++#include 374 | ++#include 375 | ++#include 376 | ++#include 377 | ++#include 378 | ++ 379 | ++static unsigned int imq_target(struct sk_buff **pskb, 380 | ++ unsigned int hooknum, 381 | ++ const struct net_device *in, 382 | ++ const struct net_device *out, 383 | ++ const void *targinfo, 384 | ++ void *userinfo) 385 | ++{ 386 | ++ struct ip6t_imq_info *mr = (struct ip6t_imq_info*)targinfo; 387 | ++ 388 | ++ (*pskb)->imq_flags = mr->todev | IMQ_F_ENQUEUE; 389 | ++ (*pskb)->nfcache |= NFC_ALTERED; 390 | ++ 391 | ++ return IP6T_CONTINUE; 392 | ++} 393 | ++ 394 | ++static int imq_checkentry(const char *tablename, 395 | ++ const struct ip6t_entry *e, 396 | ++ void *targinfo, 397 | ++ unsigned int targinfosize, 398 | ++ unsigned int hook_mask) 399 | ++{ 400 | ++ struct ip6t_imq_info *mr; 401 | ++ 402 | ++ if (targinfosize != IP6T_ALIGN(sizeof(struct ip6t_imq_info))) { 403 | ++ printk(KERN_WARNING "IMQ: invalid targinfosize\n"); 404 | ++ return 0; 405 | ++ } 406 | ++ mr = (struct ip6t_imq_info*)targinfo; 407 | ++ 408 | ++ if (strcmp(tablename, "mangle") != 0) { 409 | ++ printk(KERN_WARNING 410 | ++ "IMQ: IMQ can only be called from \"mangle\" table, not \"%s\"\n", 411 | ++ tablename); 412 | ++ return 0; 413 | ++ } 414 | ++ 415 | ++ if (mr->todev > IMQ_MAX_DEVS) { 416 | ++ printk(KERN_WARNING 417 | ++ "IMQ: invalid device specified, highest is %u\n", 418 | ++ IMQ_MAX_DEVS); 419 | ++ return 0; 420 | ++ } 421 | ++ 422 | ++ return 1; 423 | ++} 424 | ++ 425 | ++static struct ip6t_target ip6t_imq_reg = { 426 | ++ { NULL, NULL}, 427 | ++ "IMQ", 428 | ++ imq_target, 429 | ++ imq_checkentry, 430 | ++ NULL, 431 | ++ THIS_MODULE 432 | ++}; 433 | ++ 434 | ++static int __init init(void) 435 | ++{ 436 | ++ if (ip6t_register_target(&ip6t_imq_reg)) 437 | ++ return -EINVAL; 438 | ++ 439 | ++ return 0; 440 | ++} 441 | ++ 442 | ++static void __exit fini(void) 443 | ++{ 444 | ++ ip6t_unregister_target(&ip6t_imq_reg); 445 | ++} 446 | ++ 447 | ++module_init(init); 448 | ++module_exit(fini); 449 | ++MODULE_LICENSE("GPL"); 450 | diff -urN iptables-1.2.5-clean/patch-o-matic/extra/IMQ.patch.ipv6.config.in iptables-1.2.5-imq/patch-o-matic/extra/IMQ.patch.ipv6.config.in 451 | --- iptables-1.2.5-clean/patch-o-matic/extra/IMQ.patch.ipv6.config.in Thu Jan 1 01:00:00 1970 452 | +++ iptables-1.2.5-imq/patch-o-matic/extra/IMQ.patch.ipv6.config.in Mon Apr 29 01:43:37 2002 453 | @@ -0,0 +1,2 @@ 454 | + dep_tristate ' MARK target support' CONFIG_IP6_NF_TARGET_MARK $CONFIG_IP6_NF_MANGLE 455 | + dep_tristate ' IMQ target support' CONFIG_IP6_NF_TARGET_IMQ $CONFIG_IP6_NF_MANGLE 456 | diff -urN iptables-1.2.5-clean/patch-o-matic/extra/IMQ.patch.ipv6.configure.help iptables-1.2.5-imq/patch-o-matic/extra/IMQ.patch.ipv6.configure.help 457 | --- iptables-1.2.5-clean/patch-o-matic/extra/IMQ.patch.ipv6.configure.help Thu Jan 1 01:00:00 1970 458 | +++ iptables-1.2.5-imq/patch-o-matic/extra/IMQ.patch.ipv6.configure.help Mon Apr 29 01:43:37 2002 459 | @@ -0,0 +1,8 @@ 460 | +CONFIG_IP6_NF_TARGET_MARK 461 | +IMQ target support 462 | +CONFIG_IP6_NF_TARGET_IMQ 463 | + This option adds a `IMQ' target which is used to specify if and 464 | + to which imq device packets should get enqueued/dequeued. 465 | + 466 | + If you want to compile it as a module, say M here and read 467 | + . If unsure, say `N'. 468 | diff -urN iptables-1.2.5-clean/patch-o-matic/extra/IMQ.patch.ipv6.help iptables-1.2.5-imq/patch-o-matic/extra/IMQ.patch.ipv6.help 469 | --- iptables-1.2.5-clean/patch-o-matic/extra/IMQ.patch.ipv6.help Thu Jan 1 01:00:00 1970 470 | +++ iptables-1.2.5-imq/patch-o-matic/extra/IMQ.patch.ipv6.help Mon Apr 29 01:43:37 2002 471 | @@ -0,0 +1,5 @@ 472 | +Author: Patrick McHardy 473 | +Status: Working 474 | + 475 | + This patch adds a new target 'IMQ' which is required 476 | + to direct packets through an imq device. 477 | diff -urN iptables-1.2.5-clean/patch-o-matic/extra/IMQ.patch.ipv6.makefile iptables-1.2.5-imq/patch-o-matic/extra/IMQ.patch.ipv6.makefile 478 | --- iptables-1.2.5-clean/patch-o-matic/extra/IMQ.patch.ipv6.makefile Thu Jan 1 01:00:00 1970 479 | +++ iptables-1.2.5-imq/patch-o-matic/extra/IMQ.patch.ipv6.makefile Mon Apr 29 01:43:37 2002 480 | @@ -0,0 +1,2 @@ 481 | +obj-$(CONFIG_IP6_NF_TARGET_MARK) += ip6t_MARK.o 482 | +obj-$(CONFIG_IP6_NF_TARGET_IMQ) += ip6t_IMQ.o 483 | diff -urN iptables-1.2.5-clean/patch-o-matic/extra/IMQ.patch.makefile iptables-1.2.5-imq/patch-o-matic/extra/IMQ.patch.makefile 484 | --- iptables-1.2.5-clean/patch-o-matic/extra/IMQ.patch.makefile Thu Jan 1 01:00:00 1970 485 | +++ iptables-1.2.5-imq/patch-o-matic/extra/IMQ.patch.makefile Mon Apr 29 01:43:37 2002 486 | @@ -0,0 +1,2 @@ 487 | +obj-$(CONFIG_IP_NF_TARGET_MARK) += ipt_MARK.o 488 | +obj-$(CONFIG_IP_NF_TARGET_IMQ) += ipt_IMQ.o 489 | -------------------------------------------------------------------------------- /iptables/iptables-1.2.6a-imq.diff: -------------------------------------------------------------------------------- 1 | diff -urN iptables-1.2.6a-clean/extensions/.IMQ-test iptables-1.2.6a-imq/extensions/.IMQ-test 2 | --- iptables-1.2.6a-clean/extensions/.IMQ-test Thu Jan 1 01:00:00 1970 3 | +++ iptables-1.2.6a-imq/extensions/.IMQ-test Mon Apr 29 01:34:33 2002 4 | @@ -0,0 +1,3 @@ 5 | +#!/bin/sh 6 | +# True if IMQ target patch is applied. 7 | +[ -f $KERNEL_DIR/net/ipv4/netfilter/ipt_IMQ.c ] && echo IMQ 8 | diff -urN iptables-1.2.6a-clean/extensions/.IMQ-test6 iptables-1.2.6a-imq/extensions/.IMQ-test6 9 | --- iptables-1.2.6a-clean/extensions/.IMQ-test6 Thu Jan 1 01:00:00 1970 10 | +++ iptables-1.2.6a-imq/extensions/.IMQ-test6 Mon Apr 29 01:34:33 2002 11 | @@ -0,0 +1,3 @@ 12 | +#!/bin/sh 13 | +# True if IMQ target patch is applied. 14 | +[ -f $KERNEL_DIR/net/ipv6/netfilter/ip6t_IMQ.c ] && echo IMQ 15 | diff -urN iptables-1.2.6a-clean/extensions/libip6t_IMQ.c iptables-1.2.6a-imq/extensions/libip6t_IMQ.c 16 | --- iptables-1.2.6a-clean/extensions/libip6t_IMQ.c Thu Jan 1 01:00:00 1970 17 | +++ iptables-1.2.6a-imq/extensions/libip6t_IMQ.c Mon Apr 29 01:34:33 2002 18 | @@ -0,0 +1,102 @@ 19 | +/* Shared library add-on to iptables to add IMQ target support. */ 20 | +#include 21 | +#include 22 | +#include 23 | +#include 24 | + 25 | +#include 26 | +#include 27 | +#include 28 | + 29 | +/* Function which prints out usage message. */ 30 | +static void 31 | +help(void) 32 | +{ 33 | + printf( 34 | +"IMQ target v%s options:\n" 35 | +" --todev enqueue to imq, defaults to 0\n", 36 | +NETFILTER_VERSION); 37 | +} 38 | + 39 | +static struct option opts[] = { 40 | + { "todev", 1, 0, '1' }, 41 | + { 0 } 42 | +}; 43 | + 44 | +/* Initialize the target. */ 45 | +static void 46 | +init(struct ip6t_entry_target *t, unsigned int *nfcache) 47 | +{ 48 | + struct ip6t_imq_info *mr = (struct ip6t_imq_info*)t->data; 49 | + 50 | + mr->todev = 0; 51 | + *nfcache |= NFC_UNKNOWN; 52 | +} 53 | + 54 | +/* Function which parses command options; returns true if it 55 | + ate an option */ 56 | +static int 57 | +parse(int c, char **argv, int invert, unsigned int *flags, 58 | + const struct ip6t_entry *entry, 59 | + struct ip6t_entry_target **target) 60 | +{ 61 | + struct ip6t_imq_info *mr = (struct ip6t_imq_info*)(*target)->data; 62 | + 63 | + switch(c) { 64 | + case '1': 65 | + if (check_inverse(optarg, &invert, NULL, 0)) 66 | + exit_error(PARAMETER_PROBLEM, 67 | + "Unexpected `!' after --todev"); 68 | + mr->todev=atoi(optarg); 69 | + break; 70 | + default: 71 | + return 0; 72 | + } 73 | + return 1; 74 | +} 75 | + 76 | +static void 77 | +final_check(unsigned int flags) 78 | +{ 79 | +} 80 | + 81 | +/* Prints out the targinfo. */ 82 | +static void 83 | +print(const struct ip6t_ip6 *ip, 84 | + const struct ip6t_entry_target *target, 85 | + int numeric) 86 | +{ 87 | + struct ip6t_imq_info *mr = (struct ip6t_imq_info*)target->data; 88 | + 89 | + printf("IMQ: todev %u ", mr->todev); 90 | +} 91 | + 92 | +/* Saves the union ipt_targinfo in parsable form to stdout. */ 93 | +static void 94 | +save(const struct ip6t_ip6 *ip, const struct ip6t_entry_target *target) 95 | +{ 96 | + struct ip6t_imq_info *mr = (struct ip6t_imq_info*)target->data; 97 | + 98 | + printf("--todev %u", mr->todev); 99 | +} 100 | + 101 | +static 102 | +struct ip6tables_target imq 103 | += { NULL, 104 | + "IMQ", 105 | + NETFILTER_VERSION, 106 | + IP6T_ALIGN(sizeof(struct ip6t_imq_info)), 107 | + IP6T_ALIGN(sizeof(struct ip6t_imq_info)), 108 | + &help, 109 | + &init, 110 | + &parse, 111 | + &final_check, 112 | + &print, 113 | + &save, 114 | + opts 115 | +}; 116 | + 117 | +void _init(void) 118 | +{ 119 | + register_target6(&imq); 120 | +} 121 | diff -urN iptables-1.2.6a-clean/extensions/libipt_IMQ.c iptables-1.2.6a-imq/extensions/libipt_IMQ.c 122 | --- iptables-1.2.6a-clean/extensions/libipt_IMQ.c Thu Jan 1 01:00:00 1970 123 | +++ iptables-1.2.6a-imq/extensions/libipt_IMQ.c Mon Apr 29 01:34:33 2002 124 | @@ -0,0 +1,102 @@ 125 | +/* Shared library add-on to iptables to add IMQ target support. */ 126 | +#include 127 | +#include 128 | +#include 129 | +#include 130 | + 131 | +#include 132 | +#include 133 | +#include 134 | + 135 | +/* Function which prints out usage message. */ 136 | +static void 137 | +help(void) 138 | +{ 139 | + printf( 140 | +"IMQ target v%s options:\n" 141 | +" --todev enqueue to imq, defaults to 0\n", 142 | +NETFILTER_VERSION); 143 | +} 144 | + 145 | +static struct option opts[] = { 146 | + { "todev", 1, 0, '1' }, 147 | + { 0 } 148 | +}; 149 | + 150 | +/* Initialize the target. */ 151 | +static void 152 | +init(struct ipt_entry_target *t, unsigned int *nfcache) 153 | +{ 154 | + struct ipt_imq_info *mr = (struct ipt_imq_info*)t->data; 155 | + 156 | + mr->todev = 0; 157 | + *nfcache |= NFC_UNKNOWN; 158 | +} 159 | + 160 | +/* Function which parses command options; returns true if it 161 | + ate an option */ 162 | +static int 163 | +parse(int c, char **argv, int invert, unsigned int *flags, 164 | + const struct ipt_entry *entry, 165 | + struct ipt_entry_target **target) 166 | +{ 167 | + struct ipt_imq_info *mr = (struct ipt_imq_info*)(*target)->data; 168 | + 169 | + switch(c) { 170 | + case '1': 171 | + if (check_inverse(optarg, &invert, NULL, 0)) 172 | + exit_error(PARAMETER_PROBLEM, 173 | + "Unexpected `!' after --todev"); 174 | + mr->todev=atoi(optarg); 175 | + break; 176 | + default: 177 | + return 0; 178 | + } 179 | + return 1; 180 | +} 181 | + 182 | +static void 183 | +final_check(unsigned int flags) 184 | +{ 185 | +} 186 | + 187 | +/* Prints out the targinfo. */ 188 | +static void 189 | +print(const struct ipt_ip *ip, 190 | + const struct ipt_entry_target *target, 191 | + int numeric) 192 | +{ 193 | + struct ipt_imq_info *mr = (struct ipt_imq_info*)target->data; 194 | + 195 | + printf("IMQ: todev %u ", mr->todev); 196 | +} 197 | + 198 | +/* Saves the union ipt_targinfo in parsable form to stdout. */ 199 | +static void 200 | +save(const struct ipt_ip *ip, const struct ipt_entry_target *target) 201 | +{ 202 | + struct ipt_imq_info *mr = (struct ipt_imq_info*)target->data; 203 | + 204 | + printf("--todev %u", mr->todev); 205 | +} 206 | + 207 | +static 208 | +struct iptables_target imq 209 | += { NULL, 210 | + "IMQ", 211 | + NETFILTER_VERSION, 212 | + IPT_ALIGN(sizeof(struct ipt_imq_info)), 213 | + IPT_ALIGN(sizeof(struct ipt_imq_info)), 214 | + &help, 215 | + &init, 216 | + &parse, 217 | + &final_check, 218 | + &print, 219 | + &save, 220 | + opts 221 | +}; 222 | + 223 | +void _init(void) 224 | +{ 225 | + register_target(&imq); 226 | +} 227 | diff -urN iptables-1.2.6a-clean/patch-o-matic/extra/IMQ.patch iptables-1.2.6a-imq/patch-o-matic/extra/IMQ.patch 228 | --- iptables-1.2.6a-clean/patch-o-matic/extra/IMQ.patch Thu Jan 1 01:00:00 1970 229 | +++ iptables-1.2.6a-imq/patch-o-matic/extra/IMQ.patch Mon Apr 29 01:34:33 2002 230 | @@ -0,0 +1,94 @@ 231 | +diff -urN linux-2.4.18-clean/include/linux/netfilter_ipv4/ipt_IMQ.h linux-2.4.18-imq-nf/include/linux/netfilter_ipv4/ipt_IMQ.h 232 | +--- linux-2.4.18-clean/include/linux/netfilter_ipv4/ipt_IMQ.h Thu Jan 1 01:00:00 1970 233 | ++++ linux-2.4.18-imq-nf/include/linux/netfilter_ipv4/ipt_IMQ.h Tue Apr 2 21:35:20 2002 234 | +@@ -0,0 +1,8 @@ 235 | ++#ifndef _IPT_IMQ_H 236 | ++#define _IPT_IMQ_H 237 | ++ 238 | ++struct ipt_imq_info { 239 | ++ unsigned int todev; /* target imq device */ 240 | ++}; 241 | ++ 242 | ++#endif /* _IPT_IMQ_H */ 243 | +diff -urN linux-2.4.18-clean/net/ipv4/netfilter/ipt_IMQ.c linux-2.4.18-imq-nf/net/ipv4/netfilter/ipt_IMQ.c 244 | +--- linux-2.4.18-clean/net/ipv4/netfilter/ipt_IMQ.c Thu Jan 1 01:00:00 1970 245 | ++++ linux-2.4.18-imq-nf/net/ipv4/netfilter/ipt_IMQ.c Tue Apr 2 21:34:15 2002 246 | +@@ -0,0 +1,78 @@ 247 | ++/* This target marks packets to be enqueued to an imq device */ 248 | ++#include 249 | ++#include 250 | ++#include 251 | ++#include 252 | ++#include 253 | ++ 254 | ++static unsigned int imq_target(struct sk_buff **pskb, 255 | ++ unsigned int hooknum, 256 | ++ const struct net_device *in, 257 | ++ const struct net_device *out, 258 | ++ const void *targinfo, 259 | ++ void *userinfo) 260 | ++{ 261 | ++ struct ipt_imq_info *mr = (struct ipt_imq_info*)targinfo; 262 | ++ 263 | ++ (*pskb)->imq_flags = mr->todev | IMQ_F_ENQUEUE; 264 | ++ (*pskb)->nfcache |= NFC_ALTERED; 265 | ++ 266 | ++ return IPT_CONTINUE; 267 | ++} 268 | ++ 269 | ++static int imq_checkentry(const char *tablename, 270 | ++ const struct ipt_entry *e, 271 | ++ void *targinfo, 272 | ++ unsigned int targinfosize, 273 | ++ unsigned int hook_mask) 274 | ++{ 275 | ++ struct ipt_imq_info *mr; 276 | ++ 277 | ++ if (targinfosize != IPT_ALIGN(sizeof(struct ipt_imq_info))) { 278 | ++ printk(KERN_WARNING "IMQ: invalid targinfosize\n"); 279 | ++ return 0; 280 | ++ } 281 | ++ mr = (struct ipt_imq_info*)targinfo; 282 | ++ 283 | ++ if (strcmp(tablename, "mangle") != 0) { 284 | ++ printk(KERN_WARNING 285 | ++ "IMQ: IMQ can only be called from \"mangle\" table, not \"%s\"\n", 286 | ++ tablename); 287 | ++ return 0; 288 | ++ } 289 | ++ 290 | ++ if (mr->todev > IMQ_MAX_DEVS) { 291 | ++ printk(KERN_WARNING 292 | ++ "IMQ: invalid device specified, highest is %u\n", 293 | ++ IMQ_MAX_DEVS); 294 | ++ return 0; 295 | ++ } 296 | ++ 297 | ++ return 1; 298 | ++} 299 | ++ 300 | ++static struct ipt_target ipt_imq_reg = { 301 | ++ { NULL, NULL}, 302 | ++ "IMQ", 303 | ++ imq_target, 304 | ++ imq_checkentry, 305 | ++ NULL, 306 | ++ THIS_MODULE 307 | ++}; 308 | ++ 309 | ++static int __init init(void) 310 | ++{ 311 | ++ if (ipt_register_target(&ipt_imq_reg)) 312 | ++ return -EINVAL; 313 | ++ 314 | ++ return 0; 315 | ++} 316 | ++ 317 | ++static void __exit fini(void) 318 | ++{ 319 | ++ ipt_unregister_target(&ipt_imq_reg); 320 | ++} 321 | ++ 322 | ++module_init(init); 323 | ++module_exit(fini); 324 | ++MODULE_LICENSE("GPL"); 325 | diff -urN iptables-1.2.6a-clean/patch-o-matic/extra/IMQ.patch.config.in iptables-1.2.6a-imq/patch-o-matic/extra/IMQ.patch.config.in 326 | --- iptables-1.2.6a-clean/patch-o-matic/extra/IMQ.patch.config.in Thu Jan 1 01:00:00 1970 327 | +++ iptables-1.2.6a-imq/patch-o-matic/extra/IMQ.patch.config.in Mon Apr 29 01:34:33 2002 328 | @@ -0,0 +1,2 @@ 329 | + dep_tristate ' MARK target support' CONFIG_IP_NF_TARGET_MARK $CONFIG_IP_NF_MANGLE 330 | + dep_tristate ' IMQ target support' CONFIG_IP_NF_TARGET_IMQ $CONFIG_IP_NF_MANGLE 331 | diff -urN iptables-1.2.6a-clean/patch-o-matic/extra/IMQ.patch.configure.help iptables-1.2.6a-imq/patch-o-matic/extra/IMQ.patch.configure.help 332 | --- iptables-1.2.6a-clean/patch-o-matic/extra/IMQ.patch.configure.help Thu Jan 1 01:00:00 1970 333 | +++ iptables-1.2.6a-imq/patch-o-matic/extra/IMQ.patch.configure.help Mon Apr 29 01:34:33 2002 334 | @@ -0,0 +1,8 @@ 335 | +CONFIG_IP_NF_TARGET_MARK 336 | +IMQ target support 337 | +CONFIG_IP_NF_TARGET_IMQ 338 | + This option adds a `IMQ' target which is used to specify if and 339 | + to which imq device packets should get enqueued/dequeued. 340 | + 341 | + If you want to compile it as a module, say M here and read 342 | + . If unsure, say `N'. 343 | diff -urN iptables-1.2.6a-clean/patch-o-matic/extra/IMQ.patch.help iptables-1.2.6a-imq/patch-o-matic/extra/IMQ.patch.help 344 | --- iptables-1.2.6a-clean/patch-o-matic/extra/IMQ.patch.help Thu Jan 1 01:00:00 1970 345 | +++ iptables-1.2.6a-imq/patch-o-matic/extra/IMQ.patch.help Mon Apr 29 01:34:33 2002 346 | @@ -0,0 +1,5 @@ 347 | +Author: Patrick McHardy 348 | +Status: Working 349 | + 350 | + This patch adds a new target 'IMQ' which is required 351 | + to direct packets through an imq device. 352 | diff -urN iptables-1.2.6a-clean/patch-o-matic/extra/IMQ.patch.ipv6 iptables-1.2.6a-imq/patch-o-matic/extra/IMQ.patch.ipv6 353 | --- iptables-1.2.6a-clean/patch-o-matic/extra/IMQ.patch.ipv6 Thu Jan 1 01:00:00 1970 354 | +++ iptables-1.2.6a-imq/patch-o-matic/extra/IMQ.patch.ipv6 Mon Apr 29 01:34:33 2002 355 | @@ -0,0 +1,94 @@ 356 | +diff -urN linux-2.4.18-clean/include/linux/netfilter_ipv6/ip6t_IMQ.h linux-2.4.18-imq/include/linux/netfilter_ipv6/ip6t_IMQ.h 357 | +--- linux-2.4.18-clean/include/linux/netfilter_ipv6/ip6t_IMQ.h Thu Jan 1 01:00:00 1970 358 | ++++ linux-2.4.18-imq/include/linux/netfilter_ipv6/ip6t_IMQ.h Sun Apr 28 23:34:53 2002 359 | +@@ -0,0 +1,8 @@ 360 | ++#ifndef _IP6T_IMQ_H 361 | ++#define _IP6T_IMQ_H 362 | ++ 363 | ++struct ip6t_imq_info { 364 | ++ unsigned int todev; /* target imq device */ 365 | ++}; 366 | ++ 367 | ++#endif /* _IP6T_IMQ_H */ 368 | +diff -urN linux-2.4.18-clean/net/ipv6/netfilter/ip6t_IMQ.c linux-2.4.18-imq/net/ipv6/netfilter/ip6t_IMQ.c 369 | +--- linux-2.4.18-clean/net/ipv6/netfilter/ip6t_IMQ.c Thu Jan 1 01:00:00 1970 370 | ++++ linux-2.4.18-imq/net/ipv6/netfilter/ip6t_IMQ.c Sun Apr 28 23:34:11 2002 371 | +@@ -0,0 +1,78 @@ 372 | ++/* This target marks packets to be enqueued to an imq device */ 373 | ++#include 374 | ++#include 375 | ++#include 376 | ++#include 377 | ++#include 378 | ++ 379 | ++static unsigned int imq_target(struct sk_buff **pskb, 380 | ++ unsigned int hooknum, 381 | ++ const struct net_device *in, 382 | ++ const struct net_device *out, 383 | ++ const void *targinfo, 384 | ++ void *userinfo) 385 | ++{ 386 | ++ struct ip6t_imq_info *mr = (struct ip6t_imq_info*)targinfo; 387 | ++ 388 | ++ (*pskb)->imq_flags = mr->todev | IMQ_F_ENQUEUE; 389 | ++ (*pskb)->nfcache |= NFC_ALTERED; 390 | ++ 391 | ++ return IP6T_CONTINUE; 392 | ++} 393 | ++ 394 | ++static int imq_checkentry(const char *tablename, 395 | ++ const struct ip6t_entry *e, 396 | ++ void *targinfo, 397 | ++ unsigned int targinfosize, 398 | ++ unsigned int hook_mask) 399 | ++{ 400 | ++ struct ip6t_imq_info *mr; 401 | ++ 402 | ++ if (targinfosize != IP6T_ALIGN(sizeof(struct ip6t_imq_info))) { 403 | ++ printk(KERN_WARNING "IMQ: invalid targinfosize\n"); 404 | ++ return 0; 405 | ++ } 406 | ++ mr = (struct ip6t_imq_info*)targinfo; 407 | ++ 408 | ++ if (strcmp(tablename, "mangle") != 0) { 409 | ++ printk(KERN_WARNING 410 | ++ "IMQ: IMQ can only be called from \"mangle\" table, not \"%s\"\n", 411 | ++ tablename); 412 | ++ return 0; 413 | ++ } 414 | ++ 415 | ++ if (mr->todev > IMQ_MAX_DEVS) { 416 | ++ printk(KERN_WARNING 417 | ++ "IMQ: invalid device specified, highest is %u\n", 418 | ++ IMQ_MAX_DEVS); 419 | ++ return 0; 420 | ++ } 421 | ++ 422 | ++ return 1; 423 | ++} 424 | ++ 425 | ++static struct ip6t_target ip6t_imq_reg = { 426 | ++ { NULL, NULL}, 427 | ++ "IMQ", 428 | ++ imq_target, 429 | ++ imq_checkentry, 430 | ++ NULL, 431 | ++ THIS_MODULE 432 | ++}; 433 | ++ 434 | ++static int __init init(void) 435 | ++{ 436 | ++ if (ip6t_register_target(&ip6t_imq_reg)) 437 | ++ return -EINVAL; 438 | ++ 439 | ++ return 0; 440 | ++} 441 | ++ 442 | ++static void __exit fini(void) 443 | ++{ 444 | ++ ip6t_unregister_target(&ip6t_imq_reg); 445 | ++} 446 | ++ 447 | ++module_init(init); 448 | ++module_exit(fini); 449 | ++MODULE_LICENSE("GPL"); 450 | diff -urN iptables-1.2.6a-clean/patch-o-matic/extra/IMQ.patch.ipv6.config.in iptables-1.2.6a-imq/patch-o-matic/extra/IMQ.patch.ipv6.config.in 451 | --- iptables-1.2.6a-clean/patch-o-matic/extra/IMQ.patch.ipv6.config.in Thu Jan 1 01:00:00 1970 452 | +++ iptables-1.2.6a-imq/patch-o-matic/extra/IMQ.patch.ipv6.config.in Mon Apr 29 01:34:33 2002 453 | @@ -0,0 +1,2 @@ 454 | + dep_tristate ' MARK target support' CONFIG_IP6_NF_TARGET_MARK $CONFIG_IP6_NF_MANGLE 455 | + dep_tristate ' IMQ target support' CONFIG_IP6_NF_TARGET_IMQ $CONFIG_IP6_NF_MANGLE 456 | diff -urN iptables-1.2.6a-clean/patch-o-matic/extra/IMQ.patch.ipv6.configure.help iptables-1.2.6a-imq/patch-o-matic/extra/IMQ.patch.ipv6.configure.help 457 | --- iptables-1.2.6a-clean/patch-o-matic/extra/IMQ.patch.ipv6.configure.help Thu Jan 1 01:00:00 1970 458 | +++ iptables-1.2.6a-imq/patch-o-matic/extra/IMQ.patch.ipv6.configure.help Mon Apr 29 01:34:33 2002 459 | @@ -0,0 +1,8 @@ 460 | +CONFIG_IP6_NF_TARGET_MARK 461 | +IMQ target support 462 | +CONFIG_IP6_NF_TARGET_IMQ 463 | + This option adds a `IMQ' target which is used to specify if and 464 | + to which imq device packets should get enqueued/dequeued. 465 | + 466 | + If you want to compile it as a module, say M here and read 467 | + . If unsure, say `N'. 468 | diff -urN iptables-1.2.6a-clean/patch-o-matic/extra/IMQ.patch.ipv6.help iptables-1.2.6a-imq/patch-o-matic/extra/IMQ.patch.ipv6.help 469 | --- iptables-1.2.6a-clean/patch-o-matic/extra/IMQ.patch.ipv6.help Thu Jan 1 01:00:00 1970 470 | +++ iptables-1.2.6a-imq/patch-o-matic/extra/IMQ.patch.ipv6.help Mon Apr 29 01:34:33 2002 471 | @@ -0,0 +1,5 @@ 472 | +Author: Patrick McHardy 473 | +Status: Working 474 | + 475 | + This patch adds a new target 'IMQ' which is required 476 | + to direct packets through an imq device. 477 | diff -urN iptables-1.2.6a-clean/patch-o-matic/extra/IMQ.patch.ipv6.makefile iptables-1.2.6a-imq/patch-o-matic/extra/IMQ.patch.ipv6.makefile 478 | --- iptables-1.2.6a-clean/patch-o-matic/extra/IMQ.patch.ipv6.makefile Thu Jan 1 01:00:00 1970 479 | +++ iptables-1.2.6a-imq/patch-o-matic/extra/IMQ.patch.ipv6.makefile Mon Apr 29 01:34:33 2002 480 | @@ -0,0 +1,2 @@ 481 | +obj-$(CONFIG_IP6_NF_TARGET_MARK) += ip6t_MARK.o 482 | +obj-$(CONFIG_IP6_NF_TARGET_IMQ) += ip6t_IMQ.o 483 | diff -urN iptables-1.2.6a-clean/patch-o-matic/extra/IMQ.patch.makefile iptables-1.2.6a-imq/patch-o-matic/extra/IMQ.patch.makefile 484 | --- iptables-1.2.6a-clean/patch-o-matic/extra/IMQ.patch.makefile Thu Jan 1 01:00:00 1970 485 | +++ iptables-1.2.6a-imq/patch-o-matic/extra/IMQ.patch.makefile Mon Apr 29 01:34:33 2002 486 | @@ -0,0 +1,2 @@ 487 | +obj-$(CONFIG_IP_NF_TARGET_MARK) += ipt_MARK.o 488 | +obj-$(CONFIG_IP_NF_TARGET_IMQ) += ipt_IMQ.o 489 | -------------------------------------------------------------------------------- /iptables/iptables-1.2.9-imq1.diff: -------------------------------------------------------------------------------- 1 | --- userspace/extensions.orig/.IMQ-test6 Thu Jan 1 01:00:00 1970 2 | +++ userspace/extensions/.IMQ-test6 Mon Jun 16 10:12:47 2003 3 | @@ -0,0 +1,3 @@ 4 | +#!/bin/sh 5 | +# True if IMQ target patch is applied. 6 | +[ -f $KERNEL_DIR/net/ipv6/netfilter/ip6t_IMQ.c ] && echo IMQ 7 | --- userspace/extensions.orig/libip6t_IMQ.c Thu Jan 1 01:00:00 1970 8 | +++ userspace/extensions/libip6t_IMQ.c Mon Jun 16 10:12:47 2003 9 | @@ -0,0 +1,102 @@ 10 | +/* Shared library add-on to iptables to add IMQ target support. */ 11 | +#include 12 | +#include 13 | +#include 14 | +#include 15 | + 16 | +#include 17 | +#include 18 | +#include 19 | + 20 | +/* Function which prints out usage message. */ 21 | +static void 22 | +help(void) 23 | +{ 24 | + printf( 25 | +"IMQ target v%s options:\n" 26 | +" --todev enqueue to imq, defaults to 0\n", 27 | +IPTABLES_VERSION); 28 | +} 29 | + 30 | +static struct option opts[] = { 31 | + { "todev", 1, 0, '1' }, 32 | + { 0 } 33 | +}; 34 | + 35 | +/* Initialize the target. */ 36 | +static void 37 | +init(struct ip6t_entry_target *t, unsigned int *nfcache) 38 | +{ 39 | + struct ip6t_imq_info *mr = (struct ip6t_imq_info*)t->data; 40 | + 41 | + mr->todev = 0; 42 | + *nfcache |= NFC_UNKNOWN; 43 | +} 44 | + 45 | +/* Function which parses command options; returns true if it 46 | + ate an option */ 47 | +static int 48 | +parse(int c, char **argv, int invert, unsigned int *flags, 49 | + const struct ip6t_entry *entry, 50 | + struct ip6t_entry_target **target) 51 | +{ 52 | + struct ip6t_imq_info *mr = (struct ip6t_imq_info*)(*target)->data; 53 | + 54 | + switch(c) { 55 | + case '1': 56 | + if (check_inverse(optarg, &invert, NULL, 0)) 57 | + exit_error(PARAMETER_PROBLEM, 58 | + "Unexpected `!' after --todev"); 59 | + mr->todev=atoi(optarg); 60 | + break; 61 | + default: 62 | + return 0; 63 | + } 64 | + return 1; 65 | +} 66 | + 67 | +static void 68 | +final_check(unsigned int flags) 69 | +{ 70 | +} 71 | + 72 | +/* Prints out the targinfo. */ 73 | +static void 74 | +print(const struct ip6t_ip6 *ip, 75 | + const struct ip6t_entry_target *target, 76 | + int numeric) 77 | +{ 78 | + struct ip6t_imq_info *mr = (struct ip6t_imq_info*)target->data; 79 | + 80 | + printf("IMQ: todev %u ", mr->todev); 81 | +} 82 | + 83 | +/* Saves the union ipt_targinfo in parsable form to stdout. */ 84 | +static void 85 | +save(const struct ip6t_ip6 *ip, const struct ip6t_entry_target *target) 86 | +{ 87 | + struct ip6t_imq_info *mr = (struct ip6t_imq_info*)target->data; 88 | + 89 | + printf("--todev %u", mr->todev); 90 | +} 91 | + 92 | +static 93 | +struct ip6tables_target imq 94 | += { NULL, 95 | + "IMQ", 96 | + IPTABLES_VERSION, 97 | + IP6T_ALIGN(sizeof(struct ip6t_imq_info)), 98 | + IP6T_ALIGN(sizeof(struct ip6t_imq_info)), 99 | + &help, 100 | + &init, 101 | + &parse, 102 | + &final_check, 103 | + &print, 104 | + &save, 105 | + opts 106 | +}; 107 | + 108 | +void _init(void) 109 | +{ 110 | + register_target6(&imq); 111 | +} 112 | --- userspace/extensions.orig/.IMQ-test Thu Jan 1 01:00:00 1970 113 | +++ userspace/extensions/.IMQ-test Mon Jun 16 10:12:47 2003 114 | @@ -0,0 +1,3 @@ 115 | +#!/bin/sh 116 | +# True if IMQ target patch is applied. 117 | +[ -f $KERNEL_DIR/net/ipv4/netfilter/ipt_IMQ.c ] && echo IMQ 118 | --- userspace/extensions.orig/libipt_IMQ.c Thu Jan 1 01:00:00 1970 119 | +++ userspace/extensions/libipt_IMQ.c Mon Jun 16 10:12:47 2003 120 | @@ -0,0 +1,102 @@ 121 | +/* Shared library add-on to iptables to add IMQ target support. */ 122 | +#include 123 | +#include 124 | +#include 125 | +#include 126 | + 127 | +#include 128 | +#include 129 | +#include 130 | + 131 | +/* Function which prints out usage message. */ 132 | +static void 133 | +help(void) 134 | +{ 135 | + printf( 136 | +"IMQ target v%s options:\n" 137 | +" --todev enqueue to imq, defaults to 0\n", 138 | +IPTABLES_VERSION); 139 | +} 140 | + 141 | +static struct option opts[] = { 142 | + { "todev", 1, 0, '1' }, 143 | + { 0 } 144 | +}; 145 | + 146 | +/* Initialize the target. */ 147 | +static void 148 | +init(struct ipt_entry_target *t, unsigned int *nfcache) 149 | +{ 150 | + struct ipt_imq_info *mr = (struct ipt_imq_info*)t->data; 151 | + 152 | + mr->todev = 0; 153 | + *nfcache |= NFC_UNKNOWN; 154 | +} 155 | + 156 | +/* Function which parses command options; returns true if it 157 | + ate an option */ 158 | +static int 159 | +parse(int c, char **argv, int invert, unsigned int *flags, 160 | + const struct ipt_entry *entry, 161 | + struct ipt_entry_target **target) 162 | +{ 163 | + struct ipt_imq_info *mr = (struct ipt_imq_info*)(*target)->data; 164 | + 165 | + switch(c) { 166 | + case '1': 167 | + if (check_inverse(optarg, &invert, NULL, 0)) 168 | + exit_error(PARAMETER_PROBLEM, 169 | + "Unexpected `!' after --todev"); 170 | + mr->todev=atoi(optarg); 171 | + break; 172 | + default: 173 | + return 0; 174 | + } 175 | + return 1; 176 | +} 177 | + 178 | +static void 179 | +final_check(unsigned int flags) 180 | +{ 181 | +} 182 | + 183 | +/* Prints out the targinfo. */ 184 | +static void 185 | +print(const struct ipt_ip *ip, 186 | + const struct ipt_entry_target *target, 187 | + int numeric) 188 | +{ 189 | + struct ipt_imq_info *mr = (struct ipt_imq_info*)target->data; 190 | + 191 | + printf("IMQ: todev %u ", mr->todev); 192 | +} 193 | + 194 | +/* Saves the union ipt_targinfo in parsable form to stdout. */ 195 | +static void 196 | +save(const struct ipt_ip *ip, const struct ipt_entry_target *target) 197 | +{ 198 | + struct ipt_imq_info *mr = (struct ipt_imq_info*)target->data; 199 | + 200 | + printf("--todev %u", mr->todev); 201 | +} 202 | + 203 | +static 204 | +struct iptables_target imq 205 | += { NULL, 206 | + "IMQ", 207 | + IPTABLES_VERSION, 208 | + IPT_ALIGN(sizeof(struct ipt_imq_info)), 209 | + IPT_ALIGN(sizeof(struct ipt_imq_info)), 210 | + &help, 211 | + &init, 212 | + &parse, 213 | + &final_check, 214 | + &print, 215 | + &save, 216 | + opts 217 | +}; 218 | + 219 | +void _init(void) 220 | +{ 221 | + register_target(&imq); 222 | +} 223 | -------------------------------------------------------------------------------- /iptables/iptables-1.3.0-imq1.diff: -------------------------------------------------------------------------------- 1 | --- userspace/extensions.orig/.IMQ-test6 Thu Jan 1 01:00:00 1970 2 | +++ userspace/extensions/.IMQ-test6 Mon Jun 16 10:12:47 2003 3 | @@ -0,0 +1,3 @@ 4 | +#!/bin/sh 5 | +# True if IMQ target patch is applied. 6 | +[ -f $KERNEL_DIR/net/ipv6/netfilter/ip6t_IMQ.c ] && echo IMQ 7 | --- userspace/extensions.orig/libip6t_IMQ.c Thu Jan 1 01:00:00 1970 8 | +++ userspace/extensions/libip6t_IMQ.c Mon Jun 16 10:12:47 2003 9 | @@ -0,0 +1,101 @@ 10 | +/* Shared library add-on to iptables to add IMQ target support. */ 11 | +#include 12 | +#include 13 | +#include 14 | +#include 15 | + 16 | +#include 17 | +#include 18 | +#include 19 | + 20 | +/* Function which prints out usage message. */ 21 | +static void 22 | +help(void) 23 | +{ 24 | + printf( 25 | +"IMQ target v%s options:\n" 26 | +" --todev enqueue to imq, defaults to 0\n", 27 | +IPTABLES_VERSION); 28 | +} 29 | + 30 | +static struct option opts[] = { 31 | + { "todev", 1, 0, '1' }, 32 | + { 0 } 33 | +}; 34 | + 35 | +/* Initialize the target. */ 36 | +static void 37 | +init(struct ip6t_entry_target *t, unsigned int *nfcache) 38 | +{ 39 | + struct ip6t_imq_info *mr = (struct ip6t_imq_info*)t->data; 40 | + 41 | + mr->todev = 0; 42 | + *nfcache |= NFC_UNKNOWN; 43 | +} 44 | + 45 | +/* Function which parses command options; returns true if it 46 | + ate an option */ 47 | +static int 48 | +parse(int c, char **argv, int invert, unsigned int *flags, 49 | + const struct ip6t_entry *entry, 50 | + struct ip6t_entry_target **target) 51 | +{ 52 | + struct ip6t_imq_info *mr = (struct ip6t_imq_info*)(*target)->data; 53 | + 54 | + switch(c) { 55 | + case '1': 56 | + if (check_inverse(optarg, &invert, NULL, 0)) 57 | + exit_error(PARAMETER_PROBLEM, 58 | + "Unexpected `!' after --todev"); 59 | + mr->todev=atoi(optarg); 60 | + break; 61 | + default: 62 | + return 0; 63 | + } 64 | + return 1; 65 | +} 66 | + 67 | +static void 68 | +final_check(unsigned int flags) 69 | +{ 70 | +} 71 | + 72 | +/* Prints out the targinfo. */ 73 | +static void 74 | +print(const struct ip6t_ip6 *ip, 75 | + const struct ip6t_entry_target *target, 76 | + int numeric) 77 | +{ 78 | + struct ip6t_imq_info *mr = (struct ip6t_imq_info*)target->data; 79 | + 80 | + printf("IMQ: todev %u ", mr->todev); 81 | +} 82 | + 83 | +/* Saves the union ipt_targinfo in parsable form to stdout. */ 84 | +static void 85 | +save(const struct ip6t_ip6 *ip, const struct ip6t_entry_target *target) 86 | +{ 87 | + struct ip6t_imq_info *mr = (struct ip6t_imq_info*)target->data; 88 | + 89 | + printf("--todev %u", mr->todev); 90 | +} 91 | + 92 | +static struct ip6tables_target imq = { 93 | + .next = NULL, 94 | + .name = "IMQ", 95 | + .version = IPTABLES_VERSION, 96 | + .size = IP6T_ALIGN(sizeof(struct ip6t_imq_info)), 97 | + .userspacesize = IP6T_ALIGN(sizeof(struct ip6t_imq_info)), 98 | + .help = &help, 99 | + .init = &init, 100 | + .parse = &parse, 101 | + .final_check = &final_check, 102 | + .print = &print, 103 | + .save = &save, 104 | + .extra_opts = opts 105 | +}; 106 | + 107 | +void _init(void) 108 | +{ 109 | + register_target6(&imq); 110 | +} 111 | --- userspace/extensions.orig/.IMQ-test Thu Jan 1 01:00:00 1970 112 | +++ userspace/extensions/.IMQ-test Mon Jun 16 10:12:47 2003 113 | @@ -0,0 +1,3 @@ 114 | +#!/bin/sh 115 | +# True if IMQ target patch is applied. 116 | +[ -f $KERNEL_DIR/net/ipv4/netfilter/ipt_IMQ.c ] && echo IMQ 117 | --- userspace/extensions.orig/libipt_IMQ.c Thu Jan 1 01:00:00 1970 118 | +++ userspace/extensions/libipt_IMQ.c Mon Jun 16 10:12:47 2003 119 | @@ -0,0 +1,101 @@ 120 | +/* Shared library add-on to iptables to add IMQ target support. */ 121 | +#include 122 | +#include 123 | +#include 124 | +#include 125 | + 126 | +#include 127 | +#include 128 | +#include 129 | + 130 | +/* Function which prints out usage message. */ 131 | +static void 132 | +help(void) 133 | +{ 134 | + printf( 135 | +"IMQ target v%s options:\n" 136 | +" --todev enqueue to imq, defaults to 0\n", 137 | +IPTABLES_VERSION); 138 | +} 139 | + 140 | +static struct option opts[] = { 141 | + { "todev", 1, 0, '1' }, 142 | + { 0 } 143 | +}; 144 | + 145 | +/* Initialize the target. */ 146 | +static void 147 | +init(struct ipt_entry_target *t, unsigned int *nfcache) 148 | +{ 149 | + struct ipt_imq_info *mr = (struct ipt_imq_info*)t->data; 150 | + 151 | + mr->todev = 0; 152 | + *nfcache |= NFC_UNKNOWN; 153 | +} 154 | + 155 | +/* Function which parses command options; returns true if it 156 | + ate an option */ 157 | +static int 158 | +parse(int c, char **argv, int invert, unsigned int *flags, 159 | + const struct ipt_entry *entry, 160 | + struct ipt_entry_target **target) 161 | +{ 162 | + struct ipt_imq_info *mr = (struct ipt_imq_info*)(*target)->data; 163 | + 164 | + switch(c) { 165 | + case '1': 166 | + if (check_inverse(optarg, &invert, NULL, 0)) 167 | + exit_error(PARAMETER_PROBLEM, 168 | + "Unexpected `!' after --todev"); 169 | + mr->todev=atoi(optarg); 170 | + break; 171 | + default: 172 | + return 0; 173 | + } 174 | + return 1; 175 | +} 176 | + 177 | +static void 178 | +final_check(unsigned int flags) 179 | +{ 180 | +} 181 | + 182 | +/* Prints out the targinfo. */ 183 | +static void 184 | +print(const struct ipt_ip *ip, 185 | + const struct ipt_entry_target *target, 186 | + int numeric) 187 | +{ 188 | + struct ipt_imq_info *mr = (struct ipt_imq_info*)target->data; 189 | + 190 | + printf("IMQ: todev %u ", mr->todev); 191 | +} 192 | + 193 | +/* Saves the union ipt_targinfo in parsable form to stdout. */ 194 | +static void 195 | +save(const struct ipt_ip *ip, const struct ipt_entry_target *target) 196 | +{ 197 | + struct ipt_imq_info *mr = (struct ipt_imq_info*)target->data; 198 | + 199 | + printf("--todev %u", mr->todev); 200 | +} 201 | + 202 | +static struct iptables_target imq = { 203 | + .next = NULL, 204 | + .name = "IMQ", 205 | + .version = IPTABLES_VERSION, 206 | + .size = IPT_ALIGN(sizeof(struct ipt_imq_info)), 207 | + .userspacesize = IPT_ALIGN(sizeof(struct ipt_imq_info)), 208 | + .help = &help, 209 | + .init = &init, 210 | + .parse = &parse, 211 | + .final_check = &final_check, 212 | + .print = &print, 213 | + .save = &save, 214 | + .extra_opts = opts 215 | +}; 216 | + 217 | +void _init(void) 218 | +{ 219 | + register_target(&imq); 220 | +} 221 | -------------------------------------------------------------------------------- /iptables/iptables-1.3.6-imq.diff: -------------------------------------------------------------------------------- 1 | --- iptables-1.3.6.orig/extensions.orig/.IMQ-test6 Thu Jan 1 01:00:00 1970 2 | +++ iptables-1.3.6/extensions/.IMQ-test6 Mon Jun 16 10:12:47 2003 3 | @@ -0,0 +1,3 @@ 4 | +#!/bin/sh 5 | +# True if IMQ target patch is applied. 6 | +[ -f $KERNEL_DIR/net/ipv6/netfilter/ip6t_IMQ.c ] && echo IMQ 7 | --- iptables-1.3.6.orig/extensions.orig/libip6t_IMQ.c Thu Jan 1 01:00:00 1970 8 | +++ iptables-1.3.6/extensions/libip6t_IMQ.c Mon Jun 16 10:12:47 2003 9 | @@ -0,0 +1,101 @@ 10 | +/* Shared library add-on to iptables to add IMQ target support. */ 11 | +#include 12 | +#include 13 | +#include 14 | +#include 15 | + 16 | +#include 17 | +#include 18 | +#include 19 | + 20 | +/* Function which prints out usage message. */ 21 | +static void 22 | +help(void) 23 | +{ 24 | + printf( 25 | +"IMQ target v%s options:\n" 26 | +" --todev enqueue to imq, defaults to 0\n", 27 | +IPTABLES_VERSION); 28 | +} 29 | + 30 | +static struct option opts[] = { 31 | + { "todev", 1, 0, '1' }, 32 | + { 0 } 33 | +}; 34 | + 35 | +/* Initialize the target. */ 36 | +static void 37 | +init(struct ip6t_entry_target *t, unsigned int *nfcache) 38 | +{ 39 | + struct ip6t_imq_info *mr = (struct ip6t_imq_info*)t->data; 40 | + 41 | + mr->todev = 0; 42 | + *nfcache |= NFC_UNKNOWN; 43 | +} 44 | + 45 | +/* Function which parses command options; returns true if it 46 | + ate an option */ 47 | +static int 48 | +parse(int c, char **argv, int invert, unsigned int *flags, 49 | + const struct ip6t_entry *entry, 50 | + struct ip6t_entry_target **target) 51 | +{ 52 | + struct ip6t_imq_info *mr = (struct ip6t_imq_info*)(*target)->data; 53 | + 54 | + switch(c) { 55 | + case '1': 56 | + if (check_inverse(optarg, &invert, NULL, 0)) 57 | + exit_error(PARAMETER_PROBLEM, 58 | + "Unexpected `!' after --todev"); 59 | + mr->todev=atoi(optarg); 60 | + break; 61 | + default: 62 | + return 0; 63 | + } 64 | + return 1; 65 | +} 66 | + 67 | +static void 68 | +final_check(unsigned int flags) 69 | +{ 70 | +} 71 | + 72 | +/* Prints out the targinfo. */ 73 | +static void 74 | +print(const struct ip6t_ip6 *ip, 75 | + const struct ip6t_entry_target *target, 76 | + int numeric) 77 | +{ 78 | + struct ip6t_imq_info *mr = (struct ip6t_imq_info*)target->data; 79 | + 80 | + printf("IMQ: todev %u ", mr->todev); 81 | +} 82 | + 83 | +/* Saves the union ipt_targinfo in parsable form to stdout. */ 84 | +static void 85 | +save(const struct ip6t_ip6 *ip, const struct ip6t_entry_target *target) 86 | +{ 87 | + struct ip6t_imq_info *mr = (struct ip6t_imq_info*)target->data; 88 | + 89 | + printf("--todev %u", mr->todev); 90 | +} 91 | + 92 | +static struct ip6tables_target imq = { 93 | + .next = NULL, 94 | + .name = "IMQ", 95 | + .version = IPTABLES_VERSION, 96 | + .size = IP6T_ALIGN(sizeof(struct ip6t_imq_info)), 97 | + .userspacesize = IP6T_ALIGN(sizeof(struct ip6t_imq_info)), 98 | + .help = &help, 99 | + .init = &init, 100 | + .parse = &parse, 101 | + .final_check = &final_check, 102 | + .print = &print, 103 | + .save = &save, 104 | + .extra_opts = opts 105 | +}; 106 | + 107 | +static __attribute__((constructor)) void _init(void) 108 | +{ 109 | + register_target6(&imq); 110 | +} 111 | --- iptables-1.3.6.orig/extensions.orig/.IMQ-test Thu Jan 1 01:00:00 1970 112 | +++ iptables-1.3.6/extensions/.IMQ-test Mon Jun 16 10:12:47 2003 113 | @@ -0,0 +1,3 @@ 114 | +#!/bin/sh 115 | +# True if IMQ target patch is applied. 116 | +[ -f $KERNEL_DIR/net/ipv4/netfilter/ipt_IMQ.c ] && echo IMQ 117 | --- iptables-1.3.6.orig/extensions.orig/libipt_IMQ.c Thu Jan 1 01:00:00 1970 118 | +++ iptables-1.3.6/extensions/libipt_IMQ.c Mon Jun 16 10:12:47 2003 119 | @@ -0,0 +1,101 @@ 120 | +/* Shared library add-on to iptables to add IMQ target support. */ 121 | +#include 122 | +#include 123 | +#include 124 | +#include 125 | + 126 | +#include 127 | +#include 128 | +#include 129 | + 130 | +/* Function which prints out usage message. */ 131 | +static void 132 | +help(void) 133 | +{ 134 | + printf( 135 | +"IMQ target v%s options:\n" 136 | +" --todev enqueue to imq, defaults to 0\n", 137 | +IPTABLES_VERSION); 138 | +} 139 | + 140 | +static struct option opts[] = { 141 | + { "todev", 1, 0, '1' }, 142 | + { 0 } 143 | +}; 144 | + 145 | +/* Initialize the target. */ 146 | +static void 147 | +init(struct ipt_entry_target *t, unsigned int *nfcache) 148 | +{ 149 | + struct ipt_imq_info *mr = (struct ipt_imq_info*)t->data; 150 | + 151 | + mr->todev = 0; 152 | + *nfcache |= NFC_UNKNOWN; 153 | +} 154 | + 155 | +/* Function which parses command options; returns true if it 156 | + ate an option */ 157 | +static int 158 | +parse(int c, char **argv, int invert, unsigned int *flags, 159 | + const struct ipt_entry *entry, 160 | + struct ipt_entry_target **target) 161 | +{ 162 | + struct ipt_imq_info *mr = (struct ipt_imq_info*)(*target)->data; 163 | + 164 | + switch(c) { 165 | + case '1': 166 | + if (check_inverse(optarg, &invert, NULL, 0)) 167 | + exit_error(PARAMETER_PROBLEM, 168 | + "Unexpected `!' after --todev"); 169 | + mr->todev=atoi(optarg); 170 | + break; 171 | + default: 172 | + return 0; 173 | + } 174 | + return 1; 175 | +} 176 | + 177 | +static void 178 | +final_check(unsigned int flags) 179 | +{ 180 | +} 181 | + 182 | +/* Prints out the targinfo. */ 183 | +static void 184 | +print(const struct ipt_ip *ip, 185 | + const struct ipt_entry_target *target, 186 | + int numeric) 187 | +{ 188 | + struct ipt_imq_info *mr = (struct ipt_imq_info*)target->data; 189 | + 190 | + printf("IMQ: todev %u ", mr->todev); 191 | +} 192 | + 193 | +/* Saves the union ipt_targinfo in parsable form to stdout. */ 194 | +static void 195 | +save(const struct ipt_ip *ip, const struct ipt_entry_target *target) 196 | +{ 197 | + struct ipt_imq_info *mr = (struct ipt_imq_info*)target->data; 198 | + 199 | + printf("--todev %u", mr->todev); 200 | +} 201 | + 202 | +static struct iptables_target imq = { 203 | + .next = NULL, 204 | + .name = "IMQ", 205 | + .version = IPTABLES_VERSION, 206 | + .size = IPT_ALIGN(sizeof(struct ipt_imq_info)), 207 | + .userspacesize = IPT_ALIGN(sizeof(struct ipt_imq_info)), 208 | + .help = &help, 209 | + .init = &init, 210 | + .parse = &parse, 211 | + .final_check = &final_check, 212 | + .print = &print, 213 | + .save = &save, 214 | + .extra_opts = opts 215 | +}; 216 | + 217 | +static __attribute__((constructor)) void _init(void) 218 | +{ 219 | + register_target(&imq); 220 | +} 221 | 222 | -------------------------------------------------------------------------------- /iptables/iptables-1.4.0-imq.diff: -------------------------------------------------------------------------------- 1 | --- iptables-1.4.0.orig/extensions.orig/.IMQ-test6 Thu Jan 1 01:00:00 1970 2 | +++ iptables-1.4.0/extensions/.IMQ-test6 Mon Jun 16 10:12:47 2003 3 | @@ -0,0 +1,3 @@ 4 | +#!/bin/sh 5 | +# True if IMQ target patch is applied. 6 | +[ -f $KERNEL_DIR/include/linux/netfilter_ipv6/ip6t_IMQ.h ] && echo IMQ 7 | --- iptables-1.4.0.orig/extensions.orig/libip6t_IMQ.c Thu Jan 1 01:00:00 1970 8 | +++ iptables-1.4.0/extensions/libip6t_IMQ.c Mon Jun 16 10:12:47 2003 9 | @@ -0,0 +1,100 @@ 10 | +/* Shared library add-on to iptables to add IMQ target support. */ 11 | +#include 12 | +#include 13 | +#include 14 | +#include 15 | + 16 | +#include 17 | +#include 18 | +#include 19 | + 20 | +/* Function which prints out usage message. */ 21 | +static void 22 | +help(void) 23 | +{ 24 | + printf( 25 | +"IMQ target v%s options:\n" 26 | +" --todev enqueue to imq, defaults to 0\n", 27 | +IPTABLES_VERSION); 28 | +} 29 | + 30 | +static struct option opts[] = { 31 | + { "todev", 1, 0, '1' }, 32 | + { 0 } 33 | +}; 34 | + 35 | +/* Initialize the target. */ 36 | +static void 37 | +init(struct xt_entry_target *t) 38 | +{ 39 | + struct ip6t_imq_info *mr = (struct ip6t_imq_info*)t->data; 40 | + 41 | + mr->todev = 0; 42 | +} 43 | + 44 | +/* Function which parses command options; returns true if it 45 | + ate an option */ 46 | +static int 47 | +parse(int c, char **argv, int invert, unsigned int *flags, 48 | + const void *entry, 49 | + struct xt_entry_target **target) 50 | +{ 51 | + struct ip6t_imq_info *mr = (struct ip6t_imq_info*)(*target)->data; 52 | + 53 | + switch(c) { 54 | + case '1': 55 | + if (check_inverse(optarg, &invert, NULL, 0)) 56 | + exit_error(PARAMETER_PROBLEM, 57 | + "Unexpected `!' after --todev"); 58 | + mr->todev=atoi(optarg); 59 | + break; 60 | + default: 61 | + return 0; 62 | + } 63 | + return 1; 64 | +} 65 | + 66 | +static void 67 | +final_check(unsigned int flags) 68 | +{ 69 | +} 70 | + 71 | +/* Prints out the targinfo. */ 72 | +static void 73 | +print(const void *ip, 74 | + const struct xt_entry_target *target, 75 | + int numeric) 76 | +{ 77 | + struct ip6t_imq_info *mr = (struct ip6t_imq_info*)target->data; 78 | + 79 | + printf("IMQ: todev %u ", mr->todev); 80 | +} 81 | + 82 | +/* Saves the union ipt_targinfo in parsable form to stdout. */ 83 | +static void 84 | +save(const void *ip, const struct xt_entry_target *target) 85 | +{ 86 | + struct ip6t_imq_info *mr = (struct ip6t_imq_info*)target->data; 87 | + 88 | + printf("--todev %u", mr->todev); 89 | +} 90 | + 91 | +static struct ip6tables_target imq = { 92 | + .next = NULL, 93 | + .name = "IMQ", 94 | + .version = IPTABLES_VERSION, 95 | + .size = IP6T_ALIGN(sizeof(struct ip6t_imq_info)), 96 | + .userspacesize = IP6T_ALIGN(sizeof(struct ip6t_imq_info)), 97 | + .help = &help, 98 | + .init = &init, 99 | + .parse = &parse, 100 | + .final_check = &final_check, 101 | + .print = &print, 102 | + .save = &save, 103 | + .extra_opts = opts 104 | +}; 105 | + 106 | +static __attribute__((constructor)) void _init(void) 107 | +{ 108 | + register_target6(&imq); 109 | +} 110 | --- iptables-1.4.0.orig/extensions.orig/.IMQ-test Thu Jan 1 01:00:00 1970 111 | +++ iptables-1.4.0/extensions/.IMQ-test Mon Jun 16 10:12:47 2003 112 | @@ -0,0 +1,3 @@ 113 | +#!/bin/sh 114 | +# True if IMQ target patch is applied. 115 | +[ -f $KERNEL_DIR/include/linux/netfilter_ipv4/ipt_IMQ.h ] && echo IMQ 116 | --- iptables-1.4.0.orig/extensions.orig/libipt_IMQ.c Thu Jan 1 01:00:00 1970 117 | +++ iptables-1.4.0/extensions/libipt_IMQ.c Mon Jun 16 10:12:47 2003 118 | @@ -0,0 +1,100 @@ 119 | +/* Shared library add-on to iptables to add IMQ target support. */ 120 | +#include 121 | +#include 122 | +#include 123 | +#include 124 | + 125 | +#include 126 | +#include 127 | +#include 128 | + 129 | +/* Function which prints out usage message. */ 130 | +static void 131 | +help(void) 132 | +{ 133 | + printf( 134 | +"IMQ target v%s options:\n" 135 | +" --todev enqueue to imq, defaults to 0\n", 136 | +IPTABLES_VERSION); 137 | +} 138 | + 139 | +static struct option opts[] = { 140 | + { "todev", 1, 0, '1' }, 141 | + { 0 } 142 | +}; 143 | + 144 | +/* Initialize the target. */ 145 | +static void 146 | +init(struct xt_entry_target *t) 147 | +{ 148 | + struct ipt_imq_info *mr = (struct ipt_imq_info*)t->data; 149 | + 150 | + mr->todev = 0; 151 | +} 152 | + 153 | +/* Function which parses command options; returns true if it 154 | + ate an option */ 155 | +static int 156 | +parse(int c, char **argv, int invert, unsigned int *flags, 157 | + const void *entry, 158 | + struct xt_entry_target **target) 159 | +{ 160 | + struct ipt_imq_info *mr = (struct ipt_imq_info*)(*target)->data; 161 | + 162 | + switch(c) { 163 | + case '1': 164 | + if (check_inverse(optarg, &invert, NULL, 0)) 165 | + exit_error(PARAMETER_PROBLEM, 166 | + "Unexpected `!' after --todev"); 167 | + mr->todev=atoi(optarg); 168 | + break; 169 | + default: 170 | + return 0; 171 | + } 172 | + return 1; 173 | +} 174 | + 175 | +static void 176 | +final_check(unsigned int flags) 177 | +{ 178 | +} 179 | + 180 | +/* Prints out the targinfo. */ 181 | +static void 182 | +print(const void *ip, 183 | + const struct xt_entry_target *target, 184 | + int numeric) 185 | +{ 186 | + struct ipt_imq_info *mr = (struct ipt_imq_info*)target->data; 187 | + 188 | + printf("IMQ: todev %u ", mr->todev); 189 | +} 190 | + 191 | +/* Saves the union ipt_targinfo in parsable form to stdout. */ 192 | +static void 193 | +save(const void *ip, const struct xt_entry_target *target) 194 | +{ 195 | + struct ipt_imq_info *mr = (struct ipt_imq_info*)target->data; 196 | + 197 | + printf("--todev %u", mr->todev); 198 | +} 199 | + 200 | +static struct iptables_target imq = { 201 | + .next = NULL, 202 | + .name = "IMQ", 203 | + .version = IPTABLES_VERSION, 204 | + .size = IPT_ALIGN(sizeof(struct ipt_imq_info)), 205 | + .userspacesize = IPT_ALIGN(sizeof(struct ipt_imq_info)), 206 | + .help = &help, 207 | + .init = &init, 208 | + .parse = &parse, 209 | + .final_check = &final_check, 210 | + .print = &print, 211 | + .save = &save, 212 | + .extra_opts = opts 213 | +}; 214 | + 215 | +static __attribute__((constructor)) void _init(void) 216 | +{ 217 | + register_target(&imq); 218 | +} 219 | 220 | -------------------------------------------------------------------------------- /iptables/iptables-1.4.1-imq.diff: -------------------------------------------------------------------------------- 1 | --- iptables-1.4.1-rc3.orig/extensions/.IMQ-test 1970-01-01 10:00:00.000000000 +1000 2 | +++ iptables-1.4.1-rc3/extensions/.IMQ-test 2008-06-08 22:41:49.000000000 +1000 3 | @@ -0,0 +1,3 @@ 4 | +#!/bin/sh 5 | +# True if IMQ target patch is applied. 6 | +[ -f $KERNEL_DIR/include/linux/netfilter_ipv4/ipt_IMQ.h ] && echo IMQ 7 | diff -pruN iptables-1.4.1-rc3.orig/extensions/.IMQ-test6 iptables-1.4.1-rc3/extensions/.IMQ-test6 8 | --- iptables-1.4.1-rc3.orig/extensions/.IMQ-test6 1970-01-01 10:00:00.000000000 +1000 9 | +++ iptables-1.4.1-rc3/extensions/.IMQ-test6 2008-06-08 22:41:49.000000000 +1000 10 | @@ -0,0 +1,3 @@ 11 | +#!/bin/sh 12 | +# True if IMQ target patch is applied. 13 | +[ -f $KERNEL_DIR/include/linux/netfilter_ipv6/ip6t_IMQ.h ] && echo IMQ 14 | diff -pruN iptables-1.4.1-rc3.orig/extensions/libip6t_IMQ.c iptables-1.4.1-rc3/extensions/libip6t_IMQ.c 15 | --- iptables-1.4.1-rc3.orig/extensions/libip6t_IMQ.c 1970-01-01 10:00:00.000000000 +1000 16 | +++ iptables-1.4.1-rc3/extensions/libip6t_IMQ.c 2008-06-08 22:46:57.000000000 +1000 17 | @@ -0,0 +1,89 @@ 18 | +/* Shared library add-on to iptables to add IMQ target support. */ 19 | +#include 20 | +#include 21 | +#include 22 | +#include 23 | + 24 | +#include 25 | +#include 26 | +#include 27 | + 28 | +/* Function which prints out usage message. */ 29 | +static void IMQ_help(void) 30 | +{ 31 | + printf( 32 | +"IMQ target v%s options:\n" 33 | +" --todev enqueue to imq, defaults to 0\n", 34 | +XTABLES_VERSION); 35 | +} 36 | + 37 | +static struct option IMQ_opts[] = { 38 | + { "todev", 1, 0, '1' }, 39 | + { 0 } 40 | +}; 41 | + 42 | +/* Initialize the target. */ 43 | +static void IMQ_init(struct xt_entry_target *t) 44 | +{ 45 | + struct ip6t_imq_info *mr = (struct ip6t_imq_info*)t->data; 46 | + 47 | + mr->todev = 0; 48 | +} 49 | + 50 | +/* Function which parses command options; returns true if it 51 | + ate an option */ 52 | +static int IMQ_parse(int c, char **argv, int invert, unsigned int *flags, 53 | + const void *entry, 54 | + struct xt_entry_target **target) 55 | +{ 56 | + struct ip6t_imq_info *mr = (struct ip6t_imq_info*)(*target)->data; 57 | + 58 | + switch(c) { 59 | + case '1': 60 | + if (check_inverse(optarg, &invert, NULL, 0)) 61 | + exit_error(PARAMETER_PROBLEM, 62 | + "Unexpected `!' after --todev"); 63 | + mr->todev=atoi(optarg); 64 | + break; 65 | + default: 66 | + return 0; 67 | + } 68 | + return 1; 69 | +} 70 | + 71 | +/* Prints out the targinfo. */ 72 | +static void IMQ_print(const void *ip, 73 | + const struct xt_entry_target *target, 74 | + int numeric) 75 | +{ 76 | + struct ip6t_imq_info *mr = (struct ip6t_imq_info*)target->data; 77 | + 78 | + printf("IMQ: todev %u ", mr->todev); 79 | +} 80 | + 81 | +/* Saves the union ipt_targinfo in parsable form to stdout. */ 82 | +static void IMQ_save(const void *ip, const struct xt_entry_target *target) 83 | +{ 84 | + struct ip6t_imq_info *mr = (struct ip6t_imq_info*)target->data; 85 | + 86 | + printf("--todev %u", mr->todev); 87 | +} 88 | + 89 | +static struct xtables_target imq = { 90 | + .name = "IMQ", 91 | + .version = XTABLES_VERSION, 92 | + .family = PF_INET6, 93 | + .size = XT_ALIGN(sizeof(struct ip6t_imq_info)), 94 | + .userspacesize = XT_ALIGN(sizeof(struct ip6t_imq_info)), 95 | + .help = IMQ_help, 96 | + .init = IMQ_init, 97 | + .parse = IMQ_parse, 98 | + .print = IMQ_print, 99 | + .save = IMQ_save, 100 | + .extra_opts = IMQ_opts, 101 | +}; 102 | + 103 | +void _init(void) 104 | +{ 105 | + xtables_register_target(&imq); 106 | +} 107 | diff -pruN iptables-1.4.1-rc3.orig/extensions/libipt_IMQ.c iptables-1.4.1-rc3/extensions/libipt_IMQ.c 108 | --- iptables-1.4.1-rc3.orig/extensions/libipt_IMQ.c 1970-01-01 10:00:00.000000000 +1000 109 | +++ iptables-1.4.1-rc3/extensions/libipt_IMQ.c 2008-06-08 22:46:25.000000000 +1000 110 | @@ -0,0 +1,88 @@ 111 | +/* Shared library add-on to iptables to add IMQ target support. */ 112 | +#include 113 | +#include 114 | +#include 115 | +#include 116 | + 117 | +#include 118 | +#include 119 | +#include 120 | + 121 | +/* Function which prints out usage message. */ 122 | +static void IMQ_help(void) 123 | +{ 124 | + printf( 125 | +"IMQ target v%s options:\n" 126 | +" --todev enqueue to imq, defaults to 0\n", 127 | +XTABLES_VERSION); 128 | +} 129 | + 130 | +static struct option IMQ_opts[] = { 131 | + { "todev", 1, 0, '1' }, 132 | + { 0 } 133 | +}; 134 | + 135 | +/* Initialize the target. */ 136 | +static void IMQ_init(struct xt_entry_target *t) 137 | +{ 138 | + struct ipt_imq_info *mr = (struct ipt_imq_info*)t->data; 139 | + 140 | + mr->todev = 0; 141 | +} 142 | + 143 | +/* Function which parses command options; returns true if it 144 | + ate an option */ 145 | +static int IMQ_parse(int c, char **argv, int invert, unsigned int *flags, 146 | + const void *entry, struct xt_entry_target **target) 147 | +{ 148 | + struct ipt_imq_info *mr = (struct ipt_imq_info*)(*target)->data; 149 | + 150 | + switch(c) { 151 | + case '1': 152 | + if (check_inverse(optarg, &invert, NULL, 0)) 153 | + exit_error(PARAMETER_PROBLEM, 154 | + "Unexpected `!' after --todev"); 155 | + mr->todev=atoi(optarg); 156 | + break; 157 | + default: 158 | + return 0; 159 | + } 160 | + return 1; 161 | +} 162 | + 163 | +/* Prints out the targinfo. */ 164 | +static void IMQ_print(const void *ip, 165 | + const struct xt_entry_target *target, 166 | + int numeric) 167 | +{ 168 | + struct ipt_imq_info *mr = (struct ipt_imq_info*)target->data; 169 | + 170 | + printf("IMQ: todev %u ", mr->todev); 171 | +} 172 | + 173 | +/* Saves the union ipt_targinfo in parsable form to stdout. */ 174 | +static void IMQ_save(const void *ip, const struct xt_entry_target *target) 175 | +{ 176 | + struct ipt_imq_info *mr = (struct ipt_imq_info*)target->data; 177 | + 178 | + printf("--todev %u", mr->todev); 179 | +} 180 | + 181 | +static struct xtables_target imq = { 182 | + .name = "IMQ", 183 | + .version = XTABLES_VERSION, 184 | + .family = PF_INET, 185 | + .size = XT_ALIGN(sizeof(struct ipt_imq_info)), 186 | + .userspacesize = XT_ALIGN(sizeof(struct ipt_imq_info)), 187 | + .help = IMQ_help, 188 | + .init = IMQ_init, 189 | + .parse = IMQ_parse, 190 | + .print = IMQ_print, 191 | + .save = IMQ_save, 192 | + .extra_opts = IMQ_opts, 193 | +}; 194 | + 195 | +void _init(void) 196 | +{ 197 | + xtables_register_target(&imq); 198 | +} 199 | -------------------------------------------------------------------------------- /iptables/iptables-1.4.10-imq.diff: -------------------------------------------------------------------------------- 1 | diff --git a/extensions/libxt_IMQ.c b/extensions/libxt_IMQ.c 2 | new file mode 100644 3 | index 0000000..af632f2 4 | --- /dev/null 5 | +++ b/extensions/libxt_IMQ.c 6 | @@ -0,0 +1,103 @@ 7 | +/* Shared library add-on to iptables to add IMQ target support. */ 8 | +#include 9 | +#include 10 | +#include 11 | +#include 12 | + 13 | +#include 14 | +#include 15 | +#include 16 | + 17 | +/* Function which prints out usage message. */ 18 | +static void IMQ_help(void) 19 | +{ 20 | + printf( 21 | +"IMQ target options:\n" 22 | +" --todev enqueue to imq, defaults to 0\n"); 23 | + 24 | +} 25 | + 26 | +static struct option IMQ_opts[] = { 27 | + { "todev", 1, 0, '1' }, 28 | + { 0 } 29 | +}; 30 | + 31 | +/* Initialize the target. */ 32 | +static void IMQ_init(struct xt_entry_target *t) 33 | +{ 34 | + struct xt_imq_info *mr = (struct xt_imq_info*)t->data; 35 | + 36 | + mr->todev = 0; 37 | +} 38 | + 39 | +/* Function which parses command options; returns true if it 40 | + ate an option */ 41 | +static int IMQ_parse(int c, char **argv, int invert, unsigned int *flags, 42 | + const void *entry, struct xt_entry_target **target) 43 | +{ 44 | + struct xt_imq_info *mr = (struct xt_imq_info*)(*target)->data; 45 | + 46 | + switch(c) { 47 | + case '1': 48 | + if (xtables_check_inverse(optarg, &invert, NULL, 0, argv)) 49 | + xtables_error(PARAMETER_PROBLEM, 50 | + "Unexpected `!' after --todev"); 51 | + mr->todev=atoi(optarg); 52 | + break; 53 | + default: 54 | + return 0; 55 | + } 56 | + return 1; 57 | +} 58 | + 59 | +/* Prints out the targinfo. */ 60 | +static void IMQ_print(const void *ip, 61 | + const struct xt_entry_target *target, 62 | + int numeric) 63 | +{ 64 | + struct xt_imq_info *mr = (struct xt_imq_info*)target->data; 65 | + 66 | + printf("IMQ: todev %u ", mr->todev); 67 | +} 68 | + 69 | +/* Saves the union ipt_targinfo in parsable form to stdout. */ 70 | +static void IMQ_save(const void *ip, const struct xt_entry_target *target) 71 | +{ 72 | + struct xt_imq_info *mr = (struct xt_imq_info*)target->data; 73 | + 74 | + printf("--todev %u", mr->todev); 75 | +} 76 | + 77 | +static struct xtables_target imq_target = { 78 | + .name = "IMQ", 79 | + .version = XTABLES_VERSION, 80 | + .family = NFPROTO_IPV4, 81 | + .size = XT_ALIGN(sizeof(struct xt_imq_info)), 82 | + .userspacesize = XT_ALIGN(sizeof(struct xt_imq_info)), 83 | + .help = IMQ_help, 84 | + .init = IMQ_init, 85 | + .parse = IMQ_parse, 86 | + .print = IMQ_print, 87 | + .save = IMQ_save, 88 | + .extra_opts = IMQ_opts, 89 | +}; 90 | + 91 | +static struct xtables_target imq_target6 = { 92 | + .name = "IMQ", 93 | + .version = XTABLES_VERSION, 94 | + .family = NFPROTO_IPV6, 95 | + .size = XT_ALIGN(sizeof(struct xt_imq_info)), 96 | + .userspacesize = XT_ALIGN(sizeof(struct xt_imq_info)), 97 | + .help = IMQ_help, 98 | + .init = IMQ_init, 99 | + .parse = IMQ_parse, 100 | + .print = IMQ_print, 101 | + .save = IMQ_save, 102 | + .extra_opts = IMQ_opts, 103 | +}; 104 | + 105 | +// void __attribute((constructor)) nf_ext_init(void){ 106 | +void _init(void){ 107 | + xtables_register_target(&imq_target); 108 | + xtables_register_target(&imq_target6); 109 | +} 110 | diff --git a/extensions/libxt_IMQ.man b/extensions/libxt_IMQ.man 111 | new file mode 100644 112 | index 0000000..6e3e896 113 | --- /dev/null 114 | +++ b/extensions/libxt_IMQ.man 115 | @@ -0,0 +1,15 @@ 116 | +This target is used to redirect the traffic to the IMQ driver and you can apply 117 | +QoS rules like HTB or CBQ. 118 | +For example you can select only traffic comming from a specific interface or 119 | +is going out on a specific interface. 120 | +Also it permits to capture the traffic BEFORE NAT in the case of outgoing traffic 121 | +or AFTER NAT in the case of incomming traffic. 122 | +.TP 123 | +\fB\-\-to\-dev\fP \fIvalue\fP 124 | +Set the IMQ interface where to send this traffic 125 | +.PP 126 | +For example we want to redirect incomming traffic from interface eth0 to imq0 and outgoing traffic to imq1: 127 | +.IP 128 | +iptables \-t mangle \-A FORWARD \-i eth0 \-j IMQ \-\-to\-dev 0 129 | +.IP 130 | +iptables \-t mangle \-A FORWARD \-o eth0 \-j IMQ \-\-to\-dev 1 131 | diff --git a/include/linux/netfilter/xt_IMQ.h b/include/linux/netfilter/xt_IMQ.h 132 | new file mode 100644 133 | index 0000000..9b07230 134 | --- /dev/null 135 | +++ b/include/linux/netfilter/xt_IMQ.h 136 | @@ -0,0 +1,9 @@ 137 | +#ifndef _XT_IMQ_H 138 | +#define _XT_IMQ_H 139 | + 140 | +struct xt_imq_info { 141 | + unsigned int todev; /* target imq device */ 142 | +}; 143 | + 144 | +#endif /* _XT_IMQ_H */ 145 | + 146 | -------------------------------------------------------------------------------- /iptables/iptables-1.4.12-imq.diff: -------------------------------------------------------------------------------- 1 | diff -Naur iptables-1.4.12.1/extensions/libxt_IMQ.c iptables-1.4.12.1-imq/extensions/libxt_IMQ.c 2 | --- iptables-1.4.12.1/extensions/libxt_IMQ.c 1970-01-01 02:00:00.000000000 +0200 3 | +++ iptables-1.4.12.1-imq/extensions/libxt_IMQ.c 2011-09-30 13:53:21.000000000 +0300 4 | @@ -0,0 +1,105 @@ 5 | +/* Shared library add-on to iptables to add IMQ target support. */ 6 | +#include 7 | +#include 8 | +#include 9 | +#include 10 | + 11 | +#include 12 | +#include 13 | +#include 14 | + 15 | +/* Function which prints out usage message. */ 16 | +static void IMQ_help(void) 17 | +{ 18 | + printf( 19 | +"IMQ target options:\n" 20 | +" --todev enqueue to imq, defaults to 0\n"); 21 | + 22 | +} 23 | + 24 | +static struct option IMQ_opts[] = { 25 | + { "todev", 1, 0, '1' }, 26 | + { 0 } 27 | +}; 28 | + 29 | +/* Initialize the target. */ 30 | +static void IMQ_init(struct xt_entry_target *t) 31 | +{ 32 | + struct xt_imq_info *mr = (struct xt_imq_info*)t->data; 33 | + 34 | + mr->todev = 0; 35 | +} 36 | + 37 | +/* Function which parses command options; returns true if it 38 | + ate an option */ 39 | +static int IMQ_parse(int c, char **argv, int invert, unsigned int *flags, 40 | + const void *entry, struct xt_entry_target **target) 41 | +{ 42 | + struct xt_imq_info *mr = (struct xt_imq_info*)(*target)->data; 43 | + 44 | + switch(c) { 45 | + case '1': 46 | +/* if (xtables_check_inverse(optarg, &invert, NULL, 0, argv)) 47 | + xtables_error(PARAMETER_PROBLEM, 48 | + "Unexpected `!' after --todev"); 49 | +*/ 50 | + mr->todev=atoi(optarg); 51 | + break; 52 | + 53 | + default: 54 | + return 0; 55 | + } 56 | + return 1; 57 | +} 58 | + 59 | +/* Prints out the targinfo. */ 60 | +static void IMQ_print(const void *ip, 61 | + const struct xt_entry_target *target, 62 | + int numeric) 63 | +{ 64 | + struct xt_imq_info *mr = (struct xt_imq_info*)target->data; 65 | + 66 | + printf("IMQ: todev %u ", mr->todev); 67 | +} 68 | + 69 | +/* Saves the union ipt_targinfo in parsable form to stdout. */ 70 | +static void IMQ_save(const void *ip, const struct xt_entry_target *target) 71 | +{ 72 | + struct xt_imq_info *mr = (struct xt_imq_info*)target->data; 73 | + 74 | + printf(" --todev %u", mr->todev); 75 | +} 76 | + 77 | +static struct xtables_target imq_target = { 78 | + .name = "IMQ", 79 | + .version = XTABLES_VERSION, 80 | + .family = NFPROTO_IPV4, 81 | + .size = XT_ALIGN(sizeof(struct xt_imq_info)), 82 | + .userspacesize = XT_ALIGN(sizeof(struct xt_imq_info)), 83 | + .help = IMQ_help, 84 | + .init = IMQ_init, 85 | + .parse = IMQ_parse, 86 | + .print = IMQ_print, 87 | + .save = IMQ_save, 88 | + .extra_opts = IMQ_opts, 89 | +}; 90 | + 91 | +static struct xtables_target imq_target6 = { 92 | + .name = "IMQ", 93 | + .version = XTABLES_VERSION, 94 | + .family = NFPROTO_IPV6, 95 | + .size = XT_ALIGN(sizeof(struct xt_imq_info)), 96 | + .userspacesize = XT_ALIGN(sizeof(struct xt_imq_info)), 97 | + .help = IMQ_help, 98 | + .init = IMQ_init, 99 | + .parse = IMQ_parse, 100 | + .print = IMQ_print, 101 | + .save = IMQ_save, 102 | + .extra_opts = IMQ_opts, 103 | +}; 104 | + 105 | +// void __attribute((constructor)) nf_ext_init(void){ 106 | +void _init(void){ 107 | + xtables_register_target(&imq_target); 108 | + xtables_register_target(&imq_target6); 109 | +} 110 | diff -Naur iptables-1.4.12.1/extensions/libxt_IMQ.man iptables-1.4.12.1-imq/extensions/libxt_IMQ.man 111 | --- iptables-1.4.12.1/extensions/libxt_IMQ.man 1970-01-01 02:00:00.000000000 +0200 112 | +++ iptables-1.4.12.1-imq/extensions/libxt_IMQ.man 2011-09-30 13:53:21.000000000 +0300 113 | @@ -0,0 +1,15 @@ 114 | +This target is used to redirect the traffic to the IMQ driver and you can apply 115 | +QoS rules like HTB or CBQ. 116 | +For example you can select only traffic comming from a specific interface or 117 | +is going out on a specific interface. 118 | +Also it permits to capture the traffic BEFORE NAT in the case of outgoing traffic 119 | +or AFTER NAT in the case of incomming traffic. 120 | +.TP 121 | +\fB\-\-to\-dev\fP \fIvalue\fP 122 | +Set the IMQ interface where to send this traffic 123 | +.TP 124 | +Example: 125 | +.TP 126 | +Redirect incomming traffic from interface eth0 to imq0 and outgoing traffic to imq1: 127 | +iptables \-t mangle \-A FORWARD \-i eth0 \-j IMQ \-\-to\-dev 0 128 | +iptables \-t mangle \-A FORWARD \-o eth0 \-j IMQ \-\-to\-dev 1 129 | diff -Naur iptables-1.4.12.1/include/linux/netfilter/xt_IMQ.h iptables-1.4.12.1-imq/include/linux/netfilter/xt_IMQ.h 130 | --- iptables-1.4.12.1/include/linux/netfilter/xt_IMQ.h 1970-01-01 02:00:00.000000000 +0200 131 | +++ iptables-1.4.12.1-imq/include/linux/netfilter/xt_IMQ.h 2011-09-30 13:53:21.000000000 +0300 132 | @@ -0,0 +1,9 @@ 133 | +#ifndef _XT_IMQ_H 134 | +#define _XT_IMQ_H 135 | + 136 | +struct xt_imq_info { 137 | + unsigned int todev; /* target imq device */ 138 | +}; 139 | + 140 | +#endif /* _XT_IMQ_H */ 141 | + 142 | -------------------------------------------------------------------------------- /iptables/iptables-1.4.13-imq.diff: -------------------------------------------------------------------------------- 1 | diff -Naur iptables-1.4.12.2/extensions/libxt_IMQ.c iptables-1.4.12.2-imq/extensions/libxt_IMQ.c 2 | --- iptables-1.4.12.2/extensions/libxt_IMQ.c 1970-01-01 02:00:00.000000000 +0200 3 | +++ iptables-1.4.12.2-imq/extensions/libxt_IMQ.c 2011-09-30 13:53:21.000000000 +0300 4 | @@ -0,0 +1,105 @@ 5 | +/* Shared library add-on to iptables to add IMQ target support. */ 6 | +#include 7 | +#include 8 | +#include 9 | +#include 10 | + 11 | +#include 12 | +#include 13 | +#include 14 | + 15 | +/* Function which prints out usage message. */ 16 | +static void IMQ_help(void) 17 | +{ 18 | + printf( 19 | +"IMQ target options:\n" 20 | +" --todev enqueue to imq, defaults to 0\n"); 21 | + 22 | +} 23 | + 24 | +static struct option IMQ_opts[] = { 25 | + { "todev", 1, 0, '1' }, 26 | + { 0 } 27 | +}; 28 | + 29 | +/* Initialize the target. */ 30 | +static void IMQ_init(struct xt_entry_target *t) 31 | +{ 32 | + struct xt_imq_info *mr = (struct xt_imq_info*)t->data; 33 | + 34 | + mr->todev = 0; 35 | +} 36 | + 37 | +/* Function which parses command options; returns true if it 38 | + ate an option */ 39 | +static int IMQ_parse(int c, char **argv, int invert, unsigned int *flags, 40 | + const void *entry, struct xt_entry_target **target) 41 | +{ 42 | + struct xt_imq_info *mr = (struct xt_imq_info*)(*target)->data; 43 | + 44 | + switch(c) { 45 | + case '1': 46 | +/* if (xtables_check_inverse(optarg, &invert, NULL, 0, argv)) 47 | + xtables_error(PARAMETER_PROBLEM, 48 | + "Unexpected `!' after --todev"); 49 | +*/ 50 | + mr->todev=atoi(optarg); 51 | + break; 52 | + 53 | + default: 54 | + return 0; 55 | + } 56 | + return 1; 57 | +} 58 | + 59 | +/* Prints out the targinfo. */ 60 | +static void IMQ_print(const void *ip, 61 | + const struct xt_entry_target *target, 62 | + int numeric) 63 | +{ 64 | + struct xt_imq_info *mr = (struct xt_imq_info*)target->data; 65 | + 66 | + printf("IMQ: todev %u ", mr->todev); 67 | +} 68 | + 69 | +/* Saves the union ipt_targinfo in parsable form to stdout. */ 70 | +static void IMQ_save(const void *ip, const struct xt_entry_target *target) 71 | +{ 72 | + struct xt_imq_info *mr = (struct xt_imq_info*)target->data; 73 | + 74 | + printf(" --todev %u", mr->todev); 75 | +} 76 | + 77 | +static struct xtables_target imq_target = { 78 | + .name = "IMQ", 79 | + .version = XTABLES_VERSION, 80 | + .family = NFPROTO_IPV4, 81 | + .size = XT_ALIGN(sizeof(struct xt_imq_info)), 82 | + .userspacesize = XT_ALIGN(sizeof(struct xt_imq_info)), 83 | + .help = IMQ_help, 84 | + .init = IMQ_init, 85 | + .parse = IMQ_parse, 86 | + .print = IMQ_print, 87 | + .save = IMQ_save, 88 | + .extra_opts = IMQ_opts, 89 | +}; 90 | + 91 | +static struct xtables_target imq_target6 = { 92 | + .name = "IMQ", 93 | + .version = XTABLES_VERSION, 94 | + .family = NFPROTO_IPV6, 95 | + .size = XT_ALIGN(sizeof(struct xt_imq_info)), 96 | + .userspacesize = XT_ALIGN(sizeof(struct xt_imq_info)), 97 | + .help = IMQ_help, 98 | + .init = IMQ_init, 99 | + .parse = IMQ_parse, 100 | + .print = IMQ_print, 101 | + .save = IMQ_save, 102 | + .extra_opts = IMQ_opts, 103 | +}; 104 | + 105 | +// void __attribute((constructor)) nf_ext_init(void){ 106 | +void _init(void){ 107 | + xtables_register_target(&imq_target); 108 | + xtables_register_target(&imq_target6); 109 | +} 110 | diff -Naur iptables-1.4.12.2/extensions/libxt_IMQ.man iptables-1.4.12.2-imq/extensions/libxt_IMQ.man 111 | --- iptables-1.4.12.2/extensions/libxt_IMQ.man 1970-01-01 02:00:00.000000000 +0200 112 | +++ iptables-1.4.12.2-imq/extensions/libxt_IMQ.man 2011-09-30 13:53:21.000000000 +0300 113 | @@ -0,0 +1,15 @@ 114 | +This target is used to redirect the traffic to the IMQ driver and you can apply 115 | +QoS rules like HTB or CBQ. 116 | +For example you can select only traffic comming from a specific interface or 117 | +is going out on a specific interface. 118 | +Also it permits to capture the traffic BEFORE NAT in the case of outgoing traffic 119 | +or AFTER NAT in the case of incomming traffic. 120 | +.TP 121 | +\fB\-\-to\-dev\fP \fIvalue\fP 122 | +Set the IMQ interface where to send this traffic 123 | +.TP 124 | +Example: 125 | +.TP 126 | +Redirect incomming traffic from interface eth0 to imq0 and outgoing traffic to imq1: 127 | +iptables \-t mangle \-A FORWARD \-i eth0 \-j IMQ \-\-to\-dev 0 128 | +iptables \-t mangle \-A FORWARD \-o eth0 \-j IMQ \-\-to\-dev 1 129 | diff -Naur iptables-1.4.12.2/include/linux/netfilter/xt_IMQ.h iptables-1.4.12.2-imq/include/linux/netfilter/xt_IMQ.h 130 | --- iptables-1.4.12.2/include/linux/netfilter/xt_IMQ.h 1970-01-01 02:00:00.000000000 +0200 131 | +++ iptables-1.4.12.2-imq/include/linux/netfilter/xt_IMQ.h 2011-09-30 13:53:21.000000000 +0300 132 | @@ -0,0 +1,9 @@ 133 | +#ifndef _XT_IMQ_H 134 | +#define _XT_IMQ_H 135 | + 136 | +struct xt_imq_info { 137 | + unsigned int todev; /* target imq device */ 138 | +}; 139 | + 140 | +#endif /* _XT_IMQ_H */ 141 | + 142 | -------------------------------------------------------------------------------- /iptables/iptables-1.4.3.2-imq_xt.diff: -------------------------------------------------------------------------------- 1 | diff -Naurw iptables-1.4.1/extensions/.IMQ-testx iptables-1.4.1.imq/extensions/.IMQ-testx 2 | --- iptables-1.4.1/extensions/.IMQ-testx 1969-12-31 21:00:00.000000000 -0300 3 | +++ iptables-1.4.1.imq/extensions/.IMQ-testx 2008-06-24 22:20:06.000000000 -0300 4 | @@ -0,0 +1,3 @@ 5 | +#!/bin/sh 6 | +# True if IMQ target patch is applied. 7 | +[ -f $KERNEL_DIR/include/linux/netfilter/xt_IMQ.h ] && echo IMQ 8 | diff -Naurw iptables-1.4.1/extensions/libxt_IMQ.c iptables-1.4.1.imq/extensions/libxt_IMQ.c 9 | --- iptables-1.4.1/extensions/libxt_IMQ.c 1969-12-31 21:00:00.000000000 -0300 10 | +++ iptables-1.4.1.imq/extensions/libxt_IMQ.c 2008-06-24 22:31:02.000000000 -0300 11 | @@ -0,0 +1,103 @@ 12 | +/* Shared library add-on to iptables to add IMQ target support. */ 13 | +#include 14 | +#include 15 | +#include 16 | +#include 17 | + 18 | +#include 19 | +#include 20 | +#include 21 | + 22 | +/* Function which prints out usage message. */ 23 | +static void IMQ_help(void) 24 | +{ 25 | + printf( 26 | +"IMQ target options:\n" 27 | +" --todev enqueue to imq, defaults to 0\n"); 28 | + 29 | +} 30 | + 31 | +static struct option IMQ_opts[] = { 32 | + { "todev", 1, 0, '1' }, 33 | + { 0 } 34 | +}; 35 | + 36 | +/* Initialize the target. */ 37 | +static void IMQ_init(struct xt_entry_target *t) 38 | +{ 39 | + struct xt_imq_info *mr = (struct xt_imq_info*)t->data; 40 | + 41 | + mr->todev = 0; 42 | +} 43 | + 44 | +/* Function which parses command options; returns true if it 45 | + ate an option */ 46 | +static int IMQ_parse(int c, char **argv, int invert, unsigned int *flags, 47 | + const void *entry, struct xt_entry_target **target) 48 | +{ 49 | + struct xt_imq_info *mr = (struct xt_imq_info*)(*target)->data; 50 | + 51 | + switch(c) { 52 | + case '1': 53 | + if (xtables_check_inverse(optarg, &invert, NULL, 0)) 54 | + xtables_error(PARAMETER_PROBLEM, 55 | + "Unexpected `!' after --todev"); 56 | + mr->todev=atoi(optarg); 57 | + break; 58 | + default: 59 | + return 0; 60 | + } 61 | + return 1; 62 | +} 63 | + 64 | +/* Prints out the targinfo. */ 65 | +static void IMQ_print(const void *ip, 66 | + const struct xt_entry_target *target, 67 | + int numeric) 68 | +{ 69 | + struct xt_imq_info *mr = (struct xt_imq_info*)target->data; 70 | + 71 | + printf("IMQ: todev %u ", mr->todev); 72 | +} 73 | + 74 | +/* Saves the union ipt_targinfo in parsable form to stdout. */ 75 | +static void IMQ_save(const void *ip, const struct xt_entry_target *target) 76 | +{ 77 | + struct xt_imq_info *mr = (struct xt_imq_info*)target->data; 78 | + 79 | + printf("--todev %u", mr->todev); 80 | +} 81 | + 82 | +static struct xtables_target imq_target = { 83 | + .name = "IMQ", 84 | + .version = XTABLES_VERSION, 85 | + .family = NFPROTO_IPV4, 86 | + .size = XT_ALIGN(sizeof(struct xt_imq_info)), 87 | + .userspacesize = XT_ALIGN(sizeof(struct xt_imq_info)), 88 | + .help = IMQ_help, 89 | + .init = IMQ_init, 90 | + .parse = IMQ_parse, 91 | + .print = IMQ_print, 92 | + .save = IMQ_save, 93 | + .extra_opts = IMQ_opts, 94 | +}; 95 | + 96 | +static struct xtables_target imq_target6 = { 97 | + .name = "IMQ", 98 | + .version = XTABLES_VERSION, 99 | + .family = NFPROTO_IPV6, 100 | + .size = XT_ALIGN(sizeof(struct xt_imq_info)), 101 | + .userspacesize = XT_ALIGN(sizeof(struct xt_imq_info)), 102 | + .help = IMQ_help, 103 | + .init = IMQ_init, 104 | + .parse = IMQ_parse, 105 | + .print = IMQ_print, 106 | + .save = IMQ_save, 107 | + .extra_opts = IMQ_opts, 108 | +}; 109 | + 110 | +// void __attribute((constructor)) nf_ext_init(void){ 111 | +void _init(void){ 112 | + xtables_register_target(&imq_target); 113 | + xtables_register_target(&imq_target6); 114 | +} 115 | --- iptables-1.4.1.1/include/linux/netfilter/xt_IMQ.h 1970-01-01 02:00:00.000000000 +0200 116 | +++ iptables-1.4.1.1.new/include/linux/netfilter/xt_IMQ.h 2008-08-05 00:41:28.000000000 +0300 117 | @@ -0,0 +1,9 @@ 118 | +#ifndef _XT_IMQ_H 119 | +#define _XT_IMQ_H 120 | + 121 | +struct xt_imq_info { 122 | + unsigned int todev; /* target imq device */ 123 | +}; 124 | + 125 | +#endif /* _XT_IMQ_H */ 126 | + 127 | -------------------------------------------------------------------------------- /iptables/iptables-1.4.4-imq.diff: -------------------------------------------------------------------------------- 1 | diff -Naurw iptables-1.4.4/extensions/libxt_IMQ.c iptables-1.4.4.imq/extensions/libxt_IMQ.c 2 | --- iptables-1.4.4/extensions/libxt_IMQ.c 1969-12-31 21:00:00.000000000 -0300 3 | +++ iptables-1.4.4.imq/extensions/libxt_IMQ.c 2008-06-24 22:31:02.000000000 -0300 4 | @@ -0,0 +1,103 @@ 5 | +/* Shared library add-on to iptables to add IMQ target support. */ 6 | +#include 7 | +#include 8 | +#include 9 | +#include 10 | + 11 | +#include 12 | +#include 13 | +#include 14 | + 15 | +/* Function which prints out usage message. */ 16 | +static void IMQ_help(void) 17 | +{ 18 | + printf( 19 | +"IMQ target options:\n" 20 | +" --todev enqueue to imq, defaults to 0\n"); 21 | + 22 | +} 23 | + 24 | +static struct option IMQ_opts[] = { 25 | + { "todev", 1, 0, '1' }, 26 | + { 0 } 27 | +}; 28 | + 29 | +/* Initialize the target. */ 30 | +static void IMQ_init(struct xt_entry_target *t) 31 | +{ 32 | + struct xt_imq_info *mr = (struct xt_imq_info*)t->data; 33 | + 34 | + mr->todev = 0; 35 | +} 36 | + 37 | +/* Function which parses command options; returns true if it 38 | + ate an option */ 39 | +static int IMQ_parse(int c, char **argv, int invert, unsigned int *flags, 40 | + const void *entry, struct xt_entry_target **target) 41 | +{ 42 | + struct xt_imq_info *mr = (struct xt_imq_info*)(*target)->data; 43 | + 44 | + switch(c) { 45 | + case '1': 46 | + if (xtables_check_inverse(optarg, &invert, NULL, 0)) 47 | + xtables_error(PARAMETER_PROBLEM, 48 | + "Unexpected `!' after --todev"); 49 | + mr->todev=atoi(optarg); 50 | + break; 51 | + default: 52 | + return 0; 53 | + } 54 | + return 1; 55 | +} 56 | + 57 | +/* Prints out the targinfo. */ 58 | +static void IMQ_print(const void *ip, 59 | + const struct xt_entry_target *target, 60 | + int numeric) 61 | +{ 62 | + struct xt_imq_info *mr = (struct xt_imq_info*)target->data; 63 | + 64 | + printf("IMQ: todev %u ", mr->todev); 65 | +} 66 | + 67 | +/* Saves the union ipt_targinfo in parsable form to stdout. */ 68 | +static void IMQ_save(const void *ip, const struct xt_entry_target *target) 69 | +{ 70 | + struct xt_imq_info *mr = (struct xt_imq_info*)target->data; 71 | + 72 | + printf("--todev %u", mr->todev); 73 | +} 74 | + 75 | +static struct xtables_target imq_target = { 76 | + .name = "IMQ", 77 | + .version = XTABLES_VERSION, 78 | + .family = NFPROTO_IPV4, 79 | + .size = XT_ALIGN(sizeof(struct xt_imq_info)), 80 | + .userspacesize = XT_ALIGN(sizeof(struct xt_imq_info)), 81 | + .help = IMQ_help, 82 | + .init = IMQ_init, 83 | + .parse = IMQ_parse, 84 | + .print = IMQ_print, 85 | + .save = IMQ_save, 86 | + .extra_opts = IMQ_opts, 87 | +}; 88 | + 89 | +static struct xtables_target imq_target6 = { 90 | + .name = "IMQ", 91 | + .version = XTABLES_VERSION, 92 | + .family = NFPROTO_IPV6, 93 | + .size = XT_ALIGN(sizeof(struct xt_imq_info)), 94 | + .userspacesize = XT_ALIGN(sizeof(struct xt_imq_info)), 95 | + .help = IMQ_help, 96 | + .init = IMQ_init, 97 | + .parse = IMQ_parse, 98 | + .print = IMQ_print, 99 | + .save = IMQ_save, 100 | + .extra_opts = IMQ_opts, 101 | +}; 102 | + 103 | +// void __attribute((constructor)) nf_ext_init(void){ 104 | +void _init(void){ 105 | + xtables_register_target(&imq_target); 106 | + xtables_register_target(&imq_target6); 107 | +} 108 | diff -Naurw iptables-1.4.4/extensions/libxt_IMQ.c iptables-1.4.4.imq/extensions/libxt_IMQ.c 109 | --- iptables-1.4.4/include/linux/netfilter/xt_IMQ.h 1970-01-01 02:00:00.000000000 +0200 110 | +++ iptables-1.4.4.new/include/linux/netfilter/xt_IMQ.h 2008-08-05 00:41:28.000000000 +0300 111 | @@ -0,0 +1,9 @@ 112 | +#ifndef _XT_IMQ_H 113 | +#define _XT_IMQ_H 114 | + 115 | +struct xt_imq_info { 116 | + unsigned int todev; /* target imq device */ 117 | +}; 118 | + 119 | +#endif /* _XT_IMQ_H */ 120 | + 121 | -------------------------------------------------------------------------------- /iptables/iptables-1.4.6-imq.diff: -------------------------------------------------------------------------------- 1 | diff -Naurw /dev/null extensions/libxt_IMQ.c 2 | --- /dev/null 1969-12-31 21:00:00.000000000 -0300 3 | +++ extensions/libxt_IMQ.c 2008-06-24 22:31:02.000000000 -0300 4 | @@ -0,0 +1,103 @@ 5 | +/* Shared library add-on to iptables to add IMQ target support. */ 6 | +#include 7 | +#include 8 | +#include 9 | +#include 10 | + 11 | +#include 12 | +#include 13 | +#include 14 | + 15 | +/* Function which prints out usage message. */ 16 | +static void IMQ_help(void) 17 | +{ 18 | + printf( 19 | +"IMQ target options:\n" 20 | +" --todev enqueue to imq, defaults to 0\n"); 21 | + 22 | +} 23 | + 24 | +static struct option IMQ_opts[] = { 25 | + { "todev", 1, 0, '1' }, 26 | + { 0 } 27 | +}; 28 | + 29 | +/* Initialize the target. */ 30 | +static void IMQ_init(struct xt_entry_target *t) 31 | +{ 32 | + struct xt_imq_info *mr = (struct xt_imq_info*)t->data; 33 | + 34 | + mr->todev = 0; 35 | +} 36 | + 37 | +/* Function which parses command options; returns true if it 38 | + ate an option */ 39 | +static int IMQ_parse(int c, char **argv, int invert, unsigned int *flags, 40 | + const void *entry, struct xt_entry_target **target) 41 | +{ 42 | + struct xt_imq_info *mr = (struct xt_imq_info*)(*target)->data; 43 | + 44 | + switch(c) { 45 | + case '1': 46 | + if (xtables_check_inverse(optarg, &invert, NULL, 0, argv)) 47 | + xtables_error(PARAMETER_PROBLEM, 48 | + "Unexpected `!' after --todev"); 49 | + mr->todev=atoi(optarg); 50 | + break; 51 | + default: 52 | + return 0; 53 | + } 54 | + return 1; 55 | +} 56 | + 57 | +/* Prints out the targinfo. */ 58 | +static void IMQ_print(const void *ip, 59 | + const struct xt_entry_target *target, 60 | + int numeric) 61 | +{ 62 | + struct xt_imq_info *mr = (struct xt_imq_info*)target->data; 63 | + 64 | + printf("IMQ: todev %u ", mr->todev); 65 | +} 66 | + 67 | +/* Saves the union ipt_targinfo in parsable form to stdout. */ 68 | +static void IMQ_save(const void *ip, const struct xt_entry_target *target) 69 | +{ 70 | + struct xt_imq_info *mr = (struct xt_imq_info*)target->data; 71 | + 72 | + printf("--todev %u", mr->todev); 73 | +} 74 | + 75 | +static struct xtables_target imq_target = { 76 | + .name = "IMQ", 77 | + .version = XTABLES_VERSION, 78 | + .family = NFPROTO_IPV4, 79 | + .size = XT_ALIGN(sizeof(struct xt_imq_info)), 80 | + .userspacesize = XT_ALIGN(sizeof(struct xt_imq_info)), 81 | + .help = IMQ_help, 82 | + .init = IMQ_init, 83 | + .parse = IMQ_parse, 84 | + .print = IMQ_print, 85 | + .save = IMQ_save, 86 | + .extra_opts = IMQ_opts, 87 | +}; 88 | + 89 | +static struct xtables_target imq_target6 = { 90 | + .name = "IMQ", 91 | + .version = XTABLES_VERSION, 92 | + .family = NFPROTO_IPV6, 93 | + .size = XT_ALIGN(sizeof(struct xt_imq_info)), 94 | + .userspacesize = XT_ALIGN(sizeof(struct xt_imq_info)), 95 | + .help = IMQ_help, 96 | + .init = IMQ_init, 97 | + .parse = IMQ_parse, 98 | + .print = IMQ_print, 99 | + .save = IMQ_save, 100 | + .extra_opts = IMQ_opts, 101 | +}; 102 | + 103 | +// void __attribute((constructor)) nf_ext_init(void){ 104 | +void _init(void){ 105 | + xtables_register_target(&imq_target); 106 | + xtables_register_target(&imq_target6); 107 | +} 108 | diff -Naurw /dev/null extensions/libxt_IMQ.c 109 | --- /dev/null 1970-01-01 02:00:00.000000000 +0200 110 | +++ include/linux/netfilter/xt_IMQ.h 2008-08-05 00:41:28.000000000 +0300 111 | @@ -0,0 +1,9 @@ 112 | +#ifndef _XT_IMQ_H 113 | +#define _XT_IMQ_H 114 | + 115 | +struct xt_imq_info { 116 | + unsigned int todev; /* target imq device */ 117 | +}; 118 | + 119 | +#endif /* _XT_IMQ_H */ 120 | + 121 | -------------------------------------------------------------------------------- /iptables/iptables-1.6.0-imq.diff: -------------------------------------------------------------------------------- 1 | diff -Naupr iptables-1.6.0_orig/extensions/libxt_IMQ.c iptables-1.6.0/extensions/libxt_IMQ.c 2 | --- iptables-1.6.0_orig/extensions/libxt_IMQ.c 1970-01-01 07:00:00.000000000 +0700 3 | +++ iptables-1.6.0/extensions/libxt_IMQ.c 2016-05-17 22:16:54.609657870 +0600 4 | @@ -0,0 +1,105 @@ 5 | +/* Shared library add-on to iptables to add IMQ target support. */ 6 | +#include 7 | +#include 8 | +#include 9 | +#include 10 | + 11 | +#include 12 | +#include 13 | +#include 14 | + 15 | +/* Function which prints out usage message. */ 16 | +static void IMQ_help(void) 17 | +{ 18 | + printf( 19 | +"IMQ target options:\n" 20 | +" --todev enqueue to imq, defaults to 0\n"); 21 | + 22 | +} 23 | + 24 | +static struct option IMQ_opts[] = { 25 | + { "todev", 1, 0, '1' }, 26 | + { 0 } 27 | +}; 28 | + 29 | +/* Initialize the target. */ 30 | +static void IMQ_init(struct xt_entry_target *t) 31 | +{ 32 | + struct xt_imq_info *mr = (struct xt_imq_info*)t->data; 33 | + 34 | + mr->todev = 0; 35 | +} 36 | + 37 | +/* Function which parses command options; returns true if it 38 | + ate an option */ 39 | +static int IMQ_parse(int c, char **argv, int invert, unsigned int *flags, 40 | + const void *entry, struct xt_entry_target **target) 41 | +{ 42 | + struct xt_imq_info *mr = (struct xt_imq_info*)(*target)->data; 43 | + 44 | + switch(c) { 45 | + case '1': 46 | +/* if (xtables_check_inverse(optarg, &invert, NULL, 0, argv)) 47 | + xtables_error(PARAMETER_PROBLEM, 48 | + "Unexpected `!' after --todev"); 49 | +*/ 50 | + mr->todev=atoi(optarg); 51 | + break; 52 | + 53 | + default: 54 | + return 0; 55 | + } 56 | + return 1; 57 | +} 58 | + 59 | +/* Prints out the targinfo. */ 60 | +static void IMQ_print(const void *ip, 61 | + const struct xt_entry_target *target, 62 | + int numeric) 63 | +{ 64 | + struct xt_imq_info *mr = (struct xt_imq_info*)target->data; 65 | + 66 | + printf("IMQ: todev %u ", mr->todev); 67 | +} 68 | + 69 | +/* Saves the union ipt_targinfo in parsable form to stdout. */ 70 | +static void IMQ_save(const void *ip, const struct xt_entry_target *target) 71 | +{ 72 | + struct xt_imq_info *mr = (struct xt_imq_info*)target->data; 73 | + 74 | + printf(" --todev %u", mr->todev); 75 | +} 76 | + 77 | +static struct xtables_target imq_target = { 78 | + .name = "IMQ", 79 | + .version = XTABLES_VERSION, 80 | + .family = NFPROTO_IPV4, 81 | + .size = XT_ALIGN(sizeof(struct xt_imq_info)), 82 | + .userspacesize = XT_ALIGN(sizeof(struct xt_imq_info)), 83 | + .help = IMQ_help, 84 | + .init = IMQ_init, 85 | + .parse = IMQ_parse, 86 | + .print = IMQ_print, 87 | + .save = IMQ_save, 88 | + .extra_opts = IMQ_opts, 89 | +}; 90 | + 91 | +static struct xtables_target imq_target6 = { 92 | + .name = "IMQ", 93 | + .version = XTABLES_VERSION, 94 | + .family = NFPROTO_IPV6, 95 | + .size = XT_ALIGN(sizeof(struct xt_imq_info)), 96 | + .userspacesize = XT_ALIGN(sizeof(struct xt_imq_info)), 97 | + .help = IMQ_help, 98 | + .init = IMQ_init, 99 | + .parse = IMQ_parse, 100 | + .print = IMQ_print, 101 | + .save = IMQ_save, 102 | + .extra_opts = IMQ_opts, 103 | +}; 104 | + 105 | +// void __attribute((constructor)) nf_ext_init(void){ 106 | +void _init(void){ 107 | + xtables_register_target(&imq_target); 108 | + xtables_register_target(&imq_target6); 109 | +} 110 | diff -Naupr iptables-1.6.0_orig/extensions/libxt_IMQ.man iptables-1.6.0/extensions/libxt_IMQ.man 111 | --- iptables-1.6.0_orig/extensions/libxt_IMQ.man 1970-01-01 07:00:00.000000000 +0700 112 | +++ iptables-1.6.0/extensions/libxt_IMQ.man 2016-05-17 22:16:54.609657870 +0600 113 | @@ -0,0 +1,15 @@ 114 | +This target is used to redirect the traffic to the IMQ driver and you can apply 115 | +QoS rules like HTB or CBQ. 116 | +For example you can select only traffic comming from a specific interface or 117 | +is going out on a specific interface. 118 | +Also it permits to capture the traffic BEFORE NAT in the case of outgoing traffic 119 | +or AFTER NAT in the case of incomming traffic. 120 | +.TP 121 | +\fB\-\-to\-dev\fP \fIvalue\fP 122 | +Set the IMQ interface where to send this traffic 123 | +.TP 124 | +Example: 125 | +.TP 126 | +Redirect incomming traffic from interface eth0 to imq0 and outgoing traffic to imq1: 127 | +iptables \-t mangle \-A FORWARD \-i eth0 \-j IMQ \-\-to\-dev 0 128 | +iptables \-t mangle \-A FORWARD \-o eth0 \-j IMQ \-\-to\-dev 1 129 | diff -Naupr iptables-1.6.0_orig/include/linux/netfilter/xt_IMQ.h iptables-1.6.0/include/linux/netfilter/xt_IMQ.h 130 | --- iptables-1.6.0_orig/include/linux/netfilter/xt_IMQ.h 1970-01-01 07:00:00.000000000 +0700 131 | +++ iptables-1.6.0/include/linux/netfilter/xt_IMQ.h 2016-05-17 22:16:54.609657870 +0600 132 | @@ -0,0 +1,9 @@ 133 | +#ifndef _XT_IMQ_H 134 | +#define _XT_IMQ_H 135 | + 136 | +struct xt_imq_info { 137 | + unsigned int todev; /* target imq device */ 138 | +}; 139 | + 140 | +#endif /* _XT_IMQ_H */ 141 | + 142 | -------------------------------------------------------------------------------- /kernel/v2.4/linux-2.4.18-imq.diff: -------------------------------------------------------------------------------- 1 | diff -urN linux-2.4.18-clean/Documentation/Configure.help linux-2.4.18-imq/Documentation/Configure.help 2 | --- linux-2.4.18-clean/Documentation/Configure.help Mon Feb 25 20:37:51 2002 3 | +++ linux-2.4.18-imq/Documentation/Configure.help Thu May 23 14:15:12 2002 4 | @@ -8356,6 +8356,20 @@ 5 | say M here and read . The module 6 | will be called bonding.o. 7 | 8 | +Intermediate queueing device support 9 | +CONFIG_IMQ 10 | + The imq device(s) is used as placeholder for QoS queueing disciplines. 11 | + Every packet entering/leaving the ip stack can be directed through 12 | + the imq device where it's enqueued/dequeued to the attached qdisc. 13 | + This allows you to treat network devices as classes and distribute 14 | + bandwidth among them. Iptables is used to specify through which imq 15 | + device, if any, packets travel. 16 | + 17 | + If you want to compile this as a module ( = code which ca be 18 | + inserted in and removed from the running kernel whenever you want), 19 | + say M here and read . The module 20 | + will be called imq.o 21 | + 22 | SLIP (serial line) support 23 | CONFIG_SLIP 24 | Say Y if you intend to use SLIP or CSLIP (compressed SLIP) to 25 | diff -urN linux-2.4.18-clean/drivers/net/Config.in linux-2.4.18-imq/drivers/net/Config.in 26 | --- linux-2.4.18-clean/drivers/net/Config.in Mon Feb 25 20:37:59 2002 27 | +++ linux-2.4.18-imq/drivers/net/Config.in Thu May 23 14:15:12 2002 28 | @@ -8,6 +8,11 @@ 29 | tristate 'Dummy net driver support' CONFIG_DUMMY 30 | tristate 'Bonding driver support' CONFIG_BONDING 31 | tristate 'EQL (serial line load balancing) support' CONFIG_EQUALIZER 32 | +if [ "$CONFIG_NETFILTER" = "y" ]; then 33 | + tristate 'IMQ (intermediate queueing device) support' CONFIG_IMQ 34 | +else 35 | + comment 'IMQ needs CONFIG_NETFILTER enabled' 36 | +fi 37 | tristate 'Universal TUN/TAP device driver support' CONFIG_TUN 38 | if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then 39 | tristate 'Ethertap network tap (OBSOLETE)' CONFIG_ETHERTAP 40 | diff -urN linux-2.4.18-clean/drivers/net/Makefile linux-2.4.18-imq/drivers/net/Makefile 41 | --- linux-2.4.18-clean/drivers/net/Makefile Mon Feb 25 20:37:59 2002 42 | +++ linux-2.4.18-imq/drivers/net/Makefile Thu May 23 14:15:12 2002 43 | @@ -145,6 +145,7 @@ 44 | obj-$(CONFIG_STRIP) += strip.o 45 | obj-$(CONFIG_DUMMY) += dummy.o 46 | obj-$(CONFIG_BONDING) += bonding.o 47 | +obj-$(CONFIG_IMQ) += imq.o 48 | obj-$(CONFIG_DE600) += de600.o 49 | obj-$(CONFIG_DE620) += de620.o 50 | obj-$(CONFIG_AT1500) += lance.o 51 | diff -urN linux-2.4.18-clean/drivers/net/imq.c linux-2.4.18-imq/drivers/net/imq.c 52 | --- linux-2.4.18-clean/drivers/net/imq.c Thu Jan 1 01:00:00 1970 53 | +++ linux-2.4.18-imq/drivers/net/imq.c Thu May 23 14:07:49 2002 54 | @@ -0,0 +1,324 @@ 55 | +/* 56 | + * Pseudo-driver for the intermediate queue device. 57 | + * 58 | + * Authors: Patrick McHardy, 59 | + * 60 | + * The first version was written by Martin Devera, 61 | + * 62 | + * This program is free software; you can redistribute it and/or 63 | + * modify it under the terms of the GNU General Public License 64 | + * as published by the Free Software Foundation; either version 65 | + * 2 of the License, or (at your option) any later version. 66 | + */ 67 | + 68 | +#include 69 | +#include 70 | +#include 71 | +#include 72 | +#include 73 | +#include 74 | +#include 75 | +#include 76 | +#include 77 | +#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) 78 | +#include 79 | +#endif 80 | +#include 81 | +#include 82 | + 83 | +#define IMQ_HH_LEN(info) (((info)->hook == NF_IP_PRE_ROUTING) ? \ 84 | + (info)->indev->hard_header_len : \ 85 | + (info)->outdev->hard_header_len) 86 | + 87 | +static nf_hookfn imq_nf_hook; 88 | + 89 | +static struct nf_hook_ops imq_ingress_ipv4 = { 90 | + { NULL, NULL}, 91 | + imq_nf_hook, 92 | + PF_INET, 93 | + NF_IP_PRE_ROUTING, 94 | + NF_IP_PRI_MANGLE + 1 95 | +}; 96 | + 97 | +static struct nf_hook_ops imq_egress_ipv4 = { 98 | + { NULL, NULL}, 99 | + imq_nf_hook, 100 | + PF_INET, 101 | + NF_IP_POST_ROUTING, 102 | + NF_IP_PRI_LAST 103 | +}; 104 | + 105 | +#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) 106 | +static struct nf_hook_ops imq_ingress_ipv6 = { 107 | + { NULL, NULL}, 108 | + imq_nf_hook, 109 | + PF_INET6, 110 | + NF_IP6_PRE_ROUTING, 111 | + NF_IP6_PRI_MANGLE + 1 112 | +}; 113 | + 114 | +static struct nf_hook_ops imq_egress_ipv6 = { 115 | + { NULL, NULL}, 116 | + imq_nf_hook, 117 | + PF_INET6, 118 | + NF_IP6_POST_ROUTING, 119 | + NF_IP6_PRI_LAST 120 | +}; 121 | +#endif 122 | + 123 | +static unsigned int numdevs = 2; 124 | + 125 | +MODULE_PARM(numdevs, "i"); 126 | +MODULE_PARM_DESC(numdevs, "number of imq devices"); 127 | + 128 | +static struct net_device *imq_devs; 129 | + 130 | + 131 | +static struct net_device_stats *imq_get_stats(struct net_device *dev) 132 | +{ 133 | + return (struct net_device_stats *)dev->priv; 134 | +} 135 | + 136 | +/* called for packets kfree'd in qdiscs at places other than enqueue */ 137 | +static void imq_skb_destructor(struct sk_buff *skb) 138 | +{ 139 | + struct nf_info *info = skb->nf_info; 140 | + 141 | + if (info) { 142 | + if (info->indev) 143 | + dev_put(info->indev); 144 | + if (info->outdev) 145 | + dev_put(info->outdev); 146 | + kfree(info); 147 | + } 148 | +} 149 | + 150 | +static int imq_dev_xmit(struct sk_buff *skb, struct net_device *dev) 151 | +{ 152 | + struct net_device_stats *stats = (struct net_device_stats*) dev->priv; 153 | + 154 | + stats->tx_bytes += skb->len; 155 | + stats->tx_packets++; 156 | + 157 | + skb_pull(skb, IMQ_HH_LEN(skb->nf_info)); 158 | + 159 | + skb->imq_flags = 0; 160 | + skb->destructor = NULL; 161 | + 162 | + dev->trans_start = jiffies; 163 | + nf_reinject(skb, skb->nf_info, NF_ACCEPT); 164 | + 165 | + return 0; 166 | +} 167 | + 168 | +static int imq_nf_queue(struct sk_buff *skb, struct nf_info *info, 169 | + void *data) 170 | +{ 171 | + struct net_device *dev; 172 | + struct net_device_stats *stats; 173 | + struct sk_buff *skb2 = NULL; 174 | + struct Qdisc *q; 175 | + unsigned int index = skb->imq_flags&IMQ_F_IFMASK; 176 | + int ret = -1; 177 | + 178 | + if (index > numdevs) 179 | + return -1; 180 | + 181 | + dev = imq_devs + index; 182 | + if (!(dev->flags & IFF_UP)) { 183 | + skb->imq_flags = 0; 184 | + nf_reinject(skb, info, NF_ACCEPT); 185 | + return 0; 186 | + } 187 | + dev->last_rx = jiffies; 188 | + 189 | + if (skb->destructor) { 190 | + skb2 = skb; 191 | + skb = skb_clone(skb, GFP_ATOMIC); 192 | + if (!skb) 193 | + return -1; 194 | + } 195 | + skb_push(skb, IMQ_HH_LEN(info)); 196 | + skb->nf_info = info; 197 | + 198 | + stats = (struct net_device_stats *)dev->priv; 199 | + stats->rx_bytes+= skb->len; 200 | + stats->rx_packets++; 201 | + 202 | + spin_lock_bh(&dev->queue_lock); 203 | + 204 | + q = dev->qdisc; 205 | + if (q->enqueue) { 206 | + q->enqueue(skb_get(skb), q); 207 | + 208 | + if (skb_shared(skb)) { 209 | + skb->destructor = imq_skb_destructor; 210 | + kfree_skb(skb); 211 | + ret = 0; 212 | + } 213 | + } 214 | + 215 | + qdisc_run(dev); 216 | + spin_unlock_bh(&dev->queue_lock); 217 | + 218 | + if (skb2) 219 | + kfree_skb(ret ? skb : skb2); 220 | + 221 | + return ret; 222 | +} 223 | + 224 | +static unsigned int imq_nf_hook(unsigned int hook, struct sk_buff **pskb, 225 | + const struct net_device *indev, 226 | + const struct net_device *outdev, 227 | + int (*okfn)(struct sk_buff *)) 228 | +{ 229 | + if ((*pskb)->imq_flags & IMQ_F_ENQUEUE) 230 | + return NF_QUEUE; 231 | + 232 | + return NF_ACCEPT; 233 | +} 234 | + 235 | + 236 | +static int __init imq_init_hooks(void) 237 | +{ 238 | + int err; 239 | + 240 | + if ((err = nf_register_queue_handler(PF_INET, imq_nf_queue, NULL))) 241 | + goto err1; 242 | + if ((err = nf_register_hook(&imq_ingress_ipv4))) 243 | + goto err2; 244 | + if ((err = nf_register_hook(&imq_egress_ipv4))) 245 | + goto err3; 246 | +#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) 247 | + if ((err = nf_register_queue_handler(PF_INET6, imq_nf_queue, NULL))) 248 | + goto err4; 249 | + if ((err = nf_register_hook(&imq_ingress_ipv6))) 250 | + goto err5; 251 | + if ((err = nf_register_hook(&imq_egress_ipv6))) 252 | + goto err6; 253 | +#endif 254 | + 255 | + return 0; 256 | + 257 | +#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) 258 | +err6: 259 | + nf_unregister_hook(&imq_ingress_ipv6); 260 | +err5: 261 | + nf_unregister_queue_handler(PF_INET6); 262 | +err4: 263 | + nf_unregister_hook(&imq_egress_ipv4); 264 | +#endif 265 | +err3: 266 | + nf_unregister_hook(&imq_ingress_ipv4); 267 | +err2: 268 | + nf_unregister_queue_handler(PF_INET); 269 | +err1: 270 | + return err; 271 | +} 272 | + 273 | +static void __exit imq_unhook(void) 274 | +{ 275 | + nf_unregister_hook(&imq_ingress_ipv4); 276 | + nf_unregister_hook(&imq_egress_ipv4); 277 | + nf_unregister_queue_handler(PF_INET); 278 | +#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) 279 | + nf_unregister_hook(&imq_ingress_ipv6); 280 | + nf_unregister_hook(&imq_egress_ipv6); 281 | + nf_unregister_queue_handler(PF_INET6); 282 | +#endif 283 | +} 284 | + 285 | +static int __init imq_dev_init(struct net_device *dev) 286 | +{ 287 | + dev->hard_start_xmit = imq_dev_xmit; 288 | + dev->type = ARPHRD_VOID; 289 | + dev->mtu = 1500; 290 | + dev->tx_queue_len = 30; 291 | + dev->flags = IFF_NOARP; 292 | + dev->priv = kmalloc(sizeof(struct net_device_stats), GFP_KERNEL); 293 | + if (dev->priv == NULL) 294 | + return -ENOMEM; 295 | + memset(dev->priv, 0, sizeof(struct net_device_stats)); 296 | + dev->get_stats = imq_get_stats; 297 | + 298 | + return 0; 299 | +} 300 | + 301 | +static void imq_dev_uninit(struct net_device *dev) 302 | +{ 303 | + kfree(dev->priv); 304 | +} 305 | + 306 | +static int __init imq_init_devs(void) 307 | +{ 308 | + struct net_device *dev; 309 | + int i; 310 | + 311 | + if (!numdevs || numdevs > IMQ_MAX_DEVS) { 312 | + printk(KERN_ERR "numdevs has to be betweed 1 and %u\n", 313 | + IMQ_MAX_DEVS); 314 | + return -EINVAL; 315 | + } 316 | + 317 | + imq_devs = kmalloc(sizeof(struct net_device) * numdevs, GFP_KERNEL); 318 | + if (!imq_devs) 319 | + return -ENOMEM; 320 | + memset(imq_devs, 0, sizeof(struct net_device) * numdevs); 321 | + 322 | + /* we start counting at zero */ 323 | + numdevs--; 324 | + 325 | + for (i = 0, dev = imq_devs; i <= numdevs; i++, dev++) { 326 | + SET_MODULE_OWNER(dev); 327 | + strcpy(dev->name, "imq%d"); 328 | + dev->init = imq_dev_init; 329 | + dev->uninit = imq_dev_uninit; 330 | + 331 | + if (register_netdev(dev) < 0) 332 | + goto err_register; 333 | + } 334 | + return 0; 335 | + 336 | +err_register: 337 | + for (; i; i--) 338 | + unregister_netdev(--dev); 339 | + kfree(imq_devs); 340 | + return -EIO; 341 | +} 342 | + 343 | +static void imq_cleanup_devs(void) 344 | +{ 345 | + int i; 346 | + struct net_device *dev = imq_devs; 347 | + 348 | + for (i = 0; i <= numdevs; i++) 349 | + unregister_netdev(dev++); 350 | + 351 | + kfree(imq_devs); 352 | +} 353 | + 354 | +static int __init imq_init_module(void) 355 | +{ 356 | + int err; 357 | + 358 | + if ((err = imq_init_devs())) 359 | + return err; 360 | + if ((err = imq_init_hooks())) { 361 | + imq_cleanup_devs(); 362 | + return err; 363 | + } 364 | + 365 | + printk(KERN_INFO "imq driver loaded.\n"); 366 | + 367 | + return 0; 368 | +} 369 | + 370 | +static void __exit imq_cleanup_module(void) 371 | +{ 372 | + imq_unhook(); 373 | + imq_cleanup_devs(); 374 | +} 375 | + 376 | +module_init(imq_init_module); 377 | +module_exit(imq_cleanup_module); 378 | +MODULE_LICENSE("GPL"); 379 | diff -urN linux-2.4.18-clean/include/linux/imq.h linux-2.4.18-imq/include/linux/imq.h 380 | --- linux-2.4.18-clean/include/linux/imq.h Thu Jan 1 01:00:00 1970 381 | +++ linux-2.4.18-imq/include/linux/imq.h Thu May 23 14:15:12 2002 382 | @@ -0,0 +1,9 @@ 383 | +#ifndef _IMQ_H 384 | +#define _IMQ_H 385 | + 386 | +#define IMQ_MAX_DEVS 16 387 | + 388 | +#define IMQ_F_IFMASK 0x7f 389 | +#define IMQ_F_ENQUEUE 0x80 390 | + 391 | +#endif /* _IMQ_H */ 392 | diff -urN linux-2.4.18-clean/include/linux/skbuff.h linux-2.4.18-imq/include/linux/skbuff.h 393 | --- linux-2.4.18-clean/include/linux/skbuff.h Thu Nov 22 20:46:26 2001 394 | +++ linux-2.4.18-imq/include/linux/skbuff.h Thu May 23 14:15:12 2002 395 | @@ -93,6 +93,9 @@ 396 | struct nf_conntrack *master; 397 | }; 398 | #endif 399 | +#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 400 | +struct nf_info; 401 | +#endif 402 | 403 | struct sk_buff_head { 404 | /* These two members must be first. */ 405 | @@ -178,7 +181,7 @@ 406 | unsigned int len; /* Length of actual data */ 407 | unsigned int data_len; 408 | unsigned int csum; /* Checksum */ 409 | - unsigned char __unused, /* Dead field, may be reused */ 410 | + unsigned char imq_flags, /* intermediate queueing device */ 411 | cloned, /* head may be cloned (check refcnt to be sure). */ 412 | pkt_type, /* Packet class */ 413 | ip_summed; /* Driver fed us an IP checksum */ 414 | @@ -214,6 +217,9 @@ 415 | 416 | #ifdef CONFIG_NET_SCHED 417 | __u32 tc_index; /* traffic control index */ 418 | +#endif 419 | +#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 420 | + struct nf_info *nf_info; 421 | #endif 422 | }; 423 | 424 | diff -urN linux-2.4.18-clean/net/core/skbuff.c linux-2.4.18-imq/net/core/skbuff.c 425 | --- linux-2.4.18-clean/net/core/skbuff.c Fri Dec 21 18:42:05 2001 426 | +++ linux-2.4.18-imq/net/core/skbuff.c Thu May 23 14:15:12 2002 427 | @@ -202,6 +202,10 @@ 428 | /* Set up other state */ 429 | skb->len = 0; 430 | skb->cloned = 0; 431 | +#if defined(CONFIG_IMQ) || defined (CONFIG_IMQ_MODULE) 432 | + skb->imq_flags = 0; 433 | + skb->nf_info = NULL; 434 | +#endif 435 | skb->data_len = 0; 436 | 437 | atomic_set(&skb->users, 1); 438 | @@ -249,6 +253,10 @@ 439 | #ifdef CONFIG_NET_SCHED 440 | skb->tc_index = 0; 441 | #endif 442 | +#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 443 | + skb->imq_flags = 0; 444 | + skb->nf_info = NULL; 445 | +#endif 446 | } 447 | 448 | static void skb_drop_fraglist(struct sk_buff *skb) 449 | @@ -398,6 +406,10 @@ 450 | #ifdef CONFIG_NET_SCHED 451 | C(tc_index); 452 | #endif 453 | +#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 454 | + C(imq_flags); 455 | + C(nf_info); 456 | +#endif 457 | 458 | atomic_inc(&(skb_shinfo(skb)->dataref)); 459 | skb->cloned = 1; 460 | @@ -440,6 +452,10 @@ 461 | #endif 462 | #ifdef CONFIG_NET_SCHED 463 | new->tc_index = old->tc_index; 464 | +#endif 465 | +#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 466 | + new->imq_flags=old->imq_flags; 467 | + new->nf_info=old->nf_info; 468 | #endif 469 | } 470 | 471 | diff -urN linux-2.4.18-clean/net/sched/sch_generic.c linux-2.4.18-imq/net/sched/sch_generic.c 472 | --- linux-2.4.18-clean/net/sched/sch_generic.c Fri Aug 18 19:26:25 2000 473 | +++ linux-2.4.18-imq/net/sched/sch_generic.c Thu May 23 14:15:12 2002 474 | @@ -29,6 +29,9 @@ 475 | #include 476 | #include 477 | #include 478 | +#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 479 | +#include 480 | +#endif 481 | #include 482 | #include 483 | 484 | @@ -89,7 +92,11 @@ 485 | spin_unlock(&dev->queue_lock); 486 | 487 | if (!netif_queue_stopped(dev)) { 488 | - if (netdev_nit) 489 | + if (netdev_nit 490 | +#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 491 | + && !(skb->imq_flags & IMQ_F_ENQUEUE) 492 | +#endif 493 | + ) 494 | dev_queue_xmit_nit(skb, dev); 495 | 496 | if (dev->hard_start_xmit(skb, dev) == 0) { 497 | -------------------------------------------------------------------------------- /kernel/v2.4/linux-2.4.21-imq-1.diff: -------------------------------------------------------------------------------- 1 | diff -urN a/Documentation/Configure.help b/Documentation/Configure.help 2 | --- a/Documentation/Configure.help 2003-06-25 00:18:32.000000000 +0200 3 | +++ b/Documentation/Configure.help 2003-06-25 00:19:01.000000000 +0200 4 | @@ -8821,6 +8821,20 @@ 5 | say M here and read . The module 6 | will be called bonding.o. 7 | 8 | +Intermediate queueing device support 9 | +CONFIG_IMQ 10 | + The imq device(s) is used as placeholder for QoS queueing disciplines. 11 | + Every packet entering/leaving the ip stack can be directed through 12 | + the imq device where it's enqueued/dequeued to the attached qdisc. 13 | + This allows you to treat network devices as classes and distribute 14 | + bandwidth among them. Iptables is used to specify through which imq 15 | + device, if any, packets travel. 16 | + 17 | + If you want to compile this as a module ( = code which ca be 18 | + inserted in and removed from the running kernel whenever you want), 19 | + say M here and read . The module 20 | + will be called imq.o 21 | + 22 | SLIP (serial line) support 23 | CONFIG_SLIP 24 | Say Y if you intend to use SLIP or CSLIP (compressed SLIP) to 25 | diff -urN a/drivers/net/Config.in b/drivers/net/Config.in 26 | --- a/drivers/net/Config.in 2003-06-25 00:18:32.000000000 +0200 27 | +++ b/drivers/net/Config.in 2003-06-25 00:19:02.000000000 +0200 28 | @@ -7,6 +7,11 @@ 29 | tristate 'Dummy net driver support' CONFIG_DUMMY 30 | tristate 'Bonding driver support' CONFIG_BONDING 31 | tristate 'EQL (serial line load balancing) support' CONFIG_EQUALIZER 32 | +if [ "$CONFIG_NETFILTER" = "y" ]; then 33 | + tristate 'IMQ (intermediate queueing device) support' CONFIG_IMQ 34 | +else 35 | + comment 'IMQ needs CONFIG_NETFILTER enabled' 36 | +fi 37 | tristate 'Universal TUN/TAP device driver support' CONFIG_TUN 38 | if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then 39 | tristate 'Ethertap network tap (OBSOLETE)' CONFIG_ETHERTAP 40 | diff -urN a/drivers/net/imq.c b/drivers/net/imq.c 41 | --- a/drivers/net/imq.c 1970-01-01 01:00:00.000000000 +0100 42 | +++ b/drivers/net/imq.c 2003-06-25 00:20:38.000000000 +0200 43 | @@ -0,0 +1,321 @@ 44 | +/* 45 | + * Pseudo-driver for the intermediate queue device. 46 | + * 47 | + * This program is free software; you can redistribute it and/or 48 | + * modify it under the terms of the GNU General Public License 49 | + * as published by the Free Software Foundation; either version 50 | + * 2 of the License, or (at your option) any later version. 51 | + * 52 | + * Authors: Patrick McHardy, 53 | + * 54 | + * The first version was written by Martin Devera, 55 | + * 56 | + * Credits: Jan Rafaj 57 | + * - Update patch to 2.4.21 58 | + * Sebastian Strollo 59 | + * - Fix "Dead-loop on netdevice imq"-issue 60 | + */ 61 | + 62 | +#include 63 | +#include 64 | +#include 65 | +#include 66 | +#include 67 | +#include 68 | +#include 69 | +#include 70 | +#include 71 | +#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) 72 | +#include 73 | +#endif 74 | +#include 75 | +#include 76 | + 77 | +static nf_hookfn imq_nf_hook; 78 | + 79 | +static struct nf_hook_ops imq_ingress_ipv4 = { 80 | + { NULL, NULL}, 81 | + imq_nf_hook, 82 | + PF_INET, 83 | + NF_IP_PRE_ROUTING, 84 | + NF_IP_PRI_MANGLE + 1 85 | +}; 86 | + 87 | +static struct nf_hook_ops imq_egress_ipv4 = { 88 | + { NULL, NULL}, 89 | + imq_nf_hook, 90 | + PF_INET, 91 | + NF_IP_POST_ROUTING, 92 | + NF_IP_PRI_LAST 93 | +}; 94 | + 95 | +#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) 96 | +static struct nf_hook_ops imq_ingress_ipv6 = { 97 | + { NULL, NULL}, 98 | + imq_nf_hook, 99 | + PF_INET6, 100 | + NF_IP6_PRE_ROUTING, 101 | + NF_IP6_PRI_MANGLE + 1 102 | +}; 103 | + 104 | +static struct nf_hook_ops imq_egress_ipv6 = { 105 | + { NULL, NULL}, 106 | + imq_nf_hook, 107 | + PF_INET6, 108 | + NF_IP6_POST_ROUTING, 109 | + NF_IP6_PRI_LAST 110 | +}; 111 | +#endif 112 | + 113 | +static unsigned int numdevs = 2; 114 | + 115 | +MODULE_PARM(numdevs, "i"); 116 | +MODULE_PARM_DESC(numdevs, "number of imq devices"); 117 | + 118 | +static struct net_device *imq_devs; 119 | + 120 | + 121 | +static struct net_device_stats *imq_get_stats(struct net_device *dev) 122 | +{ 123 | + return (struct net_device_stats *)dev->priv; 124 | +} 125 | + 126 | +/* called for packets kfree'd in qdiscs at places other than enqueue */ 127 | +static void imq_skb_destructor(struct sk_buff *skb) 128 | +{ 129 | + struct nf_info *info = skb->nf_info; 130 | + 131 | + if (info) { 132 | + if (info->indev) 133 | + dev_put(info->indev); 134 | + if (info->outdev) 135 | + dev_put(info->outdev); 136 | + kfree(info); 137 | + } 138 | +} 139 | + 140 | +static int imq_dev_xmit(struct sk_buff *skb, struct net_device *dev) 141 | +{ 142 | + struct net_device_stats *stats = (struct net_device_stats*) dev->priv; 143 | + 144 | + stats->tx_bytes += skb->len; 145 | + stats->tx_packets++; 146 | + 147 | + skb->imq_flags = 0; 148 | + skb->destructor = NULL; 149 | + 150 | + dev->trans_start = jiffies; 151 | + nf_reinject(skb, skb->nf_info, NF_ACCEPT); 152 | + return 0; 153 | +} 154 | + 155 | +static int imq_nf_queue(struct sk_buff *skb, struct nf_info *info, 156 | + void *data) 157 | +{ 158 | + struct net_device *dev; 159 | + struct net_device_stats *stats; 160 | + struct sk_buff *skb2 = NULL; 161 | + struct Qdisc *q; 162 | + unsigned int index = skb->imq_flags&IMQ_F_IFMASK; 163 | + int ret = -1; 164 | + 165 | + if (index > numdevs) 166 | + return -1; 167 | + 168 | + dev = imq_devs + index; 169 | + if (!(dev->flags & IFF_UP)) { 170 | + skb->imq_flags = 0; 171 | + nf_reinject(skb, info, NF_ACCEPT); 172 | + return 0; 173 | + } 174 | + dev->last_rx = jiffies; 175 | + 176 | + if (skb->destructor) { 177 | + skb2 = skb; 178 | + skb = skb_clone(skb, GFP_ATOMIC); 179 | + if (!skb) 180 | + return -1; 181 | + } 182 | + skb->nf_info = info; 183 | + 184 | + stats = (struct net_device_stats *)dev->priv; 185 | + stats->rx_bytes+= skb->len; 186 | + stats->rx_packets++; 187 | + 188 | + spin_lock_bh(&dev->queue_lock); 189 | + q = dev->qdisc; 190 | + if (q->enqueue) { 191 | + q->enqueue(skb_get(skb), q); 192 | + if (skb_shared(skb)) { 193 | + skb->destructor = imq_skb_destructor; 194 | + kfree_skb(skb); 195 | + ret = 0; 196 | + } 197 | + } 198 | + if (spin_is_locked(&dev->xmit_lock)) 199 | + netif_schedule(dev); 200 | + else 201 | + qdisc_run(dev); 202 | + spin_unlock_bh(&dev->queue_lock); 203 | + 204 | + if (skb2) 205 | + kfree_skb(ret ? skb : skb2); 206 | + 207 | + return ret; 208 | +} 209 | + 210 | +static unsigned int imq_nf_hook(unsigned int hook, struct sk_buff **pskb, 211 | + const struct net_device *indev, 212 | + const struct net_device *outdev, 213 | + int (*okfn)(struct sk_buff *)) 214 | +{ 215 | + if ((*pskb)->imq_flags & IMQ_F_ENQUEUE) 216 | + return NF_QUEUE; 217 | + 218 | + return NF_ACCEPT; 219 | +} 220 | + 221 | + 222 | +static int __init imq_init_hooks(void) 223 | +{ 224 | + int err; 225 | + 226 | + if ((err = nf_register_queue_handler(PF_INET, imq_nf_queue, NULL))) 227 | + goto err1; 228 | + if ((err = nf_register_hook(&imq_ingress_ipv4))) 229 | + goto err2; 230 | + if ((err = nf_register_hook(&imq_egress_ipv4))) 231 | + goto err3; 232 | +#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) 233 | + if ((err = nf_register_queue_handler(PF_INET6, imq_nf_queue, NULL))) 234 | + goto err4; 235 | + if ((err = nf_register_hook(&imq_ingress_ipv6))) 236 | + goto err5; 237 | + if ((err = nf_register_hook(&imq_egress_ipv6))) 238 | + goto err6; 239 | +#endif 240 | + 241 | + return 0; 242 | + 243 | +#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) 244 | +err6: 245 | + nf_unregister_hook(&imq_ingress_ipv6); 246 | +err5: 247 | + nf_unregister_queue_handler(PF_INET6); 248 | +err4: 249 | + nf_unregister_hook(&imq_egress_ipv4); 250 | +#endif 251 | +err3: 252 | + nf_unregister_hook(&imq_ingress_ipv4); 253 | +err2: 254 | + nf_unregister_queue_handler(PF_INET); 255 | +err1: 256 | + return err; 257 | +} 258 | + 259 | +static void __exit imq_unhook(void) 260 | +{ 261 | + nf_unregister_hook(&imq_ingress_ipv4); 262 | + nf_unregister_hook(&imq_egress_ipv4); 263 | + nf_unregister_queue_handler(PF_INET); 264 | +#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) 265 | + nf_unregister_hook(&imq_ingress_ipv6); 266 | + nf_unregister_hook(&imq_egress_ipv6); 267 | + nf_unregister_queue_handler(PF_INET6); 268 | +#endif 269 | +} 270 | + 271 | +static int __init imq_dev_init(struct net_device *dev) 272 | +{ 273 | + dev->hard_start_xmit = imq_dev_xmit; 274 | + dev->type = ARPHRD_VOID; 275 | + dev->mtu = 1500; 276 | + dev->tx_queue_len = 30; 277 | + dev->flags = IFF_NOARP; 278 | + dev->priv = kmalloc(sizeof(struct net_device_stats), GFP_KERNEL); 279 | + if (dev->priv == NULL) 280 | + return -ENOMEM; 281 | + memset(dev->priv, 0, sizeof(struct net_device_stats)); 282 | + dev->get_stats = imq_get_stats; 283 | + 284 | + return 0; 285 | +} 286 | + 287 | +static void imq_dev_uninit(struct net_device *dev) 288 | +{ 289 | + kfree(dev->priv); 290 | +} 291 | + 292 | +static int __init imq_init_devs(void) 293 | +{ 294 | + struct net_device *dev; 295 | + int i; 296 | + 297 | + if (!numdevs || numdevs > IMQ_MAX_DEVS) { 298 | + printk(KERN_ERR "numdevs has to be betweed 1 and %u\n", 299 | + IMQ_MAX_DEVS); 300 | + return -EINVAL; 301 | + } 302 | + 303 | + imq_devs = kmalloc(sizeof(struct net_device) * numdevs, GFP_KERNEL); 304 | + if (!imq_devs) 305 | + return -ENOMEM; 306 | + memset(imq_devs, 0, sizeof(struct net_device) * numdevs); 307 | + 308 | + /* we start counting at zero */ 309 | + numdevs--; 310 | + 311 | + for (i = 0, dev = imq_devs; i <= numdevs; i++, dev++) { 312 | + SET_MODULE_OWNER(dev); 313 | + strcpy(dev->name, "imq%d"); 314 | + dev->init = imq_dev_init; 315 | + dev->uninit = imq_dev_uninit; 316 | + 317 | + if (register_netdev(dev) < 0) 318 | + goto err_register; 319 | + } 320 | + return 0; 321 | + 322 | +err_register: 323 | + for (; i; i--) 324 | + unregister_netdev(--dev); 325 | + kfree(imq_devs); 326 | + return -EIO; 327 | +} 328 | + 329 | +static void imq_cleanup_devs(void) 330 | +{ 331 | + int i; 332 | + struct net_device *dev = imq_devs; 333 | + 334 | + for (i = 0; i <= numdevs; i++) 335 | + unregister_netdev(dev++); 336 | + 337 | + kfree(imq_devs); 338 | +} 339 | + 340 | +static int __init imq_init_module(void) 341 | +{ 342 | + int err; 343 | + 344 | + if ((err = imq_init_devs())) 345 | + return err; 346 | + if ((err = imq_init_hooks())) { 347 | + imq_cleanup_devs(); 348 | + return err; 349 | + } 350 | + 351 | + printk(KERN_INFO "imq driver loaded.\n"); 352 | + 353 | + return 0; 354 | +} 355 | + 356 | +static void __exit imq_cleanup_module(void) 357 | +{ 358 | + imq_unhook(); 359 | + imq_cleanup_devs(); 360 | +} 361 | + 362 | +module_init(imq_init_module); 363 | +module_exit(imq_cleanup_module); 364 | +MODULE_LICENSE("GPL"); 365 | diff -urN a/drivers/net/Makefile b/drivers/net/Makefile 366 | --- a/drivers/net/Makefile 2003-06-25 00:18:32.000000000 +0200 367 | +++ b/drivers/net/Makefile 2003-06-25 00:19:02.000000000 +0200 368 | @@ -159,6 +159,7 @@ 369 | obj-$(CONFIG_STRIP) += strip.o 370 | obj-$(CONFIG_DUMMY) += dummy.o 371 | obj-$(CONFIG_BONDING) += bonding.o 372 | +obj-$(CONFIG_IMQ) += imq.o 373 | obj-$(CONFIG_DE600) += de600.o 374 | obj-$(CONFIG_DE620) += de620.o 375 | obj-$(CONFIG_AT1500) += lance.o 376 | diff -urN a/include/linux/imq.h b/include/linux/imq.h 377 | --- a/include/linux/imq.h 1970-01-01 01:00:00.000000000 +0100 378 | +++ b/include/linux/imq.h 2003-06-25 00:19:02.000000000 +0200 379 | @@ -0,0 +1,9 @@ 380 | +#ifndef _IMQ_H 381 | +#define _IMQ_H 382 | + 383 | +#define IMQ_MAX_DEVS 16 384 | + 385 | +#define IMQ_F_IFMASK 0x7f 386 | +#define IMQ_F_ENQUEUE 0x80 387 | + 388 | +#endif /* _IMQ_H */ 389 | diff -urN a/include/linux/skbuff.h b/include/linux/skbuff.h 390 | --- a/include/linux/skbuff.h 2003-06-25 00:18:32.000000000 +0200 391 | +++ b/include/linux/skbuff.h 2003-06-25 00:19:02.000000000 +0200 392 | @@ -93,6 +93,9 @@ 393 | struct nf_conntrack *master; 394 | }; 395 | #endif 396 | +#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 397 | +struct nf_info; 398 | +#endif 399 | 400 | struct sk_buff_head { 401 | /* These two members must be first. */ 402 | @@ -178,7 +181,7 @@ 403 | unsigned int len; /* Length of actual data */ 404 | unsigned int data_len; 405 | unsigned int csum; /* Checksum */ 406 | - unsigned char __unused, /* Dead field, may be reused */ 407 | + unsigned char imq_flags, /* intermediate queueing device */ 408 | cloned, /* head may be cloned (check refcnt to be sure). */ 409 | pkt_type, /* Packet class */ 410 | ip_summed; /* Driver fed us an IP checksum */ 411 | @@ -215,6 +218,9 @@ 412 | #ifdef CONFIG_NET_SCHED 413 | __u32 tc_index; /* traffic control index */ 414 | #endif 415 | +#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 416 | + struct nf_info *nf_info; 417 | +#endif 418 | }; 419 | 420 | #define SK_WMEM_MAX 65535 421 | diff -urN a/net/core/skbuff.c b/net/core/skbuff.c 422 | --- a/net/core/skbuff.c 2003-06-25 00:18:32.000000000 +0200 423 | +++ b/net/core/skbuff.c 2003-06-25 00:19:03.000000000 +0200 424 | @@ -202,6 +202,10 @@ 425 | /* Set up other state */ 426 | skb->len = 0; 427 | skb->cloned = 0; 428 | +#if defined(CONFIG_IMQ) || defined (CONFIG_IMQ_MODULE) 429 | + skb->imq_flags = 0; 430 | + skb->nf_info = NULL; 431 | +#endif 432 | skb->data_len = 0; 433 | 434 | atomic_set(&skb->users, 1); 435 | @@ -249,6 +253,10 @@ 436 | #ifdef CONFIG_NET_SCHED 437 | skb->tc_index = 0; 438 | #endif 439 | +#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 440 | + skb->imq_flags = 0; 441 | + skb->nf_info = NULL; 442 | +#endif 443 | } 444 | 445 | static void skb_drop_fraglist(struct sk_buff *skb) 446 | @@ -398,6 +406,10 @@ 447 | #ifdef CONFIG_NET_SCHED 448 | C(tc_index); 449 | #endif 450 | +#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 451 | + C(imq_flags); 452 | + C(nf_info); 453 | +#endif 454 | 455 | atomic_inc(&(skb_shinfo(skb)->dataref)); 456 | skb->cloned = 1; 457 | @@ -441,6 +453,10 @@ 458 | #ifdef CONFIG_NET_SCHED 459 | new->tc_index = old->tc_index; 460 | #endif 461 | +#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 462 | + new->imq_flags=old->imq_flags; 463 | + new->nf_info=old->nf_info; 464 | +#endif 465 | } 466 | 467 | /** 468 | diff -urN a/net/sched/sch_generic.c b/net/sched/sch_generic.c 469 | --- a/net/sched/sch_generic.c 2003-06-25 00:18:32.000000000 +0200 470 | +++ b/net/sched/sch_generic.c 2003-06-25 00:19:03.000000000 +0200 471 | @@ -29,6 +29,9 @@ 472 | #include 473 | #include 474 | #include 475 | +#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 476 | +#include 477 | +#endif 478 | #include 479 | #include 480 | 481 | @@ -89,7 +92,11 @@ 482 | spin_unlock(&dev->queue_lock); 483 | 484 | if (!netif_queue_stopped(dev)) { 485 | - if (netdev_nit) 486 | + if (netdev_nit 487 | +#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 488 | + && !(skb->imq_flags & IMQ_F_ENQUEUE) 489 | +#endif 490 | + ) 491 | dev_queue_xmit_nit(skb, dev); 492 | 493 | if (dev->hard_start_xmit(skb, dev) == 0) { 494 | -------------------------------------------------------------------------------- /kernel/v2.4/linux-2.4.24-imq.diff: -------------------------------------------------------------------------------- 1 | diff -urN a/Documentation/Configure.help b/Documentation/Configure.help 2 | --- a/Documentation/Configure.help 2003-06-25 00:18:32.000000000 +0200 3 | +++ b/Documentation/Configure.help 2003-06-25 00:19:01.000000000 +0200 4 | @@ -8821,6 +8821,20 @@ 5 | say M here and read . The module 6 | will be called bonding.o. 7 | 8 | +Intermediate queueing device support 9 | +CONFIG_IMQ 10 | + The imq device(s) is used as placeholder for QoS queueing disciplines. 11 | + Every packet entering/leaving the ip stack can be directed through 12 | + the imq device where it's enqueued/dequeued to the attached qdisc. 13 | + This allows you to treat network devices as classes and distribute 14 | + bandwidth among them. Iptables is used to specify through which imq 15 | + device, if any, packets travel. 16 | + 17 | + If you want to compile this as a module ( = code which ca be 18 | + inserted in and removed from the running kernel whenever you want), 19 | + say M here and read . The module 20 | + will be called imq.o 21 | + 22 | SLIP (serial line) support 23 | CONFIG_SLIP 24 | Say Y if you intend to use SLIP or CSLIP (compressed SLIP) to 25 | diff -urN a/drivers/net/Config.in b/drivers/net/Config.in 26 | --- a/drivers/net/Config.in 2003-06-25 00:18:32.000000000 +0200 27 | +++ b/drivers/net/Config.in 2003-06-25 00:19:02.000000000 +0200 28 | @@ -7,6 +7,11 @@ 29 | tristate 'Dummy net driver support' CONFIG_DUMMY 30 | tristate 'Bonding driver support' CONFIG_BONDING 31 | tristate 'EQL (serial line load balancing) support' CONFIG_EQUALIZER 32 | +if [ "$CONFIG_NETFILTER" = "y" ]; then 33 | + tristate 'IMQ (intermediate queueing device) support' CONFIG_IMQ 34 | +else 35 | + comment 'IMQ needs CONFIG_NETFILTER enabled' 36 | +fi 37 | tristate 'Universal TUN/TAP device driver support' CONFIG_TUN 38 | if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then 39 | tristate 'Ethertap network tap (OBSOLETE)' CONFIG_ETHERTAP 40 | diff -urN a/drivers/net/imq.c b/drivers/net/imq.c 41 | --- a/drivers/net/imq.c 1970-01-01 01:00:00.000000000 +0100 42 | +++ b/drivers/net/imq.c 2003-06-25 00:20:38.000000000 +0200 43 | @@ -0,0 +1,321 @@ 44 | +/* 45 | + * Pseudo-driver for the intermediate queue device. 46 | + * 47 | + * This program is free software; you can redistribute it and/or 48 | + * modify it under the terms of the GNU General Public License 49 | + * as published by the Free Software Foundation; either version 50 | + * 2 of the License, or (at your option) any later version. 51 | + * 52 | + * Authors: Patrick McHardy, 53 | + * 54 | + * The first version was written by Martin Devera, 55 | + * 56 | + * Credits: Jan Rafaj 57 | + * - Update patch to 2.4.21 58 | + * Sebastian Strollo 59 | + * - Fix "Dead-loop on netdevice imq"-issue 60 | + */ 61 | + 62 | +#include 63 | +#include 64 | +#include 65 | +#include 66 | +#include 67 | +#include 68 | +#include 69 | +#include 70 | +#include 71 | +#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) 72 | +#include 73 | +#endif 74 | +#include 75 | +#include 76 | + 77 | +static nf_hookfn imq_nf_hook; 78 | + 79 | +static struct nf_hook_ops imq_ingress_ipv4 = { 80 | + { NULL, NULL}, 81 | + imq_nf_hook, 82 | + PF_INET, 83 | + NF_IP_PRE_ROUTING, 84 | + NF_IP_PRI_MANGLE + 1 85 | +}; 86 | + 87 | +static struct nf_hook_ops imq_egress_ipv4 = { 88 | + { NULL, NULL}, 89 | + imq_nf_hook, 90 | + PF_INET, 91 | + NF_IP_POST_ROUTING, 92 | + NF_IP_PRI_LAST 93 | +}; 94 | + 95 | +#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) 96 | +static struct nf_hook_ops imq_ingress_ipv6 = { 97 | + { NULL, NULL}, 98 | + imq_nf_hook, 99 | + PF_INET6, 100 | + NF_IP6_PRE_ROUTING, 101 | + NF_IP6_PRI_MANGLE + 1 102 | +}; 103 | + 104 | +static struct nf_hook_ops imq_egress_ipv6 = { 105 | + { NULL, NULL}, 106 | + imq_nf_hook, 107 | + PF_INET6, 108 | + NF_IP6_POST_ROUTING, 109 | + NF_IP6_PRI_LAST 110 | +}; 111 | +#endif 112 | + 113 | +static unsigned int numdevs = 2; 114 | + 115 | +MODULE_PARM(numdevs, "i"); 116 | +MODULE_PARM_DESC(numdevs, "number of imq devices"); 117 | + 118 | +static struct net_device *imq_devs; 119 | + 120 | + 121 | +static struct net_device_stats *imq_get_stats(struct net_device *dev) 122 | +{ 123 | + return (struct net_device_stats *)dev->priv; 124 | +} 125 | + 126 | +/* called for packets kfree'd in qdiscs at places other than enqueue */ 127 | +static void imq_skb_destructor(struct sk_buff *skb) 128 | +{ 129 | + struct nf_info *info = skb->nf_info; 130 | + 131 | + if (info) { 132 | + if (info->indev) 133 | + dev_put(info->indev); 134 | + if (info->outdev) 135 | + dev_put(info->outdev); 136 | + kfree(info); 137 | + } 138 | +} 139 | + 140 | +static int imq_dev_xmit(struct sk_buff *skb, struct net_device *dev) 141 | +{ 142 | + struct net_device_stats *stats = (struct net_device_stats*) dev->priv; 143 | + 144 | + stats->tx_bytes += skb->len; 145 | + stats->tx_packets++; 146 | + 147 | + skb->imq_flags = 0; 148 | + skb->destructor = NULL; 149 | + 150 | + dev->trans_start = jiffies; 151 | + nf_reinject(skb, skb->nf_info, NF_ACCEPT); 152 | + return 0; 153 | +} 154 | + 155 | +static int imq_nf_queue(struct sk_buff *skb, struct nf_info *info, 156 | + void *data) 157 | +{ 158 | + struct net_device *dev; 159 | + struct net_device_stats *stats; 160 | + struct sk_buff *skb2 = NULL; 161 | + struct Qdisc *q; 162 | + unsigned int index = skb->imq_flags&IMQ_F_IFMASK; 163 | + int ret = -1; 164 | + 165 | + if (index > numdevs) 166 | + return -1; 167 | + 168 | + dev = imq_devs + index; 169 | + if (!(dev->flags & IFF_UP)) { 170 | + skb->imq_flags = 0; 171 | + nf_reinject(skb, info, NF_ACCEPT); 172 | + return 0; 173 | + } 174 | + dev->last_rx = jiffies; 175 | + 176 | + if (skb->destructor) { 177 | + skb2 = skb; 178 | + skb = skb_clone(skb, GFP_ATOMIC); 179 | + if (!skb) 180 | + return -1; 181 | + } 182 | + skb->nf_info = info; 183 | + 184 | + stats = (struct net_device_stats *)dev->priv; 185 | + stats->rx_bytes+= skb->len; 186 | + stats->rx_packets++; 187 | + 188 | + spin_lock_bh(&dev->queue_lock); 189 | + q = dev->qdisc; 190 | + if (q->enqueue) { 191 | + q->enqueue(skb_get(skb), q); 192 | + if (skb_shared(skb)) { 193 | + skb->destructor = imq_skb_destructor; 194 | + kfree_skb(skb); 195 | + ret = 0; 196 | + } 197 | + } 198 | + if (spin_is_locked(&dev->xmit_lock)) 199 | + netif_schedule(dev); 200 | + else 201 | + qdisc_run(dev); 202 | + spin_unlock_bh(&dev->queue_lock); 203 | + 204 | + if (skb2) 205 | + kfree_skb(ret ? skb : skb2); 206 | + 207 | + return ret; 208 | +} 209 | + 210 | +static unsigned int imq_nf_hook(unsigned int hook, struct sk_buff **pskb, 211 | + const struct net_device *indev, 212 | + const struct net_device *outdev, 213 | + int (*okfn)(struct sk_buff *)) 214 | +{ 215 | + if ((*pskb)->imq_flags & IMQ_F_ENQUEUE) 216 | + return NF_QUEUE; 217 | + 218 | + return NF_ACCEPT; 219 | +} 220 | + 221 | + 222 | +static int __init imq_init_hooks(void) 223 | +{ 224 | + int err; 225 | + 226 | + if ((err = nf_register_queue_handler(PF_INET, imq_nf_queue, NULL))) 227 | + goto err1; 228 | + if ((err = nf_register_hook(&imq_ingress_ipv4))) 229 | + goto err2; 230 | + if ((err = nf_register_hook(&imq_egress_ipv4))) 231 | + goto err3; 232 | +#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) 233 | + if ((err = nf_register_queue_handler(PF_INET6, imq_nf_queue, NULL))) 234 | + goto err4; 235 | + if ((err = nf_register_hook(&imq_ingress_ipv6))) 236 | + goto err5; 237 | + if ((err = nf_register_hook(&imq_egress_ipv6))) 238 | + goto err6; 239 | +#endif 240 | + 241 | + return 0; 242 | + 243 | +#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) 244 | +err6: 245 | + nf_unregister_hook(&imq_ingress_ipv6); 246 | +err5: 247 | + nf_unregister_queue_handler(PF_INET6); 248 | +err4: 249 | + nf_unregister_hook(&imq_egress_ipv4); 250 | +#endif 251 | +err3: 252 | + nf_unregister_hook(&imq_ingress_ipv4); 253 | +err2: 254 | + nf_unregister_queue_handler(PF_INET); 255 | +err1: 256 | + return err; 257 | +} 258 | + 259 | +static void __exit imq_unhook(void) 260 | +{ 261 | + nf_unregister_hook(&imq_ingress_ipv4); 262 | + nf_unregister_hook(&imq_egress_ipv4); 263 | + nf_unregister_queue_handler(PF_INET); 264 | +#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) 265 | + nf_unregister_hook(&imq_ingress_ipv6); 266 | + nf_unregister_hook(&imq_egress_ipv6); 267 | + nf_unregister_queue_handler(PF_INET6); 268 | +#endif 269 | +} 270 | + 271 | +static int __init imq_dev_init(struct net_device *dev) 272 | +{ 273 | + dev->hard_start_xmit = imq_dev_xmit; 274 | + dev->type = ARPHRD_VOID; 275 | + dev->mtu = 1500; 276 | + dev->tx_queue_len = 30; 277 | + dev->flags = IFF_NOARP; 278 | + dev->priv = kmalloc(sizeof(struct net_device_stats), GFP_KERNEL); 279 | + if (dev->priv == NULL) 280 | + return -ENOMEM; 281 | + memset(dev->priv, 0, sizeof(struct net_device_stats)); 282 | + dev->get_stats = imq_get_stats; 283 | + 284 | + return 0; 285 | +} 286 | + 287 | +static void imq_dev_uninit(struct net_device *dev) 288 | +{ 289 | + kfree(dev->priv); 290 | +} 291 | + 292 | +static int __init imq_init_devs(void) 293 | +{ 294 | + struct net_device *dev; 295 | + int i; 296 | + 297 | + if (!numdevs || numdevs > IMQ_MAX_DEVS) { 298 | + printk(KERN_ERR "numdevs has to be betweed 1 and %u\n", 299 | + IMQ_MAX_DEVS); 300 | + return -EINVAL; 301 | + } 302 | + 303 | + imq_devs = kmalloc(sizeof(struct net_device) * numdevs, GFP_KERNEL); 304 | + if (!imq_devs) 305 | + return -ENOMEM; 306 | + memset(imq_devs, 0, sizeof(struct net_device) * numdevs); 307 | + 308 | + /* we start counting at zero */ 309 | + numdevs--; 310 | + 311 | + for (i = 0, dev = imq_devs; i <= numdevs; i++, dev++) { 312 | + SET_MODULE_OWNER(dev); 313 | + strcpy(dev->name, "imq%d"); 314 | + dev->init = imq_dev_init; 315 | + dev->uninit = imq_dev_uninit; 316 | + 317 | + if (register_netdev(dev) < 0) 318 | + goto err_register; 319 | + } 320 | + return 0; 321 | + 322 | +err_register: 323 | + for (; i; i--) 324 | + unregister_netdev(--dev); 325 | + kfree(imq_devs); 326 | + return -EIO; 327 | +} 328 | + 329 | +static void imq_cleanup_devs(void) 330 | +{ 331 | + int i; 332 | + struct net_device *dev = imq_devs; 333 | + 334 | + for (i = 0; i <= numdevs; i++) 335 | + unregister_netdev(dev++); 336 | + 337 | + kfree(imq_devs); 338 | +} 339 | + 340 | +static int __init imq_init_module(void) 341 | +{ 342 | + int err; 343 | + 344 | + if ((err = imq_init_devs())) 345 | + return err; 346 | + if ((err = imq_init_hooks())) { 347 | + imq_cleanup_devs(); 348 | + return err; 349 | + } 350 | + 351 | + printk(KERN_INFO "imq driver loaded.\n"); 352 | + 353 | + return 0; 354 | +} 355 | + 356 | +static void __exit imq_cleanup_module(void) 357 | +{ 358 | + imq_unhook(); 359 | + imq_cleanup_devs(); 360 | +} 361 | + 362 | +module_init(imq_init_module); 363 | +module_exit(imq_cleanup_module); 364 | +MODULE_LICENSE("GPL"); 365 | diff -urN a/drivers/net/Makefile b/drivers/net/Makefile 366 | --- a/drivers/net/Makefile 2003-06-25 00:18:32.000000000 +0200 367 | +++ b/drivers/net/Makefile 2003-06-25 00:19:02.000000000 +0200 368 | @@ -168,6 +168,7 @@ 369 | 370 | obj-$(CONFIG_STRIP) += strip.o 371 | obj-$(CONFIG_DUMMY) += dummy.o 372 | +obj-$(CONFIG_IMQ) += imq.o 373 | obj-$(CONFIG_DE600) += de600.o 374 | obj-$(CONFIG_DE620) += de620.o 375 | obj-$(CONFIG_AT1500) += lance.o 376 | diff -urN a/include/linux/imq.h b/include/linux/imq.h 377 | --- a/include/linux/imq.h 1970-01-01 01:00:00.000000000 +0100 378 | +++ b/include/linux/imq.h 2003-06-25 00:19:02.000000000 +0200 379 | @@ -0,0 +1,9 @@ 380 | +#ifndef _IMQ_H 381 | +#define _IMQ_H 382 | + 383 | +#define IMQ_MAX_DEVS 16 384 | + 385 | +#define IMQ_F_IFMASK 0x7f 386 | +#define IMQ_F_ENQUEUE 0x80 387 | + 388 | +#endif /* _IMQ_H */ 389 | diff -urN a/include/linux/skbuff.h b/include/linux/skbuff.h 390 | --- a/include/linux/skbuff.h 2003-06-25 00:18:32.000000000 +0200 391 | +++ b/include/linux/skbuff.h 2003-06-25 00:19:02.000000000 +0200 392 | @@ -93,6 +93,9 @@ 393 | struct nf_conntrack *master; 394 | }; 395 | #endif 396 | +#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 397 | +struct nf_info; 398 | +#endif 399 | 400 | struct sk_buff_head { 401 | /* These two members must be first. */ 402 | @@ -182,7 +185,7 @@ 403 | unsigned int len; /* Length of actual data */ 404 | unsigned int data_len; 405 | unsigned int csum; /* Checksum */ 406 | - unsigned char __unused, /* Dead field, may be reused */ 407 | + unsigned char imq_flags, /* intermediate queueing device */ 408 | cloned, /* head may be cloned (check refcnt to be sure). */ 409 | pkt_type, /* Packet class */ 410 | ip_summed; /* Driver fed us an IP checksum */ 411 | @@ -219,6 +222,9 @@ 412 | #ifdef CONFIG_NET_SCHED 413 | __u32 tc_index; /* traffic control index */ 414 | #endif 415 | +#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 416 | + struct nf_info *nf_info; 417 | +#endif 418 | }; 419 | 420 | #define SK_WMEM_MAX 65535 421 | diff -urN a/net/core/skbuff.c b/net/core/skbuff.c 422 | --- a/net/core/skbuff.c 2003-06-25 00:18:32.000000000 +0200 423 | +++ b/net/core/skbuff.c 2003-06-25 00:19:03.000000000 +0200 424 | @@ -206,6 +206,10 @@ 425 | /* Set up other state */ 426 | skb->len = 0; 427 | skb->cloned = 0; 428 | +#if defined(CONFIG_IMQ) || defined (CONFIG_IMQ_MODULE) 429 | + skb->imq_flags = 0; 430 | + skb->nf_info = NULL; 431 | +#endif 432 | skb->data_len = 0; 433 | 434 | atomic_set(&skb->users, 1); 435 | @@ -254,6 +259,10 @@ 436 | #ifdef CONFIG_NET_SCHED 437 | skb->tc_index = 0; 438 | #endif 439 | +#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 440 | + skb->imq_flags = 0; 441 | + skb->nf_info = NULL; 442 | +#endif 443 | } 444 | 445 | static void skb_drop_fraglist(struct sk_buff *skb) 446 | @@ -404,6 +412,10 @@ 447 | #ifdef CONFIG_NET_SCHED 448 | C(tc_index); 449 | #endif 450 | +#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 451 | + C(imq_flags); 452 | + C(nf_info); 453 | +#endif 454 | 455 | atomic_inc(&(skb_shinfo(skb)->dataref)); 456 | skb->cloned = 1; 457 | @@ -448,6 +460,10 @@ 458 | #ifdef CONFIG_NET_SCHED 459 | new->tc_index = old->tc_index; 460 | #endif 461 | +#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 462 | + new->imq_flags=old->imq_flags; 463 | + new->nf_info=old->nf_info; 464 | +#endif 465 | } 466 | 467 | /** 468 | diff -urN a/net/sched/sch_generic.c b/net/sched/sch_generic.c 469 | --- a/net/sched/sch_generic.c 2003-06-25 00:18:32.000000000 +0200 470 | +++ b/net/sched/sch_generic.c 2003-06-25 00:19:03.000000000 +0200 471 | @@ -29,6 +29,9 @@ 472 | #include 473 | #include 474 | #include 475 | +#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 476 | +#include 477 | +#endif 478 | #include 479 | #include 480 | 481 | @@ -89,7 +92,11 @@ 482 | spin_unlock(&dev->queue_lock); 483 | 484 | if (!netif_queue_stopped(dev)) { 485 | - if (netdev_nit) 486 | + if (netdev_nit 487 | +#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 488 | + && !(skb->imq_flags & IMQ_F_ENQUEUE) 489 | +#endif 490 | + ) 491 | dev_queue_xmit_nit(skb, dev); 492 | 493 | if (dev->hard_start_xmit(skb, dev) == 0) { 494 | -------------------------------------------------------------------------------- /kernel/v2.6-multiqueue/README: -------------------------------------------------------------------------------- 1 | Pseudo-driver for the intermediate queue device. 2 | ------------------------------------------------ 3 | 4 | 5 | Kernel versions 2.6.35, 2.6.37, 2.6.38, 2.6.39 6 | -all the patches in this folder are multi-queue (see https://github.com/imq/linuximq/wiki/FAQ for what is multi queue) 7 | 8 | -------------------------------------------------------------------------------- /kernel/v2.6-multiqueue/load-imq-multiqueue.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | IMQ_IS_MQ=$(modinfo imq | grep numqueues) 4 | if [ "$IMQ_IS_MQ" = "" ]; then 5 | # load single-queue imq 6 | modprobe imq 7 | else 8 | # load multi-queue imq 9 | NUM_CPU=$(grep -c 'model name' /proc/cpuinfo) 10 | modprobe imq numqueues=$NUM_CPU 11 | fi 12 | -------------------------------------------------------------------------------- /kernel/v2.6/linux-2.6.0-imq.diff: -------------------------------------------------------------------------------- 1 | Index: drivers/net/Kconfig 2 | =================================================================== 3 | RCS file: /cvs/tgr/linux-26/drivers/net/Kconfig,v 4 | retrieving revision 1.1.1.3 5 | diff -u -r1.1.1.3 Kconfig 6 | --- drivers/net/Kconfig 28 Jul 2003 11:56:40 -0000 1.1.1.3 7 | +++ drivers/net/Kconfig 28 Jul 2003 23:08:06 -0000 8 | @@ -2399,6 +2399,22 @@ 9 | which can lead to bad results if the ATM peer loses state and 10 | changes its encapsulation unilaterally. 11 | 12 | +config IMQ 13 | + tristate "IMQ (Intermediate queueing device) support" 14 | + depends on NETDEVICES 15 | + ---help--- 16 | + The imq device(s) is used as placeholder for QoS queueing disciplines. 17 | + Every packet entering/leaving the ip stack can be directed through 18 | + the imq device where it's enqueued/dequeued to the attached qdisc. 19 | + This allows you to treat network devices as classes and distribute 20 | + bandwidth among them. Iptables is used to specify through which imq 21 | + device, if any, packets travel. 22 | + 23 | + If you want to compile this as a module ( = code which ca be 24 | + inserted in and removed from the running kernel whenever you want), 25 | + say M here and read . The module 26 | + will be called imq.o 27 | + 28 | config SLIP 29 | tristate "SLIP (serial line) support" 30 | depends on NETDEVICES 31 | Index: drivers/net/Makefile 32 | =================================================================== 33 | RCS file: /cvs/tgr/linux-26/drivers/net/Makefile,v 34 | retrieving revision 1.1.1.2 35 | diff -u -r1.1.1.2 Makefile 36 | --- drivers/net/Makefile 28 Jul 2003 11:56:35 -0000 1.1.1.2 37 | +++ drivers/net/Makefile 28 Jul 2003 23:08:06 -0000 38 | @@ -109,6 +109,7 @@ 39 | endif 40 | 41 | obj-$(CONFIG_DUMMY) += dummy.o 42 | +obj-$(CONFIG_IMQ) += imq.o 43 | obj-$(CONFIG_DE600) += de600.o 44 | obj-$(CONFIG_DE620) += de620.o 45 | obj-$(CONFIG_AT1500) += lance.o 46 | Index: drivers/net/imq.c 47 | =================================================================== 48 | RCS file: drivers/net/imq.c 49 | diff -N drivers/net/imq.c 50 | --- /dev/null 1 Jan 1970 00:00:00 -0000 51 | +++ drivers/net/imq.c 28 Jul 2003 23:08:06 -0000 52 | @@ -0,0 +1,333 @@ 53 | +/* 54 | + * Pseudo-driver for the intermediate queue device. 55 | + * 56 | + * This program is free software; you can redistribute it and/or 57 | + * modify it under the terms of the GNU General Public License 58 | + * as published by the Free Software Foundation; either version 59 | + * 2 of the License, or (at your option) any later version. 60 | + * 61 | + * Authors: Patrick McHardy, 62 | + * 63 | + * The first version was written by Martin Devera, 64 | + * 65 | + * Credits: Jan Rafaj 66 | + * - Update patch to 2.4.21 67 | + * Sebastian Strollo 68 | + * - Fix "Dead-loop on netdevice imq"-issue 69 | + */ 70 | + 71 | +#include 72 | +#include 73 | +#include 74 | +#include 75 | +#include 76 | +#include 77 | +#include 78 | +#include 79 | +#include 80 | +#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) 81 | +#include 82 | +#endif 83 | +#include 84 | +#include 85 | + 86 | +static nf_hookfn imq_nf_hook; 87 | + 88 | +static struct nf_hook_ops imq_ingress_ipv4 = { 89 | + .list = { 90 | + .next = NULL, 91 | + .prev = NULL, 92 | + }, 93 | + .hook = imq_nf_hook, 94 | + .pf = PF_INET, 95 | + .hooknum = NF_IP_PRE_ROUTING, 96 | + .priority = NF_IP_PRI_MANGLE + 1 97 | +}; 98 | + 99 | +static struct nf_hook_ops imq_egress_ipv4 = { 100 | + .list = { 101 | + .next = NULL, 102 | + .prev = NULL, 103 | + }, 104 | + .hook = imq_nf_hook, 105 | + .pf = PF_INET, 106 | + .hooknum = NF_IP_POST_ROUTING, 107 | + .priority = NF_IP_PRI_LAST 108 | +}; 109 | + 110 | +#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) 111 | +static struct nf_hook_ops imq_ingress_ipv6 = { 112 | + .list = { 113 | + .next = NULL, 114 | + .prev = NULL, 115 | + }, 116 | + .hook = imq_nf_hook, 117 | + .pf = PF_INET6, 118 | + .hooknum = NF_IP6_PRE_ROUTING, 119 | + .priority = NF_IP6_PRI_MANGLE + 1 120 | +}; 121 | + 122 | +static struct nf_hook_ops imq_egress_ipv6 = { 123 | + .list = { 124 | + .next = NULL, 125 | + .prev = NULL, 126 | + }, 127 | + .hook = imq_nf_hook, 128 | + .pf = PF_INET6, 129 | + .hooknum = NF_IP6_POST_ROUTING, 130 | + .priority = NF_IP6_PRI_LAST 131 | +}; 132 | +#endif 133 | + 134 | +static unsigned int numdevs = 2; 135 | + 136 | +MODULE_PARM(numdevs, "i"); 137 | +MODULE_PARM_DESC(numdevs, "number of imq devices"); 138 | + 139 | +static struct net_device *imq_devs; 140 | + 141 | + 142 | +static struct net_device_stats *imq_get_stats(struct net_device *dev) 143 | +{ 144 | + return (struct net_device_stats *)dev->priv; 145 | +} 146 | + 147 | +/* called for packets kfree'd in qdiscs at places other than enqueue */ 148 | +static void imq_skb_destructor(struct sk_buff *skb) 149 | +{ 150 | + struct nf_info *info = skb->nf_info; 151 | + 152 | + if (info) { 153 | + if (info->indev) 154 | + dev_put(info->indev); 155 | + if (info->outdev) 156 | + dev_put(info->outdev); 157 | + kfree(info); 158 | + } 159 | +} 160 | + 161 | +static int imq_dev_xmit(struct sk_buff *skb, struct net_device *dev) 162 | +{ 163 | + struct net_device_stats *stats = (struct net_device_stats*) dev->priv; 164 | + 165 | + stats->tx_bytes += skb->len; 166 | + stats->tx_packets++; 167 | + 168 | + skb->imq_flags = 0; 169 | + skb->destructor = NULL; 170 | + 171 | + dev->trans_start = jiffies; 172 | + nf_reinject(skb, skb->nf_info, NF_ACCEPT); 173 | + return 0; 174 | +} 175 | + 176 | +static int imq_nf_queue(struct sk_buff *skb, struct nf_info *info, 177 | + void *data) 178 | +{ 179 | + struct net_device *dev; 180 | + struct net_device_stats *stats; 181 | + struct sk_buff *skb2 = NULL; 182 | + struct Qdisc *q; 183 | + unsigned int index = skb->imq_flags&IMQ_F_IFMASK; 184 | + int ret = -1; 185 | + 186 | + if (index > numdevs) 187 | + return -1; 188 | + 189 | + dev = imq_devs + index; 190 | + if (!(dev->flags & IFF_UP)) { 191 | + skb->imq_flags = 0; 192 | + nf_reinject(skb, info, NF_ACCEPT); 193 | + return 0; 194 | + } 195 | + dev->last_rx = jiffies; 196 | + 197 | + if (skb->destructor) { 198 | + skb2 = skb; 199 | + skb = skb_clone(skb, GFP_ATOMIC); 200 | + if (!skb) 201 | + return -1; 202 | + } 203 | + skb->nf_info = info; 204 | + 205 | + stats = (struct net_device_stats *)dev->priv; 206 | + stats->rx_bytes+= skb->len; 207 | + stats->rx_packets++; 208 | + 209 | + spin_lock_bh(&dev->queue_lock); 210 | + q = dev->qdisc; 211 | + if (q->enqueue) { 212 | + q->enqueue(skb_get(skb), q); 213 | + if (skb_shared(skb)) { 214 | + skb->destructor = imq_skb_destructor; 215 | + kfree_skb(skb); 216 | + ret = 0; 217 | + } 218 | + } 219 | + if (spin_is_locked(&dev->xmit_lock)) 220 | + netif_schedule(dev); 221 | + else 222 | + qdisc_run(dev); 223 | + spin_unlock_bh(&dev->queue_lock); 224 | + 225 | + if (skb2) 226 | + kfree_skb(ret ? skb : skb2); 227 | + 228 | + return ret; 229 | +} 230 | + 231 | +static unsigned int imq_nf_hook(unsigned int hook, struct sk_buff **pskb, 232 | + const struct net_device *indev, 233 | + const struct net_device *outdev, 234 | + int (*okfn)(struct sk_buff *)) 235 | +{ 236 | + if ((*pskb)->imq_flags & IMQ_F_ENQUEUE) 237 | + return NF_QUEUE; 238 | + 239 | + return NF_ACCEPT; 240 | +} 241 | + 242 | + 243 | +static int __init imq_init_hooks(void) 244 | +{ 245 | + int err; 246 | + 247 | + if ((err = nf_register_queue_handler(PF_INET, imq_nf_queue, NULL))) 248 | + goto err1; 249 | + if ((err = nf_register_hook(&imq_ingress_ipv4))) 250 | + goto err2; 251 | + if ((err = nf_register_hook(&imq_egress_ipv4))) 252 | + goto err3; 253 | +#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) 254 | + if ((err = nf_register_queue_handler(PF_INET6, imq_nf_queue, NULL))) 255 | + goto err4; 256 | + if ((err = nf_register_hook(&imq_ingress_ipv6))) 257 | + goto err5; 258 | + if ((err = nf_register_hook(&imq_egress_ipv6))) 259 | + goto err6; 260 | +#endif 261 | + 262 | + return 0; 263 | + 264 | +#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) 265 | +err6: 266 | + nf_unregister_hook(&imq_ingress_ipv6); 267 | +err5: 268 | + nf_unregister_queue_handler(PF_INET6); 269 | +err4: 270 | + nf_unregister_hook(&imq_egress_ipv4); 271 | +#endif 272 | +err3: 273 | + nf_unregister_hook(&imq_ingress_ipv4); 274 | +err2: 275 | + nf_unregister_queue_handler(PF_INET); 276 | +err1: 277 | + return err; 278 | +} 279 | + 280 | +static void __exit imq_unhook(void) 281 | +{ 282 | + nf_unregister_hook(&imq_ingress_ipv4); 283 | + nf_unregister_hook(&imq_egress_ipv4); 284 | + nf_unregister_queue_handler(PF_INET); 285 | +#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) 286 | + nf_unregister_hook(&imq_ingress_ipv6); 287 | + nf_unregister_hook(&imq_egress_ipv6); 288 | + nf_unregister_queue_handler(PF_INET6); 289 | +#endif 290 | +} 291 | + 292 | +static int __init imq_dev_init(struct net_device *dev) 293 | +{ 294 | + dev->hard_start_xmit = imq_dev_xmit; 295 | + dev->type = ARPHRD_VOID; 296 | + dev->mtu = 1500; 297 | + dev->tx_queue_len = 30; 298 | + dev->flags = IFF_NOARP; 299 | + dev->priv = kmalloc(sizeof(struct net_device_stats), GFP_KERNEL); 300 | + if (dev->priv == NULL) 301 | + return -ENOMEM; 302 | + memset(dev->priv, 0, sizeof(struct net_device_stats)); 303 | + dev->get_stats = imq_get_stats; 304 | + 305 | + return 0; 306 | +} 307 | + 308 | +static void imq_dev_uninit(struct net_device *dev) 309 | +{ 310 | + kfree(dev->priv); 311 | +} 312 | + 313 | +static int __init imq_init_devs(void) 314 | +{ 315 | + struct net_device *dev; 316 | + int i; 317 | + 318 | + if (!numdevs || numdevs > IMQ_MAX_DEVS) { 319 | + printk(KERN_ERR "numdevs has to be betweed 1 and %u\n", 320 | + IMQ_MAX_DEVS); 321 | + return -EINVAL; 322 | + } 323 | + 324 | + imq_devs = kmalloc(sizeof(struct net_device) * numdevs, GFP_KERNEL); 325 | + if (!imq_devs) 326 | + return -ENOMEM; 327 | + memset(imq_devs, 0, sizeof(struct net_device) * numdevs); 328 | + 329 | + /* we start counting at zero */ 330 | + numdevs--; 331 | + 332 | + for (i = 0, dev = imq_devs; i <= numdevs; i++, dev++) { 333 | + SET_MODULE_OWNER(dev); 334 | + strcpy(dev->name, "imq%d"); 335 | + dev->init = imq_dev_init; 336 | + dev->uninit = imq_dev_uninit; 337 | + 338 | + if (register_netdev(dev) < 0) 339 | + goto err_register; 340 | + } 341 | + return 0; 342 | + 343 | +err_register: 344 | + for (; i; i--) 345 | + unregister_netdev(--dev); 346 | + kfree(imq_devs); 347 | + return -EIO; 348 | +} 349 | + 350 | +static void imq_cleanup_devs(void) 351 | +{ 352 | + int i; 353 | + struct net_device *dev = imq_devs; 354 | + 355 | + for (i = 0; i <= numdevs; i++) 356 | + unregister_netdev(dev++); 357 | + 358 | + kfree(imq_devs); 359 | +} 360 | + 361 | +static int __init imq_init_module(void) 362 | +{ 363 | + int err; 364 | + 365 | + if ((err = imq_init_devs())) 366 | + return err; 367 | + if ((err = imq_init_hooks())) { 368 | + imq_cleanup_devs(); 369 | + return err; 370 | + } 371 | + 372 | + printk(KERN_INFO "imq driver loaded.\n"); 373 | + 374 | + return 0; 375 | +} 376 | + 377 | +static void __exit imq_cleanup_module(void) 378 | +{ 379 | + imq_unhook(); 380 | + imq_cleanup_devs(); 381 | +} 382 | + 383 | +module_init(imq_init_module); 384 | +module_exit(imq_cleanup_module); 385 | +MODULE_LICENSE("GPL"); 386 | Index: include/linux/imq.h 387 | =================================================================== 388 | RCS file: include/linux/imq.h 389 | diff -N include/linux/imq.h 390 | --- /dev/null 1 Jan 1970 00:00:00 -0000 391 | +++ include/linux/imq.h 28 Jul 2003 23:08:07 -0000 392 | @@ -0,0 +1,9 @@ 393 | +#ifndef _IMQ_H 394 | +#define _IMQ_H 395 | + 396 | +#define IMQ_MAX_DEVS 16 397 | + 398 | +#define IMQ_F_IFMASK 0x7f 399 | +#define IMQ_F_ENQUEUE 0x80 400 | + 401 | +#endif /* _IMQ_H */ 402 | Index: include/linux/skbuff.h 403 | =================================================================== 404 | RCS file: /cvs/tgr/linux-26/include/linux/skbuff.h,v 405 | retrieving revision 1.1.1.1 406 | diff -u -r1.1.1.1 skbuff.h 407 | --- include/linux/skbuff.h 9 Jul 2003 18:40:44 -0000 1.1.1.1 408 | +++ include/linux/skbuff.h 28 Jul 2003 23:08:07 -0000 409 | @@ -98,6 +98,11 @@ 410 | struct nf_conntrack *master; 411 | }; 412 | 413 | +#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 414 | +struct nf_info; 415 | +#endif 416 | + 417 | + 418 | #if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) 419 | struct nf_bridge_info { 420 | atomic_t use; 421 | @@ -256,6 +261,11 @@ 422 | #ifdef CONFIG_NET_SCHED 423 | __u32 tc_index; /* traffic control index */ 424 | #endif 425 | +#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 426 | + unsigned char imq_flags; /* intermediate queueing device */ 427 | + struct nf_info *nf_info; 428 | +#endif 429 | + 430 | 431 | /* These elements must be at the end, see alloc_skb() for details. */ 432 | unsigned int truesize; 433 | Index: net/core/skbuff.c 434 | =================================================================== 435 | RCS file: /cvs/tgr/linux-26/net/core/skbuff.c,v 436 | retrieving revision 1.1.1.1 437 | diff -u -r1.1.1.1 skbuff.c 438 | --- net/core/skbuff.c 9 Jul 2003 18:42:29 -0000 1.1.1.1 439 | +++ net/core/skbuff.c 28 Jul 2003 23:08:07 -0000 440 | @@ -312,6 +312,10 @@ 441 | #ifdef CONFIG_NET_SCHED 442 | C(tc_index); 443 | #endif 444 | +#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 445 | + C(imq_flags); 446 | + C(nf_info); 447 | +#endif 448 | C(truesize); 449 | atomic_set(&n->users, 1); 450 | C(head); 451 | @@ -367,6 +371,12 @@ 452 | #ifdef CONFIG_NET_SCHED 453 | new->tc_index = old->tc_index; 454 | #endif 455 | +#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 456 | + new->imq_flags = old->imq_flags; 457 | + new->nf_info = old->nf_info; 458 | +#endif 459 | + 460 | + 461 | atomic_set(&new->users, 1); 462 | } 463 | 464 | Index: net/sched/sch_generic.c 465 | =================================================================== 466 | RCS file: /cvs/tgr/linux-26/net/sched/sch_generic.c,v 467 | retrieving revision 1.1.1.1 468 | diff -u -r1.1.1.1 sch_generic.c 469 | --- net/sched/sch_generic.c 9 Jul 2003 18:42:36 -0000 1.1.1.1 470 | +++ net/sched/sch_generic.c 28 Jul 2003 23:08:07 -0000 471 | @@ -30,6 +30,9 @@ 472 | #include 473 | #include 474 | #include 475 | +#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 476 | +#include 477 | +#endif 478 | #include 479 | #include 480 | 481 | @@ -90,7 +93,11 @@ 482 | spin_unlock(&dev->queue_lock); 483 | 484 | if (!netif_queue_stopped(dev)) { 485 | - if (netdev_nit) 486 | + if (netdev_nit 487 | +#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 488 | + && !(skb->imq_flags & IMQ_F_ENQUEUE) 489 | +#endif 490 | + ) 491 | dev_queue_xmit_nit(skb, dev); 492 | 493 | if (dev->hard_start_xmit(skb, dev) == 0) { 494 | -------------------------------------------------------------------------------- /kernel/v2.6/linux-2.6.1-imq.diff: -------------------------------------------------------------------------------- 1 | Index: drivers/net/Kconfig 2 | =================================================================== 3 | RCS file: /cvs/tgr/linux-26/drivers/net/Kconfig,v 4 | retrieving revision 1.1.1.3 5 | diff -u -r1.1.1.3 Kconfig 6 | --- drivers/net/Kconfig 28 Jul 2003 11:56:40 -0000 1.1.1.3 7 | +++ drivers/net/Kconfig 28 Jul 2003 23:08:06 -0000 8 | @@ -2399,6 +2399,22 @@ 9 | which can lead to bad results if the ATM peer loses state and 10 | changes its encapsulation unilaterally. 11 | 12 | +config IMQ 13 | + tristate "IMQ (Intermediate queueing device) support" 14 | + depends on NETDEVICES 15 | + ---help--- 16 | + The imq device(s) is used as placeholder for QoS queueing disciplines. 17 | + Every packet entering/leaving the ip stack can be directed through 18 | + the imq device where it's enqueued/dequeued to the attached qdisc. 19 | + This allows you to treat network devices as classes and distribute 20 | + bandwidth among them. Iptables is used to specify through which imq 21 | + device, if any, packets travel. More info at: http://www.linuximq.net 22 | + 23 | + If you want to compile this as a module ( = code which ca be 24 | + inserted in and removed from the running kernel whenever you want), 25 | + say M here and read . The module 26 | + will be called imq.o 27 | + 28 | config SLIP 29 | tristate "SLIP (serial line) support" 30 | depends on NETDEVICES 31 | Index: drivers/net/Makefile 32 | =================================================================== 33 | RCS file: /cvs/tgr/linux-26/drivers/net/Makefile,v 34 | retrieving revision 1.1.1.2 35 | diff -u -r1.1.1.2 Makefile 36 | --- drivers/net/Makefile 28 Jul 2003 11:56:35 -0000 1.1.1.2 37 | +++ drivers/net/Makefile 28 Jul 2003 23:08:06 -0000 38 | @@ -109,6 +109,7 @@ 39 | endif 40 | 41 | obj-$(CONFIG_DUMMY) += dummy.o 42 | +obj-$(CONFIG_IMQ) += imq.o 43 | obj-$(CONFIG_DE600) += de600.o 44 | obj-$(CONFIG_DE620) += de620.o 45 | obj-$(CONFIG_AT1500) += lance.o 46 | Index: drivers/net/imq.c 47 | =================================================================== 48 | RCS file: drivers/net/imq.c 49 | diff -N drivers/net/imq.c 50 | --- /dev/null 1 Jan 1970 00:00:00 -0000 51 | +++ drivers/net/imq.c 28 Jul 2003 23:08:06 -0000 52 | @@ -0,0 +1,333 @@ 53 | +/* 54 | + * Pseudo-driver for the intermediate queue device. 55 | + * 56 | + * This program is free software; you can redistribute it and/or 57 | + * modify it under the terms of the GNU General Public License 58 | + * as published by the Free Software Foundation; either version 59 | + * 2 of the License, or (at your option) any later version. 60 | + * 61 | + * Authors: Patrick McHardy, 62 | + * 63 | + * The first version was written by Martin Devera, 64 | + * 65 | + * Credits: Jan Rafaj 66 | + * - Update patch to 2.4.21 67 | + * Sebastian Strollo 68 | + * - Fix "Dead-loop on netdevice imq"-issue 69 | + */ 70 | + 71 | +#include 72 | +#include 73 | +#include 74 | +#include 75 | +#include 76 | +#include 77 | +#include 78 | +#include 79 | +#include 80 | +#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) 81 | +#include 82 | +#endif 83 | +#include 84 | +#include 85 | + 86 | +static nf_hookfn imq_nf_hook; 87 | + 88 | +static struct nf_hook_ops imq_ingress_ipv4 = { 89 | + .list = { 90 | + .next = NULL, 91 | + .prev = NULL, 92 | + }, 93 | + .hook = imq_nf_hook, 94 | + .pf = PF_INET, 95 | + .hooknum = NF_IP_PRE_ROUTING, 96 | + .priority = NF_IP_PRI_MANGLE + 1 97 | +}; 98 | + 99 | +static struct nf_hook_ops imq_egress_ipv4 = { 100 | + .list = { 101 | + .next = NULL, 102 | + .prev = NULL, 103 | + }, 104 | + .hook = imq_nf_hook, 105 | + .pf = PF_INET, 106 | + .hooknum = NF_IP_POST_ROUTING, 107 | + .priority = NF_IP_PRI_LAST 108 | +}; 109 | + 110 | +#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) 111 | +static struct nf_hook_ops imq_ingress_ipv6 = { 112 | + .list = { 113 | + .next = NULL, 114 | + .prev = NULL, 115 | + }, 116 | + .hook = imq_nf_hook, 117 | + .pf = PF_INET6, 118 | + .hooknum = NF_IP6_PRE_ROUTING, 119 | + .priority = NF_IP6_PRI_MANGLE + 1 120 | +}; 121 | + 122 | +static struct nf_hook_ops imq_egress_ipv6 = { 123 | + .list = { 124 | + .next = NULL, 125 | + .prev = NULL, 126 | + }, 127 | + .hook = imq_nf_hook, 128 | + .pf = PF_INET6, 129 | + .hooknum = NF_IP6_POST_ROUTING, 130 | + .priority = NF_IP6_PRI_LAST 131 | +}; 132 | +#endif 133 | + 134 | +static unsigned int numdevs = 2; 135 | + 136 | +MODULE_PARM(numdevs, "i"); 137 | +MODULE_PARM_DESC(numdevs, "number of imq devices"); 138 | + 139 | +static struct net_device *imq_devs; 140 | + 141 | + 142 | +static struct net_device_stats *imq_get_stats(struct net_device *dev) 143 | +{ 144 | + return (struct net_device_stats *)dev->priv; 145 | +} 146 | + 147 | +/* called for packets kfree'd in qdiscs at places other than enqueue */ 148 | +static void imq_skb_destructor(struct sk_buff *skb) 149 | +{ 150 | + struct nf_info *info = skb->nf_info; 151 | + 152 | + if (info) { 153 | + if (info->indev) 154 | + dev_put(info->indev); 155 | + if (info->outdev) 156 | + dev_put(info->outdev); 157 | + kfree(info); 158 | + } 159 | +} 160 | + 161 | +static int imq_dev_xmit(struct sk_buff *skb, struct net_device *dev) 162 | +{ 163 | + struct net_device_stats *stats = (struct net_device_stats*) dev->priv; 164 | + 165 | + stats->tx_bytes += skb->len; 166 | + stats->tx_packets++; 167 | + 168 | + skb->imq_flags = 0; 169 | + skb->destructor = NULL; 170 | + 171 | + dev->trans_start = jiffies; 172 | + nf_reinject(skb, skb->nf_info, NF_ACCEPT); 173 | + return 0; 174 | +} 175 | + 176 | +static int imq_nf_queue(struct sk_buff *skb, struct nf_info *info, 177 | + void *data) 178 | +{ 179 | + struct net_device *dev; 180 | + struct net_device_stats *stats; 181 | + struct sk_buff *skb2 = NULL; 182 | + struct Qdisc *q; 183 | + unsigned int index = skb->imq_flags&IMQ_F_IFMASK; 184 | + int ret = -1; 185 | + 186 | + if (index > numdevs) 187 | + return -1; 188 | + 189 | + dev = imq_devs + index; 190 | + if (!(dev->flags & IFF_UP)) { 191 | + skb->imq_flags = 0; 192 | + nf_reinject(skb, info, NF_ACCEPT); 193 | + return 0; 194 | + } 195 | + dev->last_rx = jiffies; 196 | + 197 | + if (skb->destructor) { 198 | + skb2 = skb; 199 | + skb = skb_clone(skb, GFP_ATOMIC); 200 | + if (!skb) 201 | + return -1; 202 | + } 203 | + skb->nf_info = info; 204 | + 205 | + stats = (struct net_device_stats *)dev->priv; 206 | + stats->rx_bytes+= skb->len; 207 | + stats->rx_packets++; 208 | + 209 | + spin_lock_bh(&dev->queue_lock); 210 | + q = dev->qdisc; 211 | + if (q->enqueue) { 212 | + q->enqueue(skb_get(skb), q); 213 | + if (skb_shared(skb)) { 214 | + skb->destructor = imq_skb_destructor; 215 | + kfree_skb(skb); 216 | + ret = 0; 217 | + } 218 | + } 219 | + if (spin_is_locked(&dev->xmit_lock)) 220 | + netif_schedule(dev); 221 | + else 222 | + qdisc_run(dev); 223 | + spin_unlock_bh(&dev->queue_lock); 224 | + 225 | + if (skb2) 226 | + kfree_skb(ret ? skb : skb2); 227 | + 228 | + return ret; 229 | +} 230 | + 231 | +static unsigned int imq_nf_hook(unsigned int hook, struct sk_buff **pskb, 232 | + const struct net_device *indev, 233 | + const struct net_device *outdev, 234 | + int (*okfn)(struct sk_buff *)) 235 | +{ 236 | + if ((*pskb)->imq_flags & IMQ_F_ENQUEUE) 237 | + return NF_QUEUE; 238 | + 239 | + return NF_ACCEPT; 240 | +} 241 | + 242 | + 243 | +static int __init imq_init_hooks(void) 244 | +{ 245 | + int err; 246 | + 247 | + if ((err = nf_register_queue_handler(PF_INET, imq_nf_queue, NULL))) 248 | + goto err1; 249 | + if ((err = nf_register_hook(&imq_ingress_ipv4))) 250 | + goto err2; 251 | + if ((err = nf_register_hook(&imq_egress_ipv4))) 252 | + goto err3; 253 | +#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) 254 | + if ((err = nf_register_queue_handler(PF_INET6, imq_nf_queue, NULL))) 255 | + goto err4; 256 | + if ((err = nf_register_hook(&imq_ingress_ipv6))) 257 | + goto err5; 258 | + if ((err = nf_register_hook(&imq_egress_ipv6))) 259 | + goto err6; 260 | +#endif 261 | + 262 | + return 0; 263 | + 264 | +#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) 265 | +err6: 266 | + nf_unregister_hook(&imq_ingress_ipv6); 267 | +err5: 268 | + nf_unregister_queue_handler(PF_INET6); 269 | +err4: 270 | + nf_unregister_hook(&imq_egress_ipv4); 271 | +#endif 272 | +err3: 273 | + nf_unregister_hook(&imq_ingress_ipv4); 274 | +err2: 275 | + nf_unregister_queue_handler(PF_INET); 276 | +err1: 277 | + return err; 278 | +} 279 | + 280 | +static void __exit imq_unhook(void) 281 | +{ 282 | + nf_unregister_hook(&imq_ingress_ipv4); 283 | + nf_unregister_hook(&imq_egress_ipv4); 284 | + nf_unregister_queue_handler(PF_INET); 285 | +#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) 286 | + nf_unregister_hook(&imq_ingress_ipv6); 287 | + nf_unregister_hook(&imq_egress_ipv6); 288 | + nf_unregister_queue_handler(PF_INET6); 289 | +#endif 290 | +} 291 | + 292 | +static int __init imq_dev_init(struct net_device *dev) 293 | +{ 294 | + dev->hard_start_xmit = imq_dev_xmit; 295 | + dev->type = ARPHRD_VOID; 296 | + dev->mtu = 1500; 297 | + dev->tx_queue_len = 30; 298 | + dev->flags = IFF_NOARP; 299 | + dev->priv = kmalloc(sizeof(struct net_device_stats), GFP_KERNEL); 300 | + if (dev->priv == NULL) 301 | + return -ENOMEM; 302 | + memset(dev->priv, 0, sizeof(struct net_device_stats)); 303 | + dev->get_stats = imq_get_stats; 304 | + 305 | + return 0; 306 | +} 307 | + 308 | +static void imq_dev_uninit(struct net_device *dev) 309 | +{ 310 | + kfree(dev->priv); 311 | +} 312 | + 313 | +static int __init imq_init_devs(void) 314 | +{ 315 | + struct net_device *dev; 316 | + int i; 317 | + 318 | + if (!numdevs || numdevs > IMQ_MAX_DEVS) { 319 | + printk(KERN_ERR "numdevs has to be betweed 1 and %u\n", 320 | + IMQ_MAX_DEVS); 321 | + return -EINVAL; 322 | + } 323 | + 324 | + imq_devs = kmalloc(sizeof(struct net_device) * numdevs, GFP_KERNEL); 325 | + if (!imq_devs) 326 | + return -ENOMEM; 327 | + memset(imq_devs, 0, sizeof(struct net_device) * numdevs); 328 | + 329 | + /* we start counting at zero */ 330 | + numdevs--; 331 | + 332 | + for (i = 0, dev = imq_devs; i <= numdevs; i++, dev++) { 333 | + SET_MODULE_OWNER(dev); 334 | + strcpy(dev->name, "imq%d"); 335 | + dev->init = imq_dev_init; 336 | + dev->uninit = imq_dev_uninit; 337 | + 338 | + if (register_netdev(dev) < 0) 339 | + goto err_register; 340 | + } 341 | + return 0; 342 | + 343 | +err_register: 344 | + for (; i; i--) 345 | + unregister_netdev(--dev); 346 | + kfree(imq_devs); 347 | + return -EIO; 348 | +} 349 | + 350 | +static void imq_cleanup_devs(void) 351 | +{ 352 | + int i; 353 | + struct net_device *dev = imq_devs; 354 | + 355 | + for (i = 0; i <= numdevs; i++) 356 | + unregister_netdev(dev++); 357 | + 358 | + kfree(imq_devs); 359 | +} 360 | + 361 | +static int __init imq_init_module(void) 362 | +{ 363 | + int err; 364 | + 365 | + if ((err = imq_init_devs())) 366 | + return err; 367 | + if ((err = imq_init_hooks())) { 368 | + imq_cleanup_devs(); 369 | + return err; 370 | + } 371 | + 372 | + printk(KERN_INFO "imq driver loaded.\n"); 373 | + 374 | + return 0; 375 | +} 376 | + 377 | +static void __exit imq_cleanup_module(void) 378 | +{ 379 | + imq_unhook(); 380 | + imq_cleanup_devs(); 381 | +} 382 | + 383 | +module_init(imq_init_module); 384 | +module_exit(imq_cleanup_module); 385 | +MODULE_LICENSE("GPL"); 386 | Index: include/linux/imq.h 387 | =================================================================== 388 | RCS file: include/linux/imq.h 389 | diff -N include/linux/imq.h 390 | --- /dev/null 1 Jan 1970 00:00:00 -0000 391 | +++ include/linux/imq.h 28 Jul 2003 23:08:07 -0000 392 | @@ -0,0 +1,9 @@ 393 | +#ifndef _IMQ_H 394 | +#define _IMQ_H 395 | + 396 | +#define IMQ_MAX_DEVS 16 397 | + 398 | +#define IMQ_F_IFMASK 0x7f 399 | +#define IMQ_F_ENQUEUE 0x80 400 | + 401 | +#endif /* _IMQ_H */ 402 | Index: include/linux/skbuff.h 403 | =================================================================== 404 | RCS file: /cvs/tgr/linux-26/include/linux/skbuff.h,v 405 | retrieving revision 1.1.1.1 406 | --- include/linux/skbuff.h.orig 2004-02-03 15:19:29.000000000 +0000 407 | +++ include/linux/skbuff.h 2004-02-03 15:44:00.000000000 +0000 408 | @@ -98,6 +98,11 @@ 409 | struct nf_conntrack *master; 410 | }; 411 | 412 | +#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 413 | +struct nf_info; 414 | +#endif 415 | + 416 | + 417 | #ifdef CONFIG_BRIDGE_NETFILTER 418 | struct nf_bridge_info { 419 | atomic_t use; 420 | @@ -261,6 +266,10 @@ 421 | #ifdef CONFIG_NET_SCHED 422 | __u32 tc_index; /* traffic control index */ 423 | #endif 424 | +#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 425 | + unsigned char imq_flags; /* intermediate queueing device */ 426 | + struct nf_info *nf_info; 427 | +#endif 428 | 429 | /* These elements must be at the end, see alloc_skb() for details. */ 430 | unsigned int truesize; 431 | Index: net/core/skbuff.c 432 | =================================================================== 433 | RCS file: /cvs/tgr/linux-26/net/core/skbuff.c,v 434 | retrieving revision 1.1.1.1 435 | diff -u -r1.1.1.1 skbuff.c 436 | --- net/core/skbuff.c 9 Jul 2003 18:42:29 -0000 1.1.1.1 437 | +++ net/core/skbuff.c 28 Jul 2003 23:08:07 -0000 438 | @@ -312,6 +312,10 @@ 439 | #ifdef CONFIG_NET_SCHED 440 | C(tc_index); 441 | #endif 442 | +#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 443 | + C(imq_flags); 444 | + C(nf_info); 445 | +#endif 446 | C(truesize); 447 | atomic_set(&n->users, 1); 448 | C(head); 449 | @@ -367,6 +371,12 @@ 450 | #ifdef CONFIG_NET_SCHED 451 | new->tc_index = old->tc_index; 452 | #endif 453 | +#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 454 | + new->imq_flags = old->imq_flags; 455 | + new->nf_info = old->nf_info; 456 | +#endif 457 | + 458 | + 459 | atomic_set(&new->users, 1); 460 | } 461 | 462 | Index: net/sched/sch_generic.c 463 | =================================================================== 464 | RCS file: /cvs/tgr/linux-26/net/sched/sch_generic.c,v 465 | retrieving revision 1.1.1.1 466 | diff -u -r1.1.1.1 sch_generic.c 467 | --- net/sched/sch_generic.c 9 Jul 2003 18:42:36 -0000 1.1.1.1 468 | +++ net/sched/sch_generic.c 28 Jul 2003 23:08:07 -0000 469 | @@ -30,6 +30,9 @@ 470 | #include 471 | #include 472 | #include 473 | +#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 474 | +#include 475 | +#endif 476 | #include 477 | #include 478 | 479 | @@ -90,7 +93,11 @@ 480 | spin_unlock(&dev->queue_lock); 481 | 482 | if (!netif_queue_stopped(dev)) { 483 | - if (netdev_nit) 484 | + if (netdev_nit 485 | +#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 486 | + && !(skb->imq_flags & IMQ_F_ENQUEUE) 487 | +#endif 488 | + ) 489 | dev_queue_xmit_nit(skb, dev); 490 | 491 | if (dev->hard_start_xmit(skb, dev) == 0) { 492 | -------------------------------------------------------------------------------- /kernel/v3.x/README: -------------------------------------------------------------------------------- 1 | Pseudo-driver for the intermediate queue device. 2 | ------------------------------------------------ 3 | 4 | 5 | Kernel version 3.x 6 | -all the patches in this folder are multi-queue (see https://github.com/imq/linuximq/wiki/FAQ for what is multi queue) 7 | 8 | -------------------------------------------------------------------------------- /kernel/v4.x/README: -------------------------------------------------------------------------------- 1 | Pseudo-driver for the intermediate queue device. 2 | ------------------------------------------------ 3 | 4 | 5 | Kernel version 4.x 6 | -all the patches in this folder are multi-queue 7 | --------------------------------------------------------------------------------