]> git.pld-linux.org Git - packages/VMware-player.git/commitdiff
- allow build on 2.6.25.14
authorAndrzej Augustynowicz <andrzej@augustynowicz.eu.org>
Sat, 30 Aug 2008 17:03:20 +0000 (17:03 +0000)
committercvs2git <feedback@pld-linux.org>
Sun, 24 Jun 2012 12:13:13 +0000 (12:13 +0000)
Changed files:
    VMware-player-vmnet.patch -> 1.1

VMware-player-vmnet.patch [new file with mode: 0644]

diff --git a/VMware-player-vmnet.patch b/VMware-player-vmnet.patch
new file mode 100644 (file)
index 0000000..c974b56
--- /dev/null
@@ -0,0 +1,1748 @@
+diff -Nur old/vmware-any-any-update117d/vmnet-only/bridge.c new/vmware-any-any-update117d/vmnet-only/bridge.c
+--- old/vmware-any-any-update117d/vmnet-only/bridge.c  2008-08-30 15:50:06.800648000 +0000
++++ new/vmware-any-any-update117d/vmnet-only/bridge.c  2008-08-30 16:10:34.153352750 +0000
+@@ -275,7 +275,7 @@
+                         struct net_device *net)  // IN: Network device
+ {
+ #ifdef VMW_NETDEV_HAS_NET
+-   if (dev_net(net) != dev_net(bridge->internalDev)) {
++   if (net->nd_net != bridge->internalDev->nd_net) {
+       return 0;
+    }
+ #endif
+diff -Nur old/vmware-any-any-update117d/vmnet-only/bridge.c~ new/vmware-any-any-update117d/vmnet-only/bridge.c~
+--- old/vmware-any-any-update117d/vmnet-only/bridge.c~ 1970-01-01 00:00:00.000000000 +0000
++++ new/vmware-any-any-update117d/vmnet-only/bridge.c~ 2008-08-30 15:57:32.192483250 +0000
+@@ -0,0 +1,1550 @@
++/* **********************************************************
++ * 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(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) {
++      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, (uint8 *)&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
++{
++#if !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) {
++      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);
++
++   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 -Nur old/vmware-any-any-update117d/vmnet-only/vmnetInt.h new/vmware-any-any-update117d/vmnet-only/vmnetInt.h
+--- old/vmware-any-any-update117d/vmnet-only/vmnetInt.h        2008-08-30 15:50:06.800648000 +0000
++++ new/vmware-any-any-update117d/vmnet-only/vmnetInt.h        2008-08-30 15:59:47.768956250 +0000
+@@ -63,7 +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
+-#      define DEV_GET(x)      __dev_get_by_name(dev_net((x)->internalDev), (x)->name)
++#      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
+@@ -89,7 +89,7 @@
+ #ifdef VMW_NETDEV_HAS_NET
+ extern struct proto vmnet_proto;
+-#   define compat_sk_alloc(_bri, _pri) sk_alloc(dev_net((_bri)->internalDev), \
++#   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;
+diff -Nur old/vmware-any-any-update117d/vmnet-only/vmnetInt.h~ new/vmware-any-any-update117d/vmnet-only/vmnetInt.h~
+--- old/vmware-any-any-update117d/vmnet-only/vmnetInt.h~       1970-01-01 00:00:00.000000000 +0000
++++ new/vmware-any-any-update117d/vmnet-only/vmnetInt.h~       2008-08-30 15:49:59.016161500 +0000
+@@ -0,0 +1,157 @@
++/* **********************************************************
++ * 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(dev_net((x)->internalDev), (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, with sock_valbool_flag() to set flag's
++ * value.  Since 2.5.71 there is sock_set_flag() to set bit to 1, and
++ * since 2.6.25-rc1 sock_valbool_flag() is gone.
++ */
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 65)
++#   define SET_SK_DEAD(_sk) (_sk)->dead = 1
++#elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 71)
++#   define SET_SK_DEAD(_sk) sock_valbool_flag(_sk, SOCK_DEAD, 1)
++#else
++#   define SET_SK_DEAD(_sk) sock_set_flag(_sk, SOCK_DEAD)
++#endif
++
++
++#ifdef VMW_NETDEV_HAS_NET
++extern struct proto vmnet_proto;
++#   define compat_sk_alloc(_bri, _pri) sk_alloc(dev_net((_bri)->internalDev), \
++                                                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
++
++
++#ifdef NF_IP_LOCAL_IN
++#define VMW_NF_INET_LOCAL_IN     NF_IP_LOCAL_IN
++#define VMW_NF_INET_POST_ROUTING NF_IP_POST_ROUTING
++#else
++#define VMW_NF_INET_LOCAL_IN     NF_INET_LOCAL_IN
++#define VMW_NF_INET_POST_ROUTING NF_INET_POST_ROUTING
++#endif
++
++
++#endif /* __VMNETINT_H__ */
This page took 0.112709 seconds and 4 git commands to generate.