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
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
In net/net.c there is a while (1) that only exits if there is a stop
condition and more then 10 packages or if there is no package received.
If GRUB is idle and enter in this loop, the only condition to leave is
if it doesn't have incoming packages. In a network with heavy traffic
this never happens.
strncpy.
* grub-core/fs/jfs.c (grub_jfs_lookup_symlink): Likewise.
* grub-core/kern/misc.c (grub_strncpy): Move from here ...
* include/grub/misc.h (grub_strncpy): ... to here. Make inline.
* grub-core/net/net.c (grub_net_addr_to_str): Use COMPILE_TIME_ASSERT
+ strcpy rather than strncpy.
* grub-core/net/net.c (receive_packets): Decrease the stop to 10
packets but stop only if stop condition is satisfied.
(grub_net_fs_read_real): Call packets_pulled after real read. Use
`stall' instead of `eof' as stop condition.
* grub-core/net/http.c (parse_line): Set `stall' on EOF.
(http_err): Likewise.
* grub-core/net/tftp.c (ack): Replace the first argument with data
instead of socket.
(tftp_receive): Stall if too many packets are in wait queue.
(tftp_packets_pulled): New function.
(grub_tftp_protocol): Set packets_pulled.
* include/grub/net.h (grub_net_packets): New field count.
(grub_net_put_packet): Increment count.
(grub_net_remove_packet): Likewise.
(grub_net_app_protocol): New field `packets_pulled'.
(grub_net): New field `stall'.
* grub-core/net/bootp.c (parse_dhcp_vendor): Parse mask.
(grub_net_configure_by_dhcp_ack): Use mask and grub_net_add_ipv4_local.
* grub-core/net/net.c (grub_net_add_addr): Split creating local route
into ...
(grub_net_add_ipv4_local): ... this.
(grub_cmd_addaddr): Use grub_net_add_ipv4_local.
* include/grub/net.h (GRUB_NET_BOOTP_NETMASK): New enum value.
(grub_net_add_ipv4_local): New proto.
* include/grub/net.h (grub_net_poll_cards): New argument stop_condition.
All users updated.
* grub-core/net/arp.c (have_pending): New var.
(pending_req): Likewise.
(grub_net_arp_send_request): Fill pending_req and use have_pending as
stop indicator.
(grub_net_arp_receive): Set have_pending.
* grub-core/net/dns.c (recv_data): New field stop.
(recv_hook): Set stop.
(grub_net_dns_lookup): Init stop and use as stop condition.
* grub-core/net/http.c (http_establish): Use headers_recv as stop
condition.
* grub-core/net/net.c (grub_net_poll_cards): New argument
stop_condition. Stop when it goes true.
* grub-core/net/tcp.c (grub_net_tcp_open): Use `established' as stop
indicator.
* grub-core/net/tftp.c (tftp_open): Use `have_oack' as stop indicator.
compact and more efficient code.
* grub-core/kern/list.c (grub_list_push): Moved from here ...
* include/grub/list.h (grub_list_push): ... to here. Set prev.
(grub_list_remove): Moved from here ...
* include/grub/list.h (grub_list_remove): ... here. Use and set prev.
(grub_prio_list_insert): Set prev.
* include/grub/list.h (grub_list): Add prev. All users updated.