From: Zhang Lubo <lubo.zhang@intel.com>
To: edk2-devel@lists.01.org
Cc: Ye Ting <ting.ye@intel.com>, Fu Siyuan <siyuan.fu@intel.com>,
Wu Jiaxin <jiaxin.wu@intel.com>
Subject: [patch] NetworkPkg: Add dns support for pxe boot based on IPv6.
Date: Fri, 14 Oct 2016 15:28:09 +0800 [thread overview]
Message-ID: <1476430089-19556-1-git-send-email-lubo.zhang@intel.com> (raw)
The BootFileURL option (59) in dhcpv6 is used to deliver
the next server address with bootfile name, as an example
"tftp://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]/BOOTFILE_NAME;
mode=octet", it can also be “tftp://domain_name/BOOTFILE_NAME;
mode=octet”, this patch is to support this case.
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Zhang Lubo <lubo.zhang@intel.com>
Cc: Ye Ting <ting.ye@intel.com>
Cc: Fu Siyuan <siyuan.fu@intel.com>
Cc: Wu Jiaxin <jiaxin.wu@intel.com>
---
NetworkPkg/UefiPxeBcDxe/PxeBcBoot.c | 18 ++-
NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c | 269 +++++++++++++++++++++++++++----
NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.h | 5 +-
NetworkPkg/UefiPxeBcDxe/PxeBcImpl.h | 3 +
NetworkPkg/UefiPxeBcDxe/UefiPxeBcDxe.inf | 4 +-
5 files changed, 261 insertions(+), 38 deletions(-)
diff --git a/NetworkPkg/UefiPxeBcDxe/PxeBcBoot.c b/NetworkPkg/UefiPxeBcDxe/PxeBcBoot.c
index 8eff13c..fc50a82 100644
--- a/NetworkPkg/UefiPxeBcDxe/PxeBcBoot.c
+++ b/NetworkPkg/UefiPxeBcDxe/PxeBcBoot.c
@@ -619,31 +619,33 @@ PxeBcDhcp6BootInfo (
}
ASSERT (Cache6->OptList[PXEBC_DHCP6_IDX_BOOT_FILE_URL] != NULL);
//
+ // Set the station address to IP layer.
+ //
+ Status = PxeBcSetIp6Address (Private);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+
+ //
// Parse (m)tftp server ip address and bootfile name.
//
Status = PxeBcExtractBootFileUrl (
+ Private,
&Private->BootFileName,
&Private->ServerIp.v6,
(CHAR8 *) (Cache6->OptList[PXEBC_DHCP6_IDX_BOOT_FILE_URL]->Data),
NTOHS (Cache6->OptList[PXEBC_DHCP6_IDX_BOOT_FILE_URL]->OpLen)
);
if (EFI_ERROR (Status)) {
return Status;
}
//
- // Set the station address to IP layer.
- //
- Status = PxeBcSetIp6Address (Private);
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- //
// Parse the value of boot file size.
//
if (Cache6->OptList[PXEBC_DHCP6_IDX_BOOT_FILE_PARAM] != NULL) {
//
// Parse it out if have the boot file parameter option.
diff --git a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c b/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c
index 41d3d30..45377e3 100644
--- a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c
+++ b/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c
@@ -91,14 +91,15 @@ PxeBcBuildDhcp6Options (
//
// Append client option request option
//
OptList[Index]->OpCode = HTONS (DHCP6_OPT_ORO);
- OptList[Index]->OpLen = HTONS (4);
+ OptList[Index]->OpLen = HTONS (6);
OptEnt.Oro = (PXEBC_DHCP6_OPTION_ORO *) OptList[Index]->Data;
OptEnt.Oro->OpCode[0] = HTONS(DHCP6_OPT_BOOT_FILE_URL);
OptEnt.Oro->OpCode[1] = HTONS(DHCP6_OPT_BOOT_FILE_PARAM);
+ OptEnt.Oro->OpCode[2] = HTONS(DHCP6_OPT_DNS_SERVERS);
Index++;
OptList[Index] = GET_NEXT_DHCP6_OPTION (OptList[Index - 1]);
//
// Append client network device interface option
@@ -214,14 +215,177 @@ PxeBcFreeBootFileOption (
RemoveEntryList (Entry);
FreePool (Node);
}
}
+/**
+ Retrieve the boot server address using the EFI_DNS6_PROTOCOL.
+
+ @param[in] Private Pointer to PxeBc private data.
+ @param[in] HostName Pointer to buffer containing hostname.
+ @param[out] IpAddress On output, pointer to buffer containing IPv6 address.
+
+ @retval EFI_SUCCESS Operation succeeded.
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate needed resources.
+ @retval EFI_DEVICE_ERROR An unexpected network error occurred.
+ @retval Others Other errors as indicated.
+
+**/
+EFI_STATUS
+PxeBcDns6 (
+ IN PXEBC_PRIVATE_DATA *Private,
+ IN CHAR16 *HostName,
+ OUT EFI_IPv6_ADDRESS *IpAddress
+ )
+{
+ EFI_STATUS Status;
+ EFI_DNS6_PROTOCOL *Dns6;
+ EFI_DNS6_CONFIG_DATA Dns6ConfigData;
+ EFI_DNS6_COMPLETION_TOKEN Token;
+ EFI_HANDLE Dns6Handle;
+ EFI_IPv6_ADDRESS *DnsServerList;
+ BOOLEAN IsDone;
+
+ Dns6 = NULL;
+ Dns6Handle = NULL;
+ DnsServerList = Private->DnsServer;
+ ZeroMem (&Token, sizeof (EFI_DNS6_COMPLETION_TOKEN));
+
+ //
+ // Create a DNSv6 child instance and get the protocol.
+ //
+ Status = NetLibCreateServiceChild (
+ Private->Controller,
+ Private->Image,
+ &gEfiDns6ServiceBindingProtocolGuid,
+ &Dns6Handle
+ );
+ if (EFI_ERROR (Status)) {
+ goto Exit;
+ }
+
+ Status = gBS->OpenProtocol (
+ Dns6Handle,
+ &gEfiDns6ProtocolGuid,
+ (VOID **) &Dns6,
+ Private->Image,
+ Private->Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (EFI_ERROR (Status)) {
+ goto Exit;
+ }
+
+ //
+ // Configure DNS6 instance for the DNS server address and protocol.
+ //
+ ZeroMem (&Dns6ConfigData, sizeof (EFI_DNS6_CONFIG_DATA));
+ Dns6ConfigData.DnsServerCount = 1;
+ Dns6ConfigData.DnsServerList = DnsServerList;
+ Dns6ConfigData.EnableDnsCache = TRUE;
+ Dns6ConfigData.Protocol = EFI_IP_PROTO_UDP;
+ IP6_COPY_ADDRESS (&Dns6ConfigData.StationIp, &Private->TmpStationIp.v6);
+ Status = Dns6->Configure (
+ Dns6,
+ &Dns6ConfigData
+ );
+ if (EFI_ERROR (Status)) {
+ goto Exit;
+ }
+
+ Token.Status = EFI_NOT_READY;
+ IsDone = FALSE;
+ //
+ // Create event to set the IsDone flag when name resolution is finished.
+ //
+ Status = gBS->CreateEvent (
+ EVT_NOTIFY_SIGNAL,
+ TPL_NOTIFY,
+ PxeBcCommonNotify,
+ &IsDone,
+ &Token.Event
+ );
+ if (EFI_ERROR (Status)) {
+ goto Exit;
+ }
+
+ //
+ // Start asynchronous name resolution.
+ //
+ Status = Dns6->HostNameToIp (Dns6, HostName, &Token);
+ if (EFI_ERROR (Status)) {
+ goto Exit;
+ }
+
+ while (!IsDone) {
+ Dns6->Poll (Dns6);
+ }
+
+ //
+ // Name resolution is done, check result.
+ //
+ Status = Token.Status;
+ if (!EFI_ERROR (Status)) {
+ if (Token.RspData.H2AData == NULL) {
+ Status = EFI_DEVICE_ERROR;
+ goto Exit;
+ }
+ if (Token.RspData.H2AData->IpCount == 0 || Token.RspData.H2AData->IpList == NULL) {
+ Status = EFI_DEVICE_ERROR;
+ goto Exit;
+ }
+ //
+ // We just return the first IPv6 address from DNS protocol.
+ //
+ IP6_COPY_ADDRESS (IpAddress, Token.RspData.H2AData->IpList);
+ Status = EFI_SUCCESS;
+ }
+
+Exit:
+ FreePool (HostName);
+
+ if (Token.Event != NULL) {
+ gBS->CloseEvent (Token.Event);
+ }
+ if (Token.RspData.H2AData != NULL) {
+ if (Token.RspData.H2AData->IpList != NULL) {
+ FreePool (Token.RspData.H2AData->IpList);
+ }
+ FreePool (Token.RspData.H2AData);
+ }
+
+ if (Dns6 != NULL) {
+ Dns6->Configure (Dns6, NULL);
+
+ gBS->CloseProtocol (
+ Dns6Handle,
+ &gEfiDns6ProtocolGuid,
+ Private->Image,
+ Private->Controller
+ );
+ }
+
+ if (Dns6Handle != NULL) {
+ NetLibDestroyServiceChild (
+ Private->Controller,
+ Private->Image,
+ &gEfiDns6ServiceBindingProtocolGuid,
+ Dns6Handle
+ );
+ }
+
+ if (DnsServerList != NULL) {
+ FreePool (DnsServerList);
+ }
+
+ return Status;
+}
/**
Parse the Boot File URL option.
+ @param[in] Private Pointer to PxeBc private data.
@param[out] FileName The pointer to the boot file name.
@param[in, out] SrvAddr The pointer to the boot server address.
@param[in] BootFile The pointer to the boot file URL option data.
@param[in] Length The length of the boot file URL option data.
@@ -230,10 +394,11 @@ PxeBcFreeBootFileOption (
@retval EFI_NOT_READY Read the input key from the keybroad has not finish.
**/
EFI_STATUS
PxeBcExtractBootFileUrl (
+ IN PXEBC_PRIVATE_DATA *Private,
OUT UINT8 **FileName,
IN OUT EFI_IPv6_ADDRESS *SrvAddr,
IN CHAR8 *BootFile,
IN UINT16 Length
)
@@ -245,12 +410,16 @@ PxeBcExtractBootFileUrl (
CHAR8 *TmpStr;
CHAR8 TmpChar;
CHAR8 *ServerAddressOption;
CHAR8 *ServerAddress;
CHAR8 *ModeStr;
+ CHAR16 *HostName;
+ BOOLEAN IpExpressedUrl;
+ UINTN Len;
EFI_STATUS Status;
+ IpExpressedUrl = TRUE;
//
// The format of the Boot File URL option is:
//
// 0 1 2 3
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
@@ -262,12 +431,12 @@ PxeBcExtractBootFileUrl (
// | |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//
//
- // Based upon RFC 5970 and UEFI 2.3 Errata D specification, bootfile-url format
- // is tftp://[SERVER_ADDRESS]/BOOTFILE_NAME
+ // Based upon RFC 5970 and UEFI 2.6, bootfile-url format can be
+ // tftp://[SERVER_ADDRESS]/BOOTFILE_NAME or tftp://domain_name/BOOTFILE_NAME
// As an example where the BOOTFILE_NAME is the EFI loader and
// SERVER_ADDRESS is the ASCII encoding of an IPV6 address.
//
PrefixLen = (UINT16) AsciiStrLen (PXEBC_DHCP6_BOOT_FILE_URL_PREFIX);
@@ -289,47 +458,80 @@ PxeBcExtractBootFileUrl (
//
// Get the part of SERVER_ADDRESS string.
//
ServerAddressOption = TmpStr;
- if (*ServerAddressOption != PXEBC_ADDR_START_DELIMITER) {
- FreePool (TmpStr);
- return EFI_INVALID_PARAMETER;
- }
+ if (*ServerAddressOption == PXEBC_ADDR_START_DELIMITER) {
+ ServerAddressOption ++;
+ ServerAddress = ServerAddressOption;
+ while (*ServerAddress != '\0' && *ServerAddress != PXEBC_ADDR_END_DELIMITER) {
+ ServerAddress++;
+ }
+
+ if (*ServerAddress != PXEBC_ADDR_END_DELIMITER) {
+ FreePool (TmpStr);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *ServerAddress = '\0';
+
+ //
+ // Convert the string of server address to Ipv6 address format and store it.
+ //
+ Status = NetLibAsciiStrToIp6 (ServerAddressOption, SrvAddr);
+ if (EFI_ERROR (Status)) {
+ FreePool (TmpStr);
+ return Status;
+ }
- ServerAddressOption ++;
- ServerAddress = ServerAddressOption;
- while (*ServerAddress != '\0' && *ServerAddress != PXEBC_ADDR_END_DELIMITER) {
- ServerAddress++;
- }
+ } else {
+ IpExpressedUrl = FALSE;
+ ServerAddress = ServerAddressOption;
+ while (*ServerAddress != '\0' && *ServerAddress != PXEBC_TFTP_URL_SEPARATOR) {
+ ServerAddress++;
+ }
- if (*ServerAddress != PXEBC_ADDR_END_DELIMITER) {
- FreePool (TmpStr);
- return EFI_INVALID_PARAMETER;
- }
+ if (*ServerAddress != PXEBC_TFTP_URL_SEPARATOR) {
+ FreePool (TmpStr);
+ return EFI_INVALID_PARAMETER;
+ }
+ *ServerAddress = '\0';
- *ServerAddress = '\0';
+ Len = AsciiStrSize (ServerAddressOption);
+ HostName = AllocateZeroPool (Len * sizeof (CHAR16));
+ if (HostName == NULL) {
+ FreePool (TmpStr);
+ return EFI_OUT_OF_RESOURCES;
+ }
+ AsciiStrToUnicodeStrS (
+ ServerAddressOption,
+ HostName,
+ Len
+ );
- //
- // Convert the string of server address to Ipv6 address format and store it.
- //
- Status = NetLibAsciiStrToIp6 (ServerAddressOption, SrvAddr);
- if (EFI_ERROR (Status)) {
- FreePool (TmpStr);
- return Status;
+ //
+ // Perform DNS resolution.
+ //
+ Status = PxeBcDns6 (Private,HostName, SrvAddr);
+ if (EFI_ERROR (Status)) {
+ FreePool (TmpStr);
+ return Status;
+ }
}
//
// Get the part of BOOTFILE_NAME string.
//
BootFileNamePtr = (CHAR8*)((UINTN)ServerAddress + 1);
- if (*BootFileNamePtr != PXEBC_TFTP_URL_SEPARATOR) {
- FreePool (TmpStr);
- return EFI_INVALID_PARAMETER;
+ if (IpExpressedUrl) {
+ if (*BootFileNamePtr != PXEBC_TFTP_URL_SEPARATOR) {
+ FreePool (TmpStr);
+ return EFI_INVALID_PARAMETER;
+ }
+ ++BootFileNamePtr;
}
- ++BootFileNamePtr;
BootFileNameLen = (UINT16)(Length - (UINT16) ((UINTN)BootFileNamePtr - (UINTN)TmpStr) + 1);
if (BootFileNameLen != 0 || FileName != NULL) {
//
// Remove trailing mode=octet if present and ignore. All other modes are
// invalid for netboot6, so reject them.
@@ -480,10 +682,12 @@ PxeBcParseDhcp6Packet (
Options[PXEBC_DHCP6_IDX_BOOT_FILE_URL] = Option;
} else if (NTOHS (Option->OpCode) == DHCP6_OPT_BOOT_FILE_PARAM) {
Options[PXEBC_DHCP6_IDX_BOOT_FILE_PARAM] = Option;
} else if (NTOHS (Option->OpCode) == DHCP6_OPT_VENDOR_CLASS) {
Options[PXEBC_DHCP6_IDX_VENDOR_CLASS] = Option;
+ } else if (NTOHS (Option->OpCode) == DHCP6_OPT_DNS_SERVERS) {
+ Options[PXEBC_DHCP6_IDX_DNS_SERVER] = Option;
}
Offset += (NTOHS (Option->OpLen) + 4);
Option = (EFI_DHCP6_PACKET_OPTION *) (Offer->Dhcp6.Option + Offset);
}
@@ -862,10 +1066,11 @@ PxeBcRetryDhcp6Binl (
ASSERT (Offer->OptList[PXEBC_DHCP6_IDX_BOOT_FILE_URL] != NULL);
//
// Parse out the next server address from the last offer, and store it
//
Status = PxeBcExtractBootFileUrl (
+ Private,
&Private->BootFileName,
&Private->ServerIp.v6,
(CHAR8 *) (Offer->OptList[PXEBC_DHCP6_IDX_BOOT_FILE_URL]->Data),
NTOHS (Offer->OptList[PXEBC_DHCP6_IDX_BOOT_FILE_URL]->OpLen)
);
@@ -1113,10 +1318,18 @@ PxeBcHandleDhcp6Offer (
SelectIndex = (UINT32) (Private->SelectIndex - 1);
ASSERT (SelectIndex < PXEBC_OFFER_MAX_NUM);
Cache6 = &Private->OfferBuffer[SelectIndex].Dhcp6;
Status = EFI_SUCCESS;
+ //
+ // First try to cache DNS server address if DHCP6 offer provides.
+ //
+ if (Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER] != NULL) {
+ Private->DnsServer = AllocateZeroPool (NTOHS (Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->OpLen));
+ CopyMem (Private->DnsServer, Cache6->OptList[PXEBC_DHCP6_IDX_DNS_SERVER]->Data, sizeof (EFI_IPv6_ADDRESS));
+ }
+
if (Cache6->OfferType == PxeOfferTypeDhcpBinl) {
//
// DhcpBinl offer is selected, so need try to request bootfilename by this offer.
//
if (EFI_ERROR (PxeBcRetryDhcp6Binl (Private, SelectIndex))) {
diff --git a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.h b/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.h
index a6d52f9..9493b16 100644
--- a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.h
+++ b/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.h
@@ -31,11 +31,12 @@
#define PXEBC_DHCP6_IDX_IA_NA 0
#define PXEBC_DHCP6_IDX_BOOT_FILE_URL 1
#define PXEBC_DHCP6_IDX_BOOT_FILE_PARAM 2
#define PXEBC_DHCP6_IDX_VENDOR_CLASS 3
-#define PXEBC_DHCP6_IDX_MAX 4
+#define PXEBC_DHCP6_IDX_DNS_SERVER 4
+#define PXEBC_DHCP6_IDX_MAX 5
#define PXEBC_DHCP6_BOOT_FILE_URL_PREFIX "tftp://"
#define PXEBC_TFTP_URL_SEPARATOR '/'
#define PXEBC_ADDR_START_DELIMITER '['
#define PXEBC_ADDR_END_DELIMITER ']'
@@ -126,10 +127,11 @@ PxeBcFreeBootFileOption (
/**
Parse the Boot File URL option.
+ @param[in] Private Pointer to PxeBc private data.
@param[out] FileName The pointer to the boot file name.
@param[in, out] SrvAddr The pointer to the boot server address.
@param[in] BootFile The pointer to the boot file URL option data.
@param[in] Length Length of the boot file URL option data.
@@ -138,10 +140,11 @@ PxeBcFreeBootFileOption (
@retval EFI_NOT_READY Read the input key from the keybroad has not finish.
**/
EFI_STATUS
PxeBcExtractBootFileUrl (
+ IN PXEBC_PRIVATE_DATA *Private,
OUT UINT8 **FileName,
IN OUT EFI_IPv6_ADDRESS *SrvAddr,
IN CHAR8 *BootFile,
IN UINT16 Length
);
diff --git a/NetworkPkg/UefiPxeBcDxe/PxeBcImpl.h b/NetworkPkg/UefiPxeBcDxe/PxeBcImpl.h
index d0f5e5b..2cdc8bf 100644
--- a/NetworkPkg/UefiPxeBcDxe/PxeBcImpl.h
+++ b/NetworkPkg/UefiPxeBcDxe/PxeBcImpl.h
@@ -30,10 +30,11 @@
#include <Protocol/Ip6Config.h>
#include <Protocol/Udp4.h>
#include <Protocol/Udp6.h>
#include <Protocol/Dhcp4.h>
#include <Protocol/Dhcp6.h>
+#include <Protocol/Dns6.h>
#include <Protocol/Mtftp4.h>
#include <Protocol/Mtftp6.h>
#include <Protocol/PxeBaseCode.h>
#include <Protocol/LoadFile.h>
#include <Protocol/PxeBaseCodeCallBack.h>
@@ -134,10 +135,11 @@ struct _PXEBC_PRIVATE_DATA {
EFI_IP6_CONFIG_PROTOCOL *Ip6Cfg;
EFI_DHCP6_PROTOCOL *Dhcp6;
EFI_MTFTP6_PROTOCOL *Mtftp6;
EFI_UDP6_PROTOCOL *Udp6Read;
EFI_UDP6_PROTOCOL *Udp6Write;
+ EFI_DNS6_PROTOCOL *Dns6;
EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL *Nii;
EFI_PXE_BASE_CODE_PROTOCOL PxeBc;
EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL LoadFileCallback;
EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL *PxeBcCallback;
@@ -167,10 +169,11 @@ struct _PXEBC_PRIVATE_DATA {
EFI_IP_ADDRESS TmpStationIp;
EFI_IP_ADDRESS StationIp;
EFI_IP_ADDRESS SubnetMask;
EFI_IP_ADDRESS GatewayIp;
EFI_IP_ADDRESS ServerIp;
+ EFI_IPv6_ADDRESS *DnsServer;
UINT16 CurSrcPort;
UINT32 IaId;
UINT32 Ip4MaxPacketSize;
UINT32 Ip6MaxPacketSize;
diff --git a/NetworkPkg/UefiPxeBcDxe/UefiPxeBcDxe.inf b/NetworkPkg/UefiPxeBcDxe/UefiPxeBcDxe.inf
index c3ca218..6d1102b 100644
--- a/NetworkPkg/UefiPxeBcDxe/UefiPxeBcDxe.inf
+++ b/NetworkPkg/UefiPxeBcDxe/UefiPxeBcDxe.inf
@@ -4,11 +4,11 @@
# This driver provides PXE Base Code Protocol which is used to accessing
# PXE-compatible device for network access or booting. It could work together
# with an IPv4 stack, an IPv6 stack or both.
#
#
-# Copyright (c) 2007 - 2015, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2007 - 2016, 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
# which accompanies this distribution. The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php.
@@ -93,10 +93,12 @@
gEfiUdp6ProtocolGuid ## TO_START
gEfiMtftp6ServiceBindingProtocolGuid ## TO_START
gEfiMtftp6ProtocolGuid ## TO_START
gEfiDhcp6ServiceBindingProtocolGuid ## TO_START
gEfiDhcp6ProtocolGuid ## TO_START
+ gEfiDns6ServiceBindingProtocolGuid ## SOMETIMES_CONSUMES
+ gEfiDns6ProtocolGuid ## SOMETIMES_CONSUMES
gEfiPxeBaseCodeCallbackProtocolGuid ## SOMETIMES_PRODUCES
gEfiPxeBaseCodeProtocolGuid ## BY_START
gEfiLoadFileProtocolGuid ## BY_START
gEfiAdapterInformationProtocolGuid ## SOMETIMES_CONSUMES
--
1.9.5.msysgit.1
next reply other threads:[~2016-10-14 7:28 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-10-14 7:28 Zhang Lubo [this message]
2016-10-17 9:04 ` [patch] NetworkPkg: Add dns support for pxe boot based on IPv6 Fu, Siyuan
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1476430089-19556-1-git-send-email-lubo.zhang@intel.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox