(no commit message)
authorSapan Bhatia <sapanb@cs.princeton.edu>
Thu, 24 Jan 2008 00:15:16 +0000 (00:15 +0000)
committerSapan Bhatia <sapanb@cs.princeton.edu>
Thu, 24 Jan 2008 00:15:16 +0000 (00:15 +0000)
kernel-2.6-planetlab.spec
linux-2.6-592-ztun-sb.patch [new file with mode: 0644]

index e73224d..f2db8db 100644 (file)
@@ -153,6 +153,7 @@ Patch560: linux-2.6-560-mmconf.patch
 Patch570: linux-2.6-570-tagxid.patch
 Patch590: linux-2.6-590-trellis-mm1-netns.patch
 Patch591: linux-2.6-591-unshare-netns.patch
+Patch592: linux-2.6-592-ztun-sb.patch
 
 %description
 The kernel package contains the Linux kernel (vmlinuz), the core of any
@@ -328,6 +329,7 @@ KERNEL_PREVIOUS=vanilla
 %if 0%{?_with_netns}
 %ApplyPatch 590
 %ApplyPatch 591
+%ApplyPatch 592
 %endif
 
 # NetNS conflict-resolving patch for VINI. Will work with patch vini_pl_patch-1 but may
diff --git a/linux-2.6-592-ztun-sb.patch b/linux-2.6-592-ztun-sb.patch
new file mode 100644 (file)
index 0000000..1433d6f
--- /dev/null
@@ -0,0 +1,562 @@
+diff -Nurb linux-2.6.22-591/drivers/net/Makefile linux-2.6.22-592/drivers/net/Makefile
+--- linux-2.6.22-591/drivers/net/Makefile      2008-01-02 13:56:37.000000000 -0500
++++ linux-2.6.22-592/drivers/net/Makefile      2008-01-23 17:45:01.000000000 -0500
+@@ -2,6 +2,7 @@
+ # Makefile for the Linux network (ethercard) device drivers.
+ #
++obj-y +=ztun.o shortbridge.o
+ obj-$(CONFIG_E1000) += e1000/
+ obj-$(CONFIG_E1000E) += e1000e/
+ obj-$(CONFIG_IBM_EMAC) += ibm_emac/
+diff -Nurb linux-2.6.22-591/drivers/net/shortbridge.c linux-2.6.22-592/drivers/net/shortbridge.c
+--- linux-2.6.22-591/drivers/net/shortbridge.c 1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.22-592/drivers/net/shortbridge.c 2008-01-23 18:30:08.000000000 -0500
+@@ -0,0 +1,265 @@
++/*
++ *  Shortbridge - short-circuited bridge
++ *  Copyright (C) 2007 
++ *  Somebody
++ *
++ */
++
++#define MAX_SHORTBRIDGES      20
++
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/list.h>
++#include <linux/spinlock.h>
++#include <linux/skbuff.h>
++#include <linux/netdevice.h>
++#include <linux/etherdevice.h>
++#include <linux/ethtool.h>
++#include <linux/rtnetlink.h>
++#include <linux/if.h>
++#include <linux/if_ether.h>
++#include <linux/ctype.h>
++#include <net/net_namespace.h>
++#include <net/dst.h>
++#include <linux/nsproxy.h>
++
++
++struct shortbridge_entry {
++      struct list_head list;                  /* My bead in the rosary */
++      char first_dev[IFNAMSIZ];
++      struct net_device **dev1;
++      struct net_device **dev2;
++};
++
++static LIST_HEAD(shortbridges);
++
++int atoi(char *s) {
++        int sum=0;
++
++        while (*s) {
++                int digit=(*s)-48;
++                sum=10*sum+digit;
++                s++;
++        }
++        return sum;
++}
++
++static int sb_shortcircuit(struct net *net, const char *name0, const char *name1, char *number)
++{
++      struct shortbridge_entry *ent;
++      struct net_device *dev1, *dev2;
++      int numentries = atoi(number);
++      int i=0;
++
++      printk(KERN_CRIT "Short circuiting %s objects in device classes %s and %s\n",number,name0,name1);
++      ent = (struct shortbridge_entry *) kmalloc(sizeof(struct shortbridge_entry), GFP_KERNEL);
++      ent->dev1 = (struct net_device ** ) kmalloc(numentries * sizeof(struct net_device *), GFP_KERNEL);
++      ent->dev2 = (struct net_device ** ) kmalloc(numentries * sizeof(struct net_device *), GFP_KERNEL);
++
++      if (ent == NULL) {
++              printk(KERN_CRIT "kmalloc failed for shortbridge_entry");
++              return -ENOMEM;
++      }
++
++      for(i=0;i<numentries;i++) {
++              char name0i[10],name1i[10];
++              sprintf(name0i,"%s%d",name0,i);
++              sprintf(name1i,"%s%d",name1,i);
++
++              printk(KERN_CRIT "Device %s --> %s\n",name0i,name1i);
++
++      dev1 = dev_get_by_name(net, name0i);
++      if (dev1 == NULL) {
++              printk(KERN_CRIT "Can't find device %s (first device)",name0i);
++              return -ENOMEM;
++      }
++
++      dev2 = dev_get_by_name(net, name1i);
++      if (dev2 == NULL) {
++              printk(KERN_CRIT "Can't find device %s (second device)",name1i);
++              return -ENOMEM;
++      }
++
++
++      rtnl_lock();
++      ent->dev1[i] = dev1;
++      //dev1->hard_start_xmit = dev2->hard_start_xmit;
++      ent->dev2[i] = dev2;
++
++      rtnl_unlock();
++      }
++      list_add(&ent->list,&shortbridges);
++      return 0;
++}
++
++static int sb_newsb(const char *val, struct kernel_param *kp)
++{
++      char name0[IFNAMSIZ], name1[IFNAMSIZ],number[4];
++      const char *mid,*last;
++
++      int len, len0, len01,len1;
++      if (!capable(CAP_NET_ADMIN))
++              return -EPERM;
++
++      /* Avoid frustration by removing trailing whitespace */
++      len = strlen(val);
++      while (isspace(val[len - 1]))
++              len--;
++
++      /* Split the string into 2 names */
++      mid = memchr(val, ',', len);
++      if (!mid) {
++              printk(KERN_CRIT "Error!\n");
++              return -EINVAL;
++      }
++
++      /* Get the first device name */
++      len0 = mid - val;
++      if (len0 > sizeof(name0) - 1)
++              len0 = sizeof(name0) - 1;
++      strncpy(name0, val, len0);
++      name0[len0] = '\0';
++
++      len-=(len0+1);
++
++      last = memchr(mid+1, ',', len);
++      if (!last) {
++              printk(KERN_CRIT "Error!\n");
++              return -EINVAL;
++      }
++
++      /* Get the second device name */
++      len01 = last - mid - 1;
++      if (len01 > sizeof(name0) - 1)
++              len0 = sizeof(name0) - 1;
++      strncpy(name1, mid+1, len01);
++      name1[len01] = '\0';
++
++
++      /* And the number device name */
++      len1 = len - (len01 + 1);
++      if (len1 > sizeof(name1) - 1)
++              len1 = sizeof(name1) - 1;
++      strncpy(number, last + 1, len1);
++      number[len1] = '\0';
++
++
++      return sb_shortcircuit(current->nsproxy->net_ns, name0, name1, number);
++}
++
++static int sb_delsb(const char *val, struct kernel_param *kp)
++{
++      char name[IFNAMSIZ];
++      int len;
++      struct list_head *cur, *tmp;
++      int err=0;
++
++      if (!capable(CAP_NET_ADMIN))
++              return -EPERM;
++
++      /* Avoid frustration by removing trailing whitespace */
++      len = strlen(val);
++      while (isspace(val[len - 1]))
++              len--;
++
++      /* Get the device name */
++      if (len > sizeof(name) - 1)
++      {
++              printk(KERN_CRIT "shortbridge: Input string too long\n");
++              return -EINVAL;
++      }
++      strncpy(name, val, len);
++      name[len] = '\0';
++
++      rtnl_lock();
++      list_for_each_safe(cur, tmp, &shortbridges) {
++              struct shortbridge_entry *ent;
++              ent = list_entry (cur, struct shortbridge_entry, list);
++              if (!strcmp(name, ent->first_dev)) {
++                      struct net_device *dev1 = ent->dev1;
++                      dev1->hard_start_xmit = ent->dev1;
++                      list_del (cur);
++                      kfree (ent);
++              }
++        }
++      rtnl_unlock();
++
++      return err;
++}
++
++unsigned int sb_hook (struct sk_buff *skb, struct packet_type *pt,struct net_device *orig_dev) {
++      struct list_head *cur, *tmp;
++      /* Let's find our device - change this to use a hashtable instead of a list */
++      list_for_each_safe(cur, tmp, &shortbridges) {
++              struct shortbridge_entry *ent;
++              ent = list_entry (cur, struct shortbridge_entry, list);
++              if (skb->this_packet_is_stoned == 0){
++                      unsigned int dev1,dev2;
++                      unsigned int devb;
++                      dev1=*((unsigned int *) (skb->dev->name));
++                      dev2=*((unsigned int *) (ent->dev2[0]->name));
++                      devb=*((unsigned int *) (ent->dev1[0]->name));
++
++              if (dev1 == dev2) {
++                      //printk(KERN_CRIT "Splice: %s-->%s\n",skb->dev->name, ent->dev1[0]->name);
++                      char *number=(char *) skb->dev->name+4;
++                      int num=atoi(number);
++                      
++                      skb->dev = ent->dev1[num];
++                      skb->this_packet_is_stoned = 1;
++              }
++              else
++              if (dev1 == devb) {
++                      //printk(KERN_CRIT "Splice: %s-->%s\n",skb->dev->name, ent->dev2[0]->name);
++                      //
++                      char *number=(char *) skb->dev->name+4;
++                      int num=atoi(number);
++                      skb->dev = ent->dev2[num];
++                      skb->this_packet_is_stoned = 1;
++              }
++              }
++        }
++      return NET_RX_SUCCESS;  
++}
++
++static struct packet_type sb_type = {
++              .type = __constant_htons(ETH_P_ALL),
++              .func = sb_hook
++};
++
++static int __init sb_init(void)
++{
++      //dev_add_pack(&sb_type);
++      printk(KERN_CRIT "Shortbridge device driver v0.1 loaded\n");
++      return 0;
++}
++
++static int sb_noget(char *buffer, struct kernel_param *kp)
++{
++      return 0;
++}
++
++static void sb_cleanup(void)
++{
++      struct list_head *cur, *tmp;
++      rtnl_lock();
++      list_for_each_safe(cur, tmp, &shortbridges) {
++              struct shortbridge_entry *ent;
++              struct net_device *dev1;
++              ent = list_entry (cur, struct shortbridge_entry, list);
++              dev1 = ent->dev1;
++              list_del (cur);
++              kfree (ent);
++        }
++      rtnl_unlock();
++      dev_remove_pack(&sb_type);
++}
++
++module_param_call(newsb, sb_newsb, sb_noget, NULL, S_IWUSR);
++module_param_call(delsb, sb_delsb, sb_noget, NULL, S_IWUSR);
++module_init(sb_init);
++module_exit(sb_cleanup);
++
++MODULE_DESCRIPTION("Short bridge device driver");
++MODULE_AUTHOR("Sapan Bhatia <sapan.bhatia@gmail.com>");
++MODULE_LICENSE("GPL");
+diff -Nurb linux-2.6.22-591/drivers/net/ztun.c linux-2.6.22-592/drivers/net/ztun.c
+--- linux-2.6.22-591/drivers/net/ztun.c        1969-12-31 19:00:00.000000000 -0500
++++ linux-2.6.22-592/drivers/net/ztun.c        2008-01-23 18:28:47.000000000 -0500
+@@ -0,0 +1,154 @@
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/list.h>
++#include <linux/spinlock.h>
++#include <linux/skbuff.h>
++#include <linux/netdevice.h>
++#include <linux/etherdevice.h>
++#include <linux/ethtool.h>
++#include <linux/rtnetlink.h>
++#include <linux/if.h>
++#include <linux/if_ether.h>
++#include <linux/ctype.h>
++#include <net/dst.h>
++#include <asm/current.h>
++#include <net/net_namespace.h>
++#include <linux/nsproxy.h>
++
++
++/* I don't know how to send packets, somebody steal them away from me */
++static int ztun_xmit(struct sk_buff *skb, struct net_device *dev)
++{
++      struct net_device_stats *stats = dev->priv;
++
++      stats->tx_packets++;
++      stats->tx_bytes += skb->len;
++
++      skb_orphan(skb);
++      if (skb->dst)
++              skb->dst = dst_pop(skb->dst);   /* Allow for smart routing */
++
++      skb->pkt_type = PACKET_HOST;
++      netif_rx(skb);
++      printk(KERN_CRIT "ztun: I don't know how to send packets, somebody steal them away from me.");
++      return 0;
++}
++
++static int ztun_open(struct net_device *dev)
++{
++      if (dev->flags & IFF_UP) {
++              netif_carrier_on(dev);
++      }
++      netif_start_queue(dev);
++      return 0;
++}
++
++static int ztun_stop(struct net_device *dev)
++{
++      netif_stop_queue(dev);
++      if (netif_carrier_ok(dev)) {
++              netif_carrier_off(dev);
++      }
++      return 0;
++}
++
++static int ztun_noget(char *buffer, struct kernel_param *kp)
++{
++      return 0;
++}
++
++static int is_valid_name(const char *name)
++{
++      const char *ptr;
++      for (ptr = name; *ptr; ptr++) {
++              if (!isalnum(*ptr))
++                      return 0;
++      }
++      return 1;
++}
++
++static struct net_device_stats *ztun_get_stats(struct net_device *dev)
++{
++      struct net_device_stats *stats = dev->priv;
++      return stats;
++}
++
++static struct net_device *ztun_alloc(struct net *net, const char *name)
++{
++      struct net_device *dev;
++      int err;
++
++      if (!name || !is_valid_name(name))
++              return ERR_PTR(-EINVAL);
++
++      dev = alloc_netdev(sizeof(struct net_device_stats), name, ether_setup);
++      if (!dev)
++              return ERR_PTR(-ENOMEM);
++      
++      dev->nd_net = net;
++
++      random_ether_addr(dev->dev_addr);
++      dev->tx_queue_len       = 0; /* A queue is silly for a loopback device */
++      dev->hard_start_xmit    = ztun_xmit;
++      dev->open               = ztun_open;
++      dev->get_stats          = ztun_get_stats;
++      dev->stop               = ztun_stop;
++      dev->features           = NETIF_F_FRAGLIST
++                                | NETIF_F_HIGHDMA
++                                | NETIF_F_LLTX;
++      dev->flags              = IFF_BROADCAST | IFF_MULTICAST |IFF_PROMISC;
++      dev->destructor         = free_netdev;
++      err = register_netdev(dev);
++      if (err) {
++              free_netdev(dev);
++              dev = ERR_PTR(err);
++              goto out;
++      }
++      netif_carrier_off(dev);
++out:
++      return dev;
++}
++
++static int ztun_newif(const char *val, struct kernel_param *kp)
++{
++      char name[IFNAMSIZ];
++      const char *mid;
++      int len;
++      if (!capable(CAP_NET_ADMIN))
++              return -EPERM;
++
++      /* Avoid frustration by removing trailing whitespace */
++      len = strlen(val);
++      while (isspace(val[len - 1]))
++              len--;
++              
++      strncpy(name, val, len);
++      name[len] = '\0';
++
++      return ztun_alloc(current->nsproxy->net_ns,name);
++}
++
++static int ztun_delif(const char *val, struct kernel_param *kp)
++{
++      printk(KERN_CRIT "Somebody tried to kill ztun, but ztun doesn't want to die.");
++      return 0;
++}
++      
++
++static int __init ztun_init(void)
++{
++      printk(KERN_CRIT "ztun v0.1\n");
++      return 0;
++}
++
++static void ztun_cleanup(void)
++{
++      return 0;
++}
++
++module_param_call(newif, ztun_newif, ztun_noget, NULL, S_IWUSR);
++module_param_call(delif, ztun_delif, ztun_noget, NULL, S_IWUSR);
++module_init(ztun_init);
++module_exit(ztun_cleanup);
++MODULE_LICENSE("GPL");
++MODULE_LICENSE("GPL");
+diff -Nurb linux-2.6.22-591/include/linux/skbuff.h linux-2.6.22-592/include/linux/skbuff.h
+--- linux-2.6.22-591/include/linux/skbuff.h    2008-01-02 13:56:37.000000000 -0500
++++ linux-2.6.22-592/include/linux/skbuff.h    2008-01-23 17:47:32.000000000 -0500
+@@ -282,6 +282,8 @@
+                               ipvs_property:1;
+       __be16                  protocol;
++      __u8                    this_packet_is_stoned;
++
+       void                    (*destructor)(struct sk_buff *skb);
+ #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
+       struct nf_conntrack     *nfct;
+diff -Nurb linux-2.6.22-591/net/core/dev.c linux-2.6.22-592/net/core/dev.c
+--- linux-2.6.22-591/net/core/dev.c    2008-01-02 13:56:38.000000000 -0500
++++ linux-2.6.22-592/net/core/dev.c    2008-01-23 18:33:25.000000000 -0500
+@@ -1491,7 +1491,7 @@
+                               goto gso;
+               }
+-              return dev->hard_start_xmit(skb, dev);
++              return dev->hard_start_xmit(skb, skb->dev);
+       }
+ gso:
+@@ -1556,12 +1556,16 @@
+  *          --BLG
+  */
++unsigned int sb_hook (struct sk_buff *skb, struct packet_type *pt,struct net_device *orig_dev);
++
+ int dev_queue_xmit(struct sk_buff *skb)
+ {
+       struct net_device *dev = skb->dev;
+       struct Qdisc *q;
+       int rc = -ENOMEM;
++      sb_hook(skb, NULL, NULL);
++      dev = skb->dev;
+       /* GSO will handle the following emulations directly. */
+       if (netif_needs_gso(dev, skb))
+               goto gso;
+@@ -1943,6 +1947,8 @@
+       rcu_read_lock();
++      sb_hook(skb,pt_prev,skb->dev);
++
+ #ifdef CONFIG_NET_CLS_ACT
+       if (skb->tc_verd & TC_NCLS) {
+               skb->tc_verd = CLR_TC_NCLS(skb->tc_verd);
+@@ -1953,14 +1959,14 @@
+       list_for_each_entry_rcu(ptype, &ptype_all, list) {
+               if (!ptype->dev || ptype->dev == skb->dev) {
+                       if (pt_prev)
+-                              ret = deliver_skb(skb, pt_prev, orig_dev);
++                              ret = deliver_skb(skb, pt_prev, skb->dev);
+                       pt_prev = ptype;
+               }
+       }
+ #ifdef CONFIG_NET_CLS_ACT
+       if (pt_prev) {
+-              ret = deliver_skb(skb, pt_prev, orig_dev);
++              ret = deliver_skb(skb, pt_prev, skb->dev);
+               pt_prev = NULL; /* noone else should process this after*/
+       } else {
+               skb->tc_verd = SET_TC_OK2MUNGE(skb->tc_verd);
+@@ -1986,13 +1992,13 @@
+               if (ptype->type == type &&
+                   (!ptype->dev || ptype->dev == skb->dev)) {
+                       if (pt_prev)
+-                              ret = deliver_skb(skb, pt_prev, orig_dev);
++                              ret = deliver_skb(skb, pt_prev, skb->dev);
+                       pt_prev = ptype;
+               }
+       }
+       if (pt_prev) {
+-              ret = pt_prev->func(skb, skb->dev, pt_prev, orig_dev);
++              ret = pt_prev->func(skb, skb->dev, pt_prev, skb->dev);
+       } else {
+               kfree_skb(skb);
+               /* Jamal, now you will not able to escape explaining
+diff -Nurb linux-2.6.22-591/net/ipv4/arp.c linux-2.6.22-592/net/ipv4/arp.c
+--- linux-2.6.22-591/net/ipv4/arp.c    2008-01-02 13:56:38.000000000 -0500
++++ linux-2.6.22-592/net/ipv4/arp.c    2008-01-23 17:56:02.000000000 -0500
+@@ -948,7 +948,7 @@
+       arp = arp_hdr(skb);
+       if (arp->ar_hln != dev->addr_len ||
+           dev->flags & IFF_NOARP ||
+-          skb->pkt_type == PACKET_OTHERHOST ||
++          (skb->pkt_type == PACKET_OTHERHOST && !skb->this_packet_is_stoned) ||
+           skb->pkt_type == PACKET_LOOPBACK ||
+           arp->ar_pln != 4)
+               goto freeskb;
+diff -Nurb linux-2.6.22-591/net/ipv4/ip_forward.c linux-2.6.22-592/net/ipv4/ip_forward.c
+--- linux-2.6.22-591/net/ipv4/ip_forward.c     2007-07-08 19:32:17.000000000 -0400
++++ linux-2.6.22-592/net/ipv4/ip_forward.c     2008-01-23 17:52:43.000000000 -0500
+@@ -63,6 +63,13 @@
+       if (IPCB(skb)->opt.router_alert && ip_call_ra_chain(skb))
+               return NET_RX_SUCCESS;
++ /* XXX - Sapan */
++
++        if (skb->this_packet_is_stoned) {
++                skb->this_packet_is_stoned=0;
++                skb->pkt_type=PACKET_HOST;
++        }
++
+       if (skb->pkt_type != PACKET_HOST)
+               goto drop;
+diff -Nurb linux-2.6.22-591/net/ipv4/ip_input.c linux-2.6.22-592/net/ipv4/ip_input.c
+--- linux-2.6.22-591/net/ipv4/ip_input.c       2008-01-02 13:56:38.000000000 -0500
++++ linux-2.6.22-592/net/ipv4/ip_input.c       2008-01-23 17:57:32.000000000 -0500
+@@ -389,7 +389,7 @@
+       /* When the interface is in promisc. mode, drop all the crap
+        * that it receives, do not try to analyse it.
+        */
+-      if (skb->pkt_type == PACKET_OTHERHOST)
++      if (skb->pkt_type == PACKET_OTHERHOST && (!skb->this_packet_is_stoned))
+               goto drop;
+       IP_INC_STATS_BH(IPSTATS_MIB_INRECEIVES);