xosski

VMware patch(not mine or tested)

Jan 9th, 2025
3
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 54.33 KB | None | 0 0
  1. root@a1-MS-7885:~/vmware-patch-temp# patch -p1 < vmware-patch.diff
  2. patching file vmmon-only/include/pgtbl.h
  3. Hunk #1 FAILED at 58.
  4. Hunk #2 FAILED at 68.
  5. Hunk #3 FAILED at 77.
  6. Hunk #4 FAILED at 86.
  7. 4 out of 4 hunks FAILED -- saving rejects to file vmmon-only/include/pgtbl.h.rej
  8. patching file vmnet-only/bridge.c
  9. Hunk #1 FAILED at 581.
  10. Hunk #2 FAILED at 894.
  11. Hunk #3 FAILED at 1410.
  12. 3 out of 3 hunks FAILED -- saving rejects to file vmnet-only/bridge.c.rej
  13. root@a1-MS-7885:~/vmware-patch-temp# cat root@a1-MS-7885:~/vmware-patch-temp# ll
  14. total 2372
  15. drwxr-xr-x 4 root root 4096 ноя 4 02:57 ./
  16. drwx------ 9 root root 4096 ноя 4 02:56 ../
  17. drwxr-xr-x 7 root root 4096 ноя 16 2022 vmmon-only/
  18. -rw-r--r-- 1 root root 1628160 ноя 4 02:54 vmmon.tar
  19. drwxr-xr-x 2 root root 4096 ноя 16 2022 vmnet-only/
  20. -rw-r--r-- 1 root root 778240 ноя 4 02:54 vmnet.tar
  21. -rw-r--r-- 1 root root 1844 ноя 4 02:55 vmware-patch.diff
  22. root@a1-MS-7885:~/vmware-patch-temp# pwd
  23. /root/vmware-patch-temp
  24. root@a1-MS-7885:~/vmware-patch-temp# patch -p0 < vmware-patch.diff
  25. can't find file to patch at input line 3
  26. Perhaps you used the wrong -p or --strip option?
  27. The text leading up to this was:
  28. --------------------------
  29. |--- a/vmmon-only/include/pgtbl.h
  30. |+++ b/vmmon-only/include/pgtbl.h
  31. ---------------------^C
  32. root@a1-MS-7885:~/vmware-patch-temp# cat vmmon-only/include/pgtbl.h.rej
  33. --- vmmon-only/include/pgtbl.h
  34. +++ vmmon-only/include/pgtbl.h
  35. @@ -58,7 +58,7 @@
  36. if (!pgd_present(*pgd)) {
  37. return INVALID_MPN;
  38. }
  39. - if (pgd_large(*pgd)) {
  40. + if (pgd_page(*pgd) && pgd_large(*pgd)) {
  41. return (pgd_pfn(*pgd) << PAGE_SHIFT) + (va & I915_GTT_PAGE_MASK);
  42. }
  43.  
  44. @@ -68,7 +68,7 @@
  45. if (!compat_p4d_present(*p4d)) {
  46. return INVALID_MPN;
  47. }
  48. - if (compat_p4d_large(*p4d)) {
  49. + if (p4d_page(*p4d) && compat_p4d_large(*p4d)) {
  50. return (compat_p4d_pfn(*p4d) << PAGE_SHIFT) + (va & I915_GTT_PAGE_MASK);
  51. }
  52.  
  53. @@ -77,7 +77,7 @@
  54. if (!pud_present(*pud)) {
  55. return INVALID_MPN;
  56. }
  57. - if (pud_large(*pud)) {
  58. + if (pud_page(*pud) && pud_large(*pud)) {
  59. return (pud_pfn(*pud) << PAGE_SHIFT) + (va & I915_GTT_PAGE_MASK);
  60. }
  61.  
  62. @@ -86,7 +86,7 @@
  63. if (!pmd_present(*pmd)) {
  64. return INVALID_MPN;
  65. }
  66. - if (pmd_large(*pmd)) {
  67. + if (pmd_page(*pmd) && pmd_large(*pmd)) {
  68. return (pmd_pfn(*pmd) << PAGE_SHIFT) + (va & I915_GTT_PAGE_MASK);
  69. }
  70.  
  71. root@a1-MS-7885:~/vmware-patch-temp# cat vmmon-only/include/pgtbl.h
  72. /*********************************************************
  73. * Copyright (C) 2002,2014-2017 VMware, Inc. All rights reserved.
  74. *
  75. * This program is free software; you can redistribute it and/or modify it
  76. * under the terms of the GNU General Public License as published by the
  77. * Free Software Foundation version 2 and no later version.
  78. *
  79. * This program is distributed in the hope that it will be useful, but
  80. * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  81. * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  82. * for more details.
  83. *
  84. * You should have received a copy of the GNU General Public License along
  85. * with this program; if not, write to the Free Software Foundation, Inc.,
  86. * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  87. *
  88. *********************************************************/
  89.  
  90. #ifndef __PGTBL_H__
  91. # define __PGTBL_H__
  92.  
  93.  
  94. #include <linux/highmem.h>
  95.  
  96. #include "compat_pgtable.h"
  97. #include "compat_spinlock.h"
  98. #include "compat_page.h"
  99.  
  100.  
  101. /*
  102. *-----------------------------------------------------------------------------
  103. *
  104. * PgtblVa2MPNLocked --
  105. *
  106. * Walks through the hardware page tables to try to find the pte
  107. * associated to a virtual address. Then maps PTE to MPN.
  108. *
  109. * Results:
  110. * INVALID_MPN on failure
  111. * mpn on success
  112. *
  113. * Side effects:
  114. * None
  115. *
  116. *-----------------------------------------------------------------------------
  117. */
  118.  
  119. static INLINE MPN
  120. PgtblVa2MPNLocked(struct mm_struct *mm, // IN: Mm structure of a process
  121. VA addr) // IN: Address in the virtual address
  122. // space of that process
  123. {
  124. pgd_t *pgd;
  125. compat_p4d_t *p4d;
  126. MPN mpn;
  127.  
  128. pgd = pgd_offset(mm, addr);
  129. if (pgd_present(*pgd) == 0) {
  130. return INVALID_MPN;
  131. }
  132. if (pgd_large(*pgd)) {
  133. /* Linux kernel does not support PGD huge pages. */
  134. /* return pgd_pfn(*pgd) + ((addr & PGD_MASK) >> PAGE_SHIFT); */
  135. return INVALID_MPN;
  136. }
  137.  
  138. p4d = compat_p4d_offset(pgd, addr);
  139. if (compat_p4d_present(*p4d) == 0) {
  140. return INVALID_MPN;
  141. }
  142. if (compat_p4d_large(*p4d)) {
  143. mpn = compat_p4d_pfn(*p4d) + ((addr & ~COMPAT_P4D_MASK) >> PAGE_SHIFT);
  144. } else {
  145. pud_t *pud;
  146.  
  147. pud = pud_offset(p4d, addr);
  148. if (pud_present(*pud) == 0) {
  149. return INVALID_MPN;
  150. }
  151. if (pud_large(*pud)) {
  152. mpn = pud_pfn(*pud) + ((addr & ~PUD_MASK) >> PAGE_SHIFT);
  153. } else {
  154. pmd_t *pmd;
  155.  
  156. pmd = pmd_offset(pud, addr);
  157. if (pmd_present(*pmd) == 0) {
  158. return INVALID_MPN;
  159. }
  160. if (pmd_large(*pmd)) {
  161. mpn = pmd_pfn(*pmd) + ((addr & ~PMD_MASK) >> PAGE_SHIFT);
  162. } else {
  163. pte_t *pte;
  164.  
  165. pte = pte_offset_map(pmd, addr);
  166. if (pte_present(*pte) == 0) {
  167. pte_unmap(pte);
  168. return INVALID_MPN;
  169. }
  170. mpn = pte_pfn(*pte);
  171. pte_unmap(pte);
  172. }
  173. }
  174. }
  175. if (mpn >= INVALID_MPN) {
  176. mpn = INVALID_MPN;
  177. }
  178. return mpn;
  179. }
  180.  
  181.  
  182. /*
  183. *-----------------------------------------------------------------------------
  184. *
  185. * PgtblVa2MPN --
  186. *
  187. * Walks through the hardware page tables of the current process to try to
  188. * find the page structure associated to a virtual address.
  189. *
  190. * Results:
  191. * Same as PgtblVa2MPNLocked()
  192. *
  193. * Side effects:
  194. * None
  195. *
  196. *-----------------------------------------------------------------------------
  197. */
  198.  
  199. static INLINE MPN
  200. PgtblVa2MPN(VA addr) // IN
  201. {
  202. struct mm_struct *mm;
  203. MPN mpn;
  204.  
  205. /* current->mm is NULL for kernel threads, so use active_mm. */
  206. mm = current->active_mm;
  207. spin_lock(&mm->page_table_lock);
  208. mpn = PgtblVa2MPNLocked(mm, addr);
  209. spin_unlock(&mm->page_table_lock);
  210. return mpn;
  211. }
  212.  
  213. #endif /* __PGTBL_H__ */
  214. root@a1-MS-7885:~/vmware-patch-temp# cat vmnet-only/bridge.c
  215. /*********************************************************
  216. * Copyright (C) 1998-2013, 2017, 2022 VMware, Inc. All rights reserved.
  217. *
  218. * This program is free software; you can redistribute it and/or modify it
  219. * under the terms of the GNU General Public License as published by the
  220. * Free Software Foundation version 2 and no later version.
  221. *
  222. * This program is distributed in the hope that it will be useful, but
  223. * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  224. * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  225. * for more details.
  226. *
  227. * You should have received a copy of the GNU General Public License along
  228. * with this program; if not, write to the Free Software Foundation, Inc.,
  229. * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  230. *
  231. *********************************************************/
  232.  
  233. #include "driver-config.h"
  234.  
  235. #define EXPORT_SYMTAB
  236.  
  237. #include <linux/kernel.h>
  238. #include <linux/version.h>
  239. #include <linux/sched.h>
  240. #include <linux/slab.h>
  241. #include <linux/poll.h>
  242.  
  243. #include <linux/netdevice.h>
  244. #include <linux/etherdevice.h>
  245. #include <linux/mm.h>
  246. #include "compat_skbuff.h"
  247. #include <linux/sockios.h>
  248. #include <linux/spinlock.h>
  249. #include "compat_sock.h"
  250.  
  251. #define __KERNEL_SYSCALLS__
  252. #include <asm/io.h>
  253.  
  254. #include <linux/proc_fs.h>
  255. #include <linux/file.h>
  256. #include <linux/ip.h>
  257. #include <linux/tcp.h>
  258. #include <linux/if_arp.h>
  259. #include <net/tcp.h>
  260. #include <net/ipv6.h>
  261.  
  262. #ifdef CONFIG_NET_RADIO
  263. # include <linux/wireless.h>
  264. #endif
  265. #include "vmnetInt.h"
  266. #include "compat_netdevice.h"
  267. #include "vnetInt.h"
  268. #include "smac.h"
  269.  
  270. #define VNET_BRIDGE_HISTORY 48
  271.  
  272. /*
  273. * Bytes reserved before start of packet. As Ethernet header has 14 bytes,
  274. * to get aligned IP header we must skip 2 bytes before packet. Not that it
  275. * matters a lot for us, but using 2 is compatible with what newer 2.6.x
  276. * kernels do.
  277. */
  278. #ifndef NET_IP_ALIGN
  279. #define NET_IP_ALIGN 2
  280. #endif
  281.  
  282. #if LOGLEVEL >= 4
  283. static struct timeval vnetTime;
  284. #endif
  285.  
  286. typedef struct VNetBridge VNetBridge;
  287.  
  288. struct VNetBridge {
  289. struct notifier_block notifier; // for device state changes
  290. char name[VNET_NAME_LEN]; // name of net device (e.g., "eth0")
  291. struct net_device *dev; // device structure for 'name'
  292. struct sock *sk; // socket associated with skb's
  293. struct packet_type pt; // used to add packet handler
  294. Bool enabledPromisc; // track if promisc enabled
  295. Bool forceSmac; // whether to use smac unconditionally
  296. struct sk_buff *history[VNET_BRIDGE_HISTORY]; // avoid duplicate packets
  297. spinlock_t historyLock; // protects 'history'
  298. VNetPort port; // connection to virtual hub
  299. Bool wirelessAdapter; // connected to wireless adapter?
  300. struct SMACState *smac; // device structure for wireless
  301. VNetEvent_Sender *eventSender; // event sender
  302. };
  303.  
  304. typedef PacketStatus (* SMACINT SMACFunc)(struct SMACState *, SMACPackets *);
  305.  
  306. static int VNetBridgeUp(VNetBridge *bridge, Bool rtnlLock);
  307. static void VNetBridgeDown(VNetBridge *bridge, Bool rtnlLock);
  308.  
  309. static int VNetBridgeNotify(struct notifier_block *this, u_long msg,
  310. void *data);
  311. static int VNetBridgeReceiveFromDev(struct sk_buff *skb,
  312. struct net_device *dev,
  313. struct packet_type *pt,
  314. struct net_device *real_dev);
  315.  
  316. static void VNetBridgeFree(VNetJack *this);
  317. static void VNetBridgeReceiveFromVNet(VNetJack *this, struct sk_buff *skb);
  318. static Bool VNetBridgeCycleDetect(VNetJack *this, int generation);
  319. static Bool VNetBridgeIsDeviceWireless(struct net_device *dev);
  320. static void VNetBridgePortsChanged(VNetJack *this);
  321. static int VNetBridgeIsBridged(VNetJack *this);
  322. static int VNetBridgeProcRead(char *page, char **start, off_t off,
  323. int count, int *eof, void *data);
  324. static void VNetBridgeComputeHeaderPosIPv6(struct sk_buff *skb);
  325. static PacketStatus VNetCallSMACFunc(struct SMACState *state,
  326. struct sk_buff **skb, void *startOfData,
  327. SMACFunc func, unsigned int len);
  328.  
  329.  
  330. /*
  331. *----------------------------------------------------------------------
  332. *
  333. * VNetBridgeStartPromisc --
  334. *
  335. * Set IFF_PROMISC on the peer interface.
  336. *
  337. * Results:
  338. * None.
  339. *
  340. * Side effects:
  341. * The peer interface IFF_PROMISC flag may be changed.
  342. *
  343. *----------------------------------------------------------------------
  344. */
  345.  
  346. static void
  347. VNetBridgeStartPromisc(VNetBridge *bridge, // IN:
  348. Bool rtnlLock) // IN: Acquire RTNL lock
  349. {
  350. struct net_device *dev = bridge->dev;
  351.  
  352. /*
  353. * Disable wireless cards from going into promiscous mode because those
  354. * cards which do support RF monitoring would not be able to function
  355. * correctly i.e. they would not be able to send data packets.
  356. */
  357. if (rtnlLock) {
  358. rtnl_lock();
  359. }
  360. if (!bridge->enabledPromisc && !bridge->wirelessAdapter) {
  361. dev_set_promiscuity(dev, 1);
  362. bridge->enabledPromisc = TRUE;
  363. LOG(0, (KERN_NOTICE "bridge-%s: enabled promiscuous mode\n",
  364. bridge->name));
  365. }
  366. if (rtnlLock) {
  367. rtnl_unlock();
  368. }
  369. }
  370.  
  371.  
  372. /*
  373. *----------------------------------------------------------------------
  374. *
  375. * VNetBridgeStopPromisc --
  376. *
  377. * Restore saved IFF_PROMISC on the peer interface.
  378. *
  379. * Results:
  380. * None.
  381. *
  382. * Side effects:
  383. * The peer interface IFF_PROMISC flag may be changed.
  384. *
  385. *----------------------------------------------------------------------
  386. */
  387.  
  388. static void
  389. VNetBridgeStopPromisc(VNetBridge *bridge, // IN:
  390. Bool rtnlLock) // IN: Acquire RTNL lock
  391. {
  392. struct net_device *dev = bridge->dev;
  393.  
  394. if (rtnlLock) {
  395. rtnl_lock();
  396. }
  397. if (bridge->enabledPromisc && !bridge->wirelessAdapter) {
  398. dev_set_promiscuity(dev, -1);
  399. bridge->enabledPromisc = FALSE;
  400. LOG(0, (KERN_NOTICE "bridge-%s: disabled promiscuous mode\n",
  401. bridge->name));
  402. }
  403. if (rtnlLock) {
  404. rtnl_unlock();
  405. }
  406. }
  407.  
  408.  
  409. /*
  410. *----------------------------------------------------------------------
  411. *
  412. * VNetBridgeDevCompatible --
  413. *
  414. * Check whether bridge and network device are compatible.
  415. *
  416. * Results:
  417. * Non-zero if device is good enough for bridge. Zero otherwise.
  418. *
  419. * Side effects:
  420. * None.
  421. *
  422. *----------------------------------------------------------------------
  423. */
  424.  
  425. static INLINE_SINGLE_CALLER int
  426. VNetBridgeDevCompatible(VNetBridge *bridge, // IN: Bridge
  427. struct net_device *net) // IN: Network device
  428. {
  429. if (dev_net(net) != &init_net) {
  430. return 0;
  431. }
  432. return strcmp(net->name, bridge->name) == 0;
  433. }
  434.  
  435.  
  436. /*
  437. *----------------------------------------------------------------------
  438. *
  439. * VNetBridge_Create --
  440. *
  441. * Creates a bridge. Allocates struct, allocates internal device,
  442. * initializes port/jack, and creates a proc entry. Finally, creates an
  443. * event sender and register itself with the kernel for device state
  444. * change notifications.
  445. *
  446. * At this time the bridge is not yet plugged into the hub, because this
  447. * will be done by the caller, i.e. the driver. But we need to know the
  448. * hub in order to create an event sender. This allows for enabling
  449. * the notification mechanism, which will instantly start firing, which in
  450. * turn will bring up the bridge (if present), which eventually will
  451. * inject bridge events. Moreover, the bridge will start injecting
  452. * packets, which will be dropped on the floor. All in all, this is not
  453. * that elegant. Alternatively, we could (i) plug into the hub inside of
  454. * this function, which would require adding a few parameters, (ii) split
  455. * the function into a create part and a registration part. Both ways are
  456. * not consistent with how driver.c plugs the ports into the hub.
  457. *
  458. * Results:
  459. * Errno. Also returns an allocated jack to connect to,
  460. * NULL on error.
  461. *
  462. * Side effects:
  463. * None.
  464. *
  465. *----------------------------------------------------------------------
  466. */
  467.  
  468. int
  469. VNetBridge_Create(const char *devName, // IN: name of device (e.g., "eth0")
  470. uint32 flags, // IN: configuration flags
  471. VNetJack *hubJack, // IN: the future hub
  472. VNetPort **ret) // OUT: port to virtual hub
  473. {
  474. VNetBridge *bridge = NULL;
  475. static unsigned id = 0;
  476. int retval = 0;
  477.  
  478. *ret = NULL;
  479.  
  480. /*
  481. * Its an error if device name is empty.
  482. */
  483.  
  484. if (devName[0] == '\0') {
  485. retval = -EINVAL;
  486. goto out;
  487. }
  488.  
  489. /* complain about unknown/unsupported flags */
  490. if (flags & ~VNET_BRFLAG_FORCE_SMAC) {
  491. retval = -EINVAL;
  492. goto out;
  493. }
  494.  
  495. /*
  496. * Allocate bridge structure
  497. */
  498.  
  499. bridge = kmalloc(sizeof *bridge, GFP_USER);
  500. if (bridge == NULL) {
  501. retval = -ENOMEM;
  502. goto out;
  503. }
  504. memset(bridge, 0, sizeof *bridge);
  505. spin_lock_init(&bridge->historyLock);
  506. memcpy(bridge->name, devName, sizeof bridge->name);
  507. NULL_TERMINATE_STRING(bridge->name);
  508.  
  509. /*
  510. * Initialize jack.
  511. */
  512.  
  513. bridge->port.id = id++;
  514. bridge->port.next = NULL;
  515.  
  516. bridge->port.jack.peer = NULL;
  517. bridge->port.jack.numPorts = 1;
  518. VNetSnprintf(bridge->port.jack.name, sizeof bridge->port.jack.name,
  519. "bridge%u", bridge->port.id);
  520. bridge->port.jack.private = bridge;
  521. bridge->port.jack.index = 0;
  522. bridge->port.jack.procEntry = NULL;
  523. bridge->port.jack.free = VNetBridgeFree;
  524. bridge->port.jack.rcv = VNetBridgeReceiveFromVNet;
  525. bridge->port.jack.cycleDetect = VNetBridgeCycleDetect;
  526. bridge->port.jack.portsChanged = VNetBridgePortsChanged;
  527. bridge->port.jack.isBridged = VNetBridgeIsBridged;
  528.  
  529. /*
  530. * Make proc entry for this jack.
  531. */
  532.  
  533. retval = VNetProc_MakeEntry(bridge->port.jack.name, S_IFREG, bridge,
  534. VNetBridgeProcRead,
  535. &bridge->port.jack.procEntry);
  536. if (retval) {
  537. if (retval == -ENXIO) {
  538. bridge->port.jack.procEntry = NULL;
  539. } else {
  540. goto out;
  541. }
  542. }
  543.  
  544. /*
  545. * Rest of fields.
  546. */
  547.  
  548. bridge->port.flags = IFF_RUNNING;
  549.  
  550. memset(bridge->port.paddr, 0, sizeof bridge->port.paddr);
  551. memset(bridge->port.ladrf, 0, sizeof bridge->port.ladrf);
  552.  
  553. bridge->port.paddr[0] = VMX86_STATIC_OUI0;
  554. bridge->port.paddr[1] = VMX86_STATIC_OUI1;
  555. bridge->port.paddr[2] = VMX86_STATIC_OUI2;
  556.  
  557. bridge->port.fileOpRead = NULL;
  558. bridge->port.fileOpWrite = NULL;
  559. bridge->port.fileOpIoctl = NULL;
  560. bridge->port.fileOpPoll = NULL;
  561.  
  562. /* misc. configuration */
  563. bridge->forceSmac = (flags & VNET_BRFLAG_FORCE_SMAC) ? TRUE : FALSE;
  564.  
  565. /* create event sender */
  566. retval = VNetHub_CreateSender(hubJack, &bridge->eventSender);
  567. if (retval != 0) {
  568. goto out;
  569. }
  570.  
  571. /*
  572. * on RHEL3 Linux 2.4.21-47 (others maybe too) the notifier does not fire
  573. * and bring up the bridge as expected, thus we bring it up manually
  574. * *before* registering the notifier (PR306435)
  575. */
  576. VNetBridgeUp(bridge, TRUE);
  577.  
  578. /*
  579. * register notifier for network device state change notifications, the
  580. * notifier will fire right away, and the notifier handler will bring up
  581. * the bridge (see exception above)
  582. */
  583. bridge->notifier.notifier_call = VNetBridgeNotify;
  584. bridge->notifier.priority = 0;
  585. register_netdevice_notifier(&bridge->notifier);
  586.  
  587. /* return bridge */
  588. *ret = &bridge->port;
  589. LOG(1, (KERN_DEBUG "bridge-%s: attached\n", bridge->name));
  590. return 0;
  591.  
  592. out:
  593. if (bridge != NULL) {
  594. kfree(bridge);
  595. }
  596. return retval;
  597. }
  598.  
  599.  
  600. /*
  601. *----------------------------------------------------------------------
  602. *
  603. * VNetBridgeFree --
  604. *
  605. * Unregister from device state notifications, disable the bridge,
  606. * destroy sender, remove proc entry, cleanup smac, and deallocate
  607. * struct.
  608. *
  609. * Results:
  610. * None.
  611. *
  612. * Side effects:
  613. * None.
  614. *
  615. *----------------------------------------------------------------------
  616. */
  617.  
  618. void
  619. VNetBridgeFree(VNetJack *this) // IN: jack to free
  620. {
  621. VNetBridge *bridge = (VNetBridge*)this->private;
  622.  
  623. /* unregister notifier */
  624. if (bridge->notifier.notifier_call != NULL) {
  625. int err;
  626.  
  627. err = compat_unregister_netdevice_notifier(&bridge->notifier);
  628. if (err != 0) {
  629. LOG(0, (KERN_NOTICE "Can't unregister netdevice notifier (%d)\n",
  630. err));
  631. }
  632. bridge->notifier.notifier_call = NULL;
  633. }
  634.  
  635. /* disable bridge */
  636. if (bridge->dev != NULL) {
  637. LOG(1, (KERN_DEBUG "bridge-%s: disabling the bridge\n", bridge->name));
  638. VNetBridgeDown(bridge, TRUE);
  639. }
  640.  
  641. /* destroy event sender */
  642. VNetEvent_DestroySender(bridge->eventSender);
  643. bridge->eventSender = NULL;
  644.  
  645. /* remove /proc entry */
  646. if (this->procEntry) {
  647. VNetProc_RemoveEntry(this->procEntry);
  648. }
  649.  
  650. if (bridge->smac){
  651. SMAC_CleanupState(&(bridge->smac));
  652. }
  653.  
  654. /* free bridge */
  655. LOG(1, (KERN_DEBUG "bridge-%s: detached\n", bridge->name));
  656. kfree(bridge);
  657. }
  658.  
  659.  
  660. /*
  661. *----------------------------------------------------------------------
  662. *
  663. * VNetCallSMACFunc --
  664. *
  665. * Wrapper for SMAC functions. The skb must be linear.
  666. *
  667. * Results:
  668. * Packet Status.
  669. *
  670. * Side effects:
  671. * The skb buffer is freed if not successful otherwise it points to
  672. * the clone.
  673. *
  674. *----------------------------------------------------------------------
  675. */
  676.  
  677. static PacketStatus
  678. VNetCallSMACFunc(struct SMACState *state, // IN: pointer to state
  679. struct sk_buff **skb, // IN/OUT: packet to process
  680. void *startOfData, // IN: points to start of data
  681. SMACFunc func, // IN: function to be called
  682. unsigned int len) // IN: length including ETH header
  683. {
  684. SMACPackets packets = { {0} };
  685. PacketStatus status;
  686.  
  687. SKB_LINEAR_ASSERT(*skb);
  688.  
  689. packets.orig.skb = *skb;
  690. packets.orig.startOfData = startOfData;
  691. packets.orig.len = len;
  692.  
  693. status = func(state, &packets);
  694. if (status != PacketStatusForwardPacket) {
  695. dev_kfree_skb(*skb);
  696. return status;
  697. }
  698.  
  699. if (packets.clone.skb) {
  700. dev_kfree_skb(*skb);
  701. *skb = packets.clone.skb;
  702. }
  703. return status;
  704. }
  705.  
  706.  
  707. /*
  708. *----------------------------------------------------------------------
  709. *
  710. * VNetBridgeReceiveFromVNet --
  711. *
  712. * This jack is receiving a packet from a vnet. This function
  713. * sends down (i.e., out on the host net device) if the packet
  714. * isn't destined for the host, and it sends up (i.e.,
  715. * simulates a receive for the host) if the packet
  716. * satisfies the host's packet filter.
  717. *
  718. * When the function sends up it keeps a reference to the
  719. * packet in a history list so that we can avoid handing
  720. * a VM a copy of its own packet.
  721. *
  722. * Results:
  723. * None.
  724. *
  725. * Side effects:
  726. * Frees skb. Checks if host device is still using
  727. * promiscuous mode.
  728. *
  729. *----------------------------------------------------------------------
  730. */
  731.  
  732. void
  733. VNetBridgeReceiveFromVNet(VNetJack *this, // IN: jack
  734. struct sk_buff *skb) // IN: pkt to receive
  735. {
  736. VNetBridge *bridge = (VNetBridge*)this->private;
  737. struct net_device *dev = bridge->dev;
  738. uint8 dest[ETH_ALEN];
  739. struct sk_buff *clone;
  740.  
  741. LOG(3, (KERN_DEBUG "bridge-%s: transmit %d\n",
  742. bridge->name, (int) skb->len));
  743.  
  744. if (!dev) {
  745. dev_kfree_skb(skb);
  746. return;
  747. }
  748.  
  749. /*
  750. * skb might be freed by wireless code, so need to keep
  751. * a local copy of the MAC rather than a pointer to it.
  752. */
  753.  
  754. memcpy(dest, SKB_2_DESTMAC(skb), ETH_ALEN);
  755.  
  756. #ifdef notdef
  757. // xxx;
  758. /*
  759. * We need to send the packet both up to the host and down
  760. * to the interface.
  761. * However, we ignore packets destined only for this hub.
  762. */
  763.  
  764. for (i = 0; i < VNET_PORTS_PER_HUB; i++) {
  765. VNetPort *p = &port->hub->port[i];
  766. if (UP_AND_RUNNING(p->flags) && MAC_EQ(dest, p->paddr)) {
  767. return;
  768. }
  769. }
  770. #endif
  771.  
  772. /*
  773. * SMAC processing. SMAC interfaces that the skb is linear, so ensure that
  774. * this is the case prior to calling out.
  775. */
  776.  
  777. if (bridge->smac) {
  778. if (compat_skb_is_nonlinear(skb) && compat_skb_linearize(skb)) {
  779. LOG(4, (KERN_NOTICE "bridge-%s: couldn't linearize, packet dropped\n",
  780. bridge->name));
  781. return;
  782. }
  783. if (VNetCallSMACFunc(bridge->smac, &skb, skb->data,
  784. SMAC_CheckPacketToHost, skb->len) !=
  785. PacketStatusForwardPacket) {
  786. LOG(4, (KERN_NOTICE "bridge-%s: packet dropped\n", bridge->name));
  787. return;
  788. }
  789. }
  790.  
  791. /*
  792. * Send down (imitate packet_sendmsg)
  793. *
  794. * Do this only if the packet is not addressed to the peer,
  795. * and the packet size is not too big.
  796. */
  797.  
  798. dev_lock_list();
  799. if (MAC_EQ(dest, dev->dev_addr) ||
  800. skb->len > dev->mtu + dev->hard_header_len) {
  801. dev_unlock_list();
  802. } else {
  803. # if 0 // XXX we should do header translation
  804. if ((dev->flags & IFF_SOFTHEADERS) != 0) {
  805. if (skb->len > dev->mtu) {
  806. clone = NULL;
  807. } else {
  808. clone = dev_alloc_skb(skb->len + dev->hard_header_len, GFP_ATOMIC);
  809. }
  810. if (clone != NULL) {
  811. skb_reserve(clone, dev->hard_header_len);
  812. if (dev->hard_header != NULL) {
  813. dev->hard_header(clone, dev, ETH_P_IP, NULL, NULL, skb->len);
  814. }
  815. memcpy(skb_put(clone, skb->len), skb->data, skb->len);
  816. }
  817. }
  818. # endif
  819. clone = skb_clone(skb, GFP_ATOMIC);
  820. if (clone == NULL) {
  821. dev_unlock_list();
  822. } else {
  823. skb_set_owner_w(clone, bridge->sk);
  824. clone->protocol = ((struct ethhdr *)skb->data)->h_proto; // XXX
  825. if ((dev->flags & IFF_UP) != 0) {
  826. dev_unlock_list();
  827. DEV_QUEUE_XMIT(clone, dev, 0);
  828. } else {
  829. dev_unlock_list();
  830. dev_kfree_skb(clone);
  831. }
  832. }
  833. }
  834.  
  835. /*
  836. * Send up (imitate Ethernet receive)
  837. *
  838. * Do this if the packet is addressed to the peer (or is broadcast, etc.).
  839. *
  840. * This packet will get back to us, via VNetBridgeReceive.
  841. * We save it so we can recognize it (and its clones) again.
  842. */
  843.  
  844. if (VNetPacketMatch(dest, dev->dev_addr, NULL, 0, allMultiFilter, dev->flags)) {
  845. clone = skb_clone(skb, GFP_ATOMIC);
  846. if (clone) {
  847. unsigned long flags;
  848. int i;
  849.  
  850. clone = skb_get(clone);
  851.  
  852. clone->dev = dev;
  853. clone->protocol = eth_type_trans(clone, dev);
  854. spin_lock_irqsave(&bridge->historyLock, flags);
  855. for (i = 0; i < VNET_BRIDGE_HISTORY; i++) {
  856. if (bridge->history[i] == NULL) {
  857. bridge->history[i] = clone;
  858. # if LOGLEVEL >= 3
  859. {
  860. int j;
  861. int count = 0;
  862. for (j = 0; j < VNET_BRIDGE_HISTORY; j++) {
  863. if (bridge->history[j] != NULL) {
  864. count++;
  865. }
  866. }
  867. LOG(3, (KERN_DEBUG "bridge-%s: host slot %d history %d\n",
  868. bridge->name, i, count));
  869. }
  870. # endif
  871. break;
  872. }
  873. }
  874. if (i >= VNET_BRIDGE_HISTORY) {
  875. LOG(1, (KERN_NOTICE "bridge-%s: history full\n",
  876. bridge->name));
  877.  
  878. for (i = 0; i < VNET_BRIDGE_HISTORY; i++) {
  879. struct sk_buff *s = bridge->history[i];
  880.  
  881. /*
  882. * We special case 0 to avoid races with another thread on
  883. * another cpu wanting to use the 0 entry. This could happen
  884. * when we release the lock to free the former entry.
  885. * See bug 11231 for details.
  886. */
  887. if (i == 0) {
  888. bridge->history[0] = clone;
  889. } else {
  890. bridge->history[i] = NULL;
  891. }
  892. if (s) {
  893. spin_unlock_irqrestore(&bridge->historyLock, flags);
  894. dev_kfree_skb(s);
  895. spin_lock_irqsave(&bridge->historyLock, flags);
  896. }
  897. }
  898. }
  899. spin_unlock_irqrestore(&bridge->historyLock, flags);
  900.  
  901. #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 18, 0)
  902. netif_rx_ni(clone);
  903. #else
  904. netif_rx(clone);
  905. #endif
  906. # if LOGLEVEL >= 4
  907. do_gettimeofday(&vnetTime);
  908. # endif
  909. }
  910. }
  911.  
  912. // xxx;
  913. dev_kfree_skb(skb);
  914. }
  915.  
  916.  
  917. /*
  918. *----------------------------------------------------------------------
  919. *
  920. * VNetBridgeCycleDetect --
  921. *
  922. * Cycle detection algorithm.
  923. *
  924. * Results:
  925. * TRUE if a cycle was detected, FALSE otherwise.
  926. *
  927. * Side effects:
  928. * None.
  929. *
  930. *----------------------------------------------------------------------
  931. */
  932.  
  933. Bool
  934. VNetBridgeCycleDetect(VNetJack *this, // IN: jack
  935. int generation) // IN: generation
  936. {
  937. VNetBridge *bridge = (VNetBridge*)this->private;
  938. return VNetCycleDetectIf(bridge->name, generation);
  939. }
  940.  
  941.  
  942. /*
  943. *----------------------------------------------------------------------
  944. *
  945. * VNetBridgePortsChanged --
  946. *
  947. * The number of ports connected to this jack has change, react
  948. * accordingly by starting/stopping promiscuous mode based on
  949. * whether any peers exist.
  950. *
  951. * Results:
  952. * None.
  953. *
  954. * Side effects:
  955. * Promiscuous mode may be started or stopped.
  956. *
  957. *----------------------------------------------------------------------
  958. */
  959.  
  960. void
  961. VNetBridgePortsChanged(VNetJack *this) // IN: jack
  962. {
  963. VNetBridge *bridge = (VNetBridge*)this->private;
  964. if (bridge->dev) {
  965. if (VNetGetAttachedPorts(this)) {
  966. VNetBridgeStartPromisc(bridge, TRUE);
  967. } else {
  968. VNetBridgeStopPromisc(bridge, TRUE);
  969. }
  970. }
  971. }
  972.  
  973.  
  974. /*
  975. *----------------------------------------------------------------------
  976. *
  977. * VNetBridgeIsBridged --
  978. *
  979. * Reports if the bridged interface is up or down.
  980. *
  981. * Results:
  982. * 1 - we are bridged but the interface is not up
  983. * 2 - we are bridged and the interface is up
  984. *
  985. * Side effects:
  986. * None.
  987. *
  988. *----------------------------------------------------------------------
  989. */
  990.  
  991. int
  992. VNetBridgeIsBridged(VNetJack *this) // IN: jack
  993. {
  994. VNetBridge *bridge = (VNetBridge*)this->private;
  995. if (bridge->dev) {
  996. return 2;
  997. } else {
  998. return 1;
  999. }
  1000. }
  1001.  
  1002. /*
  1003. *----------------------------------------------------------------------
  1004. *
  1005. * VNetBridgeIsDeviceWireless --
  1006. *
  1007. * Check if the device is a wireless adapter, depending on the version
  1008. * of the wireless extension present in the kernel.
  1009. *
  1010. * Results:
  1011. * TRUE if the device is wireless, FALSE otherwise.
  1012. *
  1013. * Side effects:
  1014. * None.
  1015. *
  1016. *----------------------------------------------------------------------
  1017. */
  1018.  
  1019. static Bool
  1020. VNetBridgeIsDeviceWireless(struct net_device *dev) //IN: sock
  1021. {
  1022. #if defined(CONFIG_WIRELESS_EXT)
  1023. return dev->ieee80211_ptr != NULL || dev->wireless_handlers != NULL;
  1024. #elif LINUX_VERSION_CODE < KERNEL_VERSION(5, 19, 0) || IS_ENABLED(CONFIG_CFG80211)
  1025. return dev->ieee80211_ptr != NULL;
  1026. #else
  1027. return FALSE;
  1028. #endif
  1029. }
  1030.  
  1031.  
  1032. /*
  1033. *----------------------------------------------------------------------
  1034. *
  1035. * VNetBridgeSendLinkStateEvent --
  1036. *
  1037. * Sends a link state event.
  1038. *
  1039. * Results:
  1040. * Returns 0 if successful, or a negative value if an error occurs.
  1041. *
  1042. * Side effects:
  1043. * None.
  1044. *
  1045. *----------------------------------------------------------------------
  1046. */
  1047. static int
  1048. VNetBridgeSendLinkStateEvent(VNetBridge *bridge, // IN: the bridge
  1049. uint32 adapter, // IN: the adapter
  1050. Bool up) // IN: the link state
  1051. {
  1052. VNet_LinkStateEvent event;
  1053. int res;
  1054.  
  1055. event.header.size = sizeof event;
  1056. res = VNetEvent_GetSenderId(bridge->eventSender, &event.header.senderId);
  1057. if (res != 0) {
  1058. LOG(1, (KERN_NOTICE "bridge-%s: can't send link state event, "
  1059. "getSenderId failed (%d)\n", bridge->name, res));
  1060. return res;
  1061. }
  1062. event.header.eventId = 0;
  1063. event.header.classSet = VNET_EVENT_CLASS_UPLINK;
  1064. event.header.type = VNET_EVENT_TYPE_LINK_STATE;
  1065. event.adapter = adapter;
  1066. event.up = up;
  1067. res = VNetEvent_Send(bridge->eventSender, &event.header);
  1068. if (res != 0) {
  1069. LOG(1, (KERN_NOTICE "bridge-%s: can't send link state event, send "
  1070. "failed (%d)\n", bridge->name, res));
  1071. }
  1072. return res;
  1073. }
  1074.  
  1075.  
  1076. /*
  1077. *----------------------------------------------------------------------
  1078. *
  1079. * VNetBridgeUp --
  1080. *
  1081. * Bring a bridge up. Gets peer's device structure, verifies
  1082. * that interface is up, checks the header length,
  1083. * allocates a socket, adds a packet handler to the network
  1084. * stack, and then places the peer's device in promiscuous
  1085. * mode.
  1086. *
  1087. * Results:
  1088. * errno.
  1089. *
  1090. * Side effects:
  1091. * Bridging may be brought up with a peer interface.
  1092. *
  1093. *----------------------------------------------------------------------
  1094. */
  1095.  
  1096. static int
  1097. VNetBridgeUp(VNetBridge *bridge, // IN: bridge struct
  1098. Bool rtnlLock) // IN: acquire RTNL lock
  1099. {
  1100. int retval = 0;
  1101.  
  1102. if (bridge->dev != NULL) {
  1103. LOG(0, (KERN_NOTICE "bridge-%s: already up\n", bridge->name));
  1104. goto out;
  1105. }
  1106.  
  1107. /*
  1108. * Get peer device structure
  1109. */
  1110.  
  1111. dev_lock_list();
  1112. bridge->dev = __dev_get_by_name(&init_net, bridge->name);
  1113. LOG(2, (KERN_DEBUG "bridge-%s: got dev %p\n",
  1114. bridge->name, bridge->dev));
  1115. if (bridge->dev == NULL) {
  1116. dev_unlock_list();
  1117. retval = -ENODEV;
  1118. goto out;
  1119. }
  1120. if (!(bridge->dev->flags & IFF_UP)) {
  1121. LOG(2, (KERN_DEBUG "bridge-%s: interface %s is not up\n",
  1122. bridge->name, bridge->dev->name));
  1123. dev_unlock_list();
  1124. retval = -ENODEV;
  1125. goto out;
  1126. }
  1127. if (bridge->dev->type != ARPHRD_ETHER) {
  1128. LOG(1, (KERN_DEBUG "bridge-%s: can't bridge with %s (header length %d, "
  1129. "type %d).\n", bridge->name, bridge->dev->name,
  1130. bridge->dev->hard_header_len, bridge->dev->type));
  1131. dev_unlock_list();
  1132. retval = -EINVAL;
  1133. goto out;
  1134. }
  1135.  
  1136. /*
  1137. * Get a socket to play with
  1138. *
  1139. * We set the dead field so we don't get a call back from dev_kfree_skb().
  1140. * (The alternative is to support the callback.)
  1141. */
  1142.  
  1143. bridge->sk = compat_sk_alloc(bridge, GFP_ATOMIC);
  1144. if (bridge->sk == NULL) {
  1145. dev_unlock_list();
  1146. retval = -ENOMEM;
  1147. goto out;
  1148. }
  1149. sock_init_data(NULL, bridge->sk);
  1150. sock_set_flag(bridge->sk, SOCK_DEAD);
  1151.  
  1152. if (VNetBridgeIsDeviceWireless(bridge->dev)) {
  1153. LOG(1, (KERN_NOTICE "bridge-%s: device is wireless, enabling SMAC\n",
  1154. bridge->name));
  1155. bridge->wirelessAdapter = TRUE;
  1156. }
  1157.  
  1158. /*
  1159. * If it is a wireless adapter initialize smac struct.
  1160. */
  1161.  
  1162. if (bridge->wirelessAdapter || bridge->forceSmac) {
  1163. SMAC_InitState(&(bridge->smac));
  1164. if (bridge->smac) {
  1165. /*
  1166. * Store the MAC address of the adapter
  1167. */
  1168.  
  1169. SMAC_SetMac(bridge->smac, bridge->dev->dev_addr);
  1170. }
  1171. }
  1172.  
  1173. /*
  1174. * Link up with the peer device by adding a
  1175. * packet handler to the networking stack.
  1176. */
  1177.  
  1178. bridge->pt.func = VNetBridgeReceiveFromDev;
  1179. bridge->pt.type = htons(ETH_P_ALL);
  1180. bridge->pt.dev = bridge->dev;
  1181.  
  1182. bridge->pt.af_packet_priv = bridge->sk;
  1183. bridge->enabledPromisc = FALSE;
  1184. dev_add_pack(&bridge->pt);
  1185. dev_unlock_list();
  1186.  
  1187. /*
  1188. * Put in promiscuous mode if need be.
  1189. */
  1190.  
  1191. mutex_lock(&vnetStructureMutex);
  1192. if (VNetGetAttachedPorts(&bridge->port.jack)) {
  1193. VNetBridgeStartPromisc(bridge, rtnlLock);
  1194. }
  1195. mutex_unlock(&vnetStructureMutex);
  1196.  
  1197. /* send link state up event */
  1198. retval = VNetBridgeSendLinkStateEvent(bridge, bridge->dev->ifindex, TRUE);
  1199. if (retval != 0) {
  1200. LOG(1, (KERN_NOTICE "bridge-%s: can't send link state event (%d)\n",
  1201. bridge->name, retval));
  1202. goto out;
  1203. }
  1204.  
  1205. LOG(1, (KERN_DEBUG "bridge-%s: up\n", bridge->name));
  1206.  
  1207. /*
  1208. * Return
  1209. */
  1210.  
  1211. out:
  1212. if (retval != 0) {
  1213. if (bridge->sk != NULL) {
  1214. sk_free(bridge->sk);
  1215. bridge->sk = NULL;
  1216. }
  1217. bridge->dev = NULL;
  1218. }
  1219. return retval;
  1220. }
  1221.  
  1222.  
  1223. /*
  1224. *----------------------------------------------------------------------
  1225. *
  1226. * VNetBridgeDown --
  1227. *
  1228. * Bring a bridge down. Stops promiscuous mode, removes the
  1229. * packet handler from the network stack, and frees the
  1230. * socket.
  1231. *
  1232. * Results:
  1233. * None.
  1234. *
  1235. * Side effects:
  1236. * Bridging is brought down.
  1237. *
  1238. *----------------------------------------------------------------------
  1239. */
  1240.  
  1241. static void
  1242. VNetBridgeDown(VNetBridge *bridge, // IN: bridge
  1243. Bool rtnlLock) // IN: acquire RTNL lock
  1244. {
  1245. int retval;
  1246.  
  1247. if (bridge->dev == NULL) {
  1248. LOG(0, (KERN_NOTICE "bridge-%s: already down\n", bridge->name));
  1249. return;
  1250. }
  1251.  
  1252. /* send link state down event */
  1253. retval = VNetBridgeSendLinkStateEvent(bridge, bridge->dev->ifindex, FALSE);
  1254. if (retval != 0) {
  1255. LOG(1, (KERN_NOTICE "bridge-%s: can't send link state event (%d)\n",
  1256. bridge->name, retval));
  1257. }
  1258.  
  1259. VNetBridgeStopPromisc(bridge, rtnlLock);
  1260. if (bridge->smac){
  1261. SMAC_SetMac(bridge->smac, NULL);
  1262. }
  1263. bridge->dev = NULL;
  1264. dev_remove_pack(&bridge->pt);
  1265. sk_free(bridge->sk);
  1266. bridge->sk = NULL;
  1267.  
  1268. LOG(1, (KERN_DEBUG "bridge-%s: down\n", bridge->name));
  1269. }
  1270.  
  1271.  
  1272. /*
  1273. *-----------------------------------------------------------------------------
  1274. *
  1275. * VNetBridgeNotifyLogBridgeUpError --
  1276. *
  1277. * Logs a bridge up error for the notify function following this function.
  1278. *
  1279. * Results:
  1280. * None.
  1281. *
  1282. * Side effects:
  1283. * None.
  1284. *
  1285. *-----------------------------------------------------------------------------
  1286. */
  1287.  
  1288. static void
  1289. VNetBridgeNotifyLogBridgeUpError(int errno, // IN: the error number
  1290. char *bridgeName, // IN: the bridge name
  1291. char *devName) // IN: the device name
  1292. {
  1293. switch (errno) {
  1294. case -ENODEV:
  1295. LOG(0, (KERN_WARNING "bridge-%s: interface %s not found or not "
  1296. "up\n", bridgeName, devName));
  1297. break;
  1298. case -EINVAL:
  1299. LOG(0, (KERN_WARNING "bridge-%s: interface %s is not a valid "
  1300. "Ethernet interface\n", bridgeName, devName));
  1301. break;
  1302. case -ENOMEM:
  1303. LOG(0, (KERN_WARNING "bridge-%s: failed to allocate memory\n",
  1304. bridgeName));
  1305. break;
  1306. default:
  1307. /* This should never happen --hpreg */
  1308. LOG(0, (KERN_WARNING "bridge-%s: failed to enable the bridge to "
  1309. "interface %s (error %d)\n", bridgeName, devName,
  1310. -errno));
  1311. break;
  1312. }
  1313. }
  1314.  
  1315.  
  1316. /*
  1317. *-----------------------------------------------------------------------------
  1318. *
  1319. * VNetBridgeNotify --
  1320. *
  1321. * Callback on peer device state change. The function brings
  1322. * the bridge up/down in response to changes in the peer device.
  1323. *
  1324. * Results:
  1325. * NOTIFY_DONE
  1326. *
  1327. * Side effects:
  1328. * Promiscuous mode is changed when bridge brought up/down.
  1329. *
  1330. *-----------------------------------------------------------------------------
  1331. */
  1332.  
  1333. static int
  1334. VNetBridgeNotify(struct notifier_block *this, // IN: callback data (bridge)
  1335. u_long msg, // IN: type of event
  1336. void *data) // IN: net_device or notifier info
  1337. {
  1338. VNetBridge *bridge = list_entry(this, VNetBridge, notifier);
  1339. struct net_device *dev;
  1340.  
  1341. #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)
  1342. dev = netdev_notifier_info_to_dev(data);
  1343. #else
  1344. dev = (struct net_device *)data;
  1345. #endif
  1346. switch (msg) {
  1347. case NETDEV_UNREGISTER:
  1348. LOG(2, (KERN_DEBUG "bridge-%s: interface %s is unregistering\n",
  1349. bridge->name, dev->name));
  1350. if (dev == bridge->dev) {
  1351. /* This should never happen --hpreg */
  1352. LOG(0, (KERN_WARNING "bridge-%s: interface %s unregistered without "
  1353. "going down! Disabling the bridge\n", bridge->name,
  1354. dev->name));
  1355. VNetBridgeDown(bridge, FALSE);
  1356. }
  1357. break;
  1358.  
  1359. case NETDEV_DOWN:
  1360. LOG(2, (KERN_DEBUG "bridge-%s: interface %s is going down\n",
  1361. bridge->name, dev->name));
  1362. if (dev == bridge->dev) {
  1363. LOG(1, (KERN_DEBUG "bridge-%s: disabling the bridge on dev down\n",
  1364. bridge->name));
  1365. VNetBridgeDown(bridge, FALSE);
  1366. }
  1367. break;
  1368.  
  1369. case NETDEV_UP:
  1370. LOG(2, (KERN_DEBUG "bridge-%s: interface %s is going up\n",
  1371. bridge->name, dev->name));
  1372. if (bridge->dev == NULL && VNetBridgeDevCompatible(bridge, dev)) {
  1373. int errno;
  1374.  
  1375. LOG(1, (KERN_DEBUG "bridge-%s: enabling the bridge on dev up\n",
  1376. bridge->name));
  1377. errno = VNetBridgeUp(bridge, FALSE);
  1378. if (errno != 0) {
  1379. VNetBridgeNotifyLogBridgeUpError(errno, bridge->name, dev->name);
  1380. }
  1381. }
  1382. break;
  1383.  
  1384. default:
  1385. LOG(2, (KERN_DEBUG "bridge-%s: interface %s is sending notification "
  1386. "0x%lx\n", bridge->name, dev->name, msg));
  1387. break;
  1388. }
  1389.  
  1390. return NOTIFY_DONE;
  1391. }
  1392.  
  1393.  
  1394. /*
  1395. *----------------------------------------------------------------------
  1396. *
  1397. * RangeInLinearSKB --
  1398. *
  1399. * Checks if the given number of bytes from a given offset resides
  1400. * within the linear part of the skb. If not then attempts to
  1401. * linearize the skb.
  1402. *
  1403. * Results:
  1404. * Returns TRUE if the range of bytes is already in the linear
  1405. * portion or if linearize succeeded. Otherwise, returns FALSE if
  1406. * the linearize operation fails.
  1407. *
  1408. * Side effects:
  1409. * As in skb_linearize().
  1410. *
  1411. *----------------------------------------------------------------------
  1412. */
  1413.  
  1414. static INLINE_SINGLE_CALLER Bool
  1415. RangeInLinearSKB(struct sk_buff *skb, // IN:
  1416. unsigned int start, // IN: Start offset
  1417. unsigned int length) // IN: How many bytes
  1418. {
  1419. if (LIKELY(!compat_skb_is_nonlinear(skb) ||
  1420. start + length <= compat_skb_headlen(skb))) {
  1421. /*
  1422. * Nothing to do.
  1423. */
  1424.  
  1425. return TRUE;
  1426. }
  1427.  
  1428. return compat_skb_linearize(skb) == 0;
  1429. }
  1430.  
  1431.  
  1432. /*
  1433. * Not all kernel versions have NEXTHDR_MOBILITY defined.
  1434. */
  1435.  
  1436. #ifndef NEXTHDR_MOBILITY
  1437. # define NEXTHDR_MOBILITY 135 /* Mobility header. */
  1438. #endif
  1439.  
  1440.  
  1441. /*
  1442. *----------------------------------------------------------------------
  1443. *
  1444. * VNetBridgeComputeHeaderPosIPv6 --
  1445. *
  1446. * Compute correct position of transport header in IPv6 packets.
  1447. *
  1448. * Results:
  1449. * None.
  1450. *
  1451. * Side effects:
  1452. * Transport header pointer updated to point to the PDU contained
  1453. * in the packet.
  1454. *
  1455. *----------------------------------------------------------------------
  1456. */
  1457.  
  1458. static void
  1459. VNetBridgeComputeHeaderPosIPv6(struct sk_buff *skb) // IN:
  1460. {
  1461. struct ipv6hdr *ipv6Hdr;
  1462. unsigned int offset; /* Offset from skb->data. */
  1463. unsigned int headerLen; /* Length of current header. */
  1464. uint8 nextHeader;
  1465.  
  1466. /*
  1467. * Check if the start of the network header is within the linear part of
  1468. * skb. If not, then linearize the skb.
  1469. */
  1470.  
  1471. if (UNLIKELY(compat_skb_network_header(skb) < skb->data ||
  1472. compat_skb_network_header(skb) >= skb->data +
  1473. compat_skb_headlen(skb))) {
  1474. if (compat_skb_linearize(skb)) {
  1475. return; /* Bail out. */
  1476. }
  1477. }
  1478.  
  1479. offset = compat_skb_network_offset(skb);
  1480. if (!RangeInLinearSKB(skb, offset, sizeof *ipv6Hdr)) {
  1481. return; /* Bail out. */
  1482. }
  1483.  
  1484. ipv6Hdr = (struct ipv6hdr *)compat_skb_network_header(skb);
  1485. headerLen = sizeof *ipv6Hdr;
  1486. offset += headerLen; /* End of IPv6 header (not including extensions). */
  1487.  
  1488. /*
  1489. * All IPv6 extension headers begin with a "next header" field (one byte),
  1490. * and most of them have a "header length" field (as the 2nd byte). In each
  1491. * iteration, we find the length of the extension header and add it to
  1492. * offset from the beginning of skb. And, in each iteration we update the
  1493. * next header variable. When we return from the following for loop, offset
  1494. * would have incremented by the length of each of the extension header,
  1495. * and next header type will be something else than an IPv6 extension header
  1496. * signifying that we have walked through the entire IPv6 header. We set
  1497. * the transport header's offset to the value of this offset before exiting
  1498. * the for loop.
  1499. */
  1500.  
  1501. nextHeader = ipv6Hdr->nexthdr;
  1502. for (;;) {
  1503. switch (nextHeader) {
  1504. case NEXTHDR_HOP:
  1505. case NEXTHDR_ROUTING:
  1506. case NEXTHDR_AUTH:
  1507. case NEXTHDR_DEST:
  1508. case NEXTHDR_MOBILITY:
  1509. /*
  1510. * We need to check two bytes in the option header: next header and
  1511. * header extension length.
  1512. */
  1513.  
  1514. if (!RangeInLinearSKB(skb, offset, 2)) {
  1515. return; /* Bail out. */
  1516. }
  1517. headerLen = skb->data[offset + 1];
  1518. if (nextHeader == NEXTHDR_AUTH) {
  1519. headerLen = (headerLen + 2) << 2; /* See RFC 2402. */
  1520. } else {
  1521. headerLen = (headerLen + 1) << 3; /* See ipv6_optlen(). */
  1522. }
  1523.  
  1524. break;
  1525.  
  1526. case NEXTHDR_FRAGMENT:
  1527. case NEXTHDR_ESP:
  1528. case NEXTHDR_NONE:
  1529. /*
  1530. * We stop walking if we find the fragment header (NEXTHDR_FRAGMENT).
  1531. * If the payload is encrypted we may not know the start of the
  1532. * transport header [1]. So, we just return. Same applies when
  1533. * nothing follows this header (NEXTHDR_NONE).
  1534. * [1]: http://www.cu.ipv6tf.org/literatura/chap8.pdf
  1535. */
  1536.  
  1537. return;
  1538.  
  1539. default:
  1540. /*
  1541. * We have walked through all IPv6 extension headers. Let's set the
  1542. * transport header and return.
  1543. */
  1544.  
  1545. compat_skb_set_transport_header(skb, offset);
  1546. return;
  1547. }
  1548.  
  1549. nextHeader = skb->data[offset];
  1550. offset += headerLen;
  1551. }
  1552. }
  1553.  
  1554.  
  1555. /*
  1556. *----------------------------------------------------------------------
  1557. *
  1558. * VNetBridgeComputeHeaderPos --
  1559. *
  1560. * Compute correct position for UDP/TCP header.
  1561. *
  1562. * Results:
  1563. * None.
  1564. *
  1565. * Side effects:
  1566. * transport header pointer updated to point to the tcp/udp header.
  1567. *
  1568. *----------------------------------------------------------------------
  1569. */
  1570.  
  1571. static INLINE_SINGLE_CALLER void
  1572. VNetBridgeComputeHeaderPos(struct sk_buff *skb) // IN: buffer to examine
  1573. {
  1574. /* Maybe some kernel gets it right... */
  1575. if (compat_skb_network_header_len(skb)) {
  1576. return;
  1577. }
  1578. switch (be16_to_cpu(skb->protocol)) {
  1579. case ETH_P_IP: {
  1580. struct iphdr *ipHdr = compat_skb_ip_header(skb);
  1581.  
  1582. compat_skb_set_transport_header(skb, compat_skb_network_offset(skb) +
  1583. ipHdr->ihl * 4);
  1584. break;
  1585. }
  1586.  
  1587. case ETH_P_IPV6:
  1588. VNetBridgeComputeHeaderPosIPv6(skb);
  1589. break;
  1590.  
  1591. default:
  1592. LOG(3, (KERN_DEBUG "Unknown EII protocol %04X: csum at %d\n",
  1593. be16_to_cpu(skb->protocol), compat_skb_csum_offset(skb)));
  1594. break;
  1595. }
  1596. }
  1597.  
  1598.  
  1599. /*
  1600. *----------------------------------------------------------------------
  1601. *
  1602. * VNetBridgeSendLargePacket --
  1603. *
  1604. * Split and send a large TCP/IPv4 sk_buff into multiple sk_buffs which
  1605. * fits on wire. Called from VNetBridgeReceiveFromDev(), which is a
  1606. * protocol handler called from the bottom half, so steady as she
  1607. * goes...
  1608. *
  1609. * skb passed in is deallocated by function.
  1610. *
  1611. * Results:
  1612. * None.
  1613. *
  1614. * Side effects:
  1615. * The incoming packet is split into multiple packets and sent to the
  1616. * vnet.
  1617. *
  1618. *----------------------------------------------------------------------
  1619. */
  1620.  
  1621. void
  1622. VNetBridgeSendLargePacket(struct sk_buff *skb, // IN: packet to split
  1623. VNetBridge *bridge) // IN: bridge
  1624. {
  1625. struct sk_buff *segs;
  1626.  
  1627. segs = skb_gso_segment(skb, 0);
  1628. dev_kfree_skb(skb);
  1629. if (IS_ERR(segs)) {
  1630. LOG(1, (KERN_DEBUG "bridge-%s: cannot segment packet: error %ld\n",
  1631. bridge->name, PTR_ERR(segs)));
  1632. return;
  1633. }
  1634.  
  1635. while (segs) {
  1636. struct sk_buff *newSkb;
  1637.  
  1638. newSkb = segs;
  1639. segs = newSkb->next;
  1640. newSkb->next = NULL;
  1641. /* Send it along */
  1642. skb = newSkb;
  1643. VNetSend(&bridge->port.jack, newSkb);
  1644. }
  1645. }
  1646.  
  1647.  
  1648. /*
  1649. *----------------------------------------------------------------------
  1650. *
  1651. * VNetBridgeReceiveFromDev --
  1652. *
  1653. * Receive a packet from a bridged peer device
  1654. *
  1655. * This is called from the bottom half. Must be careful.
  1656. *
  1657. * Results:
  1658. * errno.
  1659. *
  1660. * Side effects:
  1661. * A packet may be sent to the vnet.
  1662. *
  1663. *----------------------------------------------------------------------
  1664. */
  1665.  
  1666. int
  1667. VNetBridgeReceiveFromDev(struct sk_buff *skb, // IN: packet to receive
  1668. struct net_device *dev, // IN: unused
  1669. struct packet_type *pt, // IN: pt (pointer to bridge)
  1670. struct net_device *real_dev) // IN: real device, unused
  1671. {
  1672. VNetBridge *bridge = list_entry(pt, VNetBridge, pt);
  1673. int i;
  1674. unsigned long flags;
  1675.  
  1676. if (bridge->dev == NULL) {
  1677. LOG(3, (KERN_DEBUG "bridge-%s: received %d closed\n",
  1678. bridge->name, (int) skb->len));
  1679. dev_kfree_skb(skb);
  1680. return -EIO; // value is ignored anyway
  1681. }
  1682.  
  1683. /*
  1684. * Check is this is a packet that we sent up to the host, and if
  1685. * so then don't bother to receive the packet.
  1686. */
  1687.  
  1688. spin_lock_irqsave(&bridge->historyLock, flags);
  1689. for (i = 0; i < VNET_BRIDGE_HISTORY; i++) {
  1690. struct sk_buff *s = bridge->history[i];
  1691. if (s != NULL &&
  1692. (s == skb || SKB_IS_CLONE_OF(skb, s))) {
  1693. bridge->history[i] = NULL;
  1694. spin_unlock_irqrestore(&bridge->historyLock, flags);
  1695. dev_kfree_skb(s);
  1696. LOG(3, (KERN_DEBUG "bridge-%s: receive %d self %d\n",
  1697. bridge->name, (int) skb->len, i));
  1698. dev_kfree_skb(skb);
  1699. return 0;
  1700. }
  1701. }
  1702. spin_unlock_irqrestore(&bridge->historyLock, flags);
  1703.  
  1704. # if LOGLEVEL >= 4
  1705. {
  1706. struct timeval now;
  1707. do_gettimeofday(&now);
  1708. LOG(3, (KERN_DEBUG "bridge-%s: time %d\n",
  1709. bridge->name,
  1710. (int)((now.tv_sec * 1000000 + now.tv_usec)
  1711. - (vnetTime.tv_sec * 1000000 + vnetTime.tv_usec))));
  1712. }
  1713. # endif
  1714.  
  1715. /*
  1716. * SMAC might linearize the skb, but linearizing a shared skb is a no-no,
  1717. * so check for sharing before calling out to SMAC.
  1718. */
  1719. skb = skb_share_check(skb, GFP_ATOMIC);
  1720. if (!skb) {
  1721. return 0;
  1722. }
  1723.  
  1724. if (bridge->smac) {
  1725. /*
  1726. * Wireless driver processes the packet and processes the ethernet header
  1727. * and the length is reduced by the amount. We need the raw ethernet
  1728. * packet length hence add the ethernet header length for incoming
  1729. * packets.
  1730. *
  1731. * Note that SMAC interfaces assume skb linearity.
  1732. */
  1733. if (compat_skb_is_nonlinear(skb) && compat_skb_linearize(skb)) {
  1734. LOG(4, (KERN_NOTICE "bridge-%s: couldn't linearize, packet dropped\n",
  1735. bridge->name));
  1736. return 0;
  1737. }
  1738. if (VNetCallSMACFunc(bridge->smac, &skb, compat_skb_mac_header(skb),
  1739. SMAC_CheckPacketFromHost, skb->len + ETH_HLEN) !=
  1740. PacketStatusForwardPacket) {
  1741. LOG(4, (KERN_NOTICE "bridge-%s: packet dropped\n", bridge->name));
  1742. return 0;
  1743. }
  1744. }
  1745.  
  1746. /*
  1747. * Unbelievable... Caller sets h.raw = nh.raw before invoking us...
  1748. */
  1749. VNetBridgeComputeHeaderPos(skb);
  1750.  
  1751. skb_push(skb, skb->data - compat_skb_mac_header(skb));
  1752. LOG(3, (KERN_DEBUG "bridge-%s: receive %d\n",
  1753. bridge->name, (int) skb->len));
  1754.  
  1755. /*
  1756. * If this is a large packet, chop chop chop (if supported)...
  1757. */
  1758. if (skb_shinfo(skb)->gso_size) {
  1759. VNetBridgeSendLargePacket(skb, bridge);
  1760. } else {
  1761. VNetSend(&bridge->port.jack, skb);
  1762. }
  1763.  
  1764. return 0;
  1765. }
  1766.  
  1767.  
  1768. /*
  1769. *----------------------------------------------------------------------
  1770. *
  1771. * VNetBridgeProcRead --
  1772. *
  1773. * Callback for read operation on this bridge entry in vnets proc fs.
  1774. *
  1775. * Results:
  1776. * Length of read operation.
  1777. *
  1778. * Side effects:
  1779. * None.
  1780. *
  1781. *----------------------------------------------------------------------
  1782. */
  1783.  
  1784. int
  1785. VNetBridgeProcRead(char *page, // IN/OUT: buffer to write into
  1786. char **start, // OUT: 0 if file < 4k, else offset into page
  1787. off_t off, // IN: (unused) offset of read into the file
  1788. int count, // IN: (unused) maximum number of bytes to read
  1789. int *eof, // OUT: TRUE if there is nothing more to read
  1790. void *data) // IN: client data - pointer to bridge
  1791. {
  1792. VNetBridge *bridge = (VNetBridge*)data;
  1793. int len = 0;
  1794.  
  1795. if (!bridge) {
  1796. return len;
  1797. }
  1798.  
  1799. len += VNetPrintPort(&bridge->port, page+len);
  1800.  
  1801. len += sprintf(page+len, "dev %s ", bridge->name);
  1802.  
  1803. len += sprintf(page+len, "\n");
  1804.  
  1805. *start = 0;
  1806. *eof = 1;
  1807. return len;
  1808. }
  1809. root@a1-MS-7885:~/vmware-patch-temp# ^C
  1810. root@a1-MS-7885:~/vmware-patch-temp# ll
  1811. total 2372
  1812. drwxr-xr-x 4 root root 4096 ноя 4 02:57 ./
  1813. drwx------ 9 root root 4096 ноя 4 02:56 ../
  1814. drwxr-xr-x 7 root root 4096 ноя 16 2022 vmmon-only/
  1815. -rw-r--r-- 1 root root 1628160 ноя 4 02:54 vmmon.tar
  1816. drwxr-xr-x 2 root root 4096 ноя 4 03:00 vmnet-only/
  1817. -rw-r--r-- 1 root root 778240 ноя 4 02:54 vmnet.tar
  1818. -rw-r--r-- 1 root root 1844 ноя 4 02:55 vmware-patch.diff
  1819. root@a1-MS-7885:~/vmware-patch-temp# cat vm
  1820. vmmon-only/ vmmon.tar vmnet-only/ vmnet.tar vmware-patch.diff
  1821. root@a1-MS-7885:~/vmware-patch-temp# cat vmware-patch.diff
  1822. --- a/vmmon-only/include/pgtbl.h
  1823. +++ b/vmmon-only/include/pgtbl.h
  1824. @@ -58,7 +58,7 @@
  1825. if (!pgd_present(*pgd)) {
  1826. return INVALID_MPN;
  1827. }
  1828. - if (pgd_large(*pgd)) {
  1829. + if (pgd_page(*pgd) && pgd_large(*pgd)) {
  1830. return (pgd_pfn(*pgd) << PAGE_SHIFT) + (va & I915_GTT_PAGE_MASK);
  1831. }
  1832.  
  1833. @@ -68,7 +68,7 @@
  1834. if (!compat_p4d_present(*p4d)) {
  1835. return INVALID_MPN;
  1836. }
  1837. - if (compat_p4d_large(*p4d)) {
  1838. + if (p4d_page(*p4d) && compat_p4d_large(*p4d)) {
  1839. return (compat_p4d_pfn(*p4d) << PAGE_SHIFT) + (va & I915_GTT_PAGE_MASK);
  1840. }
  1841.  
  1842. @@ -77,7 +77,7 @@
  1843. if (!pud_present(*pud)) {
  1844. return INVALID_MPN;
  1845. }
  1846. - if (pud_large(*pud)) {
  1847. + if (pud_page(*pud) && pud_large(*pud)) {
  1848. return (pud_pfn(*pud) << PAGE_SHIFT) + (va & I915_GTT_PAGE_MASK);
  1849. }
  1850.  
  1851. @@ -86,7 +86,7 @@
  1852. if (!pmd_present(*pmd)) {
  1853. return INVALID_MPN;
  1854. }
  1855. - if (pmd_large(*pmd)) {
  1856. + if (pmd_page(*pmd) && pmd_large(*pmd)) {
  1857. return (pmd_pfn(*pmd) << PAGE_SHIFT) + (va & I915_GTT_PAGE_MASK);
  1858. }
  1859.  
  1860. --- a/vmnet-only/bridge.c
  1861. +++ b/vmnet-only/bridge.c
  1862. @@ -581,7 +581,7 @@
  1863. struct net_device *dev;
  1864. int numDevs = 0;
  1865.  
  1866. - dev_lock_list();
  1867. + rtnl_lock();
  1868. for_each_netdev(&init_net, dev) {
  1869. if (dev->flags & IFF_UP) {
  1870. numDevs++;
  1871. @@ -894,7 +894,7 @@
  1872. struct net_device *dev;
  1873. Bool success = TRUE;
  1874.  
  1875. - dev_lock_list();
  1876. + rtnl_lock();
  1877. for_each_netdev(&init_net, dev) {
  1878. if (strcmp(dev->name, bridge->devName) == 0) {
  1879. success = VNetBridgeStartDevice(bridge, dev);
  1880. @@ -1410,7 +1410,7 @@
  1881. struct sk_buff *segs;
  1882. int ret = 0;
  1883.  
  1884. - segs = skb_gso_segment(skb, 0);
  1885. + segs = skb_gso_segment(skb, dev->features & ~NETIF_F_GSO_MASK);
  1886. if (IS_ERR(segs)) {
  1887. ret = PTR_ERR(segs);
  1888. } else {
  1889. root@a1-MS-7885:~/vmware-patch-temp#
Add Comment
Please, Sign In to add comment