diff -ruN vmnet-only-patched/bridge.c vmnet-only-refixed/bridge.c
--- vmnet-only-patched/bridge.c	2009-07-08 16:21:02.000000000 +0300
+++ vmnet-only-refixed/bridge.c	2009-04-21 18:30:03.000000000 +0300
@@ -275,11 +275,7 @@
                         struct net_device *net)  // IN: Network device
 {
 #ifdef VMW_NETDEV_HAS_NET
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)
    if (dev_net(net) != dev_net(bridge->internalDev)) {
-#else
-   if (net->nd_net != bridge->internalDev->nd_net) {
-#endif
       return 0;
    }
 #endif
@@ -857,6 +853,9 @@
 static Bool
 VNetBridgeIsDeviceWireless(struct net_device *dev) //IN: sock
 {
+	return FALSE;
+}
+#if 0
 #ifdef CONFIG_WIRELESS_EXT
    return dev->wireless_handlers != NULL;
 #elif !defined CONFIG_NET_RADIO && !defined CONFIG_WLAN_80211
@@ -869,7 +868,7 @@
    return dev->get_wireless_stats != NULL;
 #endif
 }
-
+#endif
 /*
  *----------------------------------------------------------------------
  *
diff -ruN vmnet-only-patched/bridge.c.orig vmnet-only-refixed/bridge.c.orig
--- vmnet-only-patched/bridge.c.orig	1970-01-01 02:00:00.000000000 +0200
+++ vmnet-only-refixed/bridge.c.orig	2007-11-28 12:25:06.000000000 +0200
@@ -0,0 +1,1552 @@
+/* **********************************************************
+ * Copyright 1998 VMware, Inc.  All rights reserved. -- VMware Confidential
+ * **********************************************************/
+
+#include "driver-config.h"
+
+#define EXPORT_SYMTAB
+
+#include <linux/kernel.h>
+#include <linux/version.h>
+#include <linux/sched.h>
+#ifdef KERNEL_2_2
+#   include <linux/slab.h>
+#else
+#   include <linux/malloc.h>
+#endif
+#include <linux/poll.h>
+
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/mm.h>
+#include "compat_skbuff.h"
+#include <linux/sockios.h>
+#include "compat_sock.h"
+
+#define __KERNEL_SYSCALLS__
+#include <asm/io.h>
+
+#include <linux/proc_fs.h>
+#include <linux/file.h>
+#include <linux/ip.h>
+#include <linux/tcp.h>
+#include <net/tcp.h>
+
+#ifdef CONFIG_NET_RADIO
+#   include <linux/wireless.h>
+#endif
+#include "vmnetInt.h"
+#include "compat_spinlock.h"
+#include "compat_netdevice.h"
+#include "vnetInt.h"
+#include "smac.h"
+
+#define VNET_BRIDGE_HISTORY    48
+
+/*
+ * Bytes reserved before start of packet.  As Ethernet header has 14 bytes,
+ * to get aligned IP header we must skip 2 bytes before packet.  Not that it
+ * matters a lot for us, but using 2 is compatible with what newer 2.6.x
+ * kernels do.
+ */
+#ifndef NET_IP_ALIGN
+#define NET_IP_ALIGN	2
+#endif
+
+#if LOGLEVEL >= 4
+static struct timeval vnetTime;
+#endif
+
+typedef struct VNetBridge VNetBridge;
+
+struct VNetBridge {
+   struct notifier_block    notifier;       // for device state changes
+   char                     name[VNET_NAME_LEN]; // name of net device (e.g., "eth0")
+   struct net_device       *dev;            // device structure for 'name'
+   struct sock             *sk;             // socket associated with skb's
+   struct packet_type       pt;             // used to add packet handler
+   Bool                     enabledPromisc; // track if promisc enabled
+   Bool                     warnPromisc;    // tracks if warning has been logged
+   struct sk_buff          *history[VNET_BRIDGE_HISTORY];  // avoid duplicate packets
+   spinlock_t		    historyLock;    // protects 'history'
+   VNetPort                 port;           // connection to virtual hub
+   Bool                     wirelessAdapter; // connected to wireless adapter?
+   struct SMACState        *smac;           // device structure for wireless
+#ifdef VMW_NETDEV_HAS_NET
+   struct net_device       *internalDev;
+#endif
+};
+
+typedef PacketStatus (* SMACINT SMACFunc)(struct SMACState *, SMACPackets *);
+
+static int  VNetBridgeUp(VNetBridge *bridge, Bool rtnlLock);
+static void VNetBridgeDown(VNetBridge *bridge, Bool rtnlLock);
+
+static int  VNetBridgeNotify(struct notifier_block *this, u_long msg,
+			     void *data);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 14) && \
+    !defined(VMW_TL10S64_WORKAROUND)
+static int VNetBridgeReceiveFromDev(struct sk_buff *skb,
+                                    struct net_device *dev,
+                                    struct packet_type *pt);
+#else
+static int VNetBridgeReceiveFromDev(struct sk_buff *skb,
+                                    struct net_device *dev,
+                                    struct packet_type *pt,
+                                    struct net_device *real_dev);
+#endif
+
+static void VNetBridgeFree(VNetJack *this);
+static void VNetBridgeReceiveFromVNet(VNetJack *this, struct sk_buff *skb);
+static Bool VNetBridgeCycleDetect(VNetJack *this, int generation);
+static Bool VNetBridgeIsDeviceWireless(struct net_device *dev);
+static void VNetBridgePortsChanged(VNetJack *this);
+static int  VNetBridgeIsBridged(VNetJack *this);
+static int  VNetBridgeProcRead(char *page, char **start, off_t off,
+                               int count, int *eof, void *data);
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * VNetBridgeStartPromisc --
+ *
+ *      Set IFF_PROMISC on the peer interface.
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *      The peer interface IFF_PROMISC flag may be changed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+VNetBridgeStartPromisc(VNetBridge *bridge,      // IN:
+                       Bool rtnlLock)           // IN: Acquire RTNL lock
+{
+   struct net_device *dev = bridge->dev;
+
+   /*
+    * Disable wireless cards from going into promiscous mode because those
+    * cards which do support RF monitoring would not be able to function
+    * correctly i.e. they would not be able to send data packets.
+    */
+   if (rtnlLock) {
+      rtnl_lock();
+   }
+   if (!bridge->enabledPromisc && !bridge->wirelessAdapter) {
+      dev_set_promiscuity(dev, 1);
+      bridge->enabledPromisc = TRUE;
+      bridge->warnPromisc = FALSE;
+      LOG(0, (KERN_NOTICE "bridge-%s: enabled promiscuous mode\n",
+	      bridge->name));
+   }
+   if (rtnlLock) {
+      rtnl_unlock();
+   }
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * VNetBridgeStopPromisc --
+ *
+ *      Restore saved IFF_PROMISC on the peer interface.
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *      The peer interface IFF_PROMISC flag may be changed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+VNetBridgeStopPromisc(VNetBridge *bridge,       // IN:
+                      Bool rtnlLock)            // IN: Acquire RTNL lock
+{
+   struct net_device *dev = bridge->dev;
+
+   if (rtnlLock) {
+      rtnl_lock();
+   }
+   if (bridge->enabledPromisc && !bridge->wirelessAdapter) {
+      dev_set_promiscuity(dev, -1);
+      bridge->enabledPromisc = FALSE;
+      LOG(0, (KERN_NOTICE "bridge-%s: disabled promiscuous mode\n",
+	      bridge->name));
+   }
+   if (rtnlLock) {
+      rtnl_unlock();
+   }
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * VNetBridgeCheckPromisc --
+ *
+ *      Make sure IFF_PROMISC on the peer interface is set.
+ *
+ *      This can be called periodically.
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *      Hopefully enables promiscuous mode again if it should have been enabled.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static INLINE_SINGLE_CALLER void
+VNetBridgeCheckPromisc(VNetBridge *bridge)
+{
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)
+   if (bridge->enabledPromisc && !bridge->wirelessAdapter) {
+      struct net_device *dev = bridge->dev;
+      Bool devPromisc = (dev->flags & IFF_PROMISC) != 0;
+
+      if (!devPromisc) {
+         if (!bridge->warnPromisc) {
+            bridge->warnPromisc = TRUE;
+            LOG(0, (KERN_NOTICE "bridge-%s: someone disabled promiscuous mode\n"
+	            "Your Ethernet driver is not compatible with VMware's bridged networking.\n",
+                    bridge->name));
+         }
+         rtnl_lock();
+         dev_set_promiscuity(dev, 0);
+         rtnl_unlock();
+      }
+   }
+#endif
+}
+
+
+#ifdef VMW_NETDEV_HAS_NET
+/*
+ *----------------------------------------------------------------------
+ *
+ * VNetBridgeInternalSetup --
+ *
+ *      Setup callback for our bridge internal device.  Nothing to do,
+ *      generic code sets up everything we expect from device.
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *      None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+VNetBridgeInternalSetup(struct net_device *net)
+{
+   /* Do nothing. */
+}
+#endif
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * VNetBridgeDevCompatible --
+ *
+ *      Check whether bridge and network device are compatible.
+ *
+ * Results:
+ *      Non-zero if device is good enough for bridge.  Zero otherwise.
+ *
+ * Side effects:
+ *      None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static INLINE_SINGLE_CALLER int
+VNetBridgeDevCompatible(VNetBridge *bridge,      // IN: Bridge
+                        struct net_device *net)  // IN: Network device
+{
+#ifdef VMW_NETDEV_HAS_NET
+   if (net->nd_net != bridge->internalDev->nd_net) {
+      return 0;
+   }
+#endif
+   return strcmp(net->name, bridge->name) == 0;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * VNetBridge_Create --
+ *
+ *      Create a bridge.  Allocates/initializes struct, registers
+ *      with kernel for device state changes, connects to virtual
+ *      hub, initializes port/jack, and creates a proc entry.
+ *
+ * Results:
+ *      Errno. Also returns an allocated jack to connect to,
+ *      NULL on error.
+ *
+ * Side effects:
+ *      None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+VNetBridge_Create(const char *devName, // IN:  name of device (e.g., "eth0")
+                  VNetPort **ret)      // OUT: port to virtual hub
+{
+   VNetBridge *bridge = NULL;
+   static unsigned id = 0;
+   int retval = 0;
+
+   *ret = NULL;
+
+   /*
+    * Its an error if device name is empty.
+    */
+
+   if (devName[0] == '\0') {
+      retval = -EINVAL;
+      goto out;
+   }
+
+   /*
+    * Allocate bridge structure
+    */
+
+   bridge = kmalloc(sizeof *bridge, GFP_USER);
+   if (bridge == NULL) {
+      retval = -ENOMEM;
+      goto out;
+   }
+   memset(bridge, 0, sizeof *bridge);
+   spin_lock_init(&bridge->historyLock);
+   memcpy(bridge->name, devName, sizeof bridge->name);
+   NULL_TERMINATE_STRING(bridge->name);
+
+#ifdef VMW_NETDEV_HAS_NET
+   bridge->internalDev = compat_alloc_netdev(0, "vmnetX", VNetBridgeInternalSetup);
+   if (!bridge->internalDev) {
+      retval = -ENOMEM;
+      goto out;
+   }
+#endif
+
+   /*
+    * Set up notifier for network device state change
+    */
+
+   bridge->notifier.notifier_call = VNetBridgeNotify;
+   bridge->notifier.priority = 0;
+   register_netdevice_notifier(&bridge->notifier);
+
+   /*
+    * Try to bring it up
+    */
+
+   retval = VNetBridgeUp(bridge, TRUE);
+   if (retval == -ENODEV) {
+      LOG(1, (KERN_DEBUG "bridge-%s: peer interface %s not found, "
+	      "will wait for it to come up\n",
+	      bridge->name, devName));
+      retval = 0;
+   }
+   if (retval != 0) {
+      goto out;
+   }
+
+   /*
+    * Initialize jack
+    */
+
+   bridge->port.id = id++;
+   bridge->port.next = NULL;
+
+   bridge->port.jack.peer = NULL;
+   bridge->port.jack.numPorts = 1;
+   VNetSnprintf(bridge->port.jack.name, sizeof bridge->port.jack.name,
+		"bridge%u", bridge->port.id);
+   bridge->port.jack.private = bridge;
+   bridge->port.jack.index = 0;
+   bridge->port.jack.procEntry = NULL;
+   bridge->port.jack.free = VNetBridgeFree;
+   bridge->port.jack.rcv = VNetBridgeReceiveFromVNet;
+   bridge->port.jack.cycleDetect = VNetBridgeCycleDetect;
+   bridge->port.jack.portsChanged = VNetBridgePortsChanged;
+   bridge->port.jack.isBridged = VNetBridgeIsBridged;
+
+   /*
+    * Make proc entry for this jack.
+    */
+
+   retval = VNetProc_MakeEntry(NULL, bridge->port.jack.name, S_IFREG,
+                               &bridge->port.jack.procEntry);
+   if (retval) {
+      if (retval == -ENXIO) {
+         bridge->port.jack.procEntry = NULL;
+      } else {
+         goto out;
+      }
+   } else {
+      bridge->port.jack.procEntry->read_proc = VNetBridgeProcRead;
+      bridge->port.jack.procEntry->data = bridge;
+   }
+
+   /*
+    * Rest of fields.
+    */
+
+   bridge->port.flags = IFF_RUNNING;
+
+   memset(bridge->port.paddr, 0, sizeof bridge->port.paddr);
+   memset(bridge->port.ladrf, 0, sizeof bridge->port.ladrf);
+
+   bridge->port.paddr[0] = VMX86_STATIC_OUI0;
+   bridge->port.paddr[1] = VMX86_STATIC_OUI1;
+   bridge->port.paddr[2] = VMX86_STATIC_OUI2;
+
+   bridge->port.fileOpRead = NULL;
+   bridge->port.fileOpWrite = NULL;
+   bridge->port.fileOpIoctl = NULL;
+   bridge->port.fileOpPoll = NULL;
+
+   *ret = &bridge->port;
+
+   LOG(1, (KERN_DEBUG "bridge-%s: attached\n", bridge->name));
+   return 0;
+
+out:
+   if (bridge != NULL) {
+      if (bridge->notifier.notifier_call != NULL) {
+         unregister_netdevice_notifier(&bridge->notifier);
+      }
+#ifdef VMW_NETDEV_HAS_NET
+      if (bridge->internalDev) {
+         compat_free_netdev(bridge->internalDev);
+      }
+#endif
+      kfree(bridge);
+   }
+   return retval;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * VNetBridgeFree --
+ *
+ *      Disconnect the bridge, unregister from device state
+ *      notifications, remove proc entry, and deallocate struct.
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *      None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+VNetBridgeFree(VNetJack *this) // IN: jack to free
+{
+   VNetBridge *bridge = (VNetBridge*)this->private;
+
+   if (bridge->dev != NULL) {
+      VNetBridgeDown(bridge, TRUE);
+   }
+
+   unregister_netdevice_notifier(&bridge->notifier);
+
+#ifdef VMW_NETDEV_HAS_NET
+   if (bridge->internalDev) {
+      compat_free_netdev(bridge->internalDev);
+   }
+#endif
+
+   if (this->procEntry) {
+      VNetProc_RemoveEntry(this->procEntry, NULL);
+   }
+
+   if (bridge->smac){
+      SMAC_CleanupState(&(bridge->smac));
+   }
+
+   LOG(1, (KERN_DEBUG "bridge-%s: detached\n", bridge->name));
+   kfree(bridge);
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * VNetCallSMACFunc --
+ *
+ *      Wrapper for SMAC functions.
+ *
+ * Results:
+ *      Packet Status.
+ *
+ * Side effects:
+ *      The skb buffer is freed if not succesfull otherwise it points to
+ *      the clone.
+ *
+ *----------------------------------------------------------------------
+ */
+
+PacketStatus
+VNetCallSMACFunc(struct SMACState *state, // IN: pointer to state
+                 struct sk_buff **skb,    // IN/OUT: packet to process
+                 void *startOfData,       // IN: points to start of data
+                 SMACFunc func)           // IN: function to be called
+{
+   SMACPackets packets = { {0} };
+   PacketStatus status;
+
+   packets.orig.skb = *skb;
+   packets.orig.startOfData = startOfData;
+
+   status = func(state, &packets);
+   if (status != PacketStatusForwardPacket) {
+      dev_kfree_skb(*skb);
+      return status;
+   }
+
+   if (packets.clone.skb) {
+      dev_kfree_skb(*skb);
+      *skb = packets.clone.skb;
+   }
+   return status;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * VNetBridgeReceiveFromVNet --
+ *
+ *      This jack is receiving a packet from a vnet.  This function
+ *      sends down (i.e., out on the host net device) if the packet
+ *      isn't destined for the host, and it sends up (i.e.,
+ *      simulates a receive for the host) if the packet
+ *      satisfies the host's packet filter.
+ *
+ *      When the function sends up it keeps a reference to the
+ *      packet in a history list so that we can avoid handing
+ *      a VM a copy of its own packet.
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *      Frees skb.  Checks if host device is still using
+ *      promiscuous mode.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+VNetBridgeReceiveFromVNet(VNetJack        *this, // IN: jack
+                          struct sk_buff  *skb)  // IN: pkt to receive
+{
+   VNetBridge *bridge = (VNetBridge*)this->private;
+   struct net_device *dev = bridge->dev;
+   uint8 dest[ETH_ALEN];
+   struct sk_buff *clone;
+
+   LOG(3, (KERN_DEBUG "bridge-%s: transmit %d\n",
+           bridge->name, (int) skb->len));
+
+   if (!dev) {
+      dev_kfree_skb(skb);
+      return;
+   }
+
+   /*
+    * skb might be freed by wireless code, so need to keep
+    * a local copy of the MAC rather than a pointer to it.
+    */
+
+   memcpy(dest, SKB_2_DESTMAC(skb), ETH_ALEN);
+
+   /*
+    * Check promiscuous bit periodically
+    */
+
+   VNetBridgeCheckPromisc(bridge);
+
+#ifdef notdef
+   // xxx;
+   /*
+    * We need to send the packet both up to the host and down
+    * to the interface.
+    * However, we ignore packets destined only for this hub.
+    */
+
+   for (i = 0; i < VNET_PORTS_PER_HUB; i++) {
+      VNetPort *p = &port->hub->port[i];
+      if (UP_AND_RUNNING(p->flags) && MAC_EQ(dest, p->paddr)) {
+	 return;
+      }
+   }
+#endif
+
+   /*
+    * Wireless processing
+    */
+
+   if (bridge->smac) {
+      if (VNetCallSMACFunc(bridge->smac, &skb, skb->data,
+                           SMAC_CheckPacketToHost) !=
+          PacketStatusForwardPacket) {
+         LOG(4, (KERN_NOTICE "bridge-%s: packet dropped .\n",
+                 bridge->name));
+	 return;
+      }
+   }
+
+   /*
+    * Send down (imitate packet_sendmsg)
+    *
+    * Do this only if the packet is not addressed to the peer,
+    * and the packet size is not too big.
+    */
+
+   dev_lock_list();
+   if (MAC_EQ(dest, dev->dev_addr) ||
+       skb->len > dev->mtu + dev->hard_header_len + 4) {
+      dev_unlock_list();
+   } else {
+#     if 0 // XXX we should do header translation
+      if ((dev->flags & IFF_SOFTHEADERS) != 0) {
+	 if (skb->len > dev->mtu) {
+	    clone = NULL;
+	 } else {
+	    clone = dev_alloc_skb(skb->len + dev->hard_header_len, GFP_ATOMIC);
+	 }
+	 if (clone != NULL) {
+	    skb_reserve(clone, dev->hard_header_len);
+	    if (dev->hard_header != NULL) {
+	       dev->hard_header(clone, dev, ETH_P_IP, NULL, NULL, skb->len);
+	    }
+	    memcpy(skb_put(clone, skb->len), skb->data, skb->len);
+	 }
+      }
+#     endif
+      clone = skb_clone(skb, GFP_ATOMIC);
+      if (clone == NULL) {
+	 dev_unlock_list();
+      } else {
+	 struct sock *sk = bridge->sk;
+	 atomic_add(skb->truesize, &sk->sk_wmem_alloc);
+	 clone->sk = sk;
+	 clone->protocol = ((struct ethhdr *)skb->data)->h_proto; // XXX
+	 if ((dev->flags & IFF_UP) != 0) {
+	    dev_unlock_list();
+	    DEV_QUEUE_XMIT(clone, dev, 0);
+	 } else {
+	    dev_unlock_list();
+	    dev_kfree_skb(clone);
+	 }
+      }
+   }
+
+   /*
+    * Send up (imitate Ethernet receive)
+    *
+    * Do this if the packet is addressed to the peer (or is broadcast, etc.).
+    *
+    * This packet will get back to us, via VNetBridgeReceive.
+    * We save it so we can recognize it (and its clones) again.
+    */
+
+   if (VNetPacketMatch(dest, dev->dev_addr, allMultiFilter, dev->flags)) {
+      clone = skb_clone(skb, GFP_ATOMIC);
+      if (clone) {
+	 unsigned long flags;
+	 int i;
+
+	 atomic_inc(&clone->users);
+
+	 clone->dev = dev;
+	 clone->protocol = eth_type_trans(clone, dev);
+	 spin_lock_irqsave(&bridge->historyLock, flags);
+	 for (i = 0; i < VNET_BRIDGE_HISTORY; i++) {
+	    if (bridge->history[i] == NULL) {
+	       bridge->history[i] = clone;
+#	       if LOGLEVEL >= 3
+	       {
+		  int j;
+		  int count = 0;
+		  for (j = 0; j < VNET_BRIDGE_HISTORY; j++) {
+		     if (bridge->history[j] != NULL) {
+			count++;
+		     }
+		  }
+		  LOG(3, (KERN_DEBUG "bridge-%s: host slot %d history %d\n",
+			  bridge->name, i, count));
+	       }
+#	       endif
+	       break;
+	    }
+	 }
+	 if (i >= VNET_BRIDGE_HISTORY) {
+	    LOG(1, (KERN_NOTICE "bridge-%s: history full\n",
+		    bridge->name));
+
+	    for (i = 0; i < VNET_BRIDGE_HISTORY; i++) {
+	       struct sk_buff *s = bridge->history[i];
+
+	       /*
+		* We special case 0 to avoid races with another thread on
+		* another cpu wanting to use the 0 entry. This could happen
+		* when we release the lock to free the former entry.
+		* See bug 11231 for details.
+		*/
+	       if (i == 0) {
+		  bridge->history[0] = clone;
+	       } else {
+		  bridge->history[i] = NULL;
+	       }
+	       if (s) {
+	       	  spin_unlock_irqrestore(&bridge->historyLock, flags);
+		  dev_kfree_skb(s);
+		  spin_lock_irqsave(&bridge->historyLock, flags);
+	       }
+	    }
+	 }
+         spin_unlock_irqrestore(&bridge->historyLock, flags);
+
+         /*
+          * We used to cli() before calling netif_rx() here. It was probably
+          * unneeded (as we never did it in netif.c, and the code worked). In
+          * any case, now that we are using netif_rx_ni(), we should certainly
+          * not do it, or netif_rx_ni() will deadlock on the cli() lock --hpreg
+          */
+
+	 netif_rx_ni(clone);
+#	 if LOGLEVEL >= 4
+	 do_gettimeofday(&vnetTime);
+#	 endif
+      }
+   }
+
+   // xxx;
+   dev_kfree_skb(skb);
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * VNetBridgeCycleDetect --
+ *
+ *      Cycle detection algorithm.
+ *
+ * Results:
+ *      TRUE if a cycle was detected, FALSE otherwise.
+ *
+ * Side effects:
+ *      None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Bool
+VNetBridgeCycleDetect(VNetJack *this,       // IN: jack
+                      int       generation) // IN: generation
+{
+   VNetBridge *bridge = (VNetBridge*)this->private;
+   return VNetCycleDetectIf(bridge->name, generation);
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * VNetBridgePortsChanged --
+ *
+ *      The number of ports connected to this jack has change, react
+ *      accordingly by starting/stopping promiscuous mode based on
+ *      whether any peers exist.
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *      Promiscuous mode may be started or stopped.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+VNetBridgePortsChanged(VNetJack *this) // IN: jack
+{
+   VNetBridge *bridge = (VNetBridge*)this->private;
+   if (bridge->dev) {
+      if (VNetGetAttachedPorts(this)) {
+         VNetBridgeStartPromisc(bridge, TRUE);
+      } else {
+         VNetBridgeStopPromisc(bridge, TRUE);
+      }
+   }
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * VNetBridgeIsBridged --
+ *
+ *      Reports if the bridged interface is up or down.
+ *
+ * Results:
+ *      1 - we are bridged but the interface is not up
+ *      2 - we are bridged and the interface is up
+ *
+ * Side effects:
+ *      None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+VNetBridgeIsBridged(VNetJack *this) // IN: jack
+{
+   VNetBridge *bridge = (VNetBridge*)this->private;
+   if (bridge->dev) {
+      return 2;
+   } else {
+      return 1;
+   }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * VNetBridgeIsDeviceWireless --
+ *
+ *      Check if the device is a wireless adapter, depending on the version
+ *      of the wireless extension present in the kernel.
+ *
+ * Results:
+ *      TRUE if the device is wireless, FALSE otherwise.
+ *
+ * Side effects:
+ *      None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static Bool
+VNetBridgeIsDeviceWireless(struct net_device *dev) //IN: sock
+{
+#ifdef CONFIG_WIRELESS_EXT
+   return dev->wireless_handlers != NULL;
+#elif !defined(CONFIG_NET_RADIO)
+   return FALSE;
+#elif WIRELESS_EXT > 19
+   return dev->wireless_handlers != NULL;
+#elif WIRELESS_EXT > 12
+   return dev->wireless_handlers != NULL || dev->get_wireless_stats != NULL;
+#else
+   return dev->get_wireless_stats != NULL;
+#endif
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * VNetBridgeUp --
+ *
+ *      Bring a bridge up.  Gets peer's device structure, verifies
+ *      that interface is up, checks the header length,
+ *      allocates a socket, adds a packet handler to the network
+ *      stack, and then places the peer's device in promiscuous
+ *      mode.
+ *
+ * Results:
+ *      errno.
+ *
+ * Side effects:
+ *      Bridging may be brought up with a peer interface.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+VNetBridgeUp(VNetBridge *bridge, // IN: bridge struct
+             Bool rtnlLock)      // IN: acquire RTNL lock
+{
+   int retval = 0;
+
+   if (bridge->dev != NULL) {
+      LOG(0, (KERN_NOTICE "bridge-%s: already up\n", bridge->name));
+      goto out;
+   }
+
+   /*
+    * Get peer device structure
+    */
+
+   dev_lock_list();
+   bridge->dev = DEV_GET(bridge);
+   LOG(2, (KERN_DEBUG "bridge-%s: got dev %p\n",
+	   bridge->name, bridge->dev));
+   if (bridge->dev == NULL) {
+      dev_unlock_list();
+      retval = -ENODEV;
+      goto out;
+   }
+   if (!(bridge->dev->flags & IFF_UP)) {
+      LOG(2, (KERN_DEBUG "bridge-%s: interface %s is not up\n",
+              bridge->name, bridge->dev->name));
+      dev_unlock_list();
+      retval = -ENODEV;
+      goto out;
+   }
+
+   /*
+    * At a minimum, the header size should be the same as ours.
+    *
+    * XXX we should either do header translation or ensure this
+    * is an Ethernet.
+    */
+
+   if (bridge->dev->hard_header_len != ETH_HLEN && bridge->dev->hard_header_len != ETH_HLEN + 4) {
+      LOG(1, (KERN_DEBUG "bridge-%s: can't bridge with %s, bad header length %d\n", 
+	      bridge->name, bridge->dev->name, bridge->dev->hard_header_len));
+      dev_unlock_list();
+      retval = -EINVAL;
+      goto out;
+   }
+
+   /*
+    * Get a socket to play with
+    *
+    * We set the dead field so we don't get a call back from dev_kfree_skb().
+    * (The alternative is to support the callback.)
+    */
+
+   bridge->sk = compat_sk_alloc(bridge, GFP_ATOMIC);
+   if (bridge->sk == NULL) {
+      dev_unlock_list();
+      retval = -ENOMEM;
+      goto out;
+   }
+   SET_SK_DEAD(bridge->sk, 1);
+
+   bridge->wirelessAdapter = VNetBridgeIsDeviceWireless(bridge->dev);
+
+   /*
+    * If it is a wireless adapter initialize smac struct.
+    */
+
+   if (bridge->wirelessAdapter) {
+
+      LOG(1, (KERN_NOTICE "bridge-%s: is a Wireless Adapter\n", bridge->name));
+      SMAC_InitState(&(bridge->smac));
+      if (bridge->smac) {
+         /*
+          * Store the MAC address of the adapter
+          */
+
+         SMAC_SetMac(bridge->smac, bridge->dev->dev_addr);
+      }
+   }
+
+   /*
+    * Link up with the peer device by adding a
+    * packet handler to the networking stack.
+    */
+
+   bridge->pt.func = VNetBridgeReceiveFromDev;
+   bridge->pt.type = htons(ETH_P_ALL);
+   bridge->pt.dev = bridge->dev;
+
+   /*
+    * TurboLinux10 uses 2.6.0-test5, which we do not support, so special case it,
+    * 2.6.0 with tl_kernel_version_h is 2.6.0-pre5...
+    */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) || \
+   (LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 0) && defined(__tl_kernel_version_h__))
+   bridge->pt.data = bridge->sk;
+#else
+   bridge->pt.af_packet_priv = bridge->sk;
+#endif
+   bridge->enabledPromisc = FALSE;
+   bridge->warnPromisc = FALSE;
+   dev_add_pack(&bridge->pt);
+   dev_unlock_list();
+
+   /*
+    * Put in promiscuous mode if need be.
+    */
+
+   down(&vnetStructureSemaphore);
+   if (VNetGetAttachedPorts(&bridge->port.jack)) {
+      VNetBridgeStartPromisc(bridge, rtnlLock);
+   }
+   up(&vnetStructureSemaphore);
+
+   /*
+    * Finish up
+    */
+
+   LOG(1, (KERN_DEBUG "bridge-%s: up\n", bridge->name));
+
+   /*
+    * Return
+    */
+
+out:
+   if (retval != 0) {
+      if (bridge->sk != NULL) {
+	 sk_free(bridge->sk);
+	 bridge->sk = NULL;
+      }
+      bridge->dev = NULL;
+   }
+   return retval;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * VNetBridgeDown --
+ *
+ *      Bring a bridge down.  Stops promiscuous mode, removes the
+ *      packet handler from the network stack, and frees the
+ *      socket.
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *      Bridging is brought down.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+VNetBridgeDown(VNetBridge *bridge, // IN: bridge
+               Bool rtnlLock)      // IN: acquire RTNL lock
+{
+   if (bridge->dev == NULL) {
+      LOG(0, (KERN_NOTICE "bridge-%s: already down\n", bridge->name));
+      return;
+   }
+
+   VNetBridgeStopPromisc(bridge, rtnlLock);
+   if (bridge->smac){
+      SMAC_SetMac(bridge->smac, NULL);
+   }
+   bridge->dev = NULL;
+   dev_remove_pack(&bridge->pt);
+   sk_free(bridge->sk);
+   bridge->sk = NULL;
+   LOG(1, (KERN_DEBUG "bridge-%s: down\n", bridge->name));
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * VNetBridgeNotify --
+ *
+ *      Callback on peer device state change.  The function brings
+ *      the bridge up/down in response to changes in the peer device.
+ *
+ * Results:
+ *      NOTIFY_DONE
+ *
+ * Side effects:
+ *      Promiscuous mode is changed when bridge brought up/down.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+int
+VNetBridgeNotify(struct notifier_block *this, // IN: callback data (bridge)
+                 u_long msg,                  // IN: type of event
+                 void *data)                  // IN: device pertaining to event
+{
+   VNetBridge *bridge = list_entry(this, VNetBridge, notifier);
+   struct net_device *dev = (struct net_device *) data;
+
+   switch (msg) {
+   case NETDEV_UNREGISTER:
+      LOG(2, (KERN_DEBUG "bridge-%s: interface %s is unregistering\n",
+              bridge->name, dev->name));
+      if (dev == bridge->dev) {
+         /* This should never happen --hpreg */
+         LOG(0, (KERN_WARNING "bridge-%s: interface %s unregistered without "
+                 "going down! Disabling the bridge\n", bridge->name,
+                 dev->name));
+         VNetBridgeDown(bridge, FALSE);
+      }
+      break;
+
+   case NETDEV_DOWN:
+      LOG(2, (KERN_DEBUG "bridge-%s: interface %s is going down\n",
+              bridge->name, dev->name));
+      if (dev == bridge->dev) {
+         LOG(1, (KERN_DEBUG "bridge-%s: disabling the bridge\n",
+                 bridge->name));
+         VNetBridgeDown(bridge, FALSE);
+      }
+      break;
+
+   case NETDEV_UP:
+      LOG(2, (KERN_DEBUG "bridge-%s: interface %s is going up\n",
+              bridge->name, dev->name));
+      if (bridge->dev == NULL && VNetBridgeDevCompatible(bridge, dev)) {
+         int errno;
+
+         LOG(1, (KERN_DEBUG "bridge-%s: enabling the bridge\n", bridge->name));
+	 errno = VNetBridgeUp(bridge, FALSE);
+	 switch (-errno) {
+	 case 0:
+	    break;
+
+	 case ENODEV:
+            LOG(0, (KERN_WARNING "bridge-%s: interface %s not found or not "
+                    "up\n", bridge->name, dev->name));
+	    break;
+
+	 case EINVAL:
+            LOG(0, (KERN_WARNING "bridge-%s: interface %s is not a valid "
+                    "Ethernet interface\n", bridge->name, dev->name));
+	    break;
+
+	 case ENOMEM:
+            LOG(0, (KERN_WARNING "bridge-%s: failed to allocate memory\n",
+                    bridge->name));
+	    break;
+
+	 default:
+            /* This should never happen --hpreg */
+            LOG(0, (KERN_WARNING "bridge-%s: failed to enable the bridge to "
+                    "interface %s (error %d)\n", bridge->name, dev->name,
+                    -errno));
+            break;
+	 }
+      }
+      break;
+
+   default:
+      LOG(2, (KERN_DEBUG "bridge-%s: interface %s is sending notification "
+              "0x%lx\n", bridge->name, dev->name, msg));
+      break;
+   }
+
+   return NOTIFY_DONE;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * VNetBridgeComputeHeaderPos --
+ *
+ *      Compute correct position for UDP/TCP header.
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *      transport header pointer updated to point to the tcp/udp header.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static INLINE_SINGLE_CALLER void
+VNetBridgeComputeHeaderPos(struct sk_buff *skb) // IN: buffer to examine
+{
+   /* Maybe some kernel gets it right... */
+   if (compat_skb_network_header_len(skb)) {
+      return;
+   }
+   switch (be16_to_cpu(skb->protocol)) {
+      case ETH_P_IP: {
+            struct iphdr *ipHdr = compat_skb_ip_header(skb);
+
+            compat_skb_set_transport_header(skb, compat_skb_network_offset(skb) +
+                                                 ipHdr->ihl * 4);
+         }
+	 return;
+      default:
+         LOG(3, (KERN_DEBUG "Unknown EII protocol %04X: csum at %d\n",
+		 be16_to_cpu(skb->protocol), compat_skb_csum_offset(skb)));
+	 break;
+   }
+   return;
+}
+
+
+/*
+ * We deal with three types of kernels:
+ * New kernels: skb_shinfo() has gso_size member, and there is
+ *              skb_gso_segment() helper to split GSO skb into flat ones.
+ * Older kernels: skb_shinfo() has tso_size member, and there is
+ *                no helper.
+ * Oldest kernels: without any segmentation offload support.
+ */
+#if defined(NETIF_F_GSO) || LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18)
+#define VNetBridgeIsGSO(skb) skb_shinfo(skb)->gso_size
+#define VNetBridgeGSOSegment(skb) skb_gso_segment(skb, 0)
+#elif defined(NETIF_F_TSO)
+#define VNetBridgeIsGSO(skb) skb_shinfo(skb)->tso_size
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * VNetBridgeGSOSegment --
+ *
+ *	Split a large TCP/IPv4 sk_buff into multiple sk_buffs of
+ *	size skb_shinfo(skb)->tso_size
+ *	Called from VNetBridgeSendLargePacket().
+ *
+ * Results:
+ *	List of skbs created.
+ *
+ * Side effects:
+ *	The incoming packet is split into multiple packets.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static struct sk_buff *
+VNetBridgeGSOSegment(struct sk_buff *skb)        // IN: packet to split
+{
+   struct sk_buff *segs = NULL;
+   struct sk_buff **next = &segs;
+   int bytesPerPacket, bytesLeft;
+   int macHdrLen, ipHdrLen, tcpHdrLen, allHdrLen;
+   int curByteOffset;
+   uint16 ipID;
+   uint32 seqNo;
+
+   if (((struct ethhdr *)compat_skb_mac_header(skb))->h_proto != htons(ETH_P_IP)) {
+      return ERR_PTR(-EPFNOSUPPORT);
+   }
+
+   if (compat_skb_ip_header(skb)->protocol != IPPROTO_TCP) {
+      return ERR_PTR(-EPROTONOSUPPORT);
+   }
+
+   macHdrLen = compat_skb_network_header(skb) - compat_skb_mac_header(skb);
+   ipHdrLen = compat_skb_ip_header(skb)->ihl << 2;
+   tcpHdrLen = compat_skb_tcp_header(skb)->doff << 2;
+   allHdrLen = macHdrLen + ipHdrLen + tcpHdrLen;
+
+   ipID = ntohs(compat_skb_ip_header(skb)->id);
+   seqNo = ntohl(compat_skb_tcp_header(skb)->seq);
+
+   /* Host TCP stack populated this (MSS) for the host NIC driver */
+   bytesPerPacket = skb_shinfo(skb)->tso_size;
+
+   bytesLeft = skb->len - allHdrLen;
+   curByteOffset = allHdrLen;
+
+   while (bytesLeft) {
+      struct sk_buff *newSkb;
+      int payloadSize = (bytesLeft < bytesPerPacket) ? bytesLeft : bytesPerPacket;
+
+      newSkb = dev_alloc_skb(payloadSize + allHdrLen + NET_IP_ALIGN);
+      if (!newSkb) {
+         while (segs) {
+            newSkb = segs;
+            segs = segs->next;
+            newSkb->next = NULL;
+            dev_kfree_skb(newSkb);
+         }
+         return ERR_PTR(-ENOMEM);
+      }
+      skb_reserve(newSkb, NET_IP_ALIGN);
+      newSkb->dev = skb->dev;
+      newSkb->protocol = skb->protocol;
+      newSkb->pkt_type = skb->pkt_type;
+      newSkb->ip_summed = VM_CHECKSUM_PARTIAL;
+
+      /*
+       * MAC+IP+TCP copy
+       * This implies that ALL fields in the IP and TCP headers are copied from
+       * the original skb. This is convenient: we'll only fix up fields that
+       * need to be changed below
+       */
+      memcpy(skb_put(newSkb, allHdrLen), skb->data, allHdrLen);
+
+      /* Fix up pointers to different layers */
+      compat_skb_reset_mac_header(newSkb);
+      compat_skb_set_network_header(newSkb, macHdrLen);
+      compat_skb_set_transport_header(newSkb, macHdrLen + ipHdrLen);
+
+      /* Payload copy */
+      skb_copy_bits(skb, curByteOffset, compat_skb_tail_pointer(newSkb), payloadSize);
+      skb_put(newSkb, payloadSize);
+
+      curByteOffset+=payloadSize;
+      bytesLeft -= payloadSize;
+
+      /* Fix up IP hdr */
+      compat_skb_ip_header(newSkb)->tot_len = htons(payloadSize + tcpHdrLen + ipHdrLen);
+      compat_skb_ip_header(newSkb)->id = htons(ipID);
+      compat_skb_ip_header(newSkb)->check = 0;
+      /* Recompute new IP checksum */
+      compat_skb_ip_header(newSkb)->check =
+              ip_fast_csum(compat_skb_network_header(newSkb),
+                           compat_skb_ip_header(newSkb)->ihl);
+
+      /* Fix up TCP hdr */
+      compat_skb_tcp_header(newSkb)->seq = htonl(seqNo);
+      /* Clear FIN/PSH if not last packet */
+      if (bytesLeft > 0) {
+         compat_skb_tcp_header(newSkb)->fin = 0;
+         compat_skb_tcp_header(newSkb)->psh = 0;
+      }
+      /* Recompute partial TCP checksum */
+      compat_skb_tcp_header(newSkb)->check =
+         ~csum_tcpudp_magic(compat_skb_ip_header(newSkb)->saddr,
+                            compat_skb_ip_header(newSkb)->daddr,
+                            payloadSize+tcpHdrLen, IPPROTO_TCP, 0);
+
+      /* Offset of field */
+      newSkb->csum = offsetof(struct tcphdr, check);
+
+      /* Join packet to the list of segments */
+      *next = newSkb;
+      next = &newSkb->next;
+
+      /* Bump up our counters */
+      ipID++;
+      seqNo += payloadSize;
+
+   }
+   return segs;
+}
+#else
+#define VNetBridgeIsGSO(skb) (0)
+#define VNetBridgeGSOSegment(skb) ERR_PTR(-ENOSYS)
+#endif
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * VNetBridgeSendLargePacket --
+ *
+ *      Split and send a large TCP/IPv4 sk_buff into multiple sk_buffs which
+ *      fits on wire.  Called from VNetBridgeReceiveFromDev(), which is a
+ *	protocol handler called from the bottom half, so steady as she
+ *	goes...
+ *
+ *	skb passed in is deallocated by function.
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *      The incoming packet is split into multiple packets and sent to the
+ *      vnet.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+VNetBridgeSendLargePacket(struct sk_buff *skb,        // IN: packet to split
+                          VNetBridge *bridge)         // IN: bridge
+{
+   struct sk_buff *segs;
+
+   segs = VNetBridgeGSOSegment(skb);
+   dev_kfree_skb(skb);
+   if (IS_ERR(segs)) {
+      LOG(1, (KERN_DEBUG "bridge-%s: cannot segment packet: error %ld\n",
+              bridge->name, PTR_ERR(segs)));
+      return;
+   }
+
+   while (segs) {
+      struct sk_buff *newSkb;
+
+      newSkb = segs;
+      segs = newSkb->next;
+      newSkb->next = NULL;
+      /* Send it along */
+      skb = newSkb;
+      VNetSend(&bridge->port.jack, newSkb);
+   }
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * VNetBridgeReceiveFromDev --
+ *
+ *      Receive a packet from a bridged peer device
+ *
+ *      This is called from the bottom half.  Must be careful.
+ *
+ * Results:
+ *      errno.
+ *
+ * Side effects:
+ *      A packet may be sent to the vnet.
+ *
+ *----------------------------------------------------------------------
+ */
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 14) && \
+    !defined(VMW_TL10S64_WORKAROUND)
+int
+VNetBridgeReceiveFromDev(struct sk_buff *skb,         // IN: packet to receive
+                         struct net_device *dev,      // IN: unused
+                         struct packet_type *pt)      // IN: pt (pointer to bridge)
+#else
+int
+VNetBridgeReceiveFromDev(struct sk_buff *skb,         // IN: packet to receive
+                         struct net_device *dev,      // IN: unused
+                         struct packet_type *pt,      // IN: pt (pointer to bridge)
+                         struct net_device *real_dev) // IN: real device, unused
+#endif
+{
+   VNetBridge *bridge = list_entry(pt, VNetBridge, pt);
+   int i;
+   unsigned long flags;
+
+   if (bridge->dev == NULL) {
+      LOG(3, (KERN_DEBUG "bridge-%s: received %d closed\n",
+	      bridge->name, (int) skb->len));
+      dev_kfree_skb(skb);
+      return -EIO;	// value is ignored anyway
+   }
+
+   /*
+    * Check is this is a packet that we sent up to the host, and if
+    * so then don't bother to receive the packet.
+    */
+
+   spin_lock_irqsave(&bridge->historyLock, flags);
+   for (i = 0; i < VNET_BRIDGE_HISTORY; i++) {
+      struct sk_buff *s = bridge->history[i];
+      if (s != NULL &&
+	  (s == skb || SKB_IS_CLONE_OF(skb, s))) {
+	 bridge->history[i] = NULL;
+	 spin_unlock_irqrestore(&bridge->historyLock, flags);
+	 dev_kfree_skb(s);
+	 LOG(3, (KERN_DEBUG "bridge-%s: receive %d self %d\n",
+		 bridge->name, (int) skb->len, i));
+	 dev_kfree_skb(skb);
+	 return 0;
+      }
+   }
+   spin_unlock_irqrestore(&bridge->historyLock, flags);
+
+#  if LOGLEVEL >= 4
+   {
+      struct timeval now;
+      do_gettimeofday(&now);
+      LOG(3, (KERN_DEBUG "bridge-%s: time %d\n",
+	      bridge->name,
+	      (int)((now.tv_sec * 1000000 + now.tv_usec)
+                    - (vnetTime.tv_sec * 1000000 + vnetTime.tv_usec))));
+   }
+#  endif
+
+   if (bridge->smac) {
+      if (VNetCallSMACFunc(bridge->smac, &skb, compat_skb_mac_header(skb),
+                           SMAC_CheckPacketFromHost) !=
+          PacketStatusForwardPacket) {
+         LOG(4, (KERN_NOTICE "bridge-%s: packet dropped .\n",
+                 bridge->name));
+	 return 0;
+      }
+   }
+
+#ifdef KERNEL_2_3_15
+   skb = skb_share_check(skb, GFP_ATOMIC);
+   if (!skb) {
+      return 0;
+   }
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 4)
+   /*
+    * Unbelievable... Caller sets h.raw = nh.raw before invoking us...
+    */
+   VNetBridgeComputeHeaderPos(skb);
+#endif
+#endif
+
+   skb_push(skb, skb->data - compat_skb_mac_header(skb));
+   LOG(3, (KERN_DEBUG "bridge-%s: receive %d\n",
+	   bridge->name, (int) skb->len));
+
+   /*
+    * If this is a large packet, chop chop chop (if supported)...
+    */
+   if (VNetBridgeIsGSO(skb)) {
+      VNetBridgeSendLargePacket(skb, bridge);
+   } else {
+      VNetSend(&bridge->port.jack, skb);
+   }
+
+   return 0;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * VNetBridgeProcRead --
+ *
+ *      Callback for read operation on this bridge entry in vnets proc fs.
+ *
+ * Results:
+ *      Length of read operation.
+ *
+ * Side effects:
+ *      None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+VNetBridgeProcRead(char    *page,   // IN/OUT: buffer to write into
+                   char   **start,  // OUT: 0 if file < 4k, else offset into page
+                   off_t    off,    // IN: (unused) offset of read into the file
+                   int      count,  // IN: (unused) maximum number of bytes to read
+                   int     *eof,    // OUT: TRUE if there is nothing more to read
+                   void    *data)   // IN: client data - pointer to bridge
+{
+   VNetBridge *bridge = (VNetBridge*)data;
+   int len = 0;
+
+   if (!bridge) {
+      return len;
+   }
+
+   len += VNetPrintPort(&bridge->port, page+len);
+
+   len += sprintf(page+len, "dev %s ", bridge->name);
+
+   len += sprintf(page+len, "\n");
+
+   *start = 0;
+   *eof   = 1;
+   return len;
+}
diff -ruN vmnet-only-patched/compat_semaphore.h vmnet-only-refixed/compat_semaphore.h
--- vmnet-only-patched/compat_semaphore.h	2009-07-08 16:21:02.000000000 +0300
+++ vmnet-only-refixed/compat_semaphore.h	2008-10-20 16:35:18.000000000 +0300
@@ -6,11 +6,7 @@
 #   define __COMPAT_SEMAPHORE_H__
 
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
 #include <linux/semaphore.h>
-#else
-#include <asm/semaphore.h>
-#endif
 
 
 /*
diff -ruN vmnet-only-patched/compat_wait.h vmnet-only-refixed/compat_wait.h
--- vmnet-only-patched/compat_wait.h	2009-07-08 16:21:02.000000000 +0300
+++ vmnet-only-refixed/compat_wait.h	2009-04-21 18:16:24.000000000 +0300
@@ -37,14 +37,12 @@
  * /dev/epoll interface was added.  It was backported to the
  * 2.4.20-wolk4.0s.
  */
-
-#ifdef VMW_HAVE_EPOLL // {
+#if VMW_HAVE_EPOLL // {
 #define compat_poll_wqueues struct poll_wqueues
 #else // } {
 #define compat_poll_wqueues poll_table
 #endif // }
-
-#ifdef VMW_HAVE_EPOLL // {
+#if VMW_HAVE_EPOLL // {
 
 /* If prototype does not match, build will abort here */
 extern void poll_initwait(compat_poll_wqueues *);
diff -ruN vmnet-only-patched/filter.c vmnet-only-refixed/filter.c
--- vmnet-only-patched/filter.c	2009-07-08 16:21:02.000000000 +0300
+++ vmnet-only-refixed/filter.c	2008-07-24 18:21:23.000000000 +0300
@@ -13,11 +13,9 @@
 #include "compat_skbuff.h"
 #include <linux/netdevice.h>
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)
-#   define NF_IP_LOCAL_OUT NF_INET_LOCAL_OUT
-#   define NF_IP_LOCAL_IN NF_INET_LOCAL_IN
-#   define NF_IP_POST_ROUTING NF_INET_POST_ROUTING
-#endif
+#define NF_IP_LOCAL_OUT NF_INET_LOCAL_OUT
+#define NF_IP_LOCAL_IN NF_INET_LOCAL_IN
+#define NF_IP_POST_ROUTING NF_INET_POST_ROUTING
 
 /*
  * All this makes sense only if NETFILTER support is configured in our kernel.
diff -ruN vmnet-only-patched/Makefile vmnet-only-refixed/Makefile
--- vmnet-only-patched/Makefile	2009-07-08 16:21:02.000000000 +0300
+++ vmnet-only-refixed/Makefile	2007-11-28 12:19:12.000000000 +0200
@@ -15,7 +15,7 @@
 VM_UNAME = $(shell uname -r)
 
 # Header directory for the running kernel
-HEADER_DIR = ${KERNEL_DIR}/include
+HEADER_DIR = /lib/modules/$(VM_UNAME)/build/include
 
 BUILD_DIR = $(HEADER_DIR)/..
 
diff -ruN vmnet-only-patched/Makefile.kernel vmnet-only-refixed/Makefile.kernel
--- vmnet-only-patched/Makefile.kernel	2009-07-08 16:21:02.000000000 +0300
+++ vmnet-only-refixed/Makefile.kernel	2009-04-21 18:27:50.000000000 +0300
@@ -12,7 +12,8 @@
 INCLUDE := -I$(SRCROOT)
 
 EXTRA_CFLAGS := $(CC_OPTS) $(INCLUDE)
-EXTRA_CFLAGS += $(call vm_check_build, $(SRCROOT)/epoll.c,   -DVMW_HAVE_EPOLL, )
+#EXTRA_CFLAGS += $(call vm_check_build, $(SRCROOT)/epoll.c,   -DVMW_HAVE_EPOLL, )
+EXTRA_CFLAGS += -I$(HEADER_DIR) -DVMW_HAVE_EPOLL 
 EXTRA_CFLAGS += $(call vm_check_build, $(SRCROOT)/socket.c,  -DVMW_HAVE_SK_WMEM_ALLOC, )
 EXTRA_CFLAGS += $(call vm_check_build, $(SRCROOT)/sk_alloc.c,-DVMW_HAVE_SK_ALLOC_WITH_PROTO, )
 EXTRA_CFLAGS += $(call vm_check_build, $(SRCROOT)/netdev_has_net.c,-DVMW_NETDEV_HAS_NET, )
diff -ruN vmnet-only-patched/Makefile.normal vmnet-only-refixed/Makefile.normal
--- vmnet-only-patched/Makefile.normal	2009-07-08 16:21:02.000000000 +0300
+++ vmnet-only-refixed/Makefile.normal	2009-04-21 18:28:04.000000000 +0300
@@ -37,7 +37,8 @@
 	   | sed -n -e 's!^APATH!-I$(HEADER_DIR)/asm!p')
 
 CC_OPTS += -DVME_DEFAULT=$(VMWARE_VER)
-CC_OPTS += $(call vm_check_build, $(SRCROOT)/epoll.c,   -DVMW_HAVE_EPOLL, )
+#CC_OPTS += $(call vm_check_build, $(SRCROOT)/epoll.c,   -DVMW_HAVE_EPOLL, )
+EXTRA_CFLAGS += -I$(HEADER_DIR) -DVMW_HAVE_EPOLL
 CC_OPTS += $(call vm_check_build, $(SRCROOT)/socket.c,  -DVMW_HAVE_SK_WMEM_ALLOC, )
 CC_OPTS += $(call vm_check_build, $(SRCROOT)/sk_alloc.c,-DVMW_HAVE_SK_ALLOC_WITH_PROTO, )
 CC_OPTS += $(call vm_check_build, $(SRCROOT)/netdev_has_net.c,-DVMW_NETDEV_HAS_NET, )
diff -ruN vmnet-only-patched/Module.markers vmnet-only-refixed/Module.markers
--- vmnet-only-patched/Module.markers	1970-01-01 02:00:00.000000000 +0200
+++ vmnet-only-refixed/Module.markers	2008-10-20 16:35:37.000000000 +0300
@@ -0,0 +1,4 @@
+core_marker_format	vmlinux	name %s format %s
+kernel_sched_schedule	vmlinux	prev_pid %d next_pid %d prev_state %ld ## rq %p prev %p next %p
+kernel_sched_wakeup	vmlinux	pid %d state %ld ## rq %p task %p rq->curr %p
+kernel_sched_wakeup_new	vmlinux	pid %d state %ld ## rq %p task %p rq->curr %p
diff -ruN vmnet-only-patched/modules.order vmnet-only-refixed/modules.order
--- vmnet-only-patched/modules.order	1970-01-01 02:00:00.000000000 +0200
+++ vmnet-only-refixed/modules.order	2009-04-21 18:30:09.000000000 +0300
@@ -0,0 +1 @@
+kernel//home/kang/tmp/vmware-update-2.6.27-5.5.7-2/vmnet-only/vmnet.ko
diff -ruN vmnet-only-patched/netif.c vmnet-only-refixed/netif.c
--- vmnet-only-patched/netif.c	2009-07-08 16:21:02.000000000 +0300
+++ vmnet-only-refixed/netif.c	2009-04-21 18:03:24.000000000 +0300
@@ -310,7 +310,7 @@
       goto out;
    }
 
-   dev->priv = netIf;
+   dev->ml_priv = netIf;
    netIf->dev = dev;
    
    memcpy(dev->dev_addr, netIf->port.paddr, sizeof netIf->port.paddr);
@@ -552,7 +552,7 @@
 VNetNetifStartXmit(struct sk_buff    *skb, // IN:
                    struct net_device *dev) // IN:
 {
-   VNetNetIF *netIf = (VNetNetIF*)dev->priv;
+   VNetNetIF *netIf = (VNetNetIF*)dev->ml_priv;
 
    if(skb == NULL) {
       return 0;
@@ -604,7 +604,7 @@
 VNetNetifSetMAC(struct net_device *dev, // IN:
                 void *p)                // IN:
 {
-   VNetNetIF *netIf = (VNetNetIF*)dev->priv;
+   VNetNetIF *netIf = (VNetNetIF*)dev->ml_priv;
    struct sockaddr const *addr = p;
    if (!VMX86_IS_STATIC_MAC(addr->sa_data)) {
       return -EINVAL;
@@ -661,7 +661,7 @@
 struct net_device_stats *
 VNetNetifGetStats(struct net_device *dev) // IN:
 {
-   VNetNetIF *netIf = (VNetNetIF*)dev->priv;
+   VNetNetIF *netIf = (VNetNetIF*)dev->ml_priv;
    return &(netIf->stats);
 }
 
diff -ruN vmnet-only-patched/vmnetInt.h vmnet-only-refixed/vmnetInt.h
--- vmnet-only-patched/vmnetInt.h	2009-07-08 16:21:02.000000000 +0300
+++ vmnet-only-refixed/vmnetInt.h	2008-07-24 18:31:28.000000000 +0300
@@ -63,11 +63,7 @@
 #   define dev_lock_list()    read_lock(&dev_base_lock)
 #   define dev_unlock_list()  read_unlock(&dev_base_lock)
 #   ifdef VMW_NETDEV_HAS_NET
-#     if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26)
-#      define DEV_GET(x)      __dev_get_by_name((x)->internalDev->nd_net, (x)->name)
-#     else
 #      define DEV_GET(x)      __dev_get_by_name(dev_net((x)->internalDev), (x)->name)
-#     endif
 #   else
 #      define DEV_GET(x)      __dev_get_by_name((x)->name)
 #   endif
@@ -91,13 +87,8 @@
 
 #ifdef VMW_NETDEV_HAS_NET
 extern struct proto vmnet_proto;
-#  if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)
 #   define compat_sk_alloc(_bri, _pri) sk_alloc(dev_net((_bri)->internalDev), \
                                                 PF_NETLINK, _pri, &vmnet_proto)
-#  else
-#   define compat_sk_alloc(_bri, _pri) sk_alloc((_bri)->internalDev->nd_net, \
-                                                PF_NETLINK, _pri, &vmnet_proto)
-#  endif
 #elif defined(VMW_HAVE_SK_ALLOC_WITH_PROTO)
 extern struct proto vmnet_proto;
 #   define compat_sk_alloc(_bri, _pri) sk_alloc(PF_NETLINK, _pri, &vmnet_proto, 1)
diff -ruN vmnet-only-patched/vmnetInt.h.orig vmnet-only-refixed/vmnetInt.h.orig
--- vmnet-only-patched/vmnetInt.h.orig	1970-01-01 02:00:00.000000000 +0200
+++ vmnet-only-refixed/vmnetInt.h.orig	2007-11-28 12:25:06.000000000 +0200
@@ -0,0 +1,144 @@
+/* **********************************************************
+ * Copyright 1998 VMware, Inc.  All rights reserved. -- VMware Confidential
+ * **********************************************************/
+
+#ifndef __VMNETINT_H__
+#define __VMNETINT_H__
+
+
+#define INCLUDE_ALLOW_MODULE
+#include "includeCheck.h"
+#include "driver-config.h"
+
+
+/*
+ * Hide all kernel compatibility stuff in those macros
+ */
+
+/* All kernels above 2.6.23 have net namespaces. */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) && !defined(VMW_NETDEV_HAS_NET)
+#   define VMW_NETDEV_HAS_NET
+#endif
+
+/* All kernels above 2.6.23 have skb argument in nf_hookfn. */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) && !defined(VMW_NFHOOK_USES_SKB)
+#   define VMW_NFHOOK_USES_SKB
+#endif
+
+
+#ifdef KERNEL_2_4_0
+#   define compat_fop_set_owner(_pFop) do { \
+   (_pFop)->owner = THIS_MODULE;            \
+} while (0)
+#   define compat_mod_inc_refcount
+#   define compat_mod_dec_refcount
+#else
+#   define compat_fop_set_owner(_pFop)
+#   define compat_mod_inc_refcount do { \
+   MOD_INC_USE_COUNT;                   \
+} while (0)
+#   define compat_mod_dec_refcount do { \
+   MOD_DEC_USE_COUNT;                   \
+} while (0)
+#endif
+
+
+#ifdef skb_shinfo
+#  define SKB_IS_CLONE_OF(clone, skb)   (  \
+      skb_shinfo(clone) == skb_shinfo(skb) \
+   )
+#else
+#  define SKB_IS_CLONE_OF(clone, skb)   (      \
+      skb_datarefp(clone) == skb_datarefp(skb) \
+   )
+#endif
+#define DEV_QUEUE_XMIT(skb, dev, pri)   (                 \
+    (skb)->dev = (dev),                                   \
+    (skb)->priority = (pri),                              \
+    compat_skb_reset_mac_header(skb),                     \
+    compat_skb_set_network_header(skb, sizeof (struct ethhdr)),  \
+    dev_queue_xmit(skb)                                   \
+  )
+#ifdef KERNEL_2_3_15
+#   define dev_lock_list()    read_lock(&dev_base_lock)
+#   define dev_unlock_list()  read_unlock(&dev_base_lock)
+#   ifdef VMW_NETDEV_HAS_NET
+#      define DEV_GET(x)      __dev_get_by_name((x)->internalDev->nd_net, (x)->name)
+#   else
+#      define DEV_GET(x)      __dev_get_by_name((x)->name)
+#   endif
+#else
+#   define DEV_GET(x)         dev_get((x)->name)
+#endif
+
+
+/*
+ * Various fields (including 'dead') of struct sock are replaced with the
+ * 'flags' bitfield in 2.5.65 --hpreg
+ */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 65)
+#   define SET_SK_DEAD(_sk, _val) (_sk)->dead = (_val)
+#else
+#   define SET_SK_DEAD(_sk, _val) sock_valbool_flag(_sk, SOCK_DEAD, _val)
+#endif
+
+
+#ifdef VMW_NETDEV_HAS_NET
+extern struct proto vmnet_proto;
+#   define compat_sk_alloc(_bri, _pri) sk_alloc((_bri)->internalDev->nd_net, \
+                                                PF_NETLINK, _pri, &vmnet_proto)
+#elif defined(VMW_HAVE_SK_ALLOC_WITH_PROTO)
+extern struct proto vmnet_proto;
+#   define compat_sk_alloc(_bri, _pri) sk_alloc(PF_NETLINK, _pri, &vmnet_proto, 1)
+#elif defined(KERNEL_2_5_5)
+#   define compat_sk_alloc(_bri, _pri) sk_alloc(PF_NETLINK, _pri, 1, NULL)
+#else
+#   define compat_sk_alloc(_bri, _pri) sk_alloc(0, _pri, 1)
+#endif
+
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+#   define fileTraversalLock(lock) spin_lock(lock)
+#   define fileTraversalUnLock(lock) spin_unlock(lock)
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+#   define fileTraversalLock(lock) read_lock(lock)
+#   define fileTraversalUnLock(lock) read_unlock(lock)
+#else //2.2 kernels
+#   define fileTraversalLock(lock) lock_kernel()
+#   define fileTraversalUnLock(lock) unlock_kernel()
+#endif
+
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+#   define taskLock(lock) task_lock(lock)
+#   define taskUnLock(lock) task_unlock(lock)
+#else //2.2 kernels
+#   define taskLock(lock) lock_kernel()
+#   define taskUnLock(lock) unlock_kernel()
+#endif
+
+
+/* 
+ * Use CHECKSUM_HW for old kernels, if they have CHECKSUM_HW.  Use CHECKSUM_PARTIAL for 
+ * new ones even if CHECKSUM_HW is defined.  We do not do decision based on kernel version
+ * only as CHECKSUM_PARTIAL was in mm tree for some time already, and we do not test
+ * for CHECKSUM_PARTIAL existence as it may get converted to enum in future.
+ */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) && defined(CHECKSUM_HW)
+#   define VM_CHECKSUM_PARTIAL  CHECKSUM_HW
+#else
+#   define VM_CHECKSUM_PARTIAL  CHECKSUM_PARTIAL
+#endif
+
+
+/*
+ * The "owner" field in nf_hook_ops got added in 2.5.69
+ */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 69)
+#   define compat_nf_hook_owner  .owner = THIS_MODULE,
+#else
+#   define compat_nf_hook_owner
+#endif
+
+
+#endif /* __VMNETINT_H__ */