]> git.pld-linux.org Git - packages/VMware-player.git/blame - VMware-player-vmnet.patch
- allow build on 2.6.25.14
[packages/VMware-player.git] / VMware-player-vmnet.patch
CommitLineData
867ec289
AA
1diff -Nur old/vmware-any-any-update117d/vmnet-only/bridge.c new/vmware-any-any-update117d/vmnet-only/bridge.c
2--- old/vmware-any-any-update117d/vmnet-only/bridge.c 2008-08-30 15:50:06.800648000 +0000
3+++ new/vmware-any-any-update117d/vmnet-only/bridge.c 2008-08-30 16:10:34.153352750 +0000
4@@ -275,7 +275,7 @@
5 struct net_device *net) // IN: Network device
6 {
7 #ifdef VMW_NETDEV_HAS_NET
8- if (dev_net(net) != dev_net(bridge->internalDev)) {
9+ if (net->nd_net != bridge->internalDev->nd_net) {
10 return 0;
11 }
12 #endif
13diff -Nur old/vmware-any-any-update117d/vmnet-only/bridge.c~ new/vmware-any-any-update117d/vmnet-only/bridge.c~
14--- old/vmware-any-any-update117d/vmnet-only/bridge.c~ 1970-01-01 00:00:00.000000000 +0000
15+++ new/vmware-any-any-update117d/vmnet-only/bridge.c~ 2008-08-30 15:57:32.192483250 +0000
16@@ -0,0 +1,1550 @@
17+/* **********************************************************
18+ * Copyright 1998 VMware, Inc. All rights reserved. -- VMware Confidential
19+ * **********************************************************/
20+
21+#include "driver-config.h"
22+
23+#define EXPORT_SYMTAB
24+
25+#include <linux/kernel.h>
26+#include <linux/version.h>
27+#include <linux/sched.h>
28+#ifdef KERNEL_2_2
29+# include <linux/slab.h>
30+#else
31+# include <linux/malloc.h>
32+#endif
33+#include <linux/poll.h>
34+
35+#include <linux/netdevice.h>
36+#include <linux/etherdevice.h>
37+#include <linux/mm.h>
38+#include "compat_skbuff.h"
39+#include <linux/sockios.h>
40+#include "compat_sock.h"
41+
42+#define __KERNEL_SYSCALLS__
43+#include <asm/io.h>
44+
45+#include <linux/proc_fs.h>
46+#include <linux/file.h>
47+#include <linux/ip.h>
48+#include <linux/tcp.h>
49+#include <net/tcp.h>
50+
51+#ifdef CONFIG_NET_RADIO
52+# include <linux/wireless.h>
53+#endif
54+#include "vmnetInt.h"
55+#include "compat_spinlock.h"
56+#include "compat_netdevice.h"
57+#include "vnetInt.h"
58+#include "smac.h"
59+
60+#define VNET_BRIDGE_HISTORY 48
61+
62+/*
63+ * Bytes reserved before start of packet. As Ethernet header has 14 bytes,
64+ * to get aligned IP header we must skip 2 bytes before packet. Not that it
65+ * matters a lot for us, but using 2 is compatible with what newer 2.6.x
66+ * kernels do.
67+ */
68+#ifndef NET_IP_ALIGN
69+#define NET_IP_ALIGN 2
70+#endif
71+
72+#if LOGLEVEL >= 4
73+static struct timeval vnetTime;
74+#endif
75+
76+typedef struct VNetBridge VNetBridge;
77+
78+struct VNetBridge {
79+ struct notifier_block notifier; // for device state changes
80+ char name[VNET_NAME_LEN]; // name of net device (e.g., "eth0")
81+ struct net_device *dev; // device structure for 'name'
82+ struct sock *sk; // socket associated with skb's
83+ struct packet_type pt; // used to add packet handler
84+ Bool enabledPromisc; // track if promisc enabled
85+ Bool warnPromisc; // tracks if warning has been logged
86+ struct sk_buff *history[VNET_BRIDGE_HISTORY]; // avoid duplicate packets
87+ spinlock_t historyLock; // protects 'history'
88+ VNetPort port; // connection to virtual hub
89+ Bool wirelessAdapter; // connected to wireless adapter?
90+ struct SMACState *smac; // device structure for wireless
91+#ifdef VMW_NETDEV_HAS_NET
92+ struct net_device *internalDev;
93+#endif
94+};
95+
96+typedef PacketStatus (* SMACINT SMACFunc)(struct SMACState *, SMACPackets *);
97+
98+static int VNetBridgeUp(VNetBridge *bridge, Bool rtnlLock);
99+static void VNetBridgeDown(VNetBridge *bridge, Bool rtnlLock);
100+
101+static int VNetBridgeNotify(struct notifier_block *this, u_long msg,
102+ void *data);
103+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 14) && \
104+ !defined(VMW_TL10S64_WORKAROUND)
105+static int VNetBridgeReceiveFromDev(struct sk_buff *skb,
106+ struct net_device *dev,
107+ struct packet_type *pt);
108+#else
109+static int VNetBridgeReceiveFromDev(struct sk_buff *skb,
110+ struct net_device *dev,
111+ struct packet_type *pt,
112+ struct net_device *real_dev);
113+#endif
114+
115+static void VNetBridgeFree(VNetJack *this);
116+static void VNetBridgeReceiveFromVNet(VNetJack *this, struct sk_buff *skb);
117+static Bool VNetBridgeCycleDetect(VNetJack *this, int generation);
118+static Bool VNetBridgeIsDeviceWireless(struct net_device *dev);
119+static void VNetBridgePortsChanged(VNetJack *this);
120+static int VNetBridgeIsBridged(VNetJack *this);
121+static int VNetBridgeProcRead(char *page, char **start, off_t off,
122+ int count, int *eof, void *data);
123+
124+
125+/*
126+ *----------------------------------------------------------------------
127+ *
128+ * VNetBridgeStartPromisc --
129+ *
130+ * Set IFF_PROMISC on the peer interface.
131+ *
132+ * Results:
133+ * None.
134+ *
135+ * Side effects:
136+ * The peer interface IFF_PROMISC flag may be changed.
137+ *
138+ *----------------------------------------------------------------------
139+ */
140+
141+static void
142+VNetBridgeStartPromisc(VNetBridge *bridge, // IN:
143+ Bool rtnlLock) // IN: Acquire RTNL lock
144+{
145+ struct net_device *dev = bridge->dev;
146+
147+ /*
148+ * Disable wireless cards from going into promiscous mode because those
149+ * cards which do support RF monitoring would not be able to function
150+ * correctly i.e. they would not be able to send data packets.
151+ */
152+ if (rtnlLock) {
153+ rtnl_lock();
154+ }
155+ if (!bridge->enabledPromisc && !bridge->wirelessAdapter) {
156+ dev_set_promiscuity(dev, 1);
157+ bridge->enabledPromisc = TRUE;
158+ bridge->warnPromisc = FALSE;
159+ LOG(0, (KERN_NOTICE "bridge-%s: enabled promiscuous mode\n",
160+ bridge->name));
161+ }
162+ if (rtnlLock) {
163+ rtnl_unlock();
164+ }
165+}
166+
167+
168+/*
169+ *----------------------------------------------------------------------
170+ *
171+ * VNetBridgeStopPromisc --
172+ *
173+ * Restore saved IFF_PROMISC on the peer interface.
174+ *
175+ * Results:
176+ * None.
177+ *
178+ * Side effects:
179+ * The peer interface IFF_PROMISC flag may be changed.
180+ *
181+ *----------------------------------------------------------------------
182+ */
183+
184+static void
185+VNetBridgeStopPromisc(VNetBridge *bridge, // IN:
186+ Bool rtnlLock) // IN: Acquire RTNL lock
187+{
188+ struct net_device *dev = bridge->dev;
189+
190+ if (rtnlLock) {
191+ rtnl_lock();
192+ }
193+ if (bridge->enabledPromisc && !bridge->wirelessAdapter) {
194+ dev_set_promiscuity(dev, -1);
195+ bridge->enabledPromisc = FALSE;
196+ LOG(0, (KERN_NOTICE "bridge-%s: disabled promiscuous mode\n",
197+ bridge->name));
198+ }
199+ if (rtnlLock) {
200+ rtnl_unlock();
201+ }
202+}
203+
204+
205+/*
206+ *----------------------------------------------------------------------
207+ *
208+ * VNetBridgeCheckPromisc --
209+ *
210+ * Make sure IFF_PROMISC on the peer interface is set.
211+ *
212+ * This can be called periodically.
213+ *
214+ * Results:
215+ * None.
216+ *
217+ * Side effects:
218+ * Hopefully enables promiscuous mode again if it should have been enabled.
219+ *
220+ *----------------------------------------------------------------------
221+ */
222+
223+static INLINE_SINGLE_CALLER void
224+VNetBridgeCheckPromisc(VNetBridge *bridge)
225+{
226+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)
227+ if (bridge->enabledPromisc && !bridge->wirelessAdapter) {
228+ struct net_device *dev = bridge->dev;
229+ Bool devPromisc = (dev->flags & IFF_PROMISC) != 0;
230+
231+ if (!devPromisc) {
232+ if (!bridge->warnPromisc) {
233+ bridge->warnPromisc = TRUE;
234+ LOG(0, (KERN_NOTICE "bridge-%s: someone disabled promiscuous mode\n"
235+ "Your Ethernet driver is not compatible with VMware's bridged networking.\n",
236+ bridge->name));
237+ }
238+ rtnl_lock();
239+ dev_set_promiscuity(dev, 0);
240+ rtnl_unlock();
241+ }
242+ }
243+#endif
244+}
245+
246+
247+#ifdef VMW_NETDEV_HAS_NET
248+/*
249+ *----------------------------------------------------------------------
250+ *
251+ * VNetBridgeInternalSetup --
252+ *
253+ * Setup callback for our bridge internal device. Nothing to do,
254+ * generic code sets up everything we expect from device.
255+ *
256+ * Results:
257+ * None.
258+ *
259+ * Side effects:
260+ * None.
261+ *
262+ *----------------------------------------------------------------------
263+ */
264+
265+static void
266+VNetBridgeInternalSetup(struct net_device *net)
267+{
268+ /* Do nothing. */
269+}
270+#endif
271+
272+
273+/*
274+ *----------------------------------------------------------------------
275+ *
276+ * VNetBridgeDevCompatible --
277+ *
278+ * Check whether bridge and network device are compatible.
279+ *
280+ * Results:
281+ * Non-zero if device is good enough for bridge. Zero otherwise.
282+ *
283+ * Side effects:
284+ * None.
285+ *
286+ *----------------------------------------------------------------------
287+ */
288+
289+static INLINE_SINGLE_CALLER int
290+VNetBridgeDevCompatible(VNetBridge *bridge, // IN: Bridge
291+ struct net_device *net) // IN: Network device
292+{
293+#ifdef VMW_NETDEV_HAS_NET
294+ if (net->nd_net != bridge->internalDev->nd_net)) {
295+ return 0;
296+ }
297+#endif
298+ return strcmp(net->name, bridge->name) == 0;
299+}
300+
301+
302+/*
303+ *----------------------------------------------------------------------
304+ *
305+ * VNetBridge_Create --
306+ *
307+ * Create a bridge. Allocates/initializes struct, registers
308+ * with kernel for device state changes, connects to virtual
309+ * hub, initializes port/jack, and creates a proc entry.
310+ *
311+ * Results:
312+ * Errno. Also returns an allocated jack to connect to,
313+ * NULL on error.
314+ *
315+ * Side effects:
316+ * None.
317+ *
318+ *----------------------------------------------------------------------
319+ */
320+
321+int
322+VNetBridge_Create(char *devName, // IN: name of device (e.g., "eth0")
323+ VNetPort **ret) // OUT: port to virtual hub
324+{
325+ VNetBridge *bridge = NULL;
326+ static unsigned id = 0;
327+ int retval = 0;
328+
329+ *ret = NULL;
330+
331+ /*
332+ * Its an error if device name is empty.
333+ */
334+
335+ if (devName[0] == '\0') {
336+ retval = -EINVAL;
337+ goto out;
338+ }
339+
340+ /*
341+ * Allocate bridge structure
342+ */
343+
344+ bridge = kmalloc(sizeof *bridge, GFP_USER);
345+ if (bridge == NULL) {
346+ retval = -ENOMEM;
347+ goto out;
348+ }
349+ memset(bridge, 0, sizeof *bridge);
350+ spin_lock_init(&bridge->historyLock);
351+ memcpy(bridge->name, devName, sizeof bridge->name);
352+ NULL_TERMINATE_STRING(bridge->name);
353+
354+#ifdef VMW_NETDEV_HAS_NET
355+ bridge->internalDev = compat_alloc_netdev(0, "vmnetX", VNetBridgeInternalSetup);
356+ if (!bridge->internalDev) {
357+ retval = -ENOMEM;
358+ goto out;
359+ }
360+#endif
361+
362+ /*
363+ * Set up notifier for network device state change
364+ */
365+
366+ bridge->notifier.notifier_call = VNetBridgeNotify;
367+ bridge->notifier.priority = 0;
368+ register_netdevice_notifier(&bridge->notifier);
369+
370+ /*
371+ * Try to bring it up
372+ */
373+
374+ retval = VNetBridgeUp(bridge, TRUE);
375+ if (retval == -ENODEV) {
376+ LOG(1, (KERN_DEBUG "bridge-%s: peer interface %s not found, "
377+ "will wait for it to come up\n",
378+ bridge->name, devName));
379+ retval = 0;
380+ }
381+ if (retval != 0) {
382+ goto out;
383+ }
384+
385+ /*
386+ * Initialize jack
387+ */
388+
389+ bridge->port.id = id++;
390+ bridge->port.next = NULL;
391+
392+ bridge->port.jack.peer = NULL;
393+ bridge->port.jack.numPorts = 1;
394+ VNetSnprintf(bridge->port.jack.name, sizeof bridge->port.jack.name,
395+ "bridge%u", bridge->port.id);
396+ bridge->port.jack.private = bridge;
397+ bridge->port.jack.index = 0;
398+ bridge->port.jack.procEntry = NULL;
399+ bridge->port.jack.free = VNetBridgeFree;
400+ bridge->port.jack.rcv = VNetBridgeReceiveFromVNet;
401+ bridge->port.jack.cycleDetect = VNetBridgeCycleDetect;
402+ bridge->port.jack.portsChanged = VNetBridgePortsChanged;
403+ bridge->port.jack.isBridged = VNetBridgeIsBridged;
404+
405+ /*
406+ * Make proc entry for this jack.
407+ */
408+
409+ retval = VNetProc_MakeEntry(NULL, bridge->port.jack.name, S_IFREG,
410+ &bridge->port.jack.procEntry);
411+ if (retval) {
412+ if (retval == -ENXIO) {
413+ bridge->port.jack.procEntry = NULL;
414+ } else {
415+ goto out;
416+ }
417+ } else {
418+ bridge->port.jack.procEntry->read_proc = VNetBridgeProcRead;
419+ bridge->port.jack.procEntry->data = bridge;
420+ }
421+
422+ /*
423+ * Rest of fields.
424+ */
425+
426+ bridge->port.flags = IFF_RUNNING;
427+
428+ memset(bridge->port.paddr, 0, sizeof bridge->port.paddr);
429+ memset(bridge->port.ladrf, 0, sizeof bridge->port.ladrf);
430+
431+ bridge->port.paddr[0] = VMX86_STATIC_OUI0;
432+ bridge->port.paddr[1] = VMX86_STATIC_OUI1;
433+ bridge->port.paddr[2] = VMX86_STATIC_OUI2;
434+
435+ bridge->port.fileOpRead = NULL;
436+ bridge->port.fileOpWrite = NULL;
437+ bridge->port.fileOpIoctl = NULL;
438+ bridge->port.fileOpPoll = NULL;
439+
440+ *ret = &bridge->port;
441+
442+ LOG(1, (KERN_DEBUG "bridge-%s: attached\n", bridge->name));
443+ return 0;
444+
445+out:
446+ if (bridge != NULL) {
447+ if (bridge->notifier.notifier_call != NULL) {
448+ unregister_netdevice_notifier(&bridge->notifier);
449+ }
450+#ifdef VMW_NETDEV_HAS_NET
451+ if (bridge->internalDev) {
452+ compat_free_netdev(bridge->internalDev);
453+ }
454+#endif
455+ kfree(bridge);
456+ }
457+ return retval;
458+}
459+
460+
461+/*
462+ *----------------------------------------------------------------------
463+ *
464+ * VNetBridgeFree --
465+ *
466+ * Disconnect the bridge, unregister from device state
467+ * notifications, remove proc entry, and deallocate struct.
468+ *
469+ * Results:
470+ * None.
471+ *
472+ * Side effects:
473+ * None.
474+ *
475+ *----------------------------------------------------------------------
476+ */
477+
478+void
479+VNetBridgeFree(VNetJack *this) // IN: jack to free
480+{
481+ VNetBridge *bridge = (VNetBridge*)this->private;
482+
483+ if (bridge->dev != NULL) {
484+ VNetBridgeDown(bridge, TRUE);
485+ }
486+
487+ unregister_netdevice_notifier(&bridge->notifier);
488+
489+#ifdef VMW_NETDEV_HAS_NET
490+ if (bridge->internalDev) {
491+ compat_free_netdev(bridge->internalDev);
492+ }
493+#endif
494+
495+ if (this->procEntry) {
496+ VNetProc_RemoveEntry(this->procEntry, NULL);
497+ }
498+
499+ if (bridge->smac){
500+ SMAC_CleanupState(&(bridge->smac));
501+ }
502+
503+ LOG(1, (KERN_DEBUG "bridge-%s: detached\n", bridge->name));
504+ kfree(bridge);
505+}
506+
507+
508+/*
509+ *----------------------------------------------------------------------
510+ *
511+ * VNetCallSMACFunc --
512+ *
513+ * Wrapper for SMAC functions.
514+ *
515+ * Results:
516+ * Packet Status.
517+ *
518+ * Side effects:
519+ * The skb buffer is freed if not succesfull otherwise it points to
520+ * the clone.
521+ *
522+ *----------------------------------------------------------------------
523+ */
524+
525+PacketStatus
526+VNetCallSMACFunc(struct SMACState *state, // IN: pointer to state
527+ struct sk_buff **skb, // IN/OUT: packet to process
528+ void *startOfData, // IN: points to start of data
529+ SMACFunc func) // IN: function to be called
530+{
531+ SMACPackets packets = { {0} };
532+ PacketStatus status;
533+
534+ packets.orig.skb = *skb;
535+ packets.orig.startOfData = startOfData;
536+
537+ status = func(state, &packets);
538+ if (status != PacketStatusForwardPacket) {
539+ dev_kfree_skb(*skb);
540+ return status;
541+ }
542+
543+ if (packets.clone.skb) {
544+ dev_kfree_skb(*skb);
545+ *skb = packets.clone.skb;
546+ }
547+ return status;
548+}
549+
550+
551+/*
552+ *----------------------------------------------------------------------
553+ *
554+ * VNetBridgeReceiveFromVNet --
555+ *
556+ * This jack is receiving a packet from a vnet. This function
557+ * sends down (i.e., out on the host net device) if the packet
558+ * isn't destined for the host, and it sends up (i.e.,
559+ * simulates a receive for the host) if the packet
560+ * satisfies the host's packet filter.
561+ *
562+ * When the function sends up it keeps a reference to the
563+ * packet in a history list so that we can avoid handing
564+ * a VM a copy of its own packet.
565+ *
566+ * Results:
567+ * None.
568+ *
569+ * Side effects:
570+ * Frees skb. Checks if host device is still using
571+ * promiscuous mode.
572+ *
573+ *----------------------------------------------------------------------
574+ */
575+
576+void
577+VNetBridgeReceiveFromVNet(VNetJack *this, // IN: jack
578+ struct sk_buff *skb) // IN: pkt to receive
579+{
580+ VNetBridge *bridge = (VNetBridge*)this->private;
581+ struct net_device *dev = bridge->dev;
582+ uint8 dest[ETH_ALEN];
583+ struct sk_buff *clone;
584+
585+ LOG(3, (KERN_DEBUG "bridge-%s: transmit %d\n",
586+ bridge->name, (int) skb->len));
587+
588+ if (!dev) {
589+ dev_kfree_skb(skb);
590+ return;
591+ }
592+
593+ /*
594+ * skb might be freed by wireless code, so need to keep
595+ * a local copy of the MAC rather than a pointer to it.
596+ */
597+
598+ memcpy(dest, SKB_2_DESTMAC(skb), ETH_ALEN);
599+
600+ /*
601+ * Check promiscuous bit periodically
602+ */
603+
604+ VNetBridgeCheckPromisc(bridge);
605+
606+#ifdef notdef
607+ // xxx;
608+ /*
609+ * We need to send the packet both up to the host and down
610+ * to the interface.
611+ * However, we ignore packets destined only for this hub.
612+ */
613+
614+ for (i = 0; i < VNET_PORTS_PER_HUB; i++) {
615+ VNetPort *p = &port->hub->port[i];
616+ if (UP_AND_RUNNING(p->flags) && MAC_EQ(dest, p->paddr)) {
617+ return;
618+ }
619+ }
620+#endif
621+
622+ /*
623+ * Wireless processing
624+ */
625+
626+ if (bridge->smac) {
627+ if (VNetCallSMACFunc(bridge->smac, &skb, skb->data,
628+ SMAC_CheckPacketToHost) !=
629+ PacketStatusForwardPacket) {
630+ LOG(4, (KERN_NOTICE "bridge-%s: packet dropped .\n",
631+ bridge->name));
632+ return;
633+ }
634+ }
635+
636+ /*
637+ * Send down (imitate packet_sendmsg)
638+ *
639+ * Do this only if the packet is not addressed to the peer,
640+ * and the packet size is not too big.
641+ */
642+
643+ dev_lock_list();
644+ if (MAC_EQ(dest, dev->dev_addr) ||
645+ skb->len > dev->mtu + dev->hard_header_len) {
646+ dev_unlock_list();
647+ } else {
648+# if 0 // XXX we should do header translation
649+ if ((dev->flags & IFF_SOFTHEADERS) != 0) {
650+ if (skb->len > dev->mtu) {
651+ clone = NULL;
652+ } else {
653+ clone = dev_alloc_skb(skb->len + dev->hard_header_len, GFP_ATOMIC);
654+ }
655+ if (clone != NULL) {
656+ skb_reserve(clone, dev->hard_header_len);
657+ if (dev->hard_header != NULL) {
658+ dev->hard_header(clone, dev, ETH_P_IP, NULL, NULL, skb->len);
659+ }
660+ memcpy(skb_put(clone, skb->len), skb->data, skb->len);
661+ }
662+ }
663+# endif
664+ clone = skb_clone(skb, GFP_ATOMIC);
665+ if (clone == NULL) {
666+ dev_unlock_list();
667+ } else {
668+ struct sock *sk = bridge->sk;
669+ atomic_add(skb->truesize, &sk->sk_wmem_alloc);
670+ clone->sk = sk;
671+ clone->protocol = ((struct ethhdr *)skb->data)->h_proto; // XXX
672+ if ((dev->flags & IFF_UP) != 0) {
673+ dev_unlock_list();
674+ DEV_QUEUE_XMIT(clone, dev, 0);
675+ } else {
676+ dev_unlock_list();
677+ dev_kfree_skb(clone);
678+ }
679+ }
680+ }
681+
682+ /*
683+ * Send up (imitate Ethernet receive)
684+ *
685+ * Do this if the packet is addressed to the peer (or is broadcast, etc.).
686+ *
687+ * This packet will get back to us, via VNetBridgeReceive.
688+ * We save it so we can recognize it (and its clones) again.
689+ */
690+
691+ if (VNetPacketMatch(dest, dev->dev_addr, (uint8 *)&AllMultiFilter, dev->flags)) {
692+ clone = skb_clone(skb, GFP_ATOMIC);
693+ if (clone) {
694+ unsigned long flags;
695+ int i;
696+
697+ atomic_inc(&clone->users);
698+
699+ clone->dev = dev;
700+ clone->protocol = eth_type_trans(clone, dev);
701+ spin_lock_irqsave(&bridge->historyLock, flags);
702+ for (i = 0; i < VNET_BRIDGE_HISTORY; i++) {
703+ if (bridge->history[i] == NULL) {
704+ bridge->history[i] = clone;
705+# if LOGLEVEL >= 3
706+ {
707+ int j;
708+ int count = 0;
709+ for (j = 0; j < VNET_BRIDGE_HISTORY; j++) {
710+ if (bridge->history[j] != NULL) {
711+ count++;
712+ }
713+ }
714+ LOG(3, (KERN_DEBUG "bridge-%s: host slot %d history %d\n",
715+ bridge->name, i, count));
716+ }
717+# endif
718+ break;
719+ }
720+ }
721+ if (i >= VNET_BRIDGE_HISTORY) {
722+ LOG(1, (KERN_NOTICE "bridge-%s: history full\n",
723+ bridge->name));
724+
725+ for (i = 0; i < VNET_BRIDGE_HISTORY; i++) {
726+ struct sk_buff *s = bridge->history[i];
727+
728+ /*
729+ * We special case 0 to avoid races with another thread on
730+ * another cpu wanting to use the 0 entry. This could happen
731+ * when we release the lock to free the former entry.
732+ * See bug 11231 for details.
733+ */
734+ if (i == 0) {
735+ bridge->history[0] = clone;
736+ } else {
737+ bridge->history[i] = NULL;
738+ }
739+ if (s) {
740+ spin_unlock_irqrestore(&bridge->historyLock, flags);
741+ dev_kfree_skb(s);
742+ spin_lock_irqsave(&bridge->historyLock, flags);
743+ }
744+ }
745+ }
746+ spin_unlock_irqrestore(&bridge->historyLock, flags);
747+
748+ /*
749+ * We used to cli() before calling netif_rx() here. It was probably
750+ * unneeded (as we never did it in netif.c, and the code worked). In
751+ * any case, now that we are using netif_rx_ni(), we should certainly
752+ * not do it, or netif_rx_ni() will deadlock on the cli() lock --hpreg
753+ */
754+
755+ netif_rx_ni(clone);
756+# if LOGLEVEL >= 4
757+ do_gettimeofday(&vnetTime);
758+# endif
759+ }
760+ }
761+
762+ // xxx;
763+ dev_kfree_skb(skb);
764+}
765+
766+
767+/*
768+ *----------------------------------------------------------------------
769+ *
770+ * VNetBridgeCycleDetect --
771+ *
772+ * Cycle detection algorithm.
773+ *
774+ * Results:
775+ * TRUE if a cycle was detected, FALSE otherwise.
776+ *
777+ * Side effects:
778+ * None.
779+ *
780+ *----------------------------------------------------------------------
781+ */
782+
783+Bool
784+VNetBridgeCycleDetect(VNetJack *this, // IN: jack
785+ int generation) // IN: generation
786+{
787+ VNetBridge *bridge = (VNetBridge*)this->private;
788+ return VNetCycleDetectIf(bridge->name, generation);
789+}
790+
791+
792+/*
793+ *----------------------------------------------------------------------
794+ *
795+ * VNetBridgePortsChanged --
796+ *
797+ * The number of ports connected to this jack has change, react
798+ * accordingly by starting/stopping promiscuous mode based on
799+ * whether any peers exist.
800+ *
801+ * Results:
802+ * None.
803+ *
804+ * Side effects:
805+ * Promiscuous mode may be started or stopped.
806+ *
807+ *----------------------------------------------------------------------
808+ */
809+
810+void
811+VNetBridgePortsChanged(VNetJack *this) // IN: jack
812+{
813+ VNetBridge *bridge = (VNetBridge*)this->private;
814+ if (bridge->dev) {
815+ if (VNetGetAttachedPorts(this)) {
816+ VNetBridgeStartPromisc(bridge, TRUE);
817+ } else {
818+ VNetBridgeStopPromisc(bridge, TRUE);
819+ }
820+ }
821+}
822+
823+
824+/*
825+ *----------------------------------------------------------------------
826+ *
827+ * VNetBridgeIsBridged --
828+ *
829+ * Reports if the bridged interface is up or down.
830+ *
831+ * Results:
832+ * 1 - we are bridged but the interface is not up
833+ * 2 - we are bridged and the interface is up
834+ *
835+ * Side effects:
836+ * None.
837+ *
838+ *----------------------------------------------------------------------
839+ */
840+
841+int
842+VNetBridgeIsBridged(VNetJack *this) // IN: jack
843+{
844+ VNetBridge *bridge = (VNetBridge*)this->private;
845+ if (bridge->dev) {
846+ return 2;
847+ } else {
848+ return 1;
849+ }
850+}
851+
852+/*
853+ *----------------------------------------------------------------------
854+ *
855+ * VNetBridgeIsDeviceWireless --
856+ *
857+ * Check if the device is a wireless adapter, depending on the version
858+ * of the wireless extension present in the kernel.
859+ *
860+ * Results:
861+ * TRUE if the device is wireless, FALSE otherwise.
862+ *
863+ * Side effects:
864+ * None.
865+ *
866+ *----------------------------------------------------------------------
867+ */
868+
869+static Bool
870+VNetBridgeIsDeviceWireless(struct net_device *dev) //IN: sock
871+{
872+#if !defined(CONFIG_NET_RADIO)
873+ return FALSE;
874+#elif WIRELESS_EXT > 19
875+ return dev->wireless_handlers != NULL;
876+#elif WIRELESS_EXT > 12
877+ return dev->wireless_handlers != NULL || dev->get_wireless_stats != NULL;
878+#else
879+ return dev->get_wireless_stats != NULL;
880+#endif
881+}
882+
883+/*
884+ *----------------------------------------------------------------------
885+ *
886+ * VNetBridgeUp --
887+ *
888+ * Bring a bridge up. Gets peer's device structure, verifies
889+ * that interface is up, checks the header length,
890+ * allocates a socket, adds a packet handler to the network
891+ * stack, and then places the peer's device in promiscuous
892+ * mode.
893+ *
894+ * Results:
895+ * errno.
896+ *
897+ * Side effects:
898+ * Bridging may be brought up with a peer interface.
899+ *
900+ *----------------------------------------------------------------------
901+ */
902+
903+int
904+VNetBridgeUp(VNetBridge *bridge, // IN: bridge struct
905+ Bool rtnlLock) // IN: acquire RTNL lock
906+{
907+ int retval = 0;
908+
909+ if (bridge->dev != NULL) {
910+ LOG(0, (KERN_NOTICE "bridge-%s: already up\n", bridge->name));
911+ goto out;
912+ }
913+
914+ /*
915+ * Get peer device structure
916+ */
917+
918+ dev_lock_list();
919+ bridge->dev = DEV_GET(bridge);
920+ LOG(2, (KERN_DEBUG "bridge-%s: got dev %p\n",
921+ bridge->name, bridge->dev));
922+ if (bridge->dev == NULL) {
923+ dev_unlock_list();
924+ retval = -ENODEV;
925+ goto out;
926+ }
927+ if (!(bridge->dev->flags & IFF_UP)) {
928+ LOG(2, (KERN_DEBUG "bridge-%s: interface %s is not up\n",
929+ bridge->name, bridge->dev->name));
930+ dev_unlock_list();
931+ retval = -ENODEV;
932+ goto out;
933+ }
934+
935+ /*
936+ * At a minimum, the header size should be the same as ours.
937+ *
938+ * XXX we should either do header translation or ensure this
939+ * is an Ethernet.
940+ */
941+
942+ if (bridge->dev->hard_header_len != ETH_HLEN) {
943+ LOG(1, (KERN_DEBUG "bridge-%s: can't bridge with %s, bad header length %d\n",
944+ bridge->name, bridge->dev->name, bridge->dev->hard_header_len));
945+ dev_unlock_list();
946+ retval = -EINVAL;
947+ goto out;
948+ }
949+
950+ /*
951+ * Get a socket to play with
952+ *
953+ * We set the dead field so we don't get a call back from dev_kfree_skb().
954+ * (The alternative is to support the callback.)
955+ */
956+
957+ bridge->sk = compat_sk_alloc(bridge, GFP_ATOMIC);
958+ if (bridge->sk == NULL) {
959+ dev_unlock_list();
960+ retval = -ENOMEM;
961+ goto out;
962+ }
963+ SET_SK_DEAD(bridge->sk);
964+
965+ bridge->wirelessAdapter = VNetBridgeIsDeviceWireless(bridge->dev);
966+
967+ /*
968+ * If it is a wireless adapter initialize smac struct.
969+ */
970+
971+ if (bridge->wirelessAdapter) {
972+
973+ LOG(1, (KERN_NOTICE "bridge-%s: is a Wireless Adapter\n", bridge->name));
974+ SMAC_InitState(&(bridge->smac));
975+ if (bridge->smac) {
976+ /*
977+ * Store the MAC address of the adapter
978+ */
979+
980+ SMAC_SetMac(bridge->smac, bridge->dev->dev_addr);
981+ }
982+ }
983+
984+ /*
985+ * Link up with the peer device by adding a
986+ * packet handler to the networking stack.
987+ */
988+
989+ bridge->pt.func = VNetBridgeReceiveFromDev;
990+ bridge->pt.type = htons(ETH_P_ALL);
991+ bridge->pt.dev = bridge->dev;
992+
993+ /*
994+ * TurboLinux10 uses 2.6.0-test5, which we do not support, so special case it,
995+ * 2.6.0 with tl_kernel_version_h is 2.6.0-pre5...
996+ */
997+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) || \
998+ (LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 0) && defined(__tl_kernel_version_h__))
999+ bridge->pt.data = bridge->sk;
1000+#else
1001+ bridge->pt.af_packet_priv = bridge->sk;
1002+#endif
1003+ bridge->enabledPromisc = FALSE;
1004+ bridge->warnPromisc = FALSE;
1005+ dev_add_pack(&bridge->pt);
1006+ dev_unlock_list();
1007+
1008+ /*
1009+ * Put in promiscuous mode if need be.
1010+ */
1011+
1012+ down(&vnetStructureSemaphore);
1013+ if (VNetGetAttachedPorts(&bridge->port.jack)) {
1014+ VNetBridgeStartPromisc(bridge, rtnlLock);
1015+ }
1016+ up(&vnetStructureSemaphore);
1017+
1018+ /*
1019+ * Finish up
1020+ */
1021+
1022+ LOG(1, (KERN_DEBUG "bridge-%s: up\n", bridge->name));
1023+
1024+ /*
1025+ * Return
1026+ */
1027+
1028+out:
1029+ if (retval != 0) {
1030+ if (bridge->sk != NULL) {
1031+ sk_free(bridge->sk);
1032+ bridge->sk = NULL;
1033+ }
1034+ bridge->dev = NULL;
1035+ }
1036+ return retval;
1037+}
1038+
1039+
1040+/*
1041+ *----------------------------------------------------------------------
1042+ *
1043+ * VNetBridgeDown --
1044+ *
1045+ * Bring a bridge down. Stops promiscuous mode, removes the
1046+ * packet handler from the network stack, and frees the
1047+ * socket.
1048+ *
1049+ * Results:
1050+ * None.
1051+ *
1052+ * Side effects:
1053+ * Bridging is brought down.
1054+ *
1055+ *----------------------------------------------------------------------
1056+ */
1057+
1058+void
1059+VNetBridgeDown(VNetBridge *bridge, // IN: bridge
1060+ Bool rtnlLock) // IN: acquire RTNL lock
1061+{
1062+ if (bridge->dev == NULL) {
1063+ LOG(0, (KERN_NOTICE "bridge-%s: already down\n", bridge->name));
1064+ return;
1065+ }
1066+
1067+ VNetBridgeStopPromisc(bridge, rtnlLock);
1068+ if (bridge->smac){
1069+ SMAC_SetMac(bridge->smac, NULL);
1070+ }
1071+ bridge->dev = NULL;
1072+ dev_remove_pack(&bridge->pt);
1073+ sk_free(bridge->sk);
1074+ bridge->sk = NULL;
1075+ LOG(1, (KERN_DEBUG "bridge-%s: down\n", bridge->name));
1076+}
1077+
1078+
1079+/*
1080+ *-----------------------------------------------------------------------------
1081+ *
1082+ * VNetBridgeNotify --
1083+ *
1084+ * Callback on peer device state change. The function brings
1085+ * the bridge up/down in response to changes in the peer device.
1086+ *
1087+ * Results:
1088+ * NOTIFY_DONE
1089+ *
1090+ * Side effects:
1091+ * Promiscuous mode is changed when bridge brought up/down.
1092+ *
1093+ *-----------------------------------------------------------------------------
1094+ */
1095+
1096+int
1097+VNetBridgeNotify(struct notifier_block *this, // IN: callback data (bridge)
1098+ u_long msg, // IN: type of event
1099+ void *data) // IN: device pertaining to event
1100+{
1101+ VNetBridge *bridge = list_entry(this, VNetBridge, notifier);
1102+ struct net_device *dev = (struct net_device *) data;
1103+
1104+ switch (msg) {
1105+ case NETDEV_UNREGISTER:
1106+ LOG(2, (KERN_DEBUG "bridge-%s: interface %s is unregistering\n",
1107+ bridge->name, dev->name));
1108+ if (dev == bridge->dev) {
1109+ /* This should never happen --hpreg */
1110+ LOG(0, (KERN_WARNING "bridge-%s: interface %s unregistered without "
1111+ "going down! Disabling the bridge\n", bridge->name,
1112+ dev->name));
1113+ VNetBridgeDown(bridge, FALSE);
1114+ }
1115+ break;
1116+
1117+ case NETDEV_DOWN:
1118+ LOG(2, (KERN_DEBUG "bridge-%s: interface %s is going down\n",
1119+ bridge->name, dev->name));
1120+ if (dev == bridge->dev) {
1121+ LOG(1, (KERN_DEBUG "bridge-%s: disabling the bridge\n",
1122+ bridge->name));
1123+ VNetBridgeDown(bridge, FALSE);
1124+ }
1125+ break;
1126+
1127+ case NETDEV_UP:
1128+ LOG(2, (KERN_DEBUG "bridge-%s: interface %s is going up\n",
1129+ bridge->name, dev->name));
1130+ if (bridge->dev == NULL && VNetBridgeDevCompatible(bridge, dev)) {
1131+ int errno;
1132+
1133+ LOG(1, (KERN_DEBUG "bridge-%s: enabling the bridge\n", bridge->name));
1134+ errno = VNetBridgeUp(bridge, FALSE);
1135+ switch (-errno) {
1136+ case 0:
1137+ break;
1138+
1139+ case ENODEV:
1140+ LOG(0, (KERN_WARNING "bridge-%s: interface %s not found or not "
1141+ "up\n", bridge->name, dev->name));
1142+ break;
1143+
1144+ case EINVAL:
1145+ LOG(0, (KERN_WARNING "bridge-%s: interface %s is not a valid "
1146+ "Ethernet interface\n", bridge->name, dev->name));
1147+ break;
1148+
1149+ case ENOMEM:
1150+ LOG(0, (KERN_WARNING "bridge-%s: failed to allocate memory\n",
1151+ bridge->name));
1152+ break;
1153+
1154+ default:
1155+ /* This should never happen --hpreg */
1156+ LOG(0, (KERN_WARNING "bridge-%s: failed to enable the bridge to "
1157+ "interface %s (error %d)\n", bridge->name, dev->name,
1158+ -errno));
1159+ break;
1160+ }
1161+ }
1162+ break;
1163+
1164+ default:
1165+ LOG(2, (KERN_DEBUG "bridge-%s: interface %s is sending notification "
1166+ "0x%lx\n", bridge->name, dev->name, msg));
1167+ break;
1168+ }
1169+
1170+ return NOTIFY_DONE;
1171+}
1172+
1173+
1174+/*
1175+ *----------------------------------------------------------------------
1176+ *
1177+ * VNetBridgeComputeHeaderPos --
1178+ *
1179+ * Compute correct position for UDP/TCP header.
1180+ *
1181+ * Results:
1182+ * None.
1183+ *
1184+ * Side effects:
1185+ * transport header pointer updated to point to the tcp/udp header.
1186+ *
1187+ *----------------------------------------------------------------------
1188+ */
1189+
1190+static INLINE_SINGLE_CALLER void
1191+VNetBridgeComputeHeaderPos(struct sk_buff *skb) // IN: buffer to examine
1192+{
1193+ /* Maybe some kernel gets it right... */
1194+ if (compat_skb_network_header_len(skb)) {
1195+ return;
1196+ }
1197+ switch (be16_to_cpu(skb->protocol)) {
1198+ case ETH_P_IP: {
1199+ struct iphdr *ipHdr = compat_skb_ip_header(skb);
1200+
1201+ compat_skb_set_transport_header(skb, compat_skb_network_offset(skb) +
1202+ ipHdr->ihl * 4);
1203+ }
1204+ return;
1205+ default:
1206+ LOG(3, (KERN_DEBUG "Unknown EII protocol %04X: csum at %d\n",
1207+ be16_to_cpu(skb->protocol), compat_skb_csum_offset(skb)));
1208+ break;
1209+ }
1210+ return;
1211+}
1212+
1213+
1214+/*
1215+ * We deal with three types of kernels:
1216+ * New kernels: skb_shinfo() has gso_size member, and there is
1217+ * skb_gso_segment() helper to split GSO skb into flat ones.
1218+ * Older kernels: skb_shinfo() has tso_size member, and there is
1219+ * no helper.
1220+ * Oldest kernels: without any segmentation offload support.
1221+ */
1222+#if defined(NETIF_F_GSO) || LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18)
1223+#define VNetBridgeIsGSO(skb) skb_shinfo(skb)->gso_size
1224+#define VNetBridgeGSOSegment(skb) skb_gso_segment(skb, 0)
1225+#elif defined(NETIF_F_TSO)
1226+#define VNetBridgeIsGSO(skb) skb_shinfo(skb)->tso_size
1227+
1228+
1229+/*
1230+ *----------------------------------------------------------------------
1231+ *
1232+ * VNetBridgeGSOSegment --
1233+ *
1234+ * Split a large TCP/IPv4 sk_buff into multiple sk_buffs of
1235+ * size skb_shinfo(skb)->tso_size
1236+ * Called from VNetBridgeSendLargePacket().
1237+ *
1238+ * Results:
1239+ * List of skbs created.
1240+ *
1241+ * Side effects:
1242+ * The incoming packet is split into multiple packets.
1243+ *
1244+ *----------------------------------------------------------------------
1245+ */
1246+
1247+static struct sk_buff *
1248+VNetBridgeGSOSegment(struct sk_buff *skb) // IN: packet to split
1249+{
1250+ struct sk_buff *segs = NULL;
1251+ struct sk_buff **next = &segs;
1252+ int bytesPerPacket, bytesLeft;
1253+ int macHdrLen, ipHdrLen, tcpHdrLen, allHdrLen;
1254+ int curByteOffset;
1255+ uint16 ipID;
1256+ uint32 seqNo;
1257+
1258+ if (((struct ethhdr *)compat_skb_mac_header(skb))->h_proto != htons(ETH_P_IP)) {
1259+ return ERR_PTR(-EPFNOSUPPORT);
1260+ }
1261+
1262+ if (compat_skb_ip_header(skb)->protocol != IPPROTO_TCP) {
1263+ return ERR_PTR(-EPROTONOSUPPORT);
1264+ }
1265+
1266+ macHdrLen = compat_skb_network_header(skb) - compat_skb_mac_header(skb);
1267+ ipHdrLen = compat_skb_ip_header(skb)->ihl << 2;
1268+ tcpHdrLen = compat_skb_tcp_header(skb)->doff << 2;
1269+ allHdrLen = macHdrLen + ipHdrLen + tcpHdrLen;
1270+
1271+ ipID = ntohs(compat_skb_ip_header(skb)->id);
1272+ seqNo = ntohl(compat_skb_tcp_header(skb)->seq);
1273+
1274+ /* Host TCP stack populated this (MSS) for the host NIC driver */
1275+ bytesPerPacket = skb_shinfo(skb)->tso_size;
1276+
1277+ bytesLeft = skb->len - allHdrLen;
1278+ curByteOffset = allHdrLen;
1279+
1280+ while (bytesLeft) {
1281+ struct sk_buff *newSkb;
1282+ int payloadSize = (bytesLeft < bytesPerPacket) ? bytesLeft : bytesPerPacket;
1283+
1284+ newSkb = dev_alloc_skb(payloadSize + allHdrLen + NET_IP_ALIGN);
1285+ if (!newSkb) {
1286+ while (segs) {
1287+ newSkb = segs;
1288+ segs = segs->next;
1289+ newSkb->next = NULL;
1290+ dev_kfree_skb(newSkb);
1291+ }
1292+ return ERR_PTR(-ENOMEM);
1293+ }
1294+ skb_reserve(newSkb, NET_IP_ALIGN);
1295+ newSkb->dev = skb->dev;
1296+ newSkb->protocol = skb->protocol;
1297+ newSkb->pkt_type = skb->pkt_type;
1298+ newSkb->ip_summed = VM_CHECKSUM_PARTIAL;
1299+
1300+ /*
1301+ * MAC+IP+TCP copy
1302+ * This implies that ALL fields in the IP and TCP headers are copied from
1303+ * the original skb. This is convenient: we'll only fix up fields that
1304+ * need to be changed below
1305+ */
1306+ memcpy(skb_put(newSkb, allHdrLen), skb->data, allHdrLen);
1307+
1308+ /* Fix up pointers to different layers */
1309+ compat_skb_reset_mac_header(newSkb);
1310+ compat_skb_set_network_header(newSkb, macHdrLen);
1311+ compat_skb_set_transport_header(newSkb, macHdrLen + ipHdrLen);
1312+
1313+ /* Payload copy */
1314+ skb_copy_bits(skb, curByteOffset, compat_skb_tail_pointer(newSkb), payloadSize);
1315+ skb_put(newSkb, payloadSize);
1316+
1317+ curByteOffset+=payloadSize;
1318+ bytesLeft -= payloadSize;
1319+
1320+ /* Fix up IP hdr */
1321+ compat_skb_ip_header(newSkb)->tot_len = htons(payloadSize + tcpHdrLen + ipHdrLen);
1322+ compat_skb_ip_header(newSkb)->id = htons(ipID);
1323+ compat_skb_ip_header(newSkb)->check = 0;
1324+ /* Recompute new IP checksum */
1325+ compat_skb_ip_header(newSkb)->check =
1326+ ip_fast_csum(compat_skb_network_header(newSkb),
1327+ compat_skb_ip_header(newSkb)->ihl);
1328+
1329+ /* Fix up TCP hdr */
1330+ compat_skb_tcp_header(newSkb)->seq = htonl(seqNo);
1331+ /* Clear FIN/PSH if not last packet */
1332+ if (bytesLeft > 0) {
1333+ compat_skb_tcp_header(newSkb)->fin = 0;
1334+ compat_skb_tcp_header(newSkb)->psh = 0;
1335+ }
1336+ /* Recompute partial TCP checksum */
1337+ compat_skb_tcp_header(newSkb)->check =
1338+ ~csum_tcpudp_magic(compat_skb_ip_header(newSkb)->saddr,
1339+ compat_skb_ip_header(newSkb)->daddr,
1340+ payloadSize+tcpHdrLen, IPPROTO_TCP, 0);
1341+
1342+ /* Offset of field */
1343+ newSkb->csum = offsetof(struct tcphdr, check);
1344+
1345+ /* Join packet to the list of segments */
1346+ *next = newSkb;
1347+ next = &newSkb->next;
1348+
1349+ /* Bump up our counters */
1350+ ipID++;
1351+ seqNo += payloadSize;
1352+
1353+ }
1354+ return segs;
1355+}
1356+#else
1357+#define VNetBridgeIsGSO(skb) (0)
1358+#define VNetBridgeGSOSegment(skb) ERR_PTR(-ENOSYS)
1359+#endif
1360+
1361+
1362+/*
1363+ *----------------------------------------------------------------------
1364+ *
1365+ * VNetBridgeSendLargePacket --
1366+ *
1367+ * Split and send a large TCP/IPv4 sk_buff into multiple sk_buffs which
1368+ * fits on wire. Called from VNetBridgeReceiveFromDev(), which is a
1369+ * protocol handler called from the bottom half, so steady as she
1370+ * goes...
1371+ *
1372+ * skb passed in is deallocated by function.
1373+ *
1374+ * Results:
1375+ * None.
1376+ *
1377+ * Side effects:
1378+ * The incoming packet is split into multiple packets and sent to the
1379+ * vnet.
1380+ *
1381+ *----------------------------------------------------------------------
1382+ */
1383+
1384+void
1385+VNetBridgeSendLargePacket(struct sk_buff *skb, // IN: packet to split
1386+ VNetBridge *bridge) // IN: bridge
1387+{
1388+ struct sk_buff *segs;
1389+
1390+ segs = VNetBridgeGSOSegment(skb);
1391+ dev_kfree_skb(skb);
1392+ if (IS_ERR(segs)) {
1393+ LOG(1, (KERN_DEBUG "bridge-%s: cannot segment packet: error %ld\n",
1394+ bridge->name, PTR_ERR(segs)));
1395+ return;
1396+ }
1397+
1398+ while (segs) {
1399+ struct sk_buff *newSkb;
1400+
1401+ newSkb = segs;
1402+ segs = newSkb->next;
1403+ newSkb->next = NULL;
1404+ /* Send it along */
1405+ skb = newSkb;
1406+ VNetSend(&bridge->port.jack, newSkb);
1407+ }
1408+}
1409+
1410+
1411+/*
1412+ *----------------------------------------------------------------------
1413+ *
1414+ * VNetBridgeReceiveFromDev --
1415+ *
1416+ * Receive a packet from a bridged peer device
1417+ *
1418+ * This is called from the bottom half. Must be careful.
1419+ *
1420+ * Results:
1421+ * errno.
1422+ *
1423+ * Side effects:
1424+ * A packet may be sent to the vnet.
1425+ *
1426+ *----------------------------------------------------------------------
1427+ */
1428+
1429+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 14) && \
1430+ !defined(VMW_TL10S64_WORKAROUND)
1431+int
1432+VNetBridgeReceiveFromDev(struct sk_buff *skb, // IN: packet to receive
1433+ struct net_device *dev, // IN: unused
1434+ struct packet_type *pt) // IN: pt (pointer to bridge)
1435+#else
1436+int
1437+VNetBridgeReceiveFromDev(struct sk_buff *skb, // IN: packet to receive
1438+ struct net_device *dev, // IN: unused
1439+ struct packet_type *pt, // IN: pt (pointer to bridge)
1440+ struct net_device *real_dev) // IN: real device, unused
1441+#endif
1442+{
1443+ VNetBridge *bridge = list_entry(pt, VNetBridge, pt);
1444+ int i;
1445+ unsigned long flags;
1446+
1447+ if (bridge->dev == NULL) {
1448+ LOG(3, (KERN_DEBUG "bridge-%s: received %d closed\n",
1449+ bridge->name, (int) skb->len));
1450+ dev_kfree_skb(skb);
1451+ return -EIO; // value is ignored anyway
1452+ }
1453+
1454+ /*
1455+ * Check is this is a packet that we sent up to the host, and if
1456+ * so then don't bother to receive the packet.
1457+ */
1458+
1459+ spin_lock_irqsave(&bridge->historyLock, flags);
1460+ for (i = 0; i < VNET_BRIDGE_HISTORY; i++) {
1461+ struct sk_buff *s = bridge->history[i];
1462+ if (s != NULL &&
1463+ (s == skb || SKB_IS_CLONE_OF(skb, s))) {
1464+ bridge->history[i] = NULL;
1465+ spin_unlock_irqrestore(&bridge->historyLock, flags);
1466+ dev_kfree_skb(s);
1467+ LOG(3, (KERN_DEBUG "bridge-%s: receive %d self %d\n",
1468+ bridge->name, (int) skb->len, i));
1469+ dev_kfree_skb(skb);
1470+ return 0;
1471+ }
1472+ }
1473+ spin_unlock_irqrestore(&bridge->historyLock, flags);
1474+
1475+# if LOGLEVEL >= 4
1476+ {
1477+ struct timeval now;
1478+ do_gettimeofday(&now);
1479+ LOG(3, (KERN_DEBUG "bridge-%s: time %d\n",
1480+ bridge->name,
1481+ (int)((now.tv_sec * 1000000 + now.tv_usec)
1482+ - (vnetTime.tv_sec * 1000000 + vnetTime.tv_usec))));
1483+ }
1484+# endif
1485+
1486+ if (bridge->smac) {
1487+ if (VNetCallSMACFunc(bridge->smac, &skb, compat_skb_mac_header(skb),
1488+ SMAC_CheckPacketFromHost) !=
1489+ PacketStatusForwardPacket) {
1490+ LOG(4, (KERN_NOTICE "bridge-%s: packet dropped .\n",
1491+ bridge->name));
1492+ return 0;
1493+ }
1494+ }
1495+
1496+#ifdef KERNEL_2_3_15
1497+ skb = skb_share_check(skb, GFP_ATOMIC);
1498+ if (!skb) {
1499+ return 0;
1500+ }
1501+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 4)
1502+ /*
1503+ * Unbelievable... Caller sets h.raw = nh.raw before invoking us...
1504+ */
1505+ VNetBridgeComputeHeaderPos(skb);
1506+#endif
1507+#endif
1508+
1509+ skb_push(skb, skb->data - compat_skb_mac_header(skb));
1510+ LOG(3, (KERN_DEBUG "bridge-%s: receive %d\n",
1511+ bridge->name, (int) skb->len));
1512+
1513+ /*
1514+ * If this is a large packet, chop chop chop (if supported)...
1515+ */
1516+ if (VNetBridgeIsGSO(skb)) {
1517+ VNetBridgeSendLargePacket(skb, bridge);
1518+ } else {
1519+ VNetSend(&bridge->port.jack, skb);
1520+ }
1521+
1522+ return 0;
1523+}
1524+
1525+
1526+/*
1527+ *----------------------------------------------------------------------
1528+ *
1529+ * VNetBridgeProcRead --
1530+ *
1531+ * Callback for read operation on this bridge entry in vnets proc fs.
1532+ *
1533+ * Results:
1534+ * Length of read operation.
1535+ *
1536+ * Side effects:
1537+ * None.
1538+ *
1539+ *----------------------------------------------------------------------
1540+ */
1541+
1542+int
1543+VNetBridgeProcRead(char *page, // IN/OUT: buffer to write into
1544+ char **start, // OUT: 0 if file < 4k, else offset into page
1545+ off_t off, // IN: (unused) offset of read into the file
1546+ int count, // IN: (unused) maximum number of bytes to read
1547+ int *eof, // OUT: TRUE if there is nothing more to read
1548+ void *data) // IN: client data - pointer to bridge
1549+{
1550+ VNetBridge *bridge = (VNetBridge*)data;
1551+ int len = 0;
1552+
1553+ if (!bridge) {
1554+ return len;
1555+ }
1556+
1557+ len += VNetPrintPort(&bridge->port, page+len);
1558+
1559+ len += sprintf(page+len, "dev %s ", bridge->name);
1560+
1561+ len += sprintf(page+len, "\n");
1562+
1563+ *start = 0;
1564+ *eof = 1;
1565+ return len;
1566+}
1567diff -Nur old/vmware-any-any-update117d/vmnet-only/vmnetInt.h new/vmware-any-any-update117d/vmnet-only/vmnetInt.h
1568--- old/vmware-any-any-update117d/vmnet-only/vmnetInt.h 2008-08-30 15:50:06.800648000 +0000
1569+++ new/vmware-any-any-update117d/vmnet-only/vmnetInt.h 2008-08-30 15:59:47.768956250 +0000
1570@@ -63,7 +63,7 @@
1571 # define dev_lock_list() read_lock(&dev_base_lock)
1572 # define dev_unlock_list() read_unlock(&dev_base_lock)
1573 # ifdef VMW_NETDEV_HAS_NET
1574-# define DEV_GET(x) __dev_get_by_name(dev_net((x)->internalDev), (x)->name)
1575+# define DEV_GET(x) __dev_get_by_name((x)->internalDev->nd_net, (x)->name)
1576 # else
1577 # define DEV_GET(x) __dev_get_by_name((x)->name)
1578 # endif
1579@@ -89,7 +89,7 @@
1580
1581 #ifdef VMW_NETDEV_HAS_NET
1582 extern struct proto vmnet_proto;
1583-# define compat_sk_alloc(_bri, _pri) sk_alloc(dev_net((_bri)->internalDev), \
1584+# define compat_sk_alloc(_bri, _pri) sk_alloc((_bri)->internalDev->nd_net, \
1585 PF_NETLINK, _pri, &vmnet_proto)
1586 #elif defined(VMW_HAVE_SK_ALLOC_WITH_PROTO)
1587 extern struct proto vmnet_proto;
1588diff -Nur old/vmware-any-any-update117d/vmnet-only/vmnetInt.h~ new/vmware-any-any-update117d/vmnet-only/vmnetInt.h~
1589--- old/vmware-any-any-update117d/vmnet-only/vmnetInt.h~ 1970-01-01 00:00:00.000000000 +0000
1590+++ new/vmware-any-any-update117d/vmnet-only/vmnetInt.h~ 2008-08-30 15:49:59.016161500 +0000
1591@@ -0,0 +1,157 @@
1592+/* **********************************************************
1593+ * Copyright 1998 VMware, Inc. All rights reserved. -- VMware Confidential
1594+ * **********************************************************/
1595+
1596+#ifndef __VMNETINT_H__
1597+#define __VMNETINT_H__
1598+
1599+
1600+#define INCLUDE_ALLOW_MODULE
1601+#include "includeCheck.h"
1602+#include "driver-config.h"
1603+
1604+
1605+/*
1606+ * Hide all kernel compatibility stuff in those macros
1607+ */
1608+
1609+/* All kernels above 2.6.23 have net namespaces. */
1610+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) && !defined(VMW_NETDEV_HAS_NET)
1611+# define VMW_NETDEV_HAS_NET
1612+#endif
1613+
1614+/* All kernels above 2.6.23 have skb argument in nf_hookfn. */
1615+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) && !defined(VMW_NFHOOK_USES_SKB)
1616+# define VMW_NFHOOK_USES_SKB
1617+#endif
1618+
1619+
1620+#ifdef KERNEL_2_4_0
1621+# define compat_fop_set_owner(_pFop) do { \
1622+ (_pFop)->owner = THIS_MODULE; \
1623+} while (0)
1624+# define compat_mod_inc_refcount
1625+# define compat_mod_dec_refcount
1626+#else
1627+# define compat_fop_set_owner(_pFop)
1628+# define compat_mod_inc_refcount do { \
1629+ MOD_INC_USE_COUNT; \
1630+} while (0)
1631+# define compat_mod_dec_refcount do { \
1632+ MOD_DEC_USE_COUNT; \
1633+} while (0)
1634+#endif
1635+
1636+
1637+#ifdef skb_shinfo
1638+# define SKB_IS_CLONE_OF(clone, skb) ( \
1639+ skb_shinfo(clone) == skb_shinfo(skb) \
1640+ )
1641+#else
1642+# define SKB_IS_CLONE_OF(clone, skb) ( \
1643+ skb_datarefp(clone) == skb_datarefp(skb) \
1644+ )
1645+#endif
1646+#define DEV_QUEUE_XMIT(skb, dev, pri) ( \
1647+ (skb)->dev = (dev), \
1648+ (skb)->priority = (pri), \
1649+ compat_skb_reset_mac_header(skb), \
1650+ compat_skb_set_network_header(skb, sizeof (struct ethhdr)), \
1651+ dev_queue_xmit(skb) \
1652+ )
1653+#ifdef KERNEL_2_3_15
1654+# define dev_lock_list() read_lock(&dev_base_lock)
1655+# define dev_unlock_list() read_unlock(&dev_base_lock)
1656+# ifdef VMW_NETDEV_HAS_NET
1657+# define DEV_GET(x) __dev_get_by_name(dev_net((x)->internalDev), (x)->name)
1658+# else
1659+# define DEV_GET(x) __dev_get_by_name((x)->name)
1660+# endif
1661+#else
1662+# define DEV_GET(x) dev_get((x)->name)
1663+#endif
1664+
1665+
1666+/*
1667+ * Various fields (including 'dead') of struct sock are replaced with the
1668+ * 'flags' bitfield in 2.5.65, with sock_valbool_flag() to set flag's
1669+ * value. Since 2.5.71 there is sock_set_flag() to set bit to 1, and
1670+ * since 2.6.25-rc1 sock_valbool_flag() is gone.
1671+ */
1672+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 65)
1673+# define SET_SK_DEAD(_sk) (_sk)->dead = 1
1674+#elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 71)
1675+# define SET_SK_DEAD(_sk) sock_valbool_flag(_sk, SOCK_DEAD, 1)
1676+#else
1677+# define SET_SK_DEAD(_sk) sock_set_flag(_sk, SOCK_DEAD)
1678+#endif
1679+
1680+
1681+#ifdef VMW_NETDEV_HAS_NET
1682+extern struct proto vmnet_proto;
1683+# define compat_sk_alloc(_bri, _pri) sk_alloc(dev_net((_bri)->internalDev), \
1684+ PF_NETLINK, _pri, &vmnet_proto)
1685+#elif defined(VMW_HAVE_SK_ALLOC_WITH_PROTO)
1686+extern struct proto vmnet_proto;
1687+# define compat_sk_alloc(_bri, _pri) sk_alloc(PF_NETLINK, _pri, &vmnet_proto, 1)
1688+#elif defined(KERNEL_2_5_5)
1689+# define compat_sk_alloc(_bri, _pri) sk_alloc(PF_NETLINK, _pri, 1, NULL)
1690+#else
1691+# define compat_sk_alloc(_bri, _pri) sk_alloc(0, _pri, 1)
1692+#endif
1693+
1694+
1695+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
1696+# define fileTraversalLock(lock) spin_lock(lock)
1697+# define fileTraversalUnLock(lock) spin_unlock(lock)
1698+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
1699+# define fileTraversalLock(lock) read_lock(lock)
1700+# define fileTraversalUnLock(lock) read_unlock(lock)
1701+#else //2.2 kernels
1702+# define fileTraversalLock(lock) lock_kernel()
1703+# define fileTraversalUnLock(lock) unlock_kernel()
1704+#endif
1705+
1706+
1707+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
1708+# define taskLock(lock) task_lock(lock)
1709+# define taskUnLock(lock) task_unlock(lock)
1710+#else //2.2 kernels
1711+# define taskLock(lock) lock_kernel()
1712+# define taskUnLock(lock) unlock_kernel()
1713+#endif
1714+
1715+
1716+/*
1717+ * Use CHECKSUM_HW for old kernels, if they have CHECKSUM_HW. Use CHECKSUM_PARTIAL for
1718+ * new ones even if CHECKSUM_HW is defined. We do not do decision based on kernel version
1719+ * only as CHECKSUM_PARTIAL was in mm tree for some time already, and we do not test
1720+ * for CHECKSUM_PARTIAL existence as it may get converted to enum in future.
1721+ */
1722+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) && defined(CHECKSUM_HW)
1723+# define VM_CHECKSUM_PARTIAL CHECKSUM_HW
1724+#else
1725+# define VM_CHECKSUM_PARTIAL CHECKSUM_PARTIAL
1726+#endif
1727+
1728+
1729+/*
1730+ * The "owner" field in nf_hook_ops got added in 2.5.69
1731+ */
1732+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 69)
1733+# define compat_nf_hook_owner .owner = THIS_MODULE,
1734+#else
1735+# define compat_nf_hook_owner
1736+#endif
1737+
1738+
1739+#ifdef NF_IP_LOCAL_IN
1740+#define VMW_NF_INET_LOCAL_IN NF_IP_LOCAL_IN
1741+#define VMW_NF_INET_POST_ROUTING NF_IP_POST_ROUTING
1742+#else
1743+#define VMW_NF_INET_LOCAL_IN NF_INET_LOCAL_IN
1744+#define VMW_NF_INET_POST_ROUTING NF_INET_POST_ROUTING
1745+#endif
1746+
1747+
1748+#endif /* __VMNETINT_H__ */
This page took 0.198212 seconds and 4 git commands to generate.