Deferral of a packet for neighbour discovery is not really an error.
If we fail to discover a neighbour then the failure will eventually be
reported by the call to neighbour_destroy() when any outstanding I/O
buffers are discarded.
The current behaviour breaks PXE booting on FreeBSD, which seems to
treat the error return from PXENV_UDP_WRITE as a fatal error and so
never proceeds to poll PXENV_UDP_READ (and hence never allows iPXE to
receive the ARP reply and send the deferred UDP packet).
Change neighbour_tx() to return success when deferring a packet. This
fixes interoperability with FreeBSD and removes transient neighbour
cache misses from the "ifstat" error output, while leaving genuine
neighbour discovery failures visible via "ifstat" (once neighbour
discovery times out, or the interface is closed).
Debugged-by: Wissam Shoukair <wissams@mellanox.com>
Tested-by: Wissam Shoukair <wissams@mellanox.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The current API for Base16 (and Base64) encoding requires the caller
to always provide sufficient buffer space. This prevents the use of
the generic encoding/decoding functionality in some situations, such
as in formatting the hex setting types.
Implement a generic hex_encode() (based on the existing
format_hex_setting()), implement base16_encode() and base16_decode()
in terms of the more generic hex_encode() and hex_decode(), and update
all callers to provide the additional buffer length parameter.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
This fixes "initialization discards 'const' qualifier from pointer
target type" warnings with GCC 5.1.0.
Signed-off-by: Christian Hesse <mail@eworm.de>
Modified-by: Michael Brown <mcb30@ipxe.org>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The TCP Selective Acknowledgement option (specified in RFC2018)
provides a mechanism for the receiver to indicate packets that have
been received out of order (e.g. due to earlier dropped packets).
iPXE often operates in environments in which there is a high
probability of packet loss. For example, the legacy USB keyboard
emulation in some BIOSes involves polling the USB bus from within a
system management interrupt: this introduces an invisible delay of
around 500us which is long enough for around 40 full-length packets to
be dropped. Similarly, almost all 1Gbps USB2 devices will eventually
end up dropping packets because the USB2 bus does not provide enough
bandwidth to sustain a 1Gbps stream, and most devices will not provide
enough internal buffering to hold a full TCP window's worth of
received packets.
Add support for sending TCP Selective Acknowledgements. This provides
the sender with more detailed information about which packets have
been lost, and so allows for a more efficient retransmission strategy.
We include a SACK-permitted option in our SYN packet, since
experimentation shows that at least Linux peers will not include a
SACK-permitted option in the SYN-ACK packet if one was not present in
the initial SYN. (RFC2018 does not seem to mandate this behaviour,
but it is consistent with the approach taken in RFC1323.) We ignore
any received SACK options; this is safe to do since SACK is only ever
advisory and we never have to send non-trivial amounts of data.
Since our TCP receive queue is a candidate for cache discarding under
low memory conditions, we may end up discarding data that has been
reported as received via a SACK option. This is permitted by RFC2018.
We follow the stricture that SACK blocks must not report data which is
no longer held by the receiver: previously-reported blocks are
validated against the current receive queue before being included
within the current SACK block list.
Experiments in a qemu VM using forced packet drops (by setting
NETDEV_DISCARD_RATE to 32) show that implementing SACK improves
throughput by around 400%.
Experiments with a USB2 NIC (an SMSC7500) show that implementing SACK
improves throughput by around 700%, increasing the download rate from
35Mbps up to 250Mbps (which is approximately the usable bandwidth
limit for USB2).
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Microsoft IIS supports only MD5-sess for Digest authentication.
Requested-by: Andreas Hammarskjöld <junior@2PintSoftware.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Relicense files with kind permission from
Stefan Hajnoczi <stefanha@redhat.com>
alongside the contributors who have already granted such relicensing
permission.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
At some point in the past few years, binutils became more aggressive
at removing unused symbols. To function as a symbol requirement, a
relocation record must now be in a section marked with @progbits and
must not be in a section which gets discarded during the link (either
via --gc-sections or via /DISCARD/).
Update REQUIRE_SYMBOL() to generate relocation records meeting these
criteria. To minimise the impact upon the final binary size, we use
existing symbols (specified via the REQUIRING_SYMBOL() macro) as the
relocation targets where possible. We use R_386_NONE or R_X86_64_NONE
relocation types to prevent any actual unwanted relocation taking
place. Where no suitable symbol exists for REQUIRING_SYMBOL() (such
as in config.c), the macro PROVIDE_REQUIRING_SYMBOL() can be used to
generate a one-byte-long symbol to act as the relocation target.
If there are versions of binutils for which this approach fails, then
the fallback will probably involve killing off REQUEST_SYMBOL(),
redefining REQUIRE_SYMBOL() to use the current definition of
REQUEST_SYMBOL(), and postprocessing the linked ELF file with
something along the lines of "nm -u | wc -l" to check that there are
no undefined symbols remaining.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
These files cannot be automatically relicensed by util/relicense.pl
since they either contain unusual but trivial contributions (such as
the addition of __nonnull function attributes), or contain lines
dating back to the initial git revision (and so require manual
knowledge of the code's origin).
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Relicence files with kind permission from the following contributors:
Alex Williamson <alex.williamson@redhat.com>
Eduardo Habkost <ehabkost@redhat.com>
Greg Jednaszewski <jednaszewski@gmail.com>
H. Peter Anvin <hpa@zytor.com>
Marin Hannache <git@mareo.fr>
Robin Smidsrød <robin@smidsrod.no>
Shao Miller <sha0.miller@gmail.com>
Thomas Horsten <thomas@horsten.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
iPXE uses DHCP timeouts loosely based on values recommended by the
specification, but often abbreviated to reduce timeouts for reliable
and/or simple network topologies. Extract the DHCP timing parameters
to config/dhcp.h and document them. The resulting default iPXE
behavior is exactly the same, but downstreams are now afforded the
opportunity to implement spec-compliant behavior via config file
overrides.
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
Modified-by: Michael Brown <mcb30@ipxe.org>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The implementation of inet_aton() has an unknown provenance. Rewrite
this code to avoid potential licensing uncertainty.
Also move the code from core/misc.c to its logical home in net/ipv4.c,
and add a few extra test cases.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Fetching the TFTP file size is currently implemented via a custom
"tftpsize://" protocol hack. Generalise this approach to instead
close the TFTP connection whenever the parent data-transfer interface
is closed.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Windows Server 2012 R2 generates an RNDIS_INDICATE_STATUS_MSG with a
status code of 0x4002006. This status code does not appear to be
documented anywhere within the sphere of human knowledge.
Explicitly ignore this status code in order to avoid unnecessarily
cluttering the display when RNDIS debugging is enabled.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The (undocumented) VMBus protocol seems to allow for transfer
page-based packets where the data payload is split into an arbitrary
set of ranges within the transfer page set.
The RNDIS protocol includes a length field within the header of each
message, and it is known from observation that multiple RNDIS messages
can be concatenated into a single VMBus message.
iPXE currently assumes that the transfer page range boundaries are
entirely arbitrary, and uses the RNDIS header length to determine the
RNDIS message boundaries.
Windows Server 2012 R2 generates an RNDIS_INDICATE_STATUS_MSG for an
undocumented and unknown status code (0x40020006) with a malformed
RNDIS header length: the length does not cover the StatusBuffer
portion of the message. This causes iPXE to report a malformed RNDIS
message and to discard any further RNDIS messages within the same
VMBus message.
The Linux Hyper-V driver assumes that the transfer page range
boundaries correspond to RNDIS message boundaries, and so does not
notice the malformed length field in the RNDIS header.
Match the behaviour of the Linux Hyper-V driver: assume that the
transfer page range boundaries correspond to the RNDIS message
boundaries and ignore the RNDIS header length. This avoids triggering
the "malformed packet" error and also avoids unnecessary data copying:
since we now have one I/O buffer per RNDIS message, there is no longer
any need to use iob_split().
Signed-off-by: Michael Brown <mcb30@ipxe.org>
On Windows Server 2012 R2, closing and reopening the device will
sometimes result in a non-functional RX datapath. The root cause is
unknown. Clearing the receive filter before closing the device seems
to fix the problem.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The Hyper-V RNDIS implementation on Windows Server 2012 R2 requires
that we send an explicit RNDIS initialisation message in order to get
a working RX datapath.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
As of commit 03f0c23 ("[ipoib] Expose Ethernet-compatible eIPoIB
link-layer addresses and headers"), all link layers have used
addresses which fit within the DHCP chaddr field. The dhcp_chaddr()
function was therefore made obsolete by this commit, but was
accidentally left present (though unused) in the source code.
Remove the dhcp_chaddr() function and the only remaining use of it,
unnecessarily introduced in commit 08bcc0f ("[dhcp] Check for matching
chaddr in received DHCP packets").
Reported-by: Wissam Shoukair <wissams@mellanox.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
On large networks a DHCP XID collision is possible. Fix by explicitly
checking the chaddr in received DHCP packets.
Originally-fixed-by: Wissam Shoukair <wissams@mellanox.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Reject network devices which appear to be duplicates of those already
available via a different underlying hardware device. On a Xen PV-HVM
system, this allows us to filter out the emulated PCI NICs (which
would otherwise appear alongside the netfront NICs).
Note that we cannot use the Xen facility to "unplug" the emulated PCI
NICs, since there is no guarantee that the OS we subsequently load
will have a native netfront driver.
We permit devices with the same MAC address if they are attached to
the same underlying hardware device (e.g. VLAN devices).
Inspired-by: Marin Hannache <git@mareo.fr>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Some switches do not allow an individual link (as defined in IEEE Std
802.3ad-2000 section 43.3.5) to work alone in a link aggregation group
as described in section 43.3.6. This is verified on Dell's
PowerConnect M6220, based on the Broadcom Strata XGS-IV chipset.
Set the LACP_STATE_AGGREGATABLE flag in the actor.state field to
announce link aggregation in the response LACPDU, which will have the
switch enable the link aggregation group and allow frames to pass.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
When functioning as an EFI driver, drivers can be disconnected and
reconnected multiple times (e.g. via the EFI shell "connect" command,
or by running an executable such as ipxe.efi which will temporarily
disconnect existing drivers).
Minimise surprise by resetting the network device index to zero
whenever the last device is unregistered. This is not foolproof, but
it does handle the common case of having all devices unregistered and
then reregistered in the original order.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Expose the build timestamp (measured in seconds since the Epoch) and
the build name (e.g. "rtl8139.rom" or "ipxe.efi"), and provide the
product name and product short name in a single centralised location.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Parse the sense data to extract the reponse code, the sense key, the
additional sense code, and the additional sense code qualifier.
Originally-implemented-by: Hannes Reinecke <hare@suse.de>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
If ipv6_tx() is called with a non-NULL network device, a NULL or
unspecified source address, and a destination address which does not
match any routing table entry, then it will attempt to copy the source
address from a NULL pointer.
I don't think that there is currently any code path which could
trigger this behaviour, but we should probably ensure that it can
never happen.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Destination multicast addresses require a sin6_scope_id, which should
therefore be transcribed to a network device name by ipv6_sock_ntoa().
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The transmitting network device is specified via the destination
address, not the source address. There is no reason to set
sin6_scope_id on the source address.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Setting sin6_scope_id to a non-zero value will cause the check against
the "empty socket address" in udp_demux() to fail, and incoming DHCPv6
responses on interfaces other than net0 will be rejected with a
spurious "No UDP connection listening on port 546" error.
The transmitting network device is specified via the destination
address, not the source address. Fix by simply not setting
sin6_scope_id on the client socket address.
Reported-by: Anton D. Kachalov <mouse@yandex-team.ru>
Tested-by: Anton D. Kachalov <mouse@yandex-team.ru>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Get the NFS URI manipulation code out of nfs_open.c. The resulting
code is now much more readable.
Signed-off-by: Marin Hannache <git@mareo.fr>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Avoid generating syntactically invalid log messages by ensuring that
invalid characters are not present in the hostname. In particular,
ensure that any whitespace is stripped, since whitespace functions as
a field separator for syslog messages.
Reported-by: Alex Davies <adavies@jumptrading.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
An invalid free() was ironically introduced by fixing another invalid
free in commit 7aa69c4 ("[nfs] Fix an invalid free() when loading a
symlink").
Signed-off-by: Marin Hannache <git@mareo.fr>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
When running inside a virtual machine (or when using the UNDI driver),
transmitting packets can be expensive. When we receive several
packets in one poll (e.g. because a slow BIOS timer interrupt routine
has caused us to fall behind in processing), we can safely send just a
single ACK to cover all of the received packets. This reduces the
time spent transmitting and allows us to clear the backlog much
faster.
Various RFCs (starting with RFC1122) state that there should be an ACK
for at least every second segment. We choose not to enforce this
rule. Under normal operation each poll should find at most one
received packet, and we will then not delay any ACKs. We delay
(i.e. omit) ACKs only when under sufficiently heavy load that we are
finding multiple packets per poll; under these conditions it is
important to clear the backlog quickly since any delay may lead to
dropped packets.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Expand the concept of the X.509 cache to provide the functionality of
a certificate store. Certificates in the store will be automatically
used to complete certificate chains where applicable.
The certificate store may be prepopulated at build time using the
CERT=... build command line option. For example:
make bin/ipxe.usb CERT=mycert1.crt,mycert2.crt
Certificates within the certificate store are not implicitly trusted;
the trust list is specified using TRUST=... as before. For example:
make bin/ipxe.usb CERT=root.crt TRUST=root.crt
This can be used to embed the full trusted root certificate within the
iPXE binary, which is potentially useful in an HTTPS-only environment
in which there is no HTTP server from which to automatically download
cross-signed certificates or other certificate chain fragments.
This usage of CERT= extends the existing use of CERT= to specify the
client certificate. The client certificate is now identified
automatically by checking for a match against the private key. For
example:
make bin/ipxe.usb CERT=root.crt,client.crt TRUST=root.crt KEY=client.key
Signed-off-by: Michael Brown <mcb30@ipxe.org>
iPXE currently allocates a copy the certificate's common name as a
string. This string is used by the TLS and CMS code to check
certificate names against an expected name, and also appears in
debugging messages.
Provide a function x509_check_name() to centralise certificate name
checking (in preparation for adding subjectAlternativeName support),
and a function x509_name() to provide a name to be used in debugging
messages, and remove the dynamically allocated string.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
At least one HTTP server (Google's OCSP responder) has been observed
to generate a Content-Length header with trailing whitespace.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
A web server may return a 503 Service Unavailable response along with
a Retry-After header to direct the client to retry the request at a
later time.
The Retry-After header may be a number of seconds, or a full HTTP
timestamp (e.g. "Fri, 7 Mar 2014 17:22:14 GMT"). We have no
reasonable way of parsing a full HTTP timestamp; if the server chooses
to use this format then we simply retry after a fixed 5-second delay.
As per RFC 2616, in the absence of a Retry-After header we treat a
status code of 503 Service Unavailable as being equivalent to 500
Internal Server Error, and immediately fail the request.
Requested-by: Suresh Sundriyal <ssundriy@vmware.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
iPXE currently ignores ACKs which do not acknowledge any new data.
(In particular, it does not stop the retransmission timer; this is
done to prevent an immediate retransmission if a duplicate ACK is
received while the transmit queue is non-empty.)
If a peer provides a window size of zero and later sends a duplicate
ACK to update the window size, this update will therefore be ignored
and iPXE will never be able to transmit data.
Fix by updating the window size even for ACKs which do not acknowledge
new data.
Reported-by: Wissam Shoukair <wissams@mellanox.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
When opening a VLAN device, vlan_open() will call netdev_open() on the
trunk device. This will result in a call to netdev_notify(), which
will cause vlan_notify() to call vlan_sync() on the original VLAN
device, which will see that the trunk device is now open but the VLAN
device apparently isn't (since it has not yet been flagged as open by
netdev_open()). The upshot is a second attempt to open the VLAN
device, which will result in an erroneous second call to vlan_open().
This convoluted chain of events then terminates harmlessly since
vlan_open() calls netdev_open() on the trunk device, which just
returns immediately since the trunk device is by now flagged as being
already open.
Prevent this from happening by having netdev_open() flag the device as
open prior to calling the device's open() method, and reflagging it as
closed if the open() method fails.
Originally-fixed-by: Wissam Shoukair <wissams@mellanox.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
iPXE currently advertises a fixed MSS of 1460, which is correct only
for IPv4 over Ethernet. For IPv6 over Ethernet, the value should be
1440 (allowing for the larger IPv6 header). For non-Ethernet link
layers, the value should reflect the MTU of the underlying network
device.
Use tcpip_mtu() to calculate the transport-layer MTU associated with
the peer address, and calculate the MSS to allow for an optionless TCP
header as per RFC 6691.
As a side benefit, we can now fail a connection immediately with a
meaningful error message if we have no route to the destination
address.
Reported-by: Anton D. Kachalov <mouse@yandex-team.ru>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Provide the function tcpip_mtu() to allow external code to determine
the (transport-layer) maximum transmission unit for a given socket
address.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Provide the function tcpip_netdev() to allow external code to
determine the transmitting network device for a given socket address.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Add support for parsing of URIs containing literal IPv6 addresses
(e.g. "http://[fe80::69ff:fe50:5845%25net0]/boot.ipxe").
Duplicate URIs by directly copying the relevant fields, rather than by
formatting and reparsing a URI string. This relaxes the requirements
on the URI formatting code and allows it to focus on generating
human-readable URIs (e.g. by not escaping ':' characters within
literal IPv6 addresses). As a side-effect, this allows relative URIs
containing parameter lists (e.g. "../boot.php##params") to function
as expected.
Add validity check for FTP paths to ensure that only printable
characters are accepted (since FTP is a human-readable line-based
protocol with no support for character escaping).
Construct TFTP next-server+filename URIs directly, rather than parsing
a constructed "tftp://..." string,
Add self-tests for URI functions.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
When resizing DHCP options, iPXE currently calculates the length to be
copied by subtracting the destination pointer from the end of buffer
pointer. This works and guarantees not to write beyond the end of the
buffer, but may end up reading beyond the end of the buffer.
Fix by calculating the required length exactly.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Commit d4c0226 ("[dns] Support DNS search lists") introduced a
regression when handling CNAME records resolving to names longer than
the original name. The "end of name" offset stored in dns->offset was
not updated to reflect the length of the new name, causing
dns_question() to append the (empty) search suffix at an incorrect
offset within the name buffer, resulting in a mangled DNS name.
In the case of a CNAME record resolving to a name shorter than or
equal in length to the original name, then the mangling would occur in
an unused portion of the name buffer. In the common case of a name
server returning the A (or AAAA) record along with the CNAME record,
this would cause name resolution to succeed despite the mangling. (If
the name server did not return the A or AAAA record along with the
CNAME record, then the mangling would be revealed by the subsequent
invalid query packet.)
Reported-by: Nicolas Sylvain <nsylvain@gmail.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Update the DNS resolver to support DNS search lists (as provided by
DHCP option 119, DHCPv6 option 24, or NDP option 31).
Add validation code to ensure that parsing of DNS packets does not
overrun the input, get stuck in infinite loops, or (worse) write
beyond the end of allocated buffers.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Allow for equivalent IPv4 and IPv6 settings (which requires equivalent
settings to be adjacent within the settings list).
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Note that IANA has not yet assigned a DHCPv6 option code for the
syslog server. When a code is assigned, the definition of
DHCPV6_LOG_SERVERS should be updated. Until then, an IPv6 address of
a syslog server can be configured manually using e.g.
set syslog6 3ffe:302:11:2::8309
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Our policy is to prefer IPv6 addreses to IPv4 addresses, but to
request IPv6 addresses only if we have an IPv6 address for the name
server itself.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Allow for the existence of references to IPv6 setting types without
dragging in the whole IPv6 stack, by placing the definition of
setting_type_ipv6 in core/settings.c and providing weak stub methods
for parse_ipv6_setting() and format_ipv6_setting().
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The fetch_setting() family of functions may currently modify the
definition of the specified setting (e.g. to add missing type
information). Clean up this interface by requiring callers to provide
an explicit buffer to contain the completed definition of the fetched
setting, if required.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Allow for IPv6 routing table entries to be created for an on-link
prefix where a local address has not yet been assigned to the network
device.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Add support for the stateful and stateless variants of the DHCPv6
protocol. The resulting settings block is registered as
"net<x>.dhcpv6", and DHCPv6 options can be obtained using
e.g. "${net0.dhcpv6/23:ipv6}" to obtain the IPv6 DNS server address.
IPv6 addresses obtained via stateful DHCPv6 are not yet applied to the
network device.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Include IPv6 within the generic network device configurator
mechanism. The IPv6 configurator will send a router solicitation and
wait for a router advertisement to be received. (As per RFC4861
section 6.3.7, we do this even if advertisements have been received
prior to sending the router solicitation.)
Signed-off-by: Michael Brown <mcb30@ipxe.org>
iPXE supports multiple mechanisms for network device configuration:
DHCPv4 for IPv4, FIP for FCoE, and SLAAC for IPv6. At present, DHCPv4
requires an explicit action (e.g. a "dhcp" command), FIP is initiated
implicitly upon opening a network device, and SLAAC takes place
whenever a RA happens to be received.
Add a generic concept of a network device configurator, which provides
a common interface to triggering configuration and to reporting the
result of the configuration process.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Most network upper-layer drivers do not implement all three methods
(probe, notify, and remove). Save code by making all methods
optional.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
When chainloading, always retrieve the cached DHCPACK packet from the
underlying PXE stack, and apply it as the original contents of the
"net<X>.dhcp" settings block. This allows cached DHCP settings to be
used for any chainloaded iPXE binary (not just undionly.kkpxe).
This change eliminates the undocumented "use-cached" setting. Issuing
the "dhcp" command will now always result in a fresh DHCP request.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
When transmitting to a link-local or multicast destination address,
use the network device's link-local address as the source address if
no explicit source address has been specified.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The IPv6 option length field represents the length of the option data
field, not the overall length of the option.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Merge common functionality between IPv4 and IPv6 ICMP echo handling,
and add support for transmitting ICMP echo requests and delivering
ICMP echo replies to a (not yet implemented) ping_rx() function.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Replace the existing partially-implemented IPv6 stack with a fresh
implementation.
This implementation is not yet complete. The IPv6 transmit and
receive datapaths are functional (including fragment reassembly and
parsing of arbitrary extension headers). NDP neighbour solicitations
and advertisements are supported. ICMPv6 echo is supported.
At present, only link-local addresses may be used, and there is no way
to specify an IPv6 address as part of a URI (either directly or via
a DNS lookup).
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Split the protocol-independent portions of arp.c into a separate file
neighbour.c, to allow for sharing of functionality between IPv4+ARP
and IPv6+NDP.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
IPv6 link-local socket addresses require some way to specify a local
network device. We cannot simply use a pointer to the network device,
since a struct sockaddr_in6 may be long-lived and has no way to hold a
reference to the network device.
Using a network device index allows a socket address to cleanly refer
to a network device without worrying about whether or not that device
continues to exist.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Give tap devices a meaningful name, and avoid segmentation faults when
attempting to retrieve ${net0/bustype} by assigning a new bus type for
tap devices.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Allow HTTP POST requests to be generated when the URI includes a
parameter list. For example:
#!ipxe
params
param mac ${net0/mac}
param uuid ${uuid}
param asset ${asset}
chain http://boot.ipxe.org/demo/boot.php##params
Signed-off-by: Michael Brown <mcb30@ipxe.org>
This makes it possible to leave UDP debugging enabled in order to see
interesting UDP events, without flooding the console with at least one
message per packet.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
There are currently two conflicting usages of the term "named setting"
within iPXE: one refers to predefined settings (such as show up in the
"config" UI), the other refers to settings identified by a name (such
as "net0.dhcp/ip").
Split these usages into the term "predefined setting" and "named
setting" to avoid ambiguity.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Allow any iPXE command expecting a network device name to accept
"netX" as a synonym for "most recently opened network device".
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Add a facility for settings blocks to act as symbolic links to other
settings blocks, and reimplement the "netX" virtual settings block
using this facility.
The primary advantage of this approach is that unscoped settings such
as ${mac} and ${filename} will now reflect the settings obtained from
the most recently opened network device: in most cases, this will mean
the settings obtained from the most recent DHCP attempt. This should
improve conformance to the principle of least astonishment.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
On large networks with substantial numbers of monitoring agents,
unwanted TCP connection attempts may end up flooding iPXE's ARP cache.
Fix by silently dropping packets received for unrecognised TCP
connections. This should not cause problems, since many firewalls
will also silently drop any such packets.
Reported-by: Jarrod Johnson <jarrod.b.johnson@gmail.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Create an explicit concept of "settings scope" and eliminate the magic
values used for numerical setting tags.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Devices with small transmit descriptor rings may temporarily run out
of space. Provide netdev_tx_defer() to allow drivers to defer packets
for retransmission as soon as a descriptor becomes available.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
iPXE currently seeds the random number generator using the system
timer tick count. When large numbers of machines are booted
simultaneously, multiple machines may end up choosing the same DHCP
transaction ID (XID) value; this can cause problems.
Fix by using the least significant (and hence most variable) bits of
each network device's link-layer address to perturb the random number
generator. This introduces some per-machine unique data into the
random number generator's seed, and so reduces the chances of DHCP XID
collisions.
This does not affect the ANS X9.82-compatible random bit generator
used by TLS and other cryptography code, which uses an entirely
separate source of entropy.
Originally-implemented-by: Bernhard Kohl <bernhard.kohl@nsn.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The PXE spec does not specify a byte ordering for UUIDs, but RFC4578
suggests that it follows the EFI spec, in which the first three fields
are little-endian.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The PXE TFTP API allows the caller to request a particular TFTP block
size. Since mid-2008, iPXE has appended a "?blksize=xxx" parameter to
the TFTP URI constructed internally; nothing has ever parsed this
parameter. Nobody seems to have cared that this parameter has been
ignored for almost five years.
Fix by using xfer_window(), which provides a fairly natural way to
convey the block size information from the PXE TFTP API to the TFTP
protocol layer.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Some NICs (e.g. Hermon) provide hardware support for stripping the
VLAN tag, but do not provide any way for this support to be disabled.
Drivers for this hardware must therefore call vlan_find() to identify
a suitable receiving network device.
Provide a weak version of vlan_find() which will always return NULL if
VLAN support has not been enabled (either directly, or by enabling
a feature such as FCoE which requires VLAN support). This allows the
VLAN code to be omitted from builds where the user has not requested
support for VLANs.
Inspired-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The iBFT has a VLAN field that should be filled in. Add the
vlan_tag() function to extract the VLAN tag of a network device.
Since VLAN support is optional, define a weak function that returns 0
when iPXE is built without VLAN support.
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Modified-by: Michael Brown <mcb30@ipxe.org>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Allow non-data records to be split across multiple received I/O
buffers, to accommodate large certificate chains.
Reported-by: Nicola Volpini <Nicola.Volpini@kambi.com>
Tested-by: Nicola Volpini <Nicola.Volpini@kambi.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Avoid memory leaks by clearing any (non-child) settings immediately
before unregistering the network device settings block.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Including a netdev_poll() within net_tx() can cause the net_step()
loop to end up processing hundreds or thousands of packets within a
single step, since each received packet being processed may trigger a
response which, in turn causes a poll for further received packets.
Network devices must now ensure that the TX ring is at least as large
as the RX ring, in order to avoid running out of TX descriptors. This
should not cause any problems; unlike the RX ring, there is no
substantial memory cost incurred by increasing the TX ring size.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Take ownership from the ARP cache at the start of arp_destroy(), to
ensure that no code path can lead to arp_destroy() being re-entered.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
TLS servers are not obliged to implement the RFC3546 maximum fragment
length extension, and many common servers (including OpenSSL, as used
in Apache's mod_ssl) do not do so. iPXE may therefore have to cope
with TLS records of up to 16kB. Allocations for 16kB have a
non-negligible chance of failing, causing the TLS connection to abort.
Fix by maintaining the received record as a linked list of I/O
buffers, rather than a single contiguous buffer. To reduce memory
pressure, we also decrypt in situ, and deliver the decrypted data via
xfer_deliver_iob() rather than xfer_deliver_raw().
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Almost all clients of the raw-packet interfaces (UNDI and SNP) can
handle only Ethernet link layers. Expose an Ethernet-compatible link
layer to local clients, while remaining compatible with IPoIB on the
wire. This requires manipulation of ARP (but not DHCP) packets within
the IPoIB driver.
This is ugly, but it's the only viable way to allow IPoIB devices to
be driven via the raw-packet interfaces.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Commit 501527d ("[http] Treat any unexpected connection close as an
error") introduced a regression causing HTTP SAN booting to fail. At
the end of the response to the HEAD request, the call to http_done()
would erroneously believe that the server had disconnected in the
middle of the HTTP headers.
Fix by treating the header block from a HEAD request as a trailer
block. This fixes the problem and also simplifies the logic in
http_rx_header().
Reported-by: Shao Miller <shao.miller@yrdsb.edu.on.ca>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The FTP SIZE command allows us to get the size of a particular file,
as a consequence, we can now show proper transfer progression while
fetching a file using the FTP protocol.
Signed-off-by: Marin Hannache <git@mareo.fr>
Modified-by: Michael Brown <mcb30@ipxe.org>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
iPXE currently checks that the server has not closed the connection
mid-stream (i.e. in the middle of a chunked transfer, or before the
specified Content-Length has been received), but does not check that
the server got as far as starting to send data. Consequently, if the
server closes the connection before any data is transferred (e.g. if
the server gives up waiting while iPXE performs the validation steps
for TLS), then iPXE will treat this as a successful transfer of a
zero-length file.
Fix by checking the RX connection state, and forcing an error if the
server has closed the connection at an unexpected point.
Originally-fixed-by: Marin Hannache <mareo@mareo.fr>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Whenever memory pressure causes a queued packet to be discarded (and
so retransmitted), reduce the maximum TCP window to a size that would
have prevented the discard.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Discarding the active ARP cache entry in the middle of a download will
substantially disrupt the TCP stream. Try to minimise any such
disruption by treating ARP cache entries as expensive, and discarding
them only when nothing else is available to discard.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The current logic is to process at most one received packet per call
to net_poll(), on the basis that refilling the hardware descriptor
ring should be delayed as little as possible. However, this limits
the rate at which packets can be processed and ultimately ends up
adding latency which, in turn, limits the achievable throughput.
With temporary modifications in place to essentially remove all
resource constraints (heap size increased to 16MB, RX descriptor ring
increased to 64 descriptors) and a TCP window size of 1MB, the
throughput on a gigabit (i.e. 119MBps) network can be observed to fall
off exponentially from around 115MBps to around 75MBps. Changing
net_poll() to process all received packets results in a steady
119MBps throughput.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Each ARP cache entry maintains a transmission queue, which is sent out
as soon as the link-layer address is known. If multiple packets are
queued, then it is possible for memory pressure to cause the ARP cache
discarder to be invoked during transmission of the first packet, which
may cause the ARP cache entry to be deleted before the second packet
can be sent. This results in an invalid pointer dereference.
Avoid this problem by reference-counting ARP cache entries and
ensuring that an extra reference is held while processing the
transmission queue, and by using list_first_entry() rather than
list_for_each_entry_safe() to traverse the queue.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Commit ea61075 ("[tcp] Add support for TCP window scaling") introduced
a potential NULL pointer dereference by referring to the connection's
send window scale before checking whether or not the connection is
known.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The default maximum plaintext fragment length for TLS is 16kB, which
is a substantial amount of memory for iPXE to have to allocate for a
temporary decryption buffer.
Reduce the memory footprint of TLS connections by requesting a maximum
fragment length of 2kB.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The maximum unscaled TCP window (64kB) implies a maximum bandwidth of
around 300kB/s on a WAN link with an RTT of 200ms. Add support for
the TCP window scaling option to remove this upper limit.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Calculating the TCP/IP checksum on received packets accounts for a
substantial fraction of the response latency.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
FCoE requires the use of multiple local unicast link-layer addresses.
To avoid the complexity of managing multiple addresses, iPXE operates
in promiscuous mode. As a consequence, any unicast packets with
non-matching IPv4 addresses are rejected at the IPv4 layer (rather
than at the link layer).
This can cause problems when issuing a second DHCP request: if the
address chosen by the DHCP server does not match the existing address,
then the DHCP response will itself be rejected.
Fix by requesting a broadcast response from the DHCP server if the
network interface already has any IPv4 addresses.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Provide HTTP Basic authentication credentials only in response to a
401 Unauthorized response from the server.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Some headers can modify the meaning of the response code. For
example, a WWW-Authenticate header can change the interpretation of a
401 Unauthorized response from "Access denied" to "Please
authenticate".
Signed-off-by: Michael Brown <mcb30@ipxe.org>
iSCSI generally includes a full SCSI response only when an error
occurs. iscsi_scsi_done() currently passes the NULL response through
to scsi_response(), which ends up causing scsicmd_response() to
dereference a NULL pointer.
Fix by calling scsi_response() only if we have a non-NULL response.
Reported-by: Brendon Walsh <brendonwalsh@niamu.com>
Tested-by: Brendon Walsh <brendonwalsh@niamu.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
X.509 certificate processing currently produces an overwhelming amount
of debugging information. Move some of this from DBGLVL_LOG to
DBGLVL_EXTRA, to make the output more manageable.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Automatically attempt to download any required cross-signing
certificates from http://ca.ipxe.org/auto, in order to enable the use
of standard SSL certificates issued by public CAs.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
To allow for automatic download of cross-signing certificates and for
OCSP, the validation of certificates must be an asynchronous process.
Create a stub validator which uses a job-control interface to report
the result of certificate validation.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
At present, certificate chain validation is treated as an
instantaneous process that can be carried out using only data that is
already in memory. This model does not allow for validation to
include non-instantaneous steps, such as downloading a cross-signing
certificate, or determining certificate revocation status via OCSP.
Redesign the internal representation of certificate chains to allow
chains to outlive the scope of the original source of certificates
(such as a TLS Certificate record).
Allow for certificates to be cached, so that each certificate needs to
be validated only once.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
http_step() allocates a potentially large block of storage (since the
URI can be arbitrarily long), and can be invoked as part of an already
deep call stack via xfer_window_changed().
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Allow TFTP to be configured out by moving the next-server setting
definition (which is used by autoboot.c) from tftp.c to settings.c.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
sizeof(cipherspec) is obviously wrong in this context, because it will
only zero the first 4 or 8 bytes (cipherspec is a pointer).
This problem was reported by cppcheck.
Signed-off-by: Stefan Weil <sw@weilnetz.de>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Use a private ANSI escape sequence to convey the priority of an
internal syslog() message through to the syslog server.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
An ANSI escape sequence context cannot be shared between multiple
users. Make the ANSI escape sequence context part of the line console
definition and provide individual contexts for each user.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The output from text-based user interfaces such as the "config"
command is not generally meaningful for logfile-based consoles such as
syslog and vmconsole.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Add the concept of a "console usage", such as "standard output" or
"debug messages". Allow usages to be associated with each console
independently. For example, to send debugging output via the serial
port, while preventing it from appearing on the local console:
#define CONSOLE_SERIAL CONSOLE_USAGE_ALL
#define CONSOLE_PCBIOS ( CONSOLE_USAGE_ALL & ~CONSOLE_USAGE_DEBUG )
If no usages are explicitly specified, then a default set of usages
will be applied. For example:
#define CONSOLE_SERIAL
will have the same affect as
#define CONSOLE_SERIAL CONSOLE_USAGE_ALL
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Simplify code by recording the active handshake digest algorithm as a
session parameter. (Note that we must still accumulate digests for
all supported algorithms, since we don't know which digest will
eventually be used until we receive the Server Hello.)
Signed-off-by: Michael Brown <mcb30@ipxe.org>
TLSv1.1 and earlier use a hybrid of MD5 and SHA-1 to generate digests
over the handshake messages. Formalise this as a separate digest
algorithm "md5+sha1".
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Validate the server certificate against the trusted root certificate
store. The server must provide a complete certificate chain, up to
and including the trusted root certificate that is embedded into iPXE.
Note that the date and time are not yet validated.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
All axTLS files are now vanilla versions of the upstream axTLS files,
with one minor exception: the unused "ctx" parameter of
bi_int_divide() has been marked with "__unused" to avoid a compilation
error.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Advertise support for TLS version 1.1, and be prepared to downgrade to
TLS version 1.0. Tested against Apache with mod_gnutls, using the
GnuTLSPriorities directive to force specific protocol versions.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Allow packet transmission to be deferred pending successful ARP
resolution. This avoids the time spent waiting for a higher-level
protocol (e.g. TCP or TFTP) to attempt retransmission.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Some PXE stacks (observed with a QLogic 8242) will always try to
prepend a link-layer header, even if the caller uses P_UNKNOWN to
indicate that the link-layer header has already been filled in. This
results in an invalid packet being transmitted.
Work around these faulty PXE stacks where possible by stripping the
existing link-layer header and allowing the PXE stack to (re)construct
the link-layer header itself.
Originally-fixed-by: Buck Huppmann <buckh@pobox.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Some iSCSI targets respond to a PDU before receiving the padding
bytes. If the target responds quickly enough, this can cause iPXE to
start processing a new TX PDU before the padding bytes have been sent,
which results in a protocol violation.
Fix by always transmitting the padding bytes along with the data
segment.
Originally-fixed-by: Shyam Iyer <shyam_iyer@dell.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
As RFC 2616 10.3.4 explains, a 303 status is the proper HTTP 1.1
behavior for what most HTTP 1.0 clients did with code 302.
Signed-off-by: Jason Lunz <lunz@acm.org>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Abstract out the generic line-handling portions of the syslog
putchar() routine, to allow use by other console types.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Explicitly disable the syslog console when no syslog server is
defined, rather than (ab)using the socket family address as an
equivalent console-enabled flag.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Separate out the core HTTP functionality (which is shared by both HTTP
and HTTPS) from the provision of the "http://" URI opener. This
allows for builds that support only "https://" URIs.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The PXE specification requires us to request DHCP options 128 to 135
inclusive, although these have no defined purpose.
Suggested-by: Ralf Buettner <rab@bootix.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Some iSCSI targets (observed with stgt) can be configured to reject
connections that do not use header or data digests, and will respond
with "HeaderDigest=Reject" and/or "DataDigest=Reject", while still
allowing the connection to proceed to the full feature phase.
According to a strict reading of RFC3720, we are perfectly safe to
ignore these "Reject" messages: upon such a rejection "the negotiated
key is left at its current value (or default if no value was set)".
Since the default value for both HeaderDigest and DataDigest is
"None", then the only viable conclusion to be drawn is that the value
resulting from "Reject" is still "None".
Unfortunately, stgt doesn't seem to agree with this interpretation of
events, causing us to eventually report an unhelpful "connection timed
out" message to the user when we don't get any response to our first
PDU in full feature phase.
Fix by detecting any rejected parameters and immediately reporting an
error, which at least gives the user some insight as to what the real
problem may be.
Reported-by: Michal Suchanek <hramrach@centrum.cz>
Tested-by: Michal Suchanek <hramrach@centrum.cz>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Drivers are currently expected to initialise only the hardware
address, with the link-layer protocol code taking care of converting
this into a valid link-layer address. Some drivers (e.g. undinet) can
legitimately determine both the hardware and link-layer addresses,
which may differ.
Allow for this situation by checking to see if the link-layer address
is empty before initialising it from the hardware address.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
iPXE currently uses the last four bytes of the MAC address as the DHCP
transaction identifier. Reduce the probability of collisions by
generating a random transaction identifier.
Originally-implemented-by: Amos Kong <akong@redhat.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
TCP currently neglects to allow sufficient space for its own headers
when allocating I/O buffers. This problem is masked by the fact that
the maximum link-layer header size (802.11) is substantially larger
than the common Ethernet link-layer header.
Fix by allowing sufficient space for any TCP headers, as well as the
network-layer and link-layer headers.
Reported-by: Scott K Logan <logans@cottsay.net>
Debugged-by: Scott K Logan <logans@cottsay.net>
Tested-by: Scott K Logan <logans@cottsay.net>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
timer->refcnt is allowed to be NULL, in which case the timer's
expired() method may end up freeing the timer object.
Discovered using valgrind.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
When transmitting, use the broadcast link-layer address for any
broadcast address (e.g. 192.168.0.255), not just INADDR_BROADCAST
(255.255.255.255).
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Explicitly discard any unicast packets for addresses that we do not
control, to avoid unexpected behaviour when operating in promiscuous
mode (which is now the default, thanks to FCoE).
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Allow the link layer to directly report whether or not a packet is
multicast or broadcast at the time of calling pull(), rather than
relying on heuristics to determine this at a later stage.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
According to section 14.23 of RFC2616, an HTTP Host header without
port implies the default port is used. Thus, when fetching from
anywhere but port 80 for HTTP or 443 for HTTPS, the port ought to be
explicitly given in that header. Otherwise, some servers might fail
to associate the request with the correct virtual host or generate
incorrect self-referencing URLs.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The iSCSI TX process can now be woken up by the TCP socket via
xfer_window_changed(), so it is no longer valid to assume that
iscsi_tx_step() can be called in state ISCSI_TX_IDLE only immediately
after completing a transmission.
Fix by calling iscsi_tx_done() only upon a transition into state
ISCSI_TX_IDLE.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Provide support for HTTP range requests, and expose this functionality
via the iPXE block device API. This allows SAN booting from a root
path such as:
sanboot http://boot.ipxe.org/freedos/fdfullcd.iso
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Give the step() method a pointer to the containing object, rather than
a pointer to the process. This is consistent with the operation of
interface methods, and allows a single function to serve as both an
interface method and a process step() method.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
ftp_data_deliver() does nothing except pass through the received data
to the xfer interface, and so can be eliminated by using a
pass-through interface.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
At the time of attempting ARP resolution, we already know the
transmitting network device. We can therefore record ARP errors using
netdev_tx_err() so that they show up in the output of "ifstat".
Inspired-by: Dominik Russenberger <dominik.russenberger@terreactive.ch>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Allow TX errors to be recorded against a network device even when the
packet didn't make it as far as netdev_tx().
Inspired-by: Dominik Russenberger <dominik.russenberger@terreactive.ch>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
(Ab)use the "ident" field in transmitted IPv4 packets to convey
metadata about the network device. In particular:
bits 0-3 represent the low bits of the "RX" good packet counter
bits 4-7 represent the low bits of the "RXE" bad packet counter
bits 8-15 represent the transmitted packet sequence number
This allows some relevant information about the internal state of the
network device to be read out from a packet trace from a non-debug
build of iPXE. In particular, it allows a packet trace containing
packets transmitted by iPXE to indicate whether or not any packets
have been received by iPXE.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Booting from an HTTP SAN will require HTTP range requests, which are
defined only in HTTP/1.1 and above. HTTP/1.1 mandates support for
"Transfer-Encoding: chunked", so we must support it.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Commit 3f442d3 ("[tcp] Record ts_recent on first received packet")
failed to achieve its stated intention.
Fix this (and reduce the code size) by moving the ts_recent update to
tcp_rx_seq(). This is the code responsible for advancing the window,
called by both tcp_rx_syn() and tcp_rx_data(), and so the window check
is now redundant.
Reported-by: Frank Weed <zorbustheknight@gmail.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Set the current working URI to NULL rather than to "tftp://0.0.0.0/".
Reported-by: Piotr Jaroszyński <p.jaroszynski@gmail.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
For devices that start in a link-down state, the user will see a
message such as:
[Link status: The socket is not connected (http://ipxe.org/38086001)]
Waiting for link-up on net0...
This is potentially misleading, since it suggests that there is a
genuine problem. Add a dedicated error message for "link down",
giving instead:
[Link status: Down (http://ipxe.org/38086101)]
Waiting for link-up on net0...
Reported-by: Tal Aloni <tal.aloni.il@gmail.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
netdev_close() assumes that devices that are open are on the
open_list, which wasn't true if device specific opening failed.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Commit 6861304 ("[tcp] Handle out-of-order received packets")
introduced a regression in which ts_recent would not be updated until
the first packet is received in the ESTABLISHED state, i.e. the
timestamp from the SYN+ACK packet would be ignored. This causes the
connection to be dropped by strictly-conforming TCP peers, such as
FreeBSD.
Fix by delaying the timestamp window check until after processing the
received SYN flag.
Reported-by: winders@sonnet.com
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Improve the appearance of the "config" user interface by ensuring that
settings appear in some kind of logical order.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Expose a function setting_applies() to allow a caller to determine
whether or not a particular setting is applicable to a particular
settings block.
Restrict DHCP-backed settings blocks to accepting only DHCP-based
settings.
Restrict network device settings blocks to accepting only DHCP-based
settings and network device-specific settings such as "mac".
Inspired-by: Glenn Brown <glenn@myri.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The default initiator IQN is "iqn.2000-09.org.etherboot:UNKNOWN".
This is problematic for two reasons:
a) the etherboot.org domain (and hence the associated IQN namespace)
is not under the control of the iPXE project, and
b) some targets (correctly) refuse to allow concurrent connections
from different initiators using the same initiator IQN.
Solve both problems by changing the default initiator IQN to be
iqn.2010-04.org.ipxe:<hostname> if a hostname is set, or
iqn.2010-04.org.ipxe:<uuid> if no hostname is set.
Explicit initiator IQNs set via DHCP option 203 are not affected by
this change.
Unfortunately, this change is likely to break some existing
configurations, where ACL rules have been put in place referring to
the old default initiator IQN. Users may need to update ACLs, or
force the use of the old IQN using an iPXE script line such as
set initiator-iqn iqn.2000-09.org.etherboot:UNKNOWN
or a dhcpd.conf option such as
option iscsi-initiator-iqn "iqn.2000-09.org.etherboot:UNKNOWN"
Signed-off-by: Michael Brown <mcb30@ipxe.org>
After a more accurate reading of RFC 3720, it becomes clear how NOPs
are supposed to work. The current implementation (which just ignores
NOP-Ins) is sufficient to cope with NOP-Ins sent to update CmdSN, but
will need to be extended before it can cope with NOP-Ins sent as iSCSI
keepalives.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Some iSCSI targets (observed with a Synology DS207+ NAS) send
unsolicited NOP-Ins to the initiator. RFC 3720 is remarkably unclear
and possibly self-contradictory on how NOPs are supposed to work, but
it seems as though we can legitimately just ignore any unsolicited
NOP-In PDU.
Reported-by: Marc Lecuyer <marc@maxiscreen.com>
Originally-implemented-by: Thomas Miletich <thomas.miletich@gmail.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Allow functions other than realloc() to be used to reallocate DHCP
option block data, and specify the reallocation function at the time
of calling dhcpopt_init().
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The max_len field is never used, and the len field is used only by
dhcp_tx(). Remove these two fields, and perform the necessary trivial
calculation in dhcp_tx() instead.
Signed-off-by: Michael Brown <mcb30@ipxe.org>