Hi, Ersek

Thanks for your patch, we have checked-in it into EDK II (r14332).


Best Regards,
Siyuan

-----Original Message-----
From: Laszlo Ersek [mailto:[email protected]] 
Sent: Friday, May 03, 2013 7:23 AM
To: Fan, Jeff; [email protected]; [email protected]
Subject: [edk2] [PATCH] MdeModulePkg: fix PXE_DISCOVERY_CONTROL parsing in 
UefiPxeBcDxe

Environment exposing the problem
--------------------------------
- testing PXE boot in OvmfPkg,
- network driver: VirtioNetDxe,
- host: RHEL-6.4,
- libvirt network configuration
  ("/etc/libvirt/qemu/networks/default.xml"):

  <network>
    <name>default</name>
    <uuid>52a367f4-7fb2-4d03-9ba1-032982416877</uuid>
    <forward mode='nat'/>
    <bridge name='virbr0' stp='on' delay='0' />
    <mac address='52:54:00:C3:97:EB'/>
    <ip address='192.168.122.1' netmask='255.255.255.0'>
      <tftp root='/var/lib/dnsmasq' />
      <dhcp>
        <range start='192.168.122.2' end='192.168.122.254' />
        <bootp file='ovmf.pxe.Shell.efi' />
      </dhcp>
    </ip>
  </network>

- DHCP traffic on virbr0 was enabled with an extra iptables rule as
  described in:
  http://news.gmane.org/[email protected]

In this setup libvirt starts the dnsmasq daemon in such a way that it serves 
all of DNS, DHCP, and TFTP requests. The DHCP OFFER and ACK dnsmasq sends point 
back to its own TFTP server.

Problem description
-------------------
PXE booting in OVMF, running in a virtual machine on the above network, fails.

Analysis
--------
The command "tcpdump -n -i virbr0 -v -v -v" captures the following packets when 
OVMF starts in the guest (discover, offer, request, ack; quoting them entirely 
only for completeness):

  0.0.0.0.bootpc > 255.255.255.255.bootps: [udp sum ok] BOOTP/DHCP,
  Request from 52:54:00:93:83:42, length 347, xid 0x66bf647f, Flags
  [Broadcast] (0x8000)
        Client-Ethernet-Address 52:54:00:93:83:42
        Vendor-rfc1048 Extensions
          Magic Cookie 0x63825363
          DHCP-Message Option 53, length 1: Discover
          MSZ Option 57, length 2: 1472
          Parameter-Request Option 55, length 35:
            Subnet-Mask, Time-Zone, Default-Gateway, Time-Server
            IEN-Name-Server, Domain-Name-Server, Hostname, BS
            Domain-Name, RP, EP, RSZ
            TTL, BR, YD, YS
            NTP, Vendor-Option, Requested-IP, Lease-Time
            Server-ID, RN, RB, Vendor-Class
            TFTP, BF, GUID, Option 128
            Option 129, Option 130, Option 131, Option 132
            Option 133, Option 134, Option 135
          GUID Option 97, length 17: 0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0
          NDI Option 94, length 3: 1.3.0
          ARCH Option 93, length 2: 7
          Vendor-Class Option 60, length 32:
            "PXEClient:Arch:00007:UNDI:003000"
          END Option 255, length 0

  00:15:34.674645 IP (tos 0x0, ttl 64, id 26520, offset 0, flags [none],
  proto UDP (17), length 362) 192.168.122.1.bootps >
  255.255.255.255.bootpc: [udp sum ok] BOOTP/DHCP, Reply, length 334, xid
  0x66bf647f, Flags [Broadcast] (0x8000)
        Your-IP 192.168.122.54
        Server-IP 192.168.122.1
        Client-Ethernet-Address 52:54:00:93:83:42
        file "ovmf.pxe.Shell.efi"
        Vendor-rfc1048 Extensions
          Magic Cookie 0x63825363
          DHCP-Message Option 53, length 1: Offer
          Server-ID Option 54, length 4: 192.168.122.1
          Lease-Time Option 51, length 4: 3600
          RN Option 58, length 4: 1800
          RB Option 59, length 4: 3150
          Subnet-Mask Option 1, length 4: 255.255.255.0
          BR Option 28, length 4: 192.168.122.255
          Default-Gateway Option 3, length 4: 192.168.122.1
          Domain-Name-Server Option 6, length 4: 192.168.122.1
          Vendor-Class Option 60, length 9: "PXEClient"
          GUID Option 97, length 17: 0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0
          Vendor-Option Option 43, length 10: 6.1.8.10.4.0.80.88.69.255
          END Option 255, length 0

  00:15:38.122566 IP (tos 0x0, ttl 64, id 25728, offset 0, flags [none],
  proto UDP (17), length 387) 0.0.0.0.bootpc > 255.255.255.255.bootps:
  [udp sum ok] BOOTP/DHCP, Request from 52:54:00:93:83:42, length 359, xid
  0x66bf647f, Flags [Broadcast] (0x8000)
        Client-Ethernet-Address 52:54:00:93:83:42
        Vendor-rfc1048 Extensions
          Magic Cookie 0x63825363
          DHCP-Message Option 53, length 1: Request
          Server-ID Option 54, length 4: 192.168.122.1
          Requested-IP Option 50, length 4: 192.168.122.54
          MSZ Option 57, length 2: 1472
          Parameter-Request Option 55, length 35:
            Subnet-Mask, Time-Zone, Default-Gateway, Time-Server
            IEN-Name-Server, Domain-Name-Server, Hostname, BS
            Domain-Name, RP, EP, RSZ
            TTL, BR, YD, YS
            NTP, Vendor-Option, Requested-IP, Lease-Time
            Server-ID, RN, RB, Vendor-Class
            TFTP, BF, GUID, Option 128
            Option 129, Option 130, Option 131, Option 132
            Option 133, Option 134, Option 135
          GUID Option 97, length 17: 0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0
          NDI Option 94, length 3: 1.3.0
          ARCH Option 93, length 2: 7
          Vendor-Class Option 60, length 32:
            "PXEClient:Arch:00007:UNDI:003000"
          END Option 255, length 0

  00:15:38.132147 IP (tos 0x0, ttl 64, id 26521, offset 0, flags [none],
  proto UDP (17), length 362) 192.168.122.1.bootps >
  255.255.255.255.bootpc: [udp sum ok] BOOTP/DHCP, Reply, length 334, xid
  0x66bf647f, Flags [Broadcast] (0x8000)
        Your-IP 192.168.122.54
        Server-IP 192.168.122.1
        Client-Ethernet-Address 52:54:00:93:83:42
        file "ovmf.pxe.Shell.efi"
        Vendor-rfc1048 Extensions
          Magic Cookie 0x63825363
          DHCP-Message Option 53, length 1: ACK
          Server-ID Option 54, length 4: 192.168.122.1
          Lease-Time Option 51, length 4: 3600
          RN Option 58, length 4: 1800
          RB Option 59, length 4: 3150
          Subnet-Mask Option 1, length 4: 255.255.255.0
          BR Option 28, length 4: 192.168.122.255
          Default-Gateway Option 3, length 4: 192.168.122.1
          Domain-Name-Server Option 6, length 4: 192.168.122.1
          Vendor-Class Option 60, length 9: "PXEClient"
          GUID Option 97, length 17: 0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0
          Vendor-Option Option 43, length 10: 6.1.8.10.4.0.80.88.69.255
          END Option 255, length 0

