Commit Graph

18 Commits

Author SHA1 Message Date
Thomas Huth 8f8c4e6414 ipv6: Fix memory leak in set_ipv6_address() / ip6_create_ll_address()
The  set_ipv6_address() function calls ip6_create_ll_address() to
get a link-local address. The latter function uses malloc to create
a buffer for composing that address, and returns the corresponding
poniter to the caller. However, set_ipv6_address() does not free
that buffer again, so the allocated memory is lost.
Since set_ipv6_address() already allocated space for the new IPv6
address anyway, let's fix this issue by passing the buffer from
set_ipv6_address() to ip6_create_ll_address() instead, so that
ip6_create_ll_address() does not have to allocate memory at all.

Signed-off-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Andrew Jones <drjones@redhat.com>
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
2016-05-05 16:11:04 +10:00
Thomas Huth 6a70b4a732 ipv6: Clear memory after malloc if necessary
The IPv6 code uses malloc in a couple of places to allocate the memory
for a struct. But it does not properly initializes all members of the
struct after the allocation, so the uninitialized members might contain
random data. So we should better clear the whole memory for those
structs to make sure we do not run into some hard-to-reproduce random
problems later.

Reported-by: Andrew Jones <drjones@redhat.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Andrew Jones <drjones@redhat.com>
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
2016-05-05 16:11:04 +10:00
Thomas Huth 54d4589f6c ipv6: Fix possible NULL-pointer dereference in send_ipv6()
The "struct neighbor *n" pointer in send_ipv6() can be NULL, e.g.
when we're sending to multicast addresses or to a server that sits
behind a router (since we do not have an entry in the neighbor cache
in this case).
However, the final code in send_ipv6() is always using n->eth_frame
to assemble the ethernet packet, and thus silently writes the data
into the low memory (which happens unnoticed because SLOF does not
use the MMU for memory protection).
This issue is now fixed by using a separate buffer for assembling
those ethernet packets instead. The block for using the router's
MAC address is also moved out of the block that is supposed to handle
the unicast transfers, so that we do not accidentially end up in the
neighbour solicitation code here (which also relies on n != NULL).

Reported-by: Andrew Jones <drjones@redhat.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Andrew Jones <drjones@redhat.com>
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
2016-05-05 16:11:04 +10:00
Thomas Huth 640773c130 ipv6: Indent code with tabs, not with spaces
Some parts of the IPv6 code are still indented with spaces. Let's
use tabs instead as mandated by the SLOF coding conventions.

Signed-off-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
2016-04-12 13:47:48 +10:00
Thomas Huth 02facda6a5 ipv6: send_ipv6() has to return after doing NDP
The send_ipv6() function should return after doing NDP, since either
the queued packet got send out during handle_na() already, or it has
been stored to be sent out later (once the neighbor advertisment has
been received). If we don't return here, the code runs into the final
send_ether() here later, which then sends out the packet a second time.

Signed-off-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
2016-04-12 13:47:47 +10:00
Thomas Huth c006b38270 ipv6: Do not use unitialized MAC address array
The code in send_ipv6() currently basically looks like this:

	uint8_t *mac_addr, mac[6];
	mac_addr = mac;
	...
	n = find_neighbor (&ip_dst);
	if (ip6_is_multicast (&ip_dst)) {
		mac_addr = ip6_to_multicast_mac (&ip_dst, mac);
	}
	else {
		// Check if the MAC address is already cached
		if (n) {
			if (memcmp(n->mac, null_mac, ETH_ALEN) != 0)
				memcpy (mac_addr, &(n->mac), ETH_ALEN);
			/* XXX */
		}
		...
	}
	...
	fill_ethhdr (n->eth_frame, htons(ETHERTYPE_IPv6), get_mac_address(),
		     mac_addr);

That means mac_addr initially points to the uninitialized mac[6]
array on the stack. Now if there was already an entry in the neighbor
cache, but the MAC address has not been determined yet, that
uninitialized array could be used as final MAC address for fill_ethhdr()
(since there is no "else" path at the spot marked with XXX above),
resulting in random data in the MAC address field of the ethernet packet.

Let's fix this issue by letting mac_addr point to the null_mac by
default instead, so that it never points to invalid data. Also
rename mac[6] to mc_mac[6] to make it clear that this array is
only used for storing the multicast mac address.

Signed-off-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
2016-04-12 13:47:47 +10:00
Thomas Huth 39acf5a553 ipv6: Add support for sending packets through a router
The network boot over IPv6 currently fails if the TFTP server
is not in the same subnet as the SLOF client. In that case we
have to fill in the MAC address of a router into our packets
to get them to the right place.

Signed-off-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
2016-04-12 13:47:47 +10:00
Alexey Kardashevskiy f344ef9b22 net-snk: Fix gcc warnings
This replaces some local variable types and some function parameters from
signed to unsigned to fix gcc warnings.

Tested DHCP+TFTP on both IPv4 and IPv6.

The make command used to test:
make qemu WARNFLAGS=-Wextra

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Reviewed-by: Thomas Huth <thuth@redhat.com>
2016-01-29 17:10:35 +11:00
Alexey Kardashevskiy 253298295e net-snk: Fix coding style
This restyles function prototypes:
- return types on the same line;
- opening brace is on the next line.

VIM configs used for this was:
set noexpandtab
set tabstop=8
set shiftwidth=4
set cino=:0,(0

This replaces [><]* with "*" as >< are also used to resolve merge
conflicts.

This removes trailing spaces.

This removes some redundant braces.

This should cause no behavioural change.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Reviewed-by: Thomas Huth <thuth@redhat.com>
2016-01-29 17:09:58 +11:00
Thomas Huth c0fbf94bc5 net-snk: Fix memory leak in ip6_to_multicast_mac() / send_ipv6()
ip6_to_multicast_mac() uses a malloc to allocate a 6 bytes buffer
for the MAC address - which never gets freed again! That means
we're leaking memory for every multicast IPv6 packet that gets
send out. Fix it by simply using the "uint8_t mac[6]" array from
send_ipv6() instead.

Signed-off-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
2016-01-18 11:58:12 +11:00
Thomas Huth c74ddc9954 net-snk: Remove bad NEIGHBOUR_SOLICITATION code in send_ipv6()
The code that checks for NEIGHBOUR_SOLICITATION packets is bad
in two ways: First, it does not check that the packet is really
an ICMPv6 packet, so it could accidentially be triggered for UDP
or TCP packets, too. Second, the fill_ethhdr() is redundant (since
it is done at the end of the function again) and also wrong (it
uses the wrong buffer pointer to fill in the ethernet header).

All we really need here is to get the right MAC address via
ip6_to_multicast_mac() - and this is handled in the following
if-statement already (NEIGHBOUR_SOLICITATIONs are always sent
as multicast in the send_neighbour_solicitation() function), so
the bad code block can simply be removed to fix the two issues.

Signed-off-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
2016-01-18 11:58:03 +11:00
Thomas Huth 82660c5da4 net-snk: Simplify the ip6_is_multicast() function
Using a memcpy to just compare one byte looks very cumbersome.

Signed-off-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
2016-01-14 11:26:14 +11:00
Thomas Huth 9308463cfd net-snk: Move global variable definition out of the header file
The IPv6 code declares a bunch of global variables (without "extern"
keyword!) in the ipv6.h header file. This is bad style and does not
work when linking with "-fno-common" for example. So let's move
the variables to the files where they are used instead.

Signed-off-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
2016-01-14 11:26:07 +11:00
Thomas Huth a9aa48d28a net-snk: Prefer non-link-local unicast IPv6 addresses if possible
When the IPv6 code is told to create IPv6 addresses automatically
(by passing NULL as parameter to set_ipv6_address()), the netboot
code currently only uses link-local IPv6 addresses - which is bad
since they can not be routed, e.g. if the TFTP server is not on
the same link.
So set_ipv6_address(NULL) should set own_ip6 preferably to a non-local
unicast address if it has been generated successfully during ipv6_init().

Signed-off-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
2016-01-14 11:25:59 +11:00
Nikunj A Dadhania 8e6f2bba50 net-snk: use socket descriptor in the network stack
With module layer cleanup, and a fixed socket() call, start using the
fd across the network stack.

Signed-off-by: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
2014-10-29 16:17:10 +05:30
Avik Sil eab9584a40 Fix zero checksum in UDP header
As per RFC 768 (UDP), if the computed checksum  is zero, it is transmitted as all ones
(the equivalent in one's complement arithmetic).

Signed-off-by: Avik Sil <aviksil@linux.vnet.ibm.com>
Signed-off-by: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>
2014-01-20 17:19:47 +05:30
Avik Sil 0852f3807f Handle router advertisement message properly
process_ra_options was going through infinite loop due to improper handling of option_length.
Also introduction of is_ra_received() makes booting time faster since it returns as soon as
router advertisement mesage is received.

Signed-off-by: Avik Sil <aviksil@linux.vnet.ibm.com>
Signed-off-by: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>
2014-01-20 17:19:47 +05:30
Avik Sil aee78336b9 Add ipv6 support in net-snk
This patch adds support for booting from a IPv6 network. It gets the boot information
(tftp server, boot file name) from DHCPv6 server or can be specified manually using
obp-tftp arguments. To boot from a IPv6 network, type "boot net:ipv6" from the SLOF
prompt. To specify ipaddresses manually, type "boot net:ipv6,<si6addr>,<filename>,<ci6addr>"
from the SLOF prompt.

This patch is based on the IPv6 code written by the former SLOF team.

Signed-off-by: Avik Sil <aviksil@linux.vnet.ibm.com>
2013-11-17 16:22:03 +05:30