From: Sapan Bhatia Date: Thu, 24 Jan 2008 00:15:16 +0000 (+0000) Subject: (no commit message) X-Git-Tag: trellis-2.6.22-Jan-2009~65 X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;h=198fadffc522912496c1e4f51768b7e9a8feac37;p=linux-2.6.git --- diff --git a/kernel-2.6-planetlab.spec b/kernel-2.6-planetlab.spec index e73224d69..f2db8db39 100644 --- a/kernel-2.6-planetlab.spec +++ b/kernel-2.6-planetlab.spec @@ -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 index 000000000..1433d6f68 --- /dev/null +++ b/linux-2.6-592-ztun-sb.patch @@ -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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++ ++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 %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 "); ++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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++ ++/* 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);