Go to:
Gentoo Home
Documentation
Forums
Lists
Bugs
Planet
Store
Wiki
Get Gentoo!
Gentoo's Bugzilla – Attachment 197273 Details for
Bug 273173
app-emulation/vmware-modules-1.0.0.15-r2 fails to build with sys-kernel/gentoo-sources-{2.6.29-{r2,r5},2.6.30-r5}
Home
|
New
–
[Ex]
|
Browse
|
Search
|
Privacy Policy
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
vmnet module patch for kernels 2.6.29 and 2.6.30
040_all_kernel-2.6.29.patch (text/plain), 55.34 KB, created by
Jani-Matti Hätinen
on 2009-07-08 22:02:54 UTC
(
hide
)
Description:
vmnet module patch for kernels 2.6.29 and 2.6.30
Filename:
MIME Type:
Creator:
Jani-Matti Hätinen
Created:
2009-07-08 22:02:54 UTC
Size:
55.34 KB
patch
obsolete
>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__ */
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 273173
:
197271
| 197273 |
197274
|
199335
|
216747