1 diff -Nurb linux-2.6.22-591/drivers/net/Makefile linux-2.6.22-592/drivers/net/Makefile
2 --- linux-2.6.22-591/drivers/net/Makefile 2008-01-02 13:56:37.000000000 -0500
3 +++ linux-2.6.22-592/drivers/net/Makefile 2008-01-23 17:45:01.000000000 -0500
5 # Makefile for the Linux network (ethercard) device drivers.
8 +obj-y +=ztun.o shortbridge.o
9 obj-$(CONFIG_E1000) += e1000/
10 obj-$(CONFIG_E1000E) += e1000e/
11 obj-$(CONFIG_IBM_EMAC) += ibm_emac/
12 diff -Nurb linux-2.6.22-591/drivers/net/shortbridge.c linux-2.6.22-592/drivers/net/shortbridge.c
13 --- linux-2.6.22-591/drivers/net/shortbridge.c 1969-12-31 19:00:00.000000000 -0500
14 +++ linux-2.6.22-592/drivers/net/shortbridge.c 2008-01-23 18:30:08.000000000 -0500
17 + * Shortbridge - short-circuited bridge
18 + * Copyright (C) 2007
23 +#define MAX_SHORTBRIDGES 20
25 +#include <linux/module.h>
26 +#include <linux/kernel.h>
27 +#include <linux/list.h>
28 +#include <linux/spinlock.h>
29 +#include <linux/skbuff.h>
30 +#include <linux/netdevice.h>
31 +#include <linux/etherdevice.h>
32 +#include <linux/ethtool.h>
33 +#include <linux/rtnetlink.h>
34 +#include <linux/if.h>
35 +#include <linux/if_ether.h>
36 +#include <linux/ctype.h>
37 +#include <net/net_namespace.h>
39 +#include <linux/nsproxy.h>
42 +struct shortbridge_entry {
43 + struct list_head list; /* My bead in the rosary */
44 + char first_dev[IFNAMSIZ];
45 + struct net_device **dev1;
46 + struct net_device **dev2;
49 +static LIST_HEAD(shortbridges);
62 +static int sb_shortcircuit(struct net *net, const char *name0, const char *name1, char *number)
64 + struct shortbridge_entry *ent;
65 + struct net_device *dev1, *dev2;
66 + int numentries = atoi(number);
69 + printk(KERN_CRIT "Short circuiting %s objects in device classes %s and %s\n",number,name0,name1);
70 + ent = (struct shortbridge_entry *) kmalloc(sizeof(struct shortbridge_entry), GFP_KERNEL);
71 + ent->dev1 = (struct net_device ** ) kmalloc(numentries * sizeof(struct net_device *), GFP_KERNEL);
72 + ent->dev2 = (struct net_device ** ) kmalloc(numentries * sizeof(struct net_device *), GFP_KERNEL);
75 + printk(KERN_CRIT "kmalloc failed for shortbridge_entry");
79 + for(i=0;i<numentries;i++) {
80 + char name0i[10],name1i[10];
81 + sprintf(name0i,"%s%d",name0,i);
82 + sprintf(name1i,"%s%d",name1,i);
84 + printk(KERN_CRIT "Device %s --> %s\n",name0i,name1i);
86 + dev1 = dev_get_by_name(net, name0i);
88 + printk(KERN_CRIT "Can't find device %s (first device)",name0i);
92 + dev2 = dev_get_by_name(net, name1i);
94 + printk(KERN_CRIT "Can't find device %s (second device)",name1i);
100 + ent->dev1[i] = dev1;
101 + //dev1->hard_start_xmit = dev2->hard_start_xmit;
102 + ent->dev2[i] = dev2;
106 + list_add(&ent->list,&shortbridges);
110 +static int sb_newsb(const char *val, struct kernel_param *kp)
112 + char name0[IFNAMSIZ], name1[IFNAMSIZ],number[4];
113 + const char *mid,*last;
115 + int len, len0, len01,len1;
116 + if (!capable(CAP_NET_ADMIN))
119 + /* Avoid frustration by removing trailing whitespace */
121 + while (isspace(val[len - 1]))
124 + /* Split the string into 2 names */
125 + mid = memchr(val, ',', len);
127 + printk(KERN_CRIT "Error!\n");
131 + /* Get the first device name */
133 + if (len0 > sizeof(name0) - 1)
134 + len0 = sizeof(name0) - 1;
135 + strncpy(name0, val, len0);
136 + name0[len0] = '\0';
140 + last = memchr(mid+1, ',', len);
142 + printk(KERN_CRIT "Error!\n");
146 + /* Get the second device name */
147 + len01 = last - mid - 1;
148 + if (len01 > sizeof(name0) - 1)
149 + len0 = sizeof(name0) - 1;
150 + strncpy(name1, mid+1, len01);
151 + name1[len01] = '\0';
154 + /* And the number device name */
155 + len1 = len - (len01 + 1);
156 + if (len1 > sizeof(name1) - 1)
157 + len1 = sizeof(name1) - 1;
158 + strncpy(number, last + 1, len1);
159 + number[len1] = '\0';
162 + return sb_shortcircuit(current->nsproxy->net_ns, name0, name1, number);
165 +static int sb_delsb(const char *val, struct kernel_param *kp)
167 + char name[IFNAMSIZ];
169 + struct list_head *cur, *tmp;
172 + if (!capable(CAP_NET_ADMIN))
175 + /* Avoid frustration by removing trailing whitespace */
177 + while (isspace(val[len - 1]))
180 + /* Get the device name */
181 + if (len > sizeof(name) - 1)
183 + printk(KERN_CRIT "shortbridge: Input string too long\n");
186 + strncpy(name, val, len);
190 + list_for_each_safe(cur, tmp, &shortbridges) {
191 + struct shortbridge_entry *ent;
192 + ent = list_entry (cur, struct shortbridge_entry, list);
193 + if (!strcmp(name, ent->first_dev)) {
194 + struct net_device *dev1 = ent->dev1;
195 + dev1->hard_start_xmit = ent->dev1;
205 +unsigned int sb_hook (struct sk_buff *skb, struct packet_type *pt,struct net_device *orig_dev) {
206 + struct list_head *cur, *tmp;
207 + /* Let's find our device - change this to use a hashtable instead of a list */
208 + list_for_each_safe(cur, tmp, &shortbridges) {
209 + struct shortbridge_entry *ent;
210 + ent = list_entry (cur, struct shortbridge_entry, list);
211 + if (skb->this_packet_is_stoned == 0){
212 + unsigned int dev1,dev2;
214 + dev1=*((unsigned int *) (skb->dev->name));
215 + dev2=*((unsigned int *) (ent->dev2[0]->name));
216 + devb=*((unsigned int *) (ent->dev1[0]->name));
218 + if (dev1 == dev2) {
219 + //printk(KERN_CRIT "Splice: %s-->%s\n",skb->dev->name, ent->dev1[0]->name);
220 + char *number=(char *) skb->dev->name+4;
221 + int num=atoi(number);
223 + skb->dev = ent->dev1[num];
224 + skb->this_packet_is_stoned = 1;
227 + if (dev1 == devb) {
228 + //printk(KERN_CRIT "Splice: %s-->%s\n",skb->dev->name, ent->dev2[0]->name);
230 + char *number=(char *) skb->dev->name+4;
231 + int num=atoi(number);
232 + skb->dev = ent->dev2[num];
233 + skb->this_packet_is_stoned = 1;
237 + return NET_RX_SUCCESS;
240 +static struct packet_type sb_type = {
241 + .type = __constant_htons(ETH_P_ALL),
245 +static int __init sb_init(void)
247 + //dev_add_pack(&sb_type);
248 + printk(KERN_CRIT "Shortbridge device driver v0.1 loaded\n");
252 +static int sb_noget(char *buffer, struct kernel_param *kp)
257 +static void sb_cleanup(void)
259 + struct list_head *cur, *tmp;
261 + list_for_each_safe(cur, tmp, &shortbridges) {
262 + struct shortbridge_entry *ent;
263 + struct net_device *dev1;
264 + ent = list_entry (cur, struct shortbridge_entry, list);
270 + dev_remove_pack(&sb_type);
273 +module_param_call(newsb, sb_newsb, sb_noget, NULL, S_IWUSR);
274 +module_param_call(delsb, sb_delsb, sb_noget, NULL, S_IWUSR);
275 +module_init(sb_init);
276 +module_exit(sb_cleanup);
278 +MODULE_DESCRIPTION("Short bridge device driver");
279 +MODULE_AUTHOR("Sapan Bhatia <sapan.bhatia@gmail.com>");
280 +MODULE_LICENSE("GPL");
281 diff -Nurb linux-2.6.22-591/drivers/net/ztun.c linux-2.6.22-592/drivers/net/ztun.c
282 --- linux-2.6.22-591/drivers/net/ztun.c 1969-12-31 19:00:00.000000000 -0500
283 +++ linux-2.6.22-592/drivers/net/ztun.c 2008-01-23 18:28:47.000000000 -0500
285 +#include <linux/module.h>
286 +#include <linux/kernel.h>
287 +#include <linux/list.h>
288 +#include <linux/spinlock.h>
289 +#include <linux/skbuff.h>
290 +#include <linux/netdevice.h>
291 +#include <linux/etherdevice.h>
292 +#include <linux/ethtool.h>
293 +#include <linux/rtnetlink.h>
294 +#include <linux/if.h>
295 +#include <linux/if_ether.h>
296 +#include <linux/ctype.h>
297 +#include <net/dst.h>
298 +#include <asm/current.h>
299 +#include <net/net_namespace.h>
300 +#include <linux/nsproxy.h>
303 +/* I don't know how to send packets, somebody steal them away from me */
304 +static int ztun_xmit(struct sk_buff *skb, struct net_device *dev)
306 + struct net_device_stats *stats = dev->priv;
308 + stats->tx_packets++;
309 + stats->tx_bytes += skb->len;
313 + skb->dst = dst_pop(skb->dst); /* Allow for smart routing */
315 + skb->pkt_type = PACKET_HOST;
317 + printk(KERN_CRIT "ztun: I don't know how to send packets, somebody steal them away from me.");
321 +static int ztun_open(struct net_device *dev)
323 + if (dev->flags & IFF_UP) {
324 + netif_carrier_on(dev);
326 + netif_start_queue(dev);
330 +static int ztun_stop(struct net_device *dev)
332 + netif_stop_queue(dev);
333 + if (netif_carrier_ok(dev)) {
334 + netif_carrier_off(dev);
339 +static int ztun_noget(char *buffer, struct kernel_param *kp)
344 +static int is_valid_name(const char *name)
347 + for (ptr = name; *ptr; ptr++) {
348 + if (!isalnum(*ptr))
354 +static struct net_device_stats *ztun_get_stats(struct net_device *dev)
356 + struct net_device_stats *stats = dev->priv;
360 +static struct net_device *ztun_alloc(struct net *net, const char *name)
362 + struct net_device *dev;
365 + if (!name || !is_valid_name(name))
366 + return ERR_PTR(-EINVAL);
368 + dev = alloc_netdev(sizeof(struct net_device_stats), name, ether_setup);
370 + return ERR_PTR(-ENOMEM);
374 + random_ether_addr(dev->dev_addr);
375 + dev->tx_queue_len = 0; /* A queue is silly for a loopback device */
376 + dev->hard_start_xmit = ztun_xmit;
377 + dev->open = ztun_open;
378 + dev->get_stats = ztun_get_stats;
379 + dev->stop = ztun_stop;
380 + dev->features = NETIF_F_FRAGLIST
383 + dev->flags = IFF_BROADCAST | IFF_MULTICAST |IFF_PROMISC;
384 + dev->destructor = free_netdev;
385 + err = register_netdev(dev);
388 + dev = ERR_PTR(err);
391 + netif_carrier_off(dev);
396 +static int ztun_newif(const char *val, struct kernel_param *kp)
398 + char name[IFNAMSIZ];
401 + if (!capable(CAP_NET_ADMIN))
404 + /* Avoid frustration by removing trailing whitespace */
406 + while (isspace(val[len - 1]))
409 + strncpy(name, val, len);
412 + return ztun_alloc(current->nsproxy->net_ns,name);
415 +static int ztun_delif(const char *val, struct kernel_param *kp)
417 + printk(KERN_CRIT "Somebody tried to kill ztun, but ztun doesn't want to die.");
422 +static int __init ztun_init(void)
424 + printk(KERN_CRIT "ztun v0.1\n");
428 +static void ztun_cleanup(void)
433 +module_param_call(newif, ztun_newif, ztun_noget, NULL, S_IWUSR);
434 +module_param_call(delif, ztun_delif, ztun_noget, NULL, S_IWUSR);
435 +module_init(ztun_init);
436 +module_exit(ztun_cleanup);
437 +MODULE_LICENSE("GPL");
438 +MODULE_LICENSE("GPL");
439 diff -Nurb linux-2.6.22-591/include/linux/skbuff.h linux-2.6.22-592/include/linux/skbuff.h
440 --- linux-2.6.22-591/include/linux/skbuff.h 2008-01-02 13:56:37.000000000 -0500
441 +++ linux-2.6.22-592/include/linux/skbuff.h 2008-01-23 17:47:32.000000000 -0500
446 + __u8 this_packet_is_stoned;
448 void (*destructor)(struct sk_buff *skb);
449 #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
450 struct nf_conntrack *nfct;
451 diff -Nurb linux-2.6.22-591/net/core/dev.c linux-2.6.22-592/net/core/dev.c
452 --- linux-2.6.22-591/net/core/dev.c 2008-01-02 13:56:38.000000000 -0500
453 +++ linux-2.6.22-592/net/core/dev.c 2008-01-23 18:33:25.000000000 -0500
454 @@ -1491,7 +1491,7 @@
458 - return dev->hard_start_xmit(skb, dev);
459 + return dev->hard_start_xmit(skb, skb->dev);
463 @@ -1556,12 +1556,16 @@
467 +unsigned int sb_hook (struct sk_buff *skb, struct packet_type *pt,struct net_device *orig_dev);
469 int dev_queue_xmit(struct sk_buff *skb)
471 struct net_device *dev = skb->dev;
475 + sb_hook(skb, NULL, NULL);
477 /* GSO will handle the following emulations directly. */
478 if (netif_needs_gso(dev, skb))
480 @@ -1943,6 +1947,8 @@
484 + sb_hook(skb,pt_prev,skb->dev);
486 #ifdef CONFIG_NET_CLS_ACT
487 if (skb->tc_verd & TC_NCLS) {
488 skb->tc_verd = CLR_TC_NCLS(skb->tc_verd);
489 @@ -1953,14 +1959,14 @@
490 list_for_each_entry_rcu(ptype, &ptype_all, list) {
491 if (!ptype->dev || ptype->dev == skb->dev) {
493 - ret = deliver_skb(skb, pt_prev, orig_dev);
494 + ret = deliver_skb(skb, pt_prev, skb->dev);
499 #ifdef CONFIG_NET_CLS_ACT
501 - ret = deliver_skb(skb, pt_prev, orig_dev);
502 + ret = deliver_skb(skb, pt_prev, skb->dev);
503 pt_prev = NULL; /* noone else should process this after*/
505 skb->tc_verd = SET_TC_OK2MUNGE(skb->tc_verd);
506 @@ -1986,13 +1992,13 @@
507 if (ptype->type == type &&
508 (!ptype->dev || ptype->dev == skb->dev)) {
510 - ret = deliver_skb(skb, pt_prev, orig_dev);
511 + ret = deliver_skb(skb, pt_prev, skb->dev);
517 - ret = pt_prev->func(skb, skb->dev, pt_prev, orig_dev);
518 + ret = pt_prev->func(skb, skb->dev, pt_prev, skb->dev);
521 /* Jamal, now you will not able to escape explaining
522 diff -Nurb linux-2.6.22-591/net/ipv4/arp.c linux-2.6.22-592/net/ipv4/arp.c
523 --- linux-2.6.22-591/net/ipv4/arp.c 2008-01-02 13:56:38.000000000 -0500
524 +++ linux-2.6.22-592/net/ipv4/arp.c 2008-01-23 17:56:02.000000000 -0500
527 if (arp->ar_hln != dev->addr_len ||
528 dev->flags & IFF_NOARP ||
529 - skb->pkt_type == PACKET_OTHERHOST ||
530 + (skb->pkt_type == PACKET_OTHERHOST && !skb->this_packet_is_stoned) ||
531 skb->pkt_type == PACKET_LOOPBACK ||
534 diff -Nurb linux-2.6.22-591/net/ipv4/ip_forward.c linux-2.6.22-592/net/ipv4/ip_forward.c
535 --- linux-2.6.22-591/net/ipv4/ip_forward.c 2007-07-08 19:32:17.000000000 -0400
536 +++ linux-2.6.22-592/net/ipv4/ip_forward.c 2008-01-23 17:52:43.000000000 -0500
539 if (IPCB(skb)->opt.router_alert && ip_call_ra_chain(skb))
540 return NET_RX_SUCCESS;
543 + if (skb->this_packet_is_stoned) {
544 + skb->this_packet_is_stoned=0;
545 + skb->pkt_type=PACKET_HOST;
549 if (skb->pkt_type != PACKET_HOST)
551 diff -Nurb linux-2.6.22-591/net/ipv4/ip_input.c linux-2.6.22-592/net/ipv4/ip_input.c
552 --- linux-2.6.22-591/net/ipv4/ip_input.c 2008-01-02 13:56:38.000000000 -0500
553 +++ linux-2.6.22-592/net/ipv4/ip_input.c 2008-01-23 17:57:32.000000000 -0500
555 /* When the interface is in promisc. mode, drop all the crap
556 * that it receives, do not try to analyse it.
558 - if (skb->pkt_type == PACKET_OTHERHOST)
559 + if (skb->pkt_type == PACKET_OTHERHOST && (!skb->this_packet_is_stoned))
562 IP_INC_STATS_BH(IPSTATS_MIB_INRECEIVES);