In both replies of the dnsmasq daemon, the following options / tags are
present:

  file "ovmf.pxe.Shell.efi" (DHCP option 67)
  Vendor-Option Option 43, length 10: 6.1.8.10.4.0.80.88.69.255

The Vendor Options parse as follows (see "Table 2-1 PXE DHCP Options (Full 
List)" in the PXE specification v2.1):

  6.1.8                    10.4.0.80.88.69                    255
  ^ ^ ^                    ^  ^ ^ ^^^^^^^^                    ^
  | | |                    |  | | |                           |
  | | bitfield (*)         |  | | "PXE" in ASCII (decimal)    PXE_END
  | tag contents length    |  | timeout
  PXE_DISCOVERY_CONTROL    |  tag contents length
                           PXE_MENU_PROMPT

Bit 3 (value 8 decimal) in the bitfield marked with (*) has the following
meaning:

  If set, and a boot file name is present in the initial DHCP or ProxyDHCP
  offer packet, download the boot file (do not prompt/menu/discover).

The DHCP replies sent by dnsmasq contain a PXE menu prompt but lack the PXE 
menu itself (PXE_BOOT_MENU); however in any case bit 3 of PXE_DISCOVERY_CONTROL 
should prevent the DHCP client from considering the PXE prompt or menu.

The following call chain fails to parse this bit and aborts PXE booting on 
purpose, due to attempting *at all* to interpret the otherwise conflicting 
prompt & menu options in the response packets:

(all paths under "MdeModulePkg/Universal/Network/UefiPxeBcDxe")

  EfiPxeLoadFile()                                           [PxeBcImpl.c]
    DiscoverBootFile()                                       [PxeBcImpl.c]

      PxeBcSelectBootPrompt()                                [PxeBcDhcp.c]
        Timeout == 0, return EFI_SUCCESS

      PxeBcSelectBootMenu (UseDefaultItem=TRUE)              [PxeBcDhcp.c]
        !IS_VALID_BOOT_MENU, return EFI_SUCCESS

      // Local boot(PXE bootstrap server) need abort
      return EFI_ABORTED

Fix
---
A macro for testing the bit in question already exists, it is just used 
nowhere. Rename it so that it matches the PXE specification more closely, and 
utilize it in PxeBcSelectBootPrompt(): under the circumstances presented, we 
report EFI_ABORTED. That corresponds to the user cancelling the boot prompt / 
boot menu, and we proceed to load the boot file.

With the fix PXE boot works as expected.

Contributed-under: TianoCore Contribution Agreement 1.0

Signed-off-by: Laszlo Ersek <[email protected]>
---
 .../Universal/Network/UefiPxeBcDxe/PxeBcDhcp.h     |    3 ++-
 .../Universal/Network/UefiPxeBcDxe/PxeBcDhcp.c     |   15 +++++++++++++++
 2 files changed, 17 insertions(+), 1 deletions(-)

diff --git a/MdeModulePkg/Universal/Network/UefiPxeBcDxe/PxeBcDhcp.h 
b/MdeModulePkg/Universal/Network/UefiPxeBcDxe/PxeBcDhcp.h
index 5e37228..b56d10d 100644
--- a/MdeModulePkg/Universal/Network/UefiPxeBcDxe/PxeBcDhcp.h
+++ b/MdeModulePkg/Universal/Network/UefiPxeBcDxe/PxeBcDhcp.h
@@ -1,6 +1,7 @@
 /** @file
   Dhcp and Discover routines for PxeBc.
 
+Copyright (c) 2013, Red Hat, Inc.
 Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.<BR>  This 
program and the accompanying materials  are licensed and made available under 
the terms and conditions of the BSD License @@ -160,7 +161,7 @@ WITHOUT 
WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #define IS_DISABLE_BCAST_DISCOVER(x)    (((x) & BIT (0)) == BIT (0))
 #define IS_DISABLE_MCAST_DISCOVER(x)    (((x) & BIT (1)) == BIT (1))
 #define IS_ENABLE_USE_SERVER_LIST(x)    (((x) & BIT (2)) == BIT (2))
-#define IS_ENABLE_BOOT_FILE_NAME(x)     (((x) & BIT (3)) == BIT (3))
+#define IS_DISABLE_PROMPT_MENU(x)       (((x) & BIT (3)) == BIT (3))
 
 #define SET_VENDOR_OPTION_BIT_MAP(x, y) (((x)[(y) / 32]) = (UINT32) ((x)[(y) / 
32]) | BIT ((y) % 32))
 
diff --git a/MdeModulePkg/Universal/Network/UefiPxeBcDxe/PxeBcDhcp.c 
b/MdeModulePkg/Universal/Network/UefiPxeBcDxe/PxeBcDhcp.c
index fa3594d..442579b 100644
--- a/MdeModulePkg/Universal/Network/UefiPxeBcDxe/PxeBcDhcp.c
+++ b/MdeModulePkg/Universal/Network/UefiPxeBcDxe/PxeBcDhcp.c
@@ -1,6 +1,7 @@
 /** @file
   Support for PxeBc dhcp functions.
 
+Copyright (c) 2013, Red Hat, Inc.
 Copyright (c) 2007 - 2012, Intel Corporation. All rights reserved.<BR>  This 
program and the accompanying materials  are licensed and made available under 
the terms and conditions of the BSD License @@ -1537,6 +1538,20 @@ 
PxeBcSelectBootPrompt (
 
   VendorOpt = &Packet->PxeVendorOption;
 
+  //
+  // According to the PXE specification 2.1, Table 2-1 PXE DHCP Options 
+ (Full  // List), we must not consider a boot prompt or boot menu if 
+ all of the  // following hold:
+  // - the PXE_DISCOVERY_CONTROL PXE tag is present inside the Vendor Options
+  //   (=43) DHCP tag, and
+  // - the PXE_DISCOVERY_CONTROL PXE tag has bit 3 set, and  // - a 
+ boot file name has been presented with DHCP option 67.
+  //
+  if (IS_DISABLE_PROMPT_MENU (VendorOpt->DiscoverCtrl) &&
+      Packet->Dhcp4Option[PXEBC_DHCP4_TAG_INDEX_BOOTFILE] != NULL) {
+    return EFI_ABORTED;
+  }
+
   if (!IS_VALID_BOOT_PROMPT (VendorOpt->BitMap)) {
     return EFI_SUCCESS;
   }
--
1.7.1


------------------------------------------------------------------------------
Get 100% visibility into Java/.NET code with AppDynamics Lite
It's a free troubleshooting tool designed for production
Get down to code-level detail for bottlenecks, with <2% overhead.
Download for free and get started troubleshooting in minutes.
http://p.sf.net/sfu/appdyn_d2d_ap2
_______________________________________________
edk2-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/edk2-devel

------------------------------------------------------------------------------
Learn Graph Databases - Download FREE O'Reilly Book
"Graph Databases" is the definitive new guide to graph databases and 
their applications. This 200-page book is written by three acclaimed 
leaders in the field. The early access version is available now. 
Download your free book today! http://p.sf.net/sfu/neotech_d2d_may
_______________________________________________
edk2-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/edk2-devel

Reply via email to