get_card_packet() from ofnet.c allocates a netbuff based on the device's MTU:
nb = grub_netbuff_alloc (dev->mtu + 64 + 2);
In the case when the MTU is large, and the received packet is
relatively small, this leads to allocation of significantly more memory,
than it's required. An example could be transmission of TFTP packets
with 0x400 blksize via a network card with 0x10000 MTU.
This patch implements a per-card receive buffer in a way similar to efinet.c,
and makes get_card_packet() allocate a netbuff of the received data size.
Signed-off-by: Stanislav Kholmanskikh <stanislav.kholmanskikh@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
In the current code search_net_devices() uses the "alloc-mem" command
from the IEEE1275 User Interface for allocation of the transmit buffer
for the case when GRUB_IEEE1275_FLAG_VIRT_TO_REAL_BROKEN is set.
I don't have hardware where this flag is set to verify if this
workaround is still needed. However, further changes to ofnet will
require to execute this workaround one more time. Therefore, to
avoid possible duplication of code I'm moving this piece of
code into a function.
Signed-off-by: Stanislav Kholmanskikh <stanislav.kholmanskikh@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Network boot autoconfiguration sets default server to next server IP
(siaddr) from BOOTP/DHCP reply, but manual configuration using net_bootp
exports only server name. Unfortunately semantic of server name is not
clearly defined. BOOTP RFC 951 defines it only for client request, and
DHCP RFC 1541 only mentions it, without any implied usage. It looks like
this field is mostly empty in server replies.
Export next server IP as net_<interface>_next_server variable. This allows
grub configuration script to set $root/$prefix based on information obtained
by net_bootp.
Reported and tested by: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>
Cc: nikunj@linux.vnet.ibm.com
v2: change variable name to net_<interface>_next_server as discussed on the list
limit_time underflows when current time is less than 90000ms.
This causes packet fragments received during this time, i.e.,
till 90000ms pass since timer init, to be rejected.
Hence, set it to 0 if its less than 90000.
Signed-off-by: Sakar Arora <Sakar.Arora@nxp.com>
We may get more than one response before exiting out of loop in
grub_net_dns_lookup, but buffer was allocated for the first response only,
so storing answers from subsequent replies wrote past allocated size.
We never really use more than the very first address during lookup so there
is little point in collecting all of them. Just quit early if we already have
some reply.
Code needs serious redesign to actually collect multiple answers
and select the best fit according to requested type (IPv4 or IPv6).
Reported and tested by Michael Chang <mchang@suse.com>
send client arch in bootp requests, for now BIOS and x64/aarch64 EFI is
supported.
fix a bug introduced in 4d5d7be005 where
user class was encoded improperly, although this didn't seem to have any
detrimental effects.
properly insert an option terminator.
If we open new connection, we need to reset stall indication, otherwise
nothing will ever be polled (low level code rely on this field being
zero when establishing connection).
At least the apache sever is very unhappy with that extra null line and will
take more than ten seconds in responding to each range request, which slows
down a lot the entire http file transfer process or even time out.
Some DHCP servers (such as dnsmasq) tokenise parameters with commas, making
it impossible to pass boot files with commas in them. Allow using a semicolon
to separate the protocol from host if a comma wasn't found.
The current logic in the DNS resolution code allocates an address buffer
based on the number of addresses in the response packet. If we receive
multiple response packets in response to a single query packet, this means
that we will reallocate a new buffer large enough for only the addresses in
that specific packet, discarding any previous results in the process. Worse,
we still keep track of the *total* number of addresses resolved in response
to this query, not merely the number in the packet being currently processed.
Use realloc() rather than malloc() to avoid overwriting the existing data,
and allocate a buffer large enough for the total set of addresses rather
than merely the number in this specific response.
ipv6 routing in grub2 is broken, we cannot talk to anything outside our local
network or anything that doesn't route in our global namespace. This patch
fixes this by doing a couple of things
1) Read the router information off of the router advertisement. If we have a
router lifetime we need to take the source address and create a route from it.
2) Changes the routing stuff slightly to allow you to specify a gateway _and_ an
interface. Since the router advertisements come in on the link local address we
need to associate it with the global address on the card. So when we are
processing the router advertisement, either use the SLAAC interface we create
and add the route to that interface, or loop through the global addresses we
currently have on our interface and associate it with one of those addresses.
We need to have a special case here for the default route so that it gets used,
we do this by setting the masksize to 0 to mean it encompasses all networks.
The routing code will automatically select the best route so if there is a
closer match we will use that.
With this patch I can now talk to ipv6 addresses outside of my local network.
Thanks,
Signed-off-by: Josef Bacik <jbacik@fb.com>
server cannot be NULL at this point (we return error earlier if it is).
Also structure is zalloc'ed, so no need to explicitly initialize
members to 0.
Found by: Coverity scan.
CID: 73837
It's helpful to determine that a request was sent by grub in order to permit
the server to provide different information at different stages of the boot
process. Send GRUB2 as a type 77 DHCP option when sending bootp packets in
order to make this possible.
While adding tcp window scaling support I was finding that I'd get some packet
loss or reordering when transferring from large distances and grub would just
timeout. This is because we weren't ack'ing when we got our OOO packet, so the
sender didn't know it needed to retransmit anything, so eventually it would fill
the window and stop transmitting, and we'd time out. Fix this by ACK'ing when
we don't find our next sequence numbered packet. With this fix I no longer time
out. Thanks,
Signed-off-by: Josef Bacik <jbacik@fb.com>
We were resetting nb->data every time we tried a new server, but we need to do
it every time we try for a different record, otherwise we don't end up falling
back to the A record properly. Thanks,
Signed-off-by: Josef Bacik <jbacik@fb.com>
sun4v vnet devices do not implement the support of duplex and speed
instance attributes. An attempt to open such a device with
the attributes will fail:
ok select net:speed=auto,duplex=auto
Unknown key 'speed'
Unknown key 'duplex'
Manual Configuration: Host IP, boot server and filename must be specified
WARNING: /virtual-devices@100/channel-devices@200/network@0: Can't open OBP standard TFTP package
Can't open device
ok
Therefore, let's not set SUFFIX for such devices.
Signed-off-by: Stanislav Kholmanskikh <stanislav.kholmanskikh@oracle.com>
The EFI spec indicates that get_status() should return the address of the buffer
we passed into transmit to indicate the the buffer was transmitted. However we
have boxes where the firmware returns some arbitrary address instead, which
makes grub think that we've not sent anything. So since we have the SNP stuff
opened in exclusive mode just assume any non-NULL txbuf means that our transmit
occurred properly. This makes grub able to do its networking stuff properly on
our broken firmware. Thanks,
cc: Peter Jones <pjones@redhat.com>
Signed-off-by: Josef Bacik <jbacik@fb.com>
Exclusive open on SNP will close all existing protocol instances which
may disable all receive filters on interface. Reinstall them after we
opened protocol exclusively.
Also follow UEFI specification recommendation and stop interfaces when
closing them:
Unexpected system errors, reboots and hangs can occur if an OS is loaded
and the network devices are not Shutdown() and Stopped().
Also by: Mark Salter <msalter@redhat.com>
Closes: 45204
From RFC1542:
The 'giaddr' field is rather poorly named. It exists to facilitate
the transfer of BOOTREQUEST messages from a client, through BOOTP
relay agents, to servers on different networks than the client.
Similarly, it facilitates the delivery of BOOTREPLY messages from the
servers, through BOOTP relay agents, back to the client. In no case
does it represent a general IP router to be used by the client. A
BOOTP client MUST set the 'giaddr' field to zero (0.0.0.0) in all
BOOTREQUEST messages it generates.
A BOOTP client MUST NOT interpret the 'giaddr' field of a BOOTREPLY
message to be the IP address of an IP router. A BOOTP client SHOULD
completely ignore the contents of the 'giaddr' field in BOOTREPLY
messages.
Leave code ifdef'd out for the time being in case we see regression.
Suggested by: Rink Springer <rink@rink.nu>
Closes: 43396
EDK2 network stack is based on Managed Network Protocol which is layered
on top of Simple Management Protocol and does background polling. This
polling races with grub for received (and probably trasmitted) packets
which causes either serious slowdown or complete failure to load files.
Open SNP device exclusively. This destroys all child MNP instances and
stops background polling.
Exclusive open cannot be done when enumerating cards, as it would destroy
PXE information we need to autoconfigure interface; and it cannot be done
during autoconfiguration as we need to do it for non-PXE boot as well. So
move SNP open to card ->open method and add matching ->close to clean up.
Based on patch from Mark Salter <msalter@redhat.com>
Also-By: Mark Salter <msalter@redhat.com>
Closes: 41731
EDK2 PXE driver creates two child devices - IPv4 and IPv6 - with
bound SNP instance. This means we get three cards for every physical
adapter when enumerating. Not only is this confusing, this may result
in grub ignoring packets that come in via the "wrong" card.
Example of device hierarchy is
Ctrl[91] PciRoot(0x0)/Pci(0x3,0x0)
Ctrl[95] PciRoot(0x0)/Pci(0x3,0x0)/MAC(525400123456,0x1)
Ctrl[B4] PciRoot(0x0)/Pci(0x3,0x0)/MAC(525400123456,0x1)/IPv4(0.0.0.0)
Ctrl[BC] PciRoot(0x0)/Pci(0x3,0x0)/MAC(525400123456,0x1)/IPv6(0000:0000:0000:0000:0000:0000:0000:0000)
Skip PXE created virtual devices when enumerating cards. Make sure to
find real card when applying initial autoconfiguration during PXE boot,
this information is associated with one of child devices.
This reverts commits 47b2bee3ef
and 8d3c4544ff. It is not safe
to free allocated cards, dangling pointers main remain. Such
cleanup requires more changes in net core.
This restrict ARP handling to MAC and IP addresses but in practice we need
only this case anyway and other cases are very rar if exist at all. It makes
code much simpler and less error-prone.
Using the http module to download config files, produces memory errors,
after the config file is downloaded.
The error was traced to the tcp stack in grub-core/net/tcp.c. The wrong
netbuff pointer was being freed in the clean up loop.
Changing the code to free the correct netbuff pointer removes the runtime
error.
Closes 42765.
Many routers have long router advertisment interval configured by
default. The Neighbor Discovery protocol (RFC4861) has defined default
MaxRtrAdvInterval value as 600 seconds and
MinRtrAdvInterval as 0.33*MaxRtrAdvInterval. This makes
net_ipv6_autoconf fails more often than not as currently it passively
listens the RA message to perfom address autoconfiguration.
This patch tries to send router solicitation to overcome the problem of
long RA interval.
v2:
use cpu_to_be macro for network byte order conversion
add missing error handling
The structure size used in grub_netbuff_pull to get the pointer to
option header is apparently wrong, which leads to subsequent range check
failed and therefore not responding to any neighbor solicit message in my
testing.
It enables net boot even when there is no bootp/dhcp server.
* grub-core/net/drivers/ieee1275/ofnet.c: Add grub_ieee1275_parse_bootpath and
call it at grub_ieee1275_net_config_real.
* grub-core/kern/ieee1275/init.c: Add bootpath to grub_ieee1275_net_config.
* include/grub/ieee1275/ieee1275.h: Likewise.