source:
npl/kernel/linux_src/linux-4.4.5-imq.diff
@
1051986
Last change on this file since 1051986 was c5c522c, checked in by , 8 years ago | |
---|---|
|
|
File size: 45.4 KB |
-
drivers/net/Kconfig
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index f184fb5..0e08522 100644
a b config RIONET_RX_SIZE 234 234 depends on RIONET 235 235 default "128" 236 236 237 config IMQ 238 tristate "IMQ (intermediate queueing device) support" 239 depends on NETDEVICES && NETFILTER 240 ---help--- 241 The IMQ device(s) is used as placeholder for QoS queueing 242 disciplines. Every packet entering/leaving the IP stack can be 243 directed through the IMQ device where it's enqueued/dequeued to the 244 attached qdisc. This allows you to treat network devices as classes 245 and distribute bandwidth among them. Iptables is used to specify 246 through which IMQ device, if any, packets travel. 247 248 More information at: https://github.com/imq/linuximq 249 250 To compile this driver as a module, choose M here: the module 251 will be called imq. If unsure, say N. 252 253 choice 254 prompt "IMQ behavior (PRE/POSTROUTING)" 255 depends on IMQ 256 default IMQ_BEHAVIOR_AB 257 help 258 This setting defines how IMQ behaves in respect to its 259 hooking in PREROUTING and POSTROUTING. 260 261 IMQ can work in any of the following ways: 262 263 PREROUTING | POSTROUTING 264 -----------------|------------------- 265 #1 After NAT | After NAT 266 #2 After NAT | Before NAT 267 #3 Before NAT | After NAT 268 #4 Before NAT | Before NAT 269 270 The default behavior is to hook before NAT on PREROUTING 271 and after NAT on POSTROUTING (#3). 272 273 This settings are specially usefull when trying to use IMQ 274 to shape NATed clients. 275 276 More information can be found at: https://github.com/imq/linuximq 277 278 If not sure leave the default settings alone. 279 280 config IMQ_BEHAVIOR_AA 281 bool "IMQ AA" 282 help 283 This setting defines how IMQ behaves in respect to its 284 hooking in PREROUTING and POSTROUTING. 285 286 Choosing this option will make IMQ hook like this: 287 288 PREROUTING: After NAT 289 POSTROUTING: After NAT 290 291 More information can be found at: https://github.com/imq/linuximq 292 293 If not sure leave the default settings alone. 294 295 config IMQ_BEHAVIOR_AB 296 bool "IMQ AB" 297 help 298 This setting defines how IMQ behaves in respect to its 299 hooking in PREROUTING and POSTROUTING. 300 301 Choosing this option will make IMQ hook like this: 302 303 PREROUTING: After NAT 304 POSTROUTING: Before NAT 305 306 More information can be found at: https://github.com/imq/linuximq 307 308 If not sure leave the default settings alone. 309 310 config IMQ_BEHAVIOR_BA 311 bool "IMQ BA" 312 help 313 This setting defines how IMQ behaves in respect to its 314 hooking in PREROUTING and POSTROUTING. 315 316 Choosing this option will make IMQ hook like this: 317 318 PREROUTING: Before NAT 319 POSTROUTING: After NAT 320 321 More information can be found at: https://github.com/imq/linuximq 322 323 If not sure leave the default settings alone. 324 325 config IMQ_BEHAVIOR_BB 326 bool "IMQ BB" 327 help 328 This setting defines how IMQ behaves in respect to its 329 hooking in PREROUTING and POSTROUTING. 330 331 Choosing this option will make IMQ hook like this: 332 333 PREROUTING: Before NAT 334 POSTROUTING: Before NAT 335 336 More information can be found at: https://github.com/imq/linuximq 337 338 If not sure leave the default settings alone. 339 340 endchoice 341 342 config IMQ_NUM_DEVS 343 int "Number of IMQ devices" 344 range 2 16 345 depends on IMQ 346 default "16" 347 help 348 This setting defines how many IMQ devices will be created. 349 350 The default value is 16. 351 352 More information can be found at: https://github.com/imq/linuximq 353 354 If not sure leave the default settings alone. 355 237 356 config TUN 238 357 tristate "Universal TUN/TAP device driver support" 239 358 depends on INET -
drivers/net/Makefile
diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 900b0c5..e093402 100644
a b obj-$(CONFIG_IPVLAN) += ipvlan/ 10 10 obj-$(CONFIG_DUMMY) += dummy.o 11 11 obj-$(CONFIG_EQUALIZER) += eql.o 12 12 obj-$(CONFIG_IFB) += ifb.o 13 obj-$(CONFIG_IMQ) += imq.o 13 14 obj-$(CONFIG_MACVLAN) += macvlan.o 14 15 obj-$(CONFIG_MACVTAP) += macvtap.o 15 16 obj-$(CONFIG_MII) += mii.o -
new file drivers/net/imq.c
diff --git a/drivers/net/imq.c b/drivers/net/imq.c new file mode 100644 index 0000000..f80258f
- + 1 /* 2 * Pseudo-driver for the intermediate queue device. 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License 6 * as published by the Free Software Foundation; either version 7 * 2 of the License, or (at your option) any later version. 8 * 9 * Authors: Patrick McHardy, <kaber@trash.net> 10 * 11 * The first version was written by Martin Devera, <devik@cdi.cz> 12 * 13 * See Creditis.txt 14 */ 15 16 #include <linux/module.h> 17 #include <linux/kernel.h> 18 #include <linux/moduleparam.h> 19 #include <linux/list.h> 20 #include <linux/skbuff.h> 21 #include <linux/netdevice.h> 22 #include <linux/etherdevice.h> 23 #include <linux/rtnetlink.h> 24 #include <linux/if_arp.h> 25 #include <linux/netfilter.h> 26 #include <linux/netfilter_ipv4.h> 27 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 28 #include <linux/netfilter_ipv6.h> 29 #endif 30 #include <linux/imq.h> 31 #include <net/pkt_sched.h> 32 #include <net/netfilter/nf_queue.h> 33 #include <net/sock.h> 34 #include <linux/ip.h> 35 #include <linux/ipv6.h> 36 #include <linux/if_vlan.h> 37 #include <linux/if_pppox.h> 38 #include <net/ip.h> 39 #include <net/ipv6.h> 40 41 static int imq_nf_queue(struct nf_queue_entry *entry, unsigned queue_num); 42 43 static nf_hookfn imq_nf_hook; 44 45 static struct nf_hook_ops imq_ops[] = { 46 { 47 /* imq_ingress_ipv4 */ 48 .hook = imq_nf_hook, 49 .pf = PF_INET, 50 .hooknum = NF_INET_PRE_ROUTING, 51 #if defined(CONFIG_IMQ_BEHAVIOR_BA) || defined(CONFIG_IMQ_BEHAVIOR_BB) 52 .priority = NF_IP_PRI_MANGLE + 1, 53 #else 54 .priority = NF_IP_PRI_NAT_DST + 1, 55 #endif 56 }, 57 { 58 /* imq_egress_ipv4 */ 59 .hook = imq_nf_hook, 60 .pf = PF_INET, 61 .hooknum = NF_INET_POST_ROUTING, 62 #if defined(CONFIG_IMQ_BEHAVIOR_AA) || defined(CONFIG_IMQ_BEHAVIOR_BA) 63 .priority = NF_IP_PRI_LAST, 64 #else 65 .priority = NF_IP_PRI_NAT_SRC - 1, 66 #endif 67 }, 68 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 69 { 70 /* imq_ingress_ipv6 */ 71 .hook = imq_nf_hook, 72 .pf = PF_INET6, 73 .hooknum = NF_INET_PRE_ROUTING, 74 #if defined(CONFIG_IMQ_BEHAVIOR_BA) || defined(CONFIG_IMQ_BEHAVIOR_BB) 75 .priority = NF_IP6_PRI_MANGLE + 1, 76 #else 77 .priority = NF_IP6_PRI_NAT_DST + 1, 78 #endif 79 }, 80 { 81 /* imq_egress_ipv6 */ 82 .hook = imq_nf_hook, 83 .pf = PF_INET6, 84 .hooknum = NF_INET_POST_ROUTING, 85 #if defined(CONFIG_IMQ_BEHAVIOR_AA) || defined(CONFIG_IMQ_BEHAVIOR_BA) 86 .priority = NF_IP6_PRI_LAST, 87 #else 88 .priority = NF_IP6_PRI_NAT_SRC - 1, 89 #endif 90 }, 91 #endif 92 }; 93 94 #if defined(CONFIG_IMQ_NUM_DEVS) 95 static int numdevs = CONFIG_IMQ_NUM_DEVS; 96 #else 97 static int numdevs = IMQ_MAX_DEVS; 98 #endif 99 100 static struct net_device *imq_devs_cache[IMQ_MAX_DEVS]; 101 102 #define IMQ_MAX_QUEUES 32 103 static int numqueues = 1; 104 static u32 imq_hashrnd; 105 static int imq_dev_accurate_stats = 1; 106 107 static inline __be16 pppoe_proto(const struct sk_buff *skb) 108 { 109 return *((__be16 *)(skb_mac_header(skb) + ETH_HLEN + 110 sizeof(struct pppoe_hdr))); 111 } 112 113 static u16 imq_hash(struct net_device *dev, struct sk_buff *skb) 114 { 115 unsigned int pull_len; 116 u16 protocol = skb->protocol; 117 u32 addr1, addr2; 118 u32 hash, ihl = 0; 119 union { 120 u16 in16[2]; 121 u32 in32; 122 } ports; 123 u8 ip_proto; 124 125 pull_len = 0; 126 127 recheck: 128 switch (protocol) { 129 case htons(ETH_P_8021Q): { 130 if (unlikely(skb_pull(skb, VLAN_HLEN) == NULL)) 131 goto other; 132 133 pull_len += VLAN_HLEN; 134 skb->network_header += VLAN_HLEN; 135 136 protocol = vlan_eth_hdr(skb)->h_vlan_encapsulated_proto; 137 goto recheck; 138 } 139 140 case htons(ETH_P_PPP_SES): { 141 if (unlikely(skb_pull(skb, PPPOE_SES_HLEN) == NULL)) 142 goto other; 143 144 pull_len += PPPOE_SES_HLEN; 145 skb->network_header += PPPOE_SES_HLEN; 146 147 protocol = pppoe_proto(skb); 148 goto recheck; 149 } 150 151 case htons(ETH_P_IP): { 152 const struct iphdr *iph = ip_hdr(skb); 153 154 if (unlikely(!pskb_may_pull(skb, sizeof(struct iphdr)))) 155 goto other; 156 157 addr1 = iph->daddr; 158 addr2 = iph->saddr; 159 160 ip_proto = !(ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) ? 161 iph->protocol : 0; 162 ihl = ip_hdrlen(skb); 163 164 break; 165 } 166 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 167 case htons(ETH_P_IPV6): { 168 const struct ipv6hdr *iph = ipv6_hdr(skb); 169 __be16 fo = 0; 170 171 if (unlikely(!pskb_may_pull(skb, sizeof(struct ipv6hdr)))) 172 goto other; 173 174 addr1 = iph->daddr.s6_addr32[3]; 175 addr2 = iph->saddr.s6_addr32[3]; 176 ihl = ipv6_skip_exthdr(skb, sizeof(struct ipv6hdr), &ip_proto, 177 &fo); 178 if (unlikely(ihl < 0)) 179 goto other; 180 181 break; 182 } 183 #endif 184 default: 185 other: 186 if (pull_len != 0) { 187 skb_push(skb, pull_len); 188 skb->network_header -= pull_len; 189 } 190 191 return (u16)(ntohs(protocol) % dev->real_num_tx_queues); 192 } 193 194 if (addr1 > addr2) 195 swap(addr1, addr2); 196 197 switch (ip_proto) { 198 case IPPROTO_TCP: 199 case IPPROTO_UDP: 200 case IPPROTO_DCCP: 201 case IPPROTO_ESP: 202 case IPPROTO_AH: 203 case IPPROTO_SCTP: 204 case IPPROTO_UDPLITE: { 205 if (likely(skb_copy_bits(skb, ihl, &ports.in32, 4) >= 0)) { 206 if (ports.in16[0] > ports.in16[1]) 207 swap(ports.in16[0], ports.in16[1]); 208 break; 209 } 210 /* fall-through */ 211 } 212 default: 213 ports.in32 = 0; 214 break; 215 } 216 217 if (pull_len != 0) { 218 skb_push(skb, pull_len); 219 skb->network_header -= pull_len; 220 } 221 222 hash = jhash_3words(addr1, addr2, ports.in32, imq_hashrnd ^ ip_proto); 223 224 return (u16)(((u64)hash * dev->real_num_tx_queues) >> 32); 225 } 226 227 static inline bool sk_tx_queue_recorded(struct sock *sk) 228 { 229 return (sk_tx_queue_get(sk) >= 0); 230 } 231 232 static struct netdev_queue *imq_select_queue(struct net_device *dev, 233 struct sk_buff *skb) 234 { 235 u16 queue_index = 0; 236 u32 hash; 237 238 if (likely(dev->real_num_tx_queues == 1)) 239 goto out; 240 241 /* IMQ can be receiving ingress or engress packets. */ 242 243 /* Check first for if rx_queue is set */ 244 if (skb_rx_queue_recorded(skb)) { 245 queue_index = skb_get_rx_queue(skb); 246 goto out; 247 } 248 249 /* Check if socket has tx_queue set */ 250 if (sk_tx_queue_recorded(skb->sk)) { 251 queue_index = sk_tx_queue_get(skb->sk); 252 goto out; 253 } 254 255 /* Try use socket hash */ 256 if (skb->sk && skb->sk->sk_hash) { 257 hash = skb->sk->sk_hash; 258 queue_index = 259 (u16)(((u64)hash * dev->real_num_tx_queues) >> 32); 260 goto out; 261 } 262 263 /* Generate hash from packet data */ 264 queue_index = imq_hash(dev, skb); 265 266 out: 267 if (unlikely(queue_index >= dev->real_num_tx_queues)) 268 queue_index = (u16)((u32)queue_index % dev->real_num_tx_queues); 269 270 skb_set_queue_mapping(skb, queue_index); 271 return netdev_get_tx_queue(dev, queue_index); 272 } 273 274 static struct net_device_stats *imq_get_stats(struct net_device *dev) 275 { 276 return &dev->stats; 277 } 278 279 /* called for packets kfree'd in qdiscs at places other than enqueue */ 280 static void imq_skb_destructor(struct sk_buff *skb) 281 { 282 struct nf_queue_entry *entry = skb->nf_queue_entry; 283 284 skb->nf_queue_entry = NULL; 285 286 if (entry) { 287 nf_queue_entry_release_refs(entry); 288 kfree(entry); 289 } 290 291 skb_restore_cb(skb); /* kfree backup */ 292 } 293 294 static void imq_done_check_queue_mapping(struct sk_buff *skb, 295 struct net_device *dev) 296 { 297 unsigned int queue_index; 298 299 /* Don't let queue_mapping be left too large after exiting IMQ */ 300 if (likely(skb->dev != dev && skb->dev != NULL)) { 301 queue_index = skb_get_queue_mapping(skb); 302 if (unlikely(queue_index >= skb->dev->real_num_tx_queues)) { 303 queue_index = (u16)((u32)queue_index % 304 skb->dev->real_num_tx_queues); 305 skb_set_queue_mapping(skb, queue_index); 306 } 307 } else { 308 /* skb->dev was IMQ device itself or NULL, be on safe side and 309 * just clear queue mapping. 310 */ 311 skb_set_queue_mapping(skb, 0); 312 } 313 } 314 315 static netdev_tx_t imq_dev_xmit(struct sk_buff *skb, struct net_device *dev) 316 { 317 struct nf_queue_entry *entry = skb->nf_queue_entry; 318 319 skb->nf_queue_entry = NULL; 320 dev->trans_start = jiffies; 321 322 dev->stats.tx_bytes += skb->len; 323 dev->stats.tx_packets++; 324 325 if (unlikely(entry == NULL)) { 326 /* We don't know what is going on here.. packet is queued for 327 * imq device, but (probably) not by us. 328 * 329 * If this packet was not send here by imq_nf_queue(), then 330 * skb_save_cb() was not used and skb_free() should not show: 331 * WARNING: IMQ: kfree_skb: skb->cb_next:.. 332 * and/or 333 * WARNING: IMQ: kfree_skb: skb->nf_queue_entry... 334 * 335 * However if this message is shown, then IMQ is somehow broken 336 * and you should report this to linuximq.net. 337 */ 338 339 /* imq_dev_xmit is black hole that eats all packets, report that 340 * we eat this packet happily and increase dropped counters. 341 */ 342 343 dev->stats.tx_dropped++; 344 dev_kfree_skb(skb); 345 346 return NETDEV_TX_OK; 347 } 348 349 skb_restore_cb(skb); /* restore skb->cb */ 350 351 skb->imq_flags = 0; 352 skb->destructor = NULL; 353 354 imq_done_check_queue_mapping(skb, dev); 355 356 nf_reinject(entry, NF_ACCEPT); 357 358 return NETDEV_TX_OK; 359 } 360 361 static struct net_device *get_imq_device_by_index(int index) 362 { 363 struct net_device *dev = NULL; 364 struct net *net; 365 char buf[8]; 366 367 /* get device by name and cache result */ 368 snprintf(buf, sizeof(buf), "imq%d", index); 369 370 /* Search device from all namespaces. */ 371 for_each_net(net) { 372 dev = dev_get_by_name(net, buf); 373 if (dev) 374 break; 375 } 376 377 if (WARN_ON_ONCE(dev == NULL)) { 378 /* IMQ device not found. Exotic config? */ 379 return ERR_PTR(-ENODEV); 380 } 381 382 imq_devs_cache[index] = dev; 383 dev_put(dev); 384 385 return dev; 386 } 387 388 static struct nf_queue_entry *nf_queue_entry_dup(struct nf_queue_entry *e) 389 { 390 struct nf_queue_entry *entry = kmemdup(e, e->size, GFP_ATOMIC); 391 if (entry) { 392 nf_queue_entry_get_refs(entry); 393 return entry; 394 } 395 return NULL; 396 } 397 398 #ifdef CONFIG_BRIDGE_NETFILTER 399 /* When called from bridge netfilter, skb->data must point to MAC header 400 * before calling skb_gso_segment(). Else, original MAC header is lost 401 * and segmented skbs will be sent to wrong destination. 402 */ 403 static void nf_bridge_adjust_skb_data(struct sk_buff *skb) 404 { 405 if (skb->nf_bridge) 406 __skb_push(skb, skb->network_header - skb->mac_header); 407 } 408 409 static void nf_bridge_adjust_segmented_data(struct sk_buff *skb) 410 { 411 if (skb->nf_bridge) 412 __skb_pull(skb, skb->network_header - skb->mac_header); 413 } 414 #else 415 #define nf_bridge_adjust_skb_data(s) do {} while (0) 416 #define nf_bridge_adjust_segmented_data(s) do {} while (0) 417 #endif 418 419 static void free_entry(struct nf_queue_entry *entry) 420 { 421 nf_queue_entry_release_refs(entry); 422 kfree(entry); 423 } 424 425 static int __imq_nf_queue(struct nf_queue_entry *entry, struct net_device *dev); 426 427 static int __imq_nf_queue_gso(struct nf_queue_entry *entry, 428 struct net_device *dev, struct sk_buff *skb) 429 { 430 int ret = -ENOMEM; 431 struct nf_queue_entry *entry_seg; 432 433 nf_bridge_adjust_segmented_data(skb); 434 435 if (skb->next == NULL) { /* last packet, no need to copy entry */ 436 struct sk_buff *gso_skb = entry->skb; 437 entry->skb = skb; 438 ret = __imq_nf_queue(entry, dev); 439 if (ret) 440 entry->skb = gso_skb; 441 return ret; 442 } 443 444 skb->next = NULL; 445 446 entry_seg = nf_queue_entry_dup(entry); 447 if (entry_seg) { 448 entry_seg->skb = skb; 449 ret = __imq_nf_queue(entry_seg, dev); 450 if (ret) 451 free_entry(entry_seg); 452 } 453 return ret; 454 } 455 456 static int imq_nf_queue(struct nf_queue_entry *entry, unsigned queue_num) 457 { 458 struct sk_buff *skb, *segs; 459 struct net_device *dev; 460 unsigned int queued; 461 int index, retval, err; 462 463 index = entry->skb->imq_flags & IMQ_F_IFMASK; 464 if (unlikely(index > numdevs - 1)) { 465 if (net_ratelimit()) 466 pr_warn("IMQ: invalid device specified, highest is %u\n", 467 numdevs - 1); 468 retval = -EINVAL; 469 goto out_no_dev; 470 } 471 472 /* check for imq device by index from cache */ 473 dev = imq_devs_cache[index]; 474 if (unlikely(!dev)) { 475 dev = get_imq_device_by_index(index); 476 if (IS_ERR(dev)) { 477 retval = PTR_ERR(dev); 478 goto out_no_dev; 479 } 480 } 481 482 if (unlikely(!(dev->flags & IFF_UP))) { 483 entry->skb->imq_flags = 0; 484 retval = -ECANCELED; 485 goto out_no_dev; 486 } 487 488 /* Since 3.10.x, GSO handling moved here as result of upstream commit 489 * a5fedd43d5f6c94c71053a66e4c3d2e35f1731a2 (netfilter: move 490 * skb_gso_segment into nfnetlink_queue module). 491 * 492 * Following code replicates the gso handling from 493 * 'net/netfilter/nfnetlink_queue_core.c':nfqnl_enqueue_packet(). 494 */ 495 496 skb = entry->skb; 497 498 switch (entry->state.pf) { 499 case NFPROTO_IPV4: 500 skb->protocol = htons(ETH_P_IP); 501 break; 502 case NFPROTO_IPV6: 503 skb->protocol = htons(ETH_P_IPV6); 504 break; 505 } 506 507 if (!skb_is_gso(entry->skb)) 508 return __imq_nf_queue(entry, dev); 509 510 nf_bridge_adjust_skb_data(skb); 511 segs = skb_gso_segment(skb, 0); 512 /* Does not use PTR_ERR to limit the number of error codes that can be 513 * returned by nf_queue. For instance, callers rely on -ECANCELED to 514 * mean 'ignore this hook'. 515 */ 516 err = -ENOBUFS; 517 if (IS_ERR(segs)) 518 goto out_err; 519 queued = 0; 520 err = 0; 521 do { 522 struct sk_buff *nskb = segs->next; 523 if (nskb && nskb->next) 524 nskb->cb_next = NULL; 525 if (err == 0) 526 err = __imq_nf_queue_gso(entry, dev, segs); 527 if (err == 0) 528 queued++; 529 else 530 kfree_skb(segs); 531 segs = nskb; 532 } while (segs); 533 534 if (queued) { 535 if (err) /* some segments are already queued */ 536 free_entry(entry); 537 kfree_skb(skb); 538 return 0; 539 } 540 541 out_err: 542 nf_bridge_adjust_segmented_data(skb); 543 retval = err; 544 out_no_dev: 545 return retval; 546 } 547 548 static int __imq_nf_queue(struct nf_queue_entry *entry, struct net_device *dev) 549 { 550 struct sk_buff *skb_orig, *skb, *skb_shared, *skb_popd; 551 struct Qdisc *q; 552 struct netdev_queue *txq; 553 spinlock_t *root_lock; 554 int users; 555 int retval = -EINVAL; 556 unsigned int orig_queue_index; 557 558 dev->last_rx = jiffies; 559 560 skb = entry->skb; 561 skb_orig = NULL; 562 563 /* skb has owner? => make clone */ 564 if (unlikely(skb->destructor)) { 565 skb_orig = skb; 566 skb = skb_clone(skb, GFP_ATOMIC); 567 if (unlikely(!skb)) { 568 retval = -ENOMEM; 569 goto out; 570 } 571 skb->cb_next = NULL; 572 entry->skb = skb; 573 } 574 575 dev->stats.rx_bytes += skb->len; 576 dev->stats.rx_packets++; 577 578 if (!skb->dev) { 579 /* skb->dev == NULL causes problems, try the find cause. */ 580 if (net_ratelimit()) { 581 dev_warn(&dev->dev, 582 "received packet with skb->dev == NULL\n"); 583 dump_stack(); 584 } 585 586 skb->dev = dev; 587 } 588 589 /* Disables softirqs for lock below */ 590 rcu_read_lock_bh(); 591 592 /* Multi-queue selection */ 593 orig_queue_index = skb_get_queue_mapping(skb); 594 txq = imq_select_queue(dev, skb); 595 596 q = rcu_dereference(txq->qdisc); 597 if (unlikely(!q->enqueue)) 598 goto packet_not_eaten_by_imq_dev; 599 600 skb->nf_queue_entry = entry; 601 root_lock = qdisc_lock(q); 602 spin_lock(root_lock); 603 604 users = atomic_read(&skb->users); 605 606 skb_shared = skb_get(skb); /* increase reference count by one */ 607 608 /* backup skb->cb, as qdisc layer will overwrite it */ 609 skb_save_cb(skb_shared); 610 qdisc_enqueue_root(skb_shared, q); /* might kfree_skb */ 611 if (likely(atomic_read(&skb_shared->users) == users + 1)) { 612 bool validate; 613 614 kfree_skb(skb_shared); /* decrease reference count by one */ 615 616 skb->destructor = &imq_skb_destructor; 617 618 skb_popd = qdisc_dequeue_skb(q, &validate); 619 620 /* cloned? */ 621 if (unlikely(skb_orig)) 622 kfree_skb(skb_orig); /* free original */ 623 624 spin_unlock(root_lock); 625 626 #if 0 627 /* schedule qdisc dequeue */ 628 __netif_schedule(q); 629 #else 630 if (likely(skb_popd)) { 631 /* Note that we validate skb (GSO, checksum, ...) outside of locks */ 632 if (validate) 633 skb_popd = validate_xmit_skb_list(skb_popd, dev); 634 635 if (skb_popd) { 636 int dummy_ret; 637 int cpu = smp_processor_id(); /* ok because BHs are off */ 638 639 txq = skb_get_tx_queue(dev, skb_popd); 640 /* 641 IMQ device will not be frozen or stoped, and it always be successful. 642 So we need not check its status and return value to accelerate. 643 */ 644 if (imq_dev_accurate_stats && txq->xmit_lock_owner != cpu) { 645 HARD_TX_LOCK(dev, txq, cpu); 646 if (!netif_xmit_frozen_or_stopped(txq)) { 647 dev_hard_start_xmit(skb_popd, dev, txq, &dummy_ret); 648 } 649 HARD_TX_UNLOCK(dev, txq); 650 } else { 651 if (!netif_xmit_frozen_or_stopped(txq)) { 652 dev_hard_start_xmit(skb_popd, dev, txq, &dummy_ret); 653 } 654 } 655 } 656 } else { 657 /* No ready skb, then schedule it */ 658 __netif_schedule(q); 659 } 660 #endif 661 rcu_read_unlock_bh(); 662 retval = 0; 663 goto out; 664 } else { 665 skb_restore_cb(skb_shared); /* restore skb->cb */ 666 skb->nf_queue_entry = NULL; 667 /* 668 * qdisc dropped packet and decreased skb reference count of 669 * skb, so we don't really want to and try refree as that would 670 * actually destroy the skb. 671 */ 672 spin_unlock(root_lock); 673 goto packet_not_eaten_by_imq_dev; 674 } 675 676 packet_not_eaten_by_imq_dev: 677 skb_set_queue_mapping(skb, orig_queue_index); 678 rcu_read_unlock_bh(); 679 680 /* cloned? restore original */ 681 if (unlikely(skb_orig)) { 682 kfree_skb(skb); 683 entry->skb = skb_orig; 684 } 685 retval = -1; 686 out: 687 return retval; 688 } 689 static unsigned int imq_nf_hook(void *priv, 690 struct sk_buff *skb, 691 const struct nf_hook_state *state) 692 { 693 return (skb->imq_flags & IMQ_F_ENQUEUE) ? NF_IMQ_QUEUE : NF_ACCEPT; 694 } 695 696 static int imq_close(struct net_device *dev) 697 { 698 netif_stop_queue(dev); 699 return 0; 700 } 701 702 static int imq_open(struct net_device *dev) 703 { 704 netif_start_queue(dev); 705 return 0; 706 } 707 708 static const struct net_device_ops imq_netdev_ops = { 709 .ndo_open = imq_open, 710 .ndo_stop = imq_close, 711 .ndo_start_xmit = imq_dev_xmit, 712 .ndo_get_stats = imq_get_stats, 713 }; 714 715 static void imq_setup(struct net_device *dev) 716 { 717 dev->netdev_ops = &imq_netdev_ops; 718 dev->type = ARPHRD_VOID; 719 dev->mtu = 16000; /* too small? */ 720 dev->tx_queue_len = 11000; /* too big? */ 721 dev->flags = IFF_NOARP; 722 dev->features = NETIF_F_SG | NETIF_F_FRAGLIST | 723 NETIF_F_GSO | NETIF_F_HW_CSUM | 724 NETIF_F_HIGHDMA; 725 dev->priv_flags &= ~(IFF_XMIT_DST_RELEASE | 726 IFF_TX_SKB_SHARING); 727 } 728 729 static int imq_validate(struct nlattr *tb[], struct nlattr *data[]) 730 { 731 int ret = 0; 732 733 if (tb[IFLA_ADDRESS]) { 734 if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN) { 735 ret = -EINVAL; 736 goto end; 737 } 738 if (!is_valid_ether_addr(nla_data(tb[IFLA_ADDRESS]))) { 739 ret = -EADDRNOTAVAIL; 740 goto end; 741 } 742 } 743 return 0; 744 end: 745 pr_warn("IMQ: imq_validate failed (%d)\n", ret); 746 return ret; 747 } 748 749 static struct rtnl_link_ops imq_link_ops __read_mostly = { 750 .kind = "imq", 751 .priv_size = 0, 752 .setup = imq_setup, 753 .validate = imq_validate, 754 }; 755 756 static const struct nf_queue_handler imq_nfqh = { 757 .outfn = imq_nf_queue, 758 }; 759 760 static int __init imq_init_hooks(void) 761 { 762 int ret; 763 764 nf_register_queue_imq_handler(&imq_nfqh); 765 766 ret = nf_register_hooks(imq_ops, ARRAY_SIZE(imq_ops)); 767 if (ret < 0) 768 nf_unregister_queue_imq_handler(); 769 770 return ret; 771 } 772 773 static int __init imq_init_one(int index) 774 { 775 struct net_device *dev; 776 int ret; 777 778 dev = alloc_netdev_mq(0, "imq%d", NET_NAME_UNKNOWN, imq_setup, numqueues); 779 if (!dev) 780 return -ENOMEM; 781 782 ret = dev_alloc_name(dev, dev->name); 783 if (ret < 0) 784 goto fail; 785 786 dev->rtnl_link_ops = &imq_link_ops; 787 ret = register_netdevice(dev); 788 if (ret < 0) 789 goto fail; 790 791 return 0; 792 fail: 793 free_netdev(dev); 794 return ret; 795 } 796 797 static int __init imq_init_devs(void) 798 { 799 int err, i; 800 801 if (numdevs < 1 || numdevs > IMQ_MAX_DEVS) { 802 pr_err("IMQ: numdevs has to be betweed 1 and %u\n", 803 IMQ_MAX_DEVS); 804 return -EINVAL; 805 } 806 807 if (numqueues < 1 || numqueues > IMQ_MAX_QUEUES) { 808 pr_err("IMQ: numqueues has to be betweed 1 and %u\n", 809 IMQ_MAX_QUEUES); 810 return -EINVAL; 811 } 812 813 get_random_bytes(&imq_hashrnd, sizeof(imq_hashrnd)); 814 815 rtnl_lock(); 816 err = __rtnl_link_register(&imq_link_ops); 817 818 for (i = 0; i < numdevs && !err; i++) 819 err = imq_init_one(i); 820 821 if (err) { 822 __rtnl_link_unregister(&imq_link_ops); 823 memset(imq_devs_cache, 0, sizeof(imq_devs_cache)); 824 } 825 rtnl_unlock(); 826 827 return err; 828 } 829 830 static int __init imq_init_module(void) 831 { 832 int err; 833 834 #if defined(CONFIG_IMQ_NUM_DEVS) 835 BUILD_BUG_ON(CONFIG_IMQ_NUM_DEVS > 16); 836 BUILD_BUG_ON(CONFIG_IMQ_NUM_DEVS < 2); 837 BUILD_BUG_ON(CONFIG_IMQ_NUM_DEVS - 1 > IMQ_F_IFMASK); 838 #endif 839 840 err = imq_init_devs(); 841 if (err) { 842 pr_err("IMQ: Error trying imq_init_devs(net)\n"); 843 return err; 844 } 845 846 err = imq_init_hooks(); 847 if (err) { 848 pr_err(KERN_ERR "IMQ: Error trying imq_init_hooks()\n"); 849 rtnl_link_unregister(&imq_link_ops); 850 memset(imq_devs_cache, 0, sizeof(imq_devs_cache)); 851 return err; 852 } 853 854 pr_info("IMQ driver loaded successfully. (numdevs = %d, numqueues = %d, imq_dev_accurate_stats = %d)\n", 855 numdevs, numqueues, imq_dev_accurate_stats); 856 857 #if defined(CONFIG_IMQ_BEHAVIOR_BA) || defined(CONFIG_IMQ_BEHAVIOR_BB) 858 pr_info("\tHooking IMQ before NAT on PREROUTING.\n"); 859 #else 860 pr_info("\tHooking IMQ after NAT on PREROUTING.\n"); 861 #endif 862 #if defined(CONFIG_IMQ_BEHAVIOR_AB) || defined(CONFIG_IMQ_BEHAVIOR_BB) 863 pr_info("\tHooking IMQ before NAT on POSTROUTING.\n"); 864 #else 865 pr_info("\tHooking IMQ after NAT on POSTROUTING.\n"); 866 #endif 867 868 return 0; 869 } 870 871 static void __exit imq_unhook(void) 872 { 873 nf_unregister_hooks(imq_ops, ARRAY_SIZE(imq_ops)); 874 nf_unregister_queue_imq_handler(); 875 } 876 877 static void __exit imq_cleanup_devs(void) 878 { 879 rtnl_link_unregister(&imq_link_ops); 880 memset(imq_devs_cache, 0, sizeof(imq_devs_cache)); 881 } 882 883 static void __exit imq_exit_module(void) 884 { 885 imq_unhook(); 886 imq_cleanup_devs(); 887 pr_info("IMQ driver unloaded successfully.\n"); 888 } 889 890 module_init(imq_init_module); 891 module_exit(imq_exit_module); 892 893 module_param(numdevs, int, 0); 894 module_param(numqueues, int, 0); 895 module_param(imq_dev_accurate_stats, int, 0); 896 MODULE_PARM_DESC(numdevs, "number of IMQ devices (how many imq* devices will be created)"); 897 MODULE_PARM_DESC(numqueues, "number of queues per IMQ device"); 898 MODULE_PARM_DESC(imq_dev_accurate_stats, "Notify if need the accurate imq device stats"); 899 900 MODULE_AUTHOR("http://https://github.com/imq/linuximq"); 901 MODULE_DESCRIPTION("Pseudo-driver for the intermediate queue device. See https://github.com/imq/linuximq/wiki for more information."); 902 MODULE_LICENSE("GPL"); 903 MODULE_ALIAS_RTNL_LINK("imq"); -
new file include/linux/imq.h
diff --git a/include/linux/imq.h b/include/linux/imq.h new file mode 100644 index 0000000..1babb09
- + 1 #ifndef _IMQ_H 2 #define _IMQ_H 3 4 /* IFMASK (16 device indexes, 0 to 15) and flag(s) fit in 5 bits */ 5 #define IMQ_F_BITS 5 6 7 #define IMQ_F_IFMASK 0x0f 8 #define IMQ_F_ENQUEUE 0x10 9 10 #define IMQ_MAX_DEVS (IMQ_F_IFMASK + 1) 11 12 #endif /* _IMQ_H */ 13 -
include/linux/netdevice.h
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 3143c84..e213b31 100644
a b static inline void netif_tx_unlock_bh(struct net_device *dev) 3341 3341 } \ 3342 3342 } 3343 3343 3344 #define HARD_TX_LOCK_BH(dev, txq) { \ 3345 if ((dev->features & NETIF_F_LLTX) == 0) { \ 3346 __netif_tx_lock_bh(txq); \ 3347 } \ 3348 } 3349 3350 #define HARD_TX_UNLOCK_BH(dev, txq) { \ 3351 if ((dev->features & NETIF_F_LLTX) == 0) { \ 3352 __netif_tx_unlock_bh(txq); \ 3353 } \ 3354 } 3355 3356 3344 3357 static inline void netif_tx_disable(struct net_device *dev) 3345 3358 { 3346 3359 unsigned int i; -
new file include/linux/netfilter/xt_IMQ.h
diff --git a/include/linux/netfilter/xt_IMQ.h b/include/linux/netfilter/xt_IMQ.h new file mode 100644 index 0000000..9b07230
- + 1 #ifndef _XT_IMQ_H 2 #define _XT_IMQ_H 3 4 struct xt_imq_info { 5 unsigned int todev; /* target imq device */ 6 }; 7 8 #endif /* _XT_IMQ_H */ 9 -
new file include/linux/netfilter_ipv4/ipt_IMQ.h
diff --git a/include/linux/netfilter_ipv4/ipt_IMQ.h b/include/linux/netfilter_ipv4/ipt_IMQ.h new file mode 100644 index 0000000..7af320f
- + 1 #ifndef _IPT_IMQ_H 2 #define _IPT_IMQ_H 3 4 /* Backwards compatibility for old userspace */ 5 #include <linux/netfilter/xt_IMQ.h> 6 7 #define ipt_imq_info xt_imq_info 8 9 #endif /* _IPT_IMQ_H */ 10 -
new file include/linux/netfilter_ipv6/ip6t_IMQ.h
diff --git a/include/linux/netfilter_ipv6/ip6t_IMQ.h b/include/linux/netfilter_ipv6/ip6t_IMQ.h new file mode 100644 index 0000000..198ac01
- + 1 #ifndef _IP6T_IMQ_H 2 #define _IP6T_IMQ_H 3 4 /* Backwards compatibility for old userspace */ 5 #include <linux/netfilter/xt_IMQ.h> 6 7 #define ip6t_imq_info xt_imq_info 8 9 #endif /* _IP6T_IMQ_H */ 10 -
include/linux/skbuff.h
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 4355129..47914c0 100644
a b 38 38 #include <linux/splice.h> 39 39 #include <linux/in6.h> 40 40 #include <net/flow.h> 41 #if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 42 #include <linux/imq.h> 43 #endif 44 41 45 42 46 /* A. Checksumming of received packets by device. 43 47 * … … struct sk_buff { 566 570 * first. This is owned by whoever has the skb queued ATM. 567 571 */ 568 572 char cb[48] __aligned(8); 573 #if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 574 void *cb_next; 575 #endif 569 576 570 577 unsigned long _skb_refdst; 571 578 void (*destructor)(struct sk_buff *skb); … … struct sk_buff { 575 582 #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) 576 583 struct nf_conntrack *nfct; 577 584 #endif 585 #if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 586 struct nf_queue_entry *nf_queue_entry; 587 #endif 578 588 #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER) 579 589 struct nf_bridge_info *nf_bridge; 580 590 #endif … … struct sk_buff { 642 652 __u8 inner_protocol_type:1; 643 653 __u8 remcsum_offload:1; 644 654 /* 3 or 5 bit hole */ 655 #if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 656 __u8 imq_flags:IMQ_F_BITS; 657 #endif 645 658 646 659 #ifdef CONFIG_NET_SCHED 647 660 __u16 tc_index; /* traffic control index */ … … void kfree_skb_list(struct sk_buff *segs); 798 811 void skb_tx_error(struct sk_buff *skb); 799 812 void consume_skb(struct sk_buff *skb); 800 813 void __kfree_skb(struct sk_buff *skb); 814 815 #if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 816 int skb_save_cb(struct sk_buff *skb); 817 int skb_restore_cb(struct sk_buff *skb); 818 #endif 819 801 820 extern struct kmem_cache *skbuff_head_cache; 802 821 803 822 void kfree_skb_partial(struct sk_buff *skb, bool head_stolen); … … static inline void __nf_copy(struct sk_buff *dst, const struct sk_buff *src, 3344 3363 if (copy) 3345 3364 dst->nfctinfo = src->nfctinfo; 3346 3365 #endif 3366 #if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 3367 dst->imq_flags = src->imq_flags; 3368 dst->nf_queue_entry = src->nf_queue_entry; 3369 #endif 3347 3370 #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER) 3348 3371 dst->nf_bridge = src->nf_bridge; 3349 3372 nf_bridge_get(src->nf_bridge); -
include/net/netfilter/nf_queue.h
diff --git a/include/net/netfilter/nf_queue.h b/include/net/netfilter/nf_queue.h index 9c5638a..b173aa7 100644
a b struct nf_queue_handler { 31 31 void nf_register_queue_handler(const struct nf_queue_handler *qh); 32 32 void nf_unregister_queue_handler(void); 33 33 void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict); 34 void nf_queue_entry_release_refs(struct nf_queue_entry *entry); 35 36 #if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 37 void nf_register_queue_imq_handler(const struct nf_queue_handler *qh); 38 void nf_unregister_queue_imq_handler(void); 39 #endif 34 40 35 41 void nf_queue_entry_get_refs(struct nf_queue_entry *entry); 36 42 void nf_queue_entry_release_refs(struct nf_queue_entry *entry); -
include/net/pkt_sched.h
diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h index 401038d..4668849 100644
a b int sch_direct_xmit(struct sk_buff *skb, struct Qdisc *q, 104 104 105 105 void __qdisc_run(struct Qdisc *q); 106 106 107 struct sk_buff *qdisc_dequeue_skb(struct Qdisc *q, bool *validate); 108 107 109 static inline void qdisc_run(struct Qdisc *q) 108 110 { 109 111 if (qdisc_run_begin(q)) -
include/net/sch_generic.h
diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h index b2a8e63..d9feaa3 100644
a b static inline int qdisc_enqueue(struct sk_buff *skb, struct Qdisc *sch) 506 506 return sch->enqueue(skb, sch); 507 507 } 508 508 509 static inline int qdisc_enqueue_root(struct sk_buff *skb, struct Qdisc *sch) 510 { 511 qdisc_skb_cb(skb)->pkt_len = skb->len; 512 return qdisc_enqueue(skb, sch) & NET_XMIT_MASK; 513 } 514 509 515 static inline bool qdisc_is_percpu_stats(const struct Qdisc *q) 510 516 { 511 517 return q->flags & TCQ_F_CPUSTATS; -
include/uapi/linux/netfilter.h
diff --git a/include/uapi/linux/netfilter.h b/include/uapi/linux/netfilter.h index d93f949..23fb6d1 100644
a b 14 14 #define NF_QUEUE 3 15 15 #define NF_REPEAT 4 16 16 #define NF_STOP 5 17 #define NF_MAX_VERDICT NF_STOP 17 #define NF_IMQ_QUEUE 6 18 #define NF_MAX_VERDICT NF_IMQ_QUEUE 18 19 19 20 /* we overload the higher bits for encoding auxiliary data such as the queue 20 21 * number or errno values. Not nice, but better than additional function -
net/core/dev.c
diff --git a/net/core/dev.c b/net/core/dev.c index ae00b89..1cdcd02 100644
a b 137 137 #include <linux/errqueue.h> 138 138 #include <linux/hrtimer.h> 139 139 #include <linux/netfilter_ingress.h> 140 #if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 141 #include <linux/imq.h> 142 #endif 140 143 141 144 #include "net-sysfs.h" 142 145 … … static int xmit_one(struct sk_buff *skb, struct net_device *dev, 2705 2708 unsigned int len; 2706 2709 int rc; 2707 2710 2711 #if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 2712 if ((!list_empty(&ptype_all) || !list_empty(&dev->ptype_all)) && 2713 !(skb->imq_flags & IMQ_F_ENQUEUE)) 2714 #else 2708 2715 if (!list_empty(&ptype_all) || !list_empty(&dev->ptype_all)) 2716 #endif 2709 2717 dev_queue_xmit_nit(skb, dev); 2710 2718 2711 2719 len = skb->len; … … out: 2743 2751 *ret = rc; 2744 2752 return skb; 2745 2753 } 2754 EXPORT_SYMBOL(dev_hard_start_xmit); 2746 2755 2747 2756 static struct sk_buff *validate_xmit_vlan(struct sk_buff *skb, 2748 2757 netdev_features_t features) … … struct sk_buff *validate_xmit_skb_list(struct sk_buff *skb, struct net_device *d 2831 2840 } 2832 2841 return head; 2833 2842 } 2843 //EXPORT_SYMBOL(validate_xmit_skb_list); 2834 2844 2835 2845 static void qdisc_pkt_len_init(struct sk_buff *skb) 2836 2846 { -
net/core/skbuff.c
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index b2df375..bc3c51e 100644
a b 79 79 static struct kmem_cache *skbuff_fclone_cache __read_mostly; 80 80 int sysctl_max_skb_frags __read_mostly = MAX_SKB_FRAGS; 81 81 EXPORT_SYMBOL(sysctl_max_skb_frags); 82 #if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 83 static struct kmem_cache *skbuff_cb_store_cache __read_mostly; 84 #endif 85 86 #if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 87 /* Control buffer save/restore for IMQ devices */ 88 struct skb_cb_table { 89 char cb[48] __aligned(8); 90 void *cb_next; 91 atomic_t refcnt; 92 }; 93 94 static DEFINE_SPINLOCK(skb_cb_store_lock); 95 96 int skb_save_cb(struct sk_buff *skb) 97 { 98 struct skb_cb_table *next; 99 100 next = kmem_cache_alloc(skbuff_cb_store_cache, GFP_ATOMIC); 101 if (!next) 102 return -ENOMEM; 103 104 BUILD_BUG_ON(sizeof(skb->cb) != sizeof(next->cb)); 105 106 memcpy(next->cb, skb->cb, sizeof(skb->cb)); 107 next->cb_next = skb->cb_next; 108 109 atomic_set(&next->refcnt, 1); 110 111 skb->cb_next = next; 112 return 0; 113 } 114 EXPORT_SYMBOL(skb_save_cb); 115 116 int skb_restore_cb(struct sk_buff *skb) 117 { 118 struct skb_cb_table *next; 119 120 if (!skb->cb_next) 121 return 0; 122 123 next = skb->cb_next; 124 125 BUILD_BUG_ON(sizeof(skb->cb) != sizeof(next->cb)); 126 127 memcpy(skb->cb, next->cb, sizeof(skb->cb)); 128 skb->cb_next = next->cb_next; 129 130 spin_lock(&skb_cb_store_lock); 131 132 if (atomic_dec_and_test(&next->refcnt)) 133 kmem_cache_free(skbuff_cb_store_cache, next); 134 135 spin_unlock(&skb_cb_store_lock); 136 137 return 0; 138 } 139 EXPORT_SYMBOL(skb_restore_cb); 140 141 static void skb_copy_stored_cb(struct sk_buff * , const struct sk_buff * ) __attribute__ ((unused)); 142 static void skb_copy_stored_cb(struct sk_buff *new, const struct sk_buff *__old) 143 { 144 struct skb_cb_table *next; 145 struct sk_buff *old; 146 147 if (!__old->cb_next) { 148 new->cb_next = NULL; 149 return; 150 } 151 152 spin_lock(&skb_cb_store_lock); 153 154 old = (struct sk_buff *)__old; 155 156 next = old->cb_next; 157 atomic_inc(&next->refcnt); 158 new->cb_next = next; 159 160 spin_unlock(&skb_cb_store_lock); 161 } 162 #endif 82 163 83 164 /** 84 165 * skb_panic - private function for out-of-line support … … static void skb_release_head_state(struct sk_buff *skb) 643 724 WARN_ON(in_irq()); 644 725 skb->destructor(skb); 645 726 } 727 #if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 728 /* 729 * This should not happen. When it does, avoid memleak by restoring 730 * the chain of cb-backups. 731 */ 732 while (skb->cb_next != NULL) { 733 if (net_ratelimit()) 734 pr_warn("IMQ: kfree_skb: skb->cb_next: %08x\n", 735 (unsigned int)(uintptr_t)skb->cb_next); 736 737 skb_restore_cb(skb); 738 } 739 /* 740 * This should not happen either, nf_queue_entry is nullified in 741 * imq_dev_xmit(). If we have non-NULL nf_queue_entry then we are 742 * leaking entry pointers, maybe memory. We don't know if this is 743 * pointer to already freed memory, or should this be freed. 744 * If this happens we need to add refcounting, etc for nf_queue_entry. 745 */ 746 if (skb->nf_queue_entry && net_ratelimit()) 747 pr_warn("%s\n", "IMQ: kfree_skb: skb->nf_queue_entry != NULL"); 748 #endif 646 749 #if IS_ENABLED(CONFIG_NF_CONNTRACK) 647 750 nf_conntrack_put(skb->nfct); 648 751 #endif … … static void __copy_skb_header(struct sk_buff *new, const struct sk_buff *old) 765 868 new->sp = secpath_get(old->sp); 766 869 #endif 767 870 __nf_copy(new, old, false); 871 #if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 872 new->cb_next = NULL; 873 /*skb_copy_stored_cb(new, old);*/ 874 #endif 768 875 769 876 /* Note : this field could be in headers_start/headers_end section 770 877 * It is not yet because we do not want to have a 16 bit hole … … void __init skb_init(void) 3325 3432 0, 3326 3433 SLAB_HWCACHE_ALIGN|SLAB_PANIC, 3327 3434 NULL); 3435 #if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 3436 skbuff_cb_store_cache = kmem_cache_create("skbuff_cb_store_cache", 3437 sizeof(struct skb_cb_table), 3438 0, 3439 SLAB_HWCACHE_ALIGN|SLAB_PANIC, 3440 NULL); 3441 #endif 3328 3442 } 3329 3443 3330 3444 /** -
net/ipv6/ip6_output.c
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index e6a7bd15..c81496e 100644
a b static int ip6_finish_output2(struct net *net, struct sock *sk, struct sk_buff * 65 65 struct in6_addr *nexthop; 66 66 int ret; 67 67 68 skb->protocol = htons(ETH_P_IPV6);69 skb->dev = dev;70 71 68 if (ipv6_addr_is_multicast(&ipv6_hdr(skb)->daddr)) { 72 69 struct inet6_dev *idev = ip6_dst_idev(skb_dst(skb)); 73 70 … … int ip6_output(struct net *net, struct sock *sk, struct sk_buff *skb) 142 139 return 0; 143 140 } 144 141 142 /* 143 * IMQ-patch: moved setting skb->dev and skb->protocol from 144 * ip6_finish_output2 to fix crashing at netif_skb_features(). 145 */ 146 skb->protocol = htons(ETH_P_IPV6); 147 skb->dev = dev; 148 145 149 return NF_HOOK_COND(NFPROTO_IPV6, NF_INET_POST_ROUTING, 146 150 net, sk, skb, NULL, dev, 147 151 ip6_finish_output, -
net/netfilter/Kconfig
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig index 4692782..dce47db 100644
a b config NETFILTER_XT_TARGET_LOG 785 785 786 786 To compile it as a module, choose M here. If unsure, say N. 787 787 788 config NETFILTER_XT_TARGET_IMQ 789 tristate '"IMQ" target support' 790 depends on NETFILTER_XTABLES 791 depends on IP_NF_MANGLE || IP6_NF_MANGLE 792 select IMQ 793 default m if NETFILTER_ADVANCED=n 794 help 795 This option adds a `IMQ' target which is used to specify if and 796 to which imq device packets should get enqueued/dequeued. 797 798 To compile it as a module, choose M here. If unsure, say N. 799 788 800 config NETFILTER_XT_TARGET_MARK 789 801 tristate '"MARK" target support' 790 802 depends on NETFILTER_ADVANCED -
net/netfilter/Makefile
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile index 7638c36..614ad8a 100644
a b obj-$(CONFIG_NETFILTER_XT_TARGET_CT) += xt_CT.o 108 108 obj-$(CONFIG_NETFILTER_XT_TARGET_DSCP) += xt_DSCP.o 109 109 obj-$(CONFIG_NETFILTER_XT_TARGET_HL) += xt_HL.o 110 110 obj-$(CONFIG_NETFILTER_XT_TARGET_HMARK) += xt_HMARK.o 111 obj-$(CONFIG_NETFILTER_XT_TARGET_IMQ) += xt_IMQ.o 111 112 obj-$(CONFIG_NETFILTER_XT_TARGET_LED) += xt_LED.o 112 113 obj-$(CONFIG_NETFILTER_XT_TARGET_LOG) += xt_LOG.o 113 114 obj-$(CONFIG_NETFILTER_XT_TARGET_NETMAP) += xt_NETMAP.o -
net/netfilter/core.c
diff --git a/net/netfilter/core.c b/net/netfilter/core.c index f39276d..9877a27 100644
a b next_hook: 311 311 ret = NF_DROP_GETERR(verdict); 312 312 if (ret == 0) 313 313 ret = -EPERM; 314 } else if ((verdict & NF_VERDICT_MASK) == NF_QUEUE) { 314 } else if ((verdict & NF_VERDICT_MASK) == NF_QUEUE || 315 (verdict & NF_VERDICT_MASK) == NF_IMQ_QUEUE) { 315 316 int err = nf_queue(skb, elem, state, 316 verdict >> NF_VERDICT_QBITS); 317 verdict >> NF_VERDICT_QBITS, 318 verdict & NF_VERDICT_MASK); 317 319 if (err < 0) { 318 320 if (err == -ESRCH && 319 321 (verdict & NF_VERDICT_FLAG_QUEUE_BYPASS)) -
net/netfilter/nf_internals.h
diff --git a/net/netfilter/nf_internals.h b/net/netfilter/nf_internals.h index 0655225..25d4141 100644
a b unsigned int nf_iterate(struct list_head *head, struct sk_buff *skb, 18 18 19 19 /* nf_queue.c */ 20 20 int nf_queue(struct sk_buff *skb, struct nf_hook_ops *elem, 21 struct nf_hook_state *state, unsigned int queuenum );21 struct nf_hook_state *state, unsigned int queuenum, unsigned int queuetype); 22 22 void nf_queue_nf_hook_drop(struct net *net, struct nf_hook_ops *ops); 23 23 int __init netfilter_queue_init(void); 24 24 -
net/netfilter/nf_queue.c
diff --git a/net/netfilter/nf_queue.c b/net/netfilter/nf_queue.c index 5baa8e2..9740e8c 100644
a b 28 28 */ 29 29 static const struct nf_queue_handler __rcu *queue_handler __read_mostly; 30 30 31 #if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 32 static const struct nf_queue_handler __rcu *queue_imq_handler __read_mostly; 33 34 void nf_register_queue_imq_handler(const struct nf_queue_handler *qh) 35 { 36 rcu_assign_pointer(queue_imq_handler, qh); 37 } 38 EXPORT_SYMBOL_GPL(nf_register_queue_imq_handler); 39 40 void nf_unregister_queue_imq_handler(void) 41 { 42 RCU_INIT_POINTER(queue_imq_handler, NULL); 43 synchronize_rcu(); 44 } 45 EXPORT_SYMBOL_GPL(nf_unregister_queue_imq_handler); 46 #endif 47 31 48 /* return EBUSY when somebody else is registered, return EEXIST if the 32 49 * same handler is registered, return 0 in case of success. */ 33 50 void nf_register_queue_handler(const struct nf_queue_handler *qh) … … void nf_queue_nf_hook_drop(struct net *net, struct nf_hook_ops *ops) 116 133 int nf_queue(struct sk_buff *skb, 117 134 struct nf_hook_ops *elem, 118 135 struct nf_hook_state *state, 119 unsigned int queuenum) 136 unsigned int queuenum, 137 unsigned int queuetype) 120 138 { 121 139 int status = -ENOENT; 122 140 struct nf_queue_entry *entry = NULL; … … int nf_queue(struct sk_buff *skb, 124 142 const struct nf_queue_handler *qh; 125 143 126 144 /* QUEUE == DROP if no one is waiting, to be safe. */ 127 qh = rcu_dereference(queue_handler); 145 if (queuetype == NF_IMQ_QUEUE) { 146 #if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) 147 qh = rcu_dereference(queue_imq_handler); 148 #else 149 BUG(); 150 goto err_unlock; 151 #endif 152 } else { 153 qh = rcu_dereference(queue_handler); 154 } 155 128 156 if (!qh) { 129 157 status = -ESRCH; 130 158 goto err; … … void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict) 199 227 local_bh_enable(); 200 228 break; 201 229 case NF_QUEUE: 230 case NF_IMQ_QUEUE: 202 231 err = nf_queue(skb, elem, &entry->state, 203 verdict >> NF_VERDICT_QBITS); 232 verdict >> NF_VERDICT_QBITS, 233 verdict & NF_VERDICT_MASK); 204 234 if (err < 0) { 205 235 if (err == -ESRCH && 206 236 (verdict & NF_VERDICT_FLAG_QUEUE_BYPASS)) -
new file net/netfilter/xt_IMQ.c
diff --git a/net/netfilter/xt_IMQ.c b/net/netfilter/xt_IMQ.c new file mode 100644 index 0000000..86d7b84
- + 1 /* 2 * This target marks packets to be enqueued to an imq device 3 */ 4 #include <linux/module.h> 5 #include <linux/skbuff.h> 6 #include <linux/netfilter/x_tables.h> 7 #include <linux/netfilter/xt_IMQ.h> 8 #include <linux/imq.h> 9 10 static unsigned int imq_target(struct sk_buff *pskb, 11 const struct xt_action_param *par) 12 { 13 const struct xt_imq_info *mr = par->targinfo; 14 15 pskb->imq_flags = (mr->todev & IMQ_F_IFMASK) | IMQ_F_ENQUEUE; 16 17 return XT_CONTINUE; 18 } 19 20 static int imq_checkentry(const struct xt_tgchk_param *par) 21 { 22 struct xt_imq_info *mr = par->targinfo; 23 24 if (mr->todev > IMQ_MAX_DEVS - 1) { 25 pr_warn("IMQ: invalid device specified, highest is %u\n", 26 IMQ_MAX_DEVS - 1); 27 return -EINVAL; 28 } 29 30 return 0; 31 } 32 33 static struct xt_target xt_imq_reg[] __read_mostly = { 34 { 35 .name = "IMQ", 36 .family = AF_INET, 37 .checkentry = imq_checkentry, 38 .target = imq_target, 39 .targetsize = sizeof(struct xt_imq_info), 40 .table = "mangle", 41 .me = THIS_MODULE 42 }, 43 { 44 .name = "IMQ", 45 .family = AF_INET6, 46 .checkentry = imq_checkentry, 47 .target = imq_target, 48 .targetsize = sizeof(struct xt_imq_info), 49 .table = "mangle", 50 .me = THIS_MODULE 51 }, 52 }; 53 54 static int __init imq_init(void) 55 { 56 return xt_register_targets(xt_imq_reg, ARRAY_SIZE(xt_imq_reg)); 57 } 58 59 static void __exit imq_fini(void) 60 { 61 xt_unregister_targets(xt_imq_reg, ARRAY_SIZE(xt_imq_reg)); 62 } 63 64 module_init(imq_init); 65 module_exit(imq_fini); 66 67 MODULE_AUTHOR("http://https://github.com/imq/linuximq"); 68 MODULE_DESCRIPTION("Pseudo-driver for the intermediate queue device. See https://github.com/imq/linuximq/wiki for more information."); 69 MODULE_LICENSE("GPL"); 70 MODULE_ALIAS("ipt_IMQ"); 71 MODULE_ALIAS("ip6t_IMQ"); 72 -
net/sched/sch_generic.c
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c index e82a1ad..b55331d 100644
a b static struct sk_buff *dequeue_skb(struct Qdisc *q, bool *validate, 108 108 return skb; 109 109 } 110 110 111 struct sk_buff *qdisc_dequeue_skb(struct Qdisc *q, bool *validate) 112 { 113 int packets; 114 115 return dequeue_skb(q, validate, &packets); 116 } 117 EXPORT_SYMBOL(qdisc_dequeue_skb); 118 111 119 static inline int handle_dev_cpu_collision(struct sk_buff *skb, 112 120 struct netdev_queue *dev_queue, 113 121 struct Qdisc *q)
Note: See TracBrowser
for help on using the repository browser.