ipv6_prefix_find() wrongly tests if the unicast address is in use
instead of the prefix. This has two implications:
- The function can return an expired prefix to net_if_ipv6_prefix_add(),
which will do nothing more to enable it (since it assumes that it is
already enabled). As a result, the prefix will not be used by the
rest of the stack due to prefix->is_used being false.
- ipv6_prefix_find() loops using a bound of NET_IF_MAX_IPV6_PREFIX, but
the size of the unicast[] array is defined by NET_IF_MAX_IPV6_ADDR.
This could lead to an out-of-bound access if NET_IF_MAX_IPV6_ADDR is
smaller than NET_IF_MAX_IPV6_PREFIX.
Signed-off-by: Florian Vaussard <florian.vaussard@gmail.com>
With the introduction of `EXPERIMENTAL` and `WARN_EXPERIMENTAL` in
Zephyr all subsys/net and drivers/ethernet/Kconfig.e1000 settings
having `[EXPERIMENTAL]` in their prompt has has been updated to include
`select EXPERIMENTAL` so that developers can enable warnings when
experimental features are enabled.
The following settings has EXPERIMENTAL removed as they are considered
mature:
- NET_OFFLOAD
- NET_PROMISCUOUS_MODE
Signed-off-by: Torsten Rasmussen <Torsten.Rasmussen@nordicsemi.no>
Add __printf_like modifier to validate strings used by shell.
Fixing warnings triggered by this change.
Signed-off-by: Krzysztof Chruscinski <krzysztof.chruscinski@nordicsemi.no>
If data for `context_sendto()` was provided in a form of
`struct msghdr` (for instance via `sendmsg()`), it was not verified that
the provided data would actually fit into allocated net_pkt. In result,
and error could be returned in case the provided data was larger than
net_pkt allows.
Fix this, by verifying the remaining buffer length when iterating over
`struct msghdr`. Once the buffer is filled up, break the loop. In
result, functions like `sendmsg()` will return the actual length of data
sent instead of an error.
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
As per #38352, we would like to start building out PTP (IEEE 1588)
support for superset of gPTP functionality in Zephyr. This is the first
step to abstract away some key interfaces from NET_GPTP umbrella to
NET_L2_PTP.
Signed-off-by: Alex Sergeev <asergeev@carbonrobotics.com>
RFC 2460 Sec. 5 requires that a ICMPv6 Time Exceeded message is sent
upon reassembly timeout, if we received the first fragment (i.e. the one
with a Fragment Offset of zero).
Implement this requirement.
Signed-off-by: Florian Vaussard <florian.vaussard@gmail.com>
The purpose of shift_packets() is to make room to insert one fragment in
the list. This is not what it does currently, potentially leading to
-ENOMEM even if there is enough free room.
To see the current behaviour, let's assume that we receive 3 fragments
in reverse order:
- Frag3(offset = 0x40, M=0)
- Frag2(offset = 0x20, M=1)
- Frag1(offset = 0x00, M=1)
After receiving Frag3 and Frag2, pkt[] will look like:
.-------.-------.-------.
| Frag2 | Frag3 | NULL |
| 0x20 | 0x40 | |
'-------'-------'-------'
pkt[0] pkt[1] pkt[2]
When receiving Frag1, shift_packets(pos = 0) is called to make some room
at position 0. It will iterate up to i = 2 where there is a free
element. The current algorithm will try to shift pkt[0] to pkt[2], which
is indeed impossible but also unnecessary. It is only required to shift
pkt[0] and pkt[1] by one element in order to free pkt[0] to insert
Frag1.
Update the algorithm in order to shift the memory only by one element.
As a result, the ENOMEM test is only simpler: as long as we encounter
one free element, we are guaranteed that we can shift by one element.
Also assign a NULL value to the newly freed element since memmove() only
copy bytes.
Signed-off-by: Florian Vaussard <florian.vaussard@gmail.com>
Currently net_ipv6_handle_fragment_hdr() performs 2 distinct tests: it
checks the M-bit of the most recent fragment to decide if we can proceed
with the reassembly. Then it performs some sanity checks which can lead
to dropping the whole packet if not successful.
The test on the M-bit assumes that fragments arrive in order. But this
will fail if packets arrive out-of-order, since the last fragment can
arrive before some other fragments. In that case, we proceed with the
reassembly but it will fail because not all the fragments have been
received.
We need a more complete check before proceeding with the reassembly:
- We received the first fragment (offset = 0)
- All intermediate fragments are contiguous
- The More bit of the last fragment is 0
Since these conditions can also detect a malformed fragmented packet, we
can replace the existing sanity check that is performed before
reassembly. As a bonus, we can now detect and rejected overlapping
fragments, since this can have some security issues (see RFC 5722).
Signed-off-by: Florian Vaussard <florian.vaussard@gmail.com>
Currently we only store the fragment offset. But in some cases it might
be necessary to also inspect the M-bit (More Fragment) of all received
fragments.
Modify the semantics of the field to store all the flags, rename the
setter to account for this change, and add a getter for the M-bit.
Signed-off-by: Florian Vaussard <florian.vaussard@gmail.com>
The special handling of the 1st fragment in unnecessary, since it will
be correctly handled even without it. Moreover it causes some corner
cases, like a single packet with a fragment header (M=0), to be
incorrectly handled since the reassembly code is skipped.
Remove the special handling of the 1st fragment to fix these problems.
Signed-off-by: Florian Vaussard <florian.vaussard@gmail.com>
Currently the requirement of the length being a multiple of 8 is not
tested for the first fragment, since the first fragment takes a
different path due to the goto.
Move the test earlier in the process, so that it is performed on all
fragments, including the first one.
Signed-off-by: Florian Vaussard <florian.vaussard@gmail.com>
If we have less fragments than what can be stored in the reassembly
array, some loops will blindly dereference NULL pointers.
Add checks for NULL pointers when necessary and exit the loop.
Signed-off-by: Florian Vaussard <florian.vaussard@gmail.com>
Currently the stack is limited to a maximum of 2 incoming fragments per
packet. While this can be enough in most cases, it might not be enough
in other cases.
Make this value configurable at build time.
Signed-off-by: Florian Vaussard <florian.vaussard@gmail.com>
Currently prev_hdr_offset always equals 6, which is the offset of
the nexthdr field in the IPv6 header. This value is used to overwrite it
when removing an IPv6 Fragment header, so it will work as long as there
is no other Extension header between the IPv6 header and the Fragment
header.
However this does not work in the other cases: the nexthdr field of the
IPv6 header will be overwritten instead of the nexthdr field of the last
Extension header before the Fragment, leading to unwanted results.
Update prev_hdr_offset so that it always point to the nexthdr field of
the previous header, either the IPv6 header or an Extension header.
Signed-off-by: Florian Vaussard <florian.vaussard@gmail.com>
The current validation code waits to process the header before rejecting
it, while some checks can be already enforced when reading the nexthdr
field of the previous header.
The main problem is a wrong pointer field in the resulting ICMPv6 error
message: the pointer should have the offset of the invalid nexthdr
field, while currently it will the offset the invalid header.
To solve that problem, reorganize the loop in two parts: the first
switch validates nexthdr, while the second switch processes the current
header. This allows to reject invalid nexthdr earlier.
The check for duplicated headers is also generalized, so that we can
catch other kind of headers (like the Fragment header).
Signed-off-by: Florian Vaussard <florian.vaussard@gmail.com>
By definition, NET_IPV6_NEXTHDR_NONE is void. So we must stop processing
before trying to read any data, since we will start reading values that
are outside the Extension Header (likely the payload, if any).
Signed-off-by: Florian Vaussard <florian.vaussard@gmail.com>
When an unknown option is encountered, an ICMPv6 error message must be
sent in some cases. The message contains a pointer field, which must be
the offset to the unknown option. Currently the offset is computed from
the beginning of the option list, while it should be computed with
respect to the beginning of the IPv6 header.
Record the offset when reading the option type and pass it later to
ipv6_drop_on_unknown_option() to correctly set the pointer field. Also
rename the argument in ipv6_drop_on_unknown_option() to make the
purpose more clear.
Signed-off-by: Florian Vaussard <florian.vaussard@gmail.com>
Currently PADN data are not skipped, which results in the stack to think
that the next header starts in the middle of the padding. We have to
skip the bytes before going on.
Also clarify the PAD1 does not have any length field.
Signed-off-by: Florian Vaussard <florian.vaussard@gmail.com>
The current names are confusing. Indeed "nexthdr" if the type of the
header currently processed, while "next_nexthdr" is the nexthdr field of
the current header.
Rename them to improve readability and make it less error-prone.
Signed-off-by: Florian Vaussard <florian.vaussard@gmail.com>
ICMPv6 error messages are not sent (on native_posix) because the first
net_pkt_write() returns an error.
pkt has just been allocated using net_pkt_alloc_with_buffer(). Trying to
write an empty packet in overwrite mode will result in an error. There
is no need to be in overwrite mode, since we want to write the LL
src/dst addresses at the beginning.
Signed-off-by: Florian Vaussard <florian.vaussard@gmail.com>
net_packet_socket_input() was changed to hardcode the return of
NET_CONTINUE and that caused a segmentation fault/crash in
net_core/process_data(), in cases when pkt was unreferred and
NET_OK was returned from net_conn_input()
This happened with socket combo of: AF_PACKET+SOCK_RAW+IPPROTO_RAW.
Signed-off-by: Jani Hirsimäki <jani.hirsimaki@nordicsemi.no>
The nbr_lock var actually depends on CONFIG_NET_IPV6_NBR_CACHE
(not CONFIG_NET_IPV6_ND), so move its initialization call.
Signed-off-by: Stancu Florin <niflostancu@gmail.com>
Listing a neighbour table with "net nbr" command, when a neighbour w/o
assigned link address was present, resulted in an assert condition. Add
additional check to prevent this.
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
TCP state machine gets stuck in TCP_FIN_WAIT_2 state
when server responds with [ FIN, PSH, ACK ]
Fixes#37842
Signed-off-by: Nicolas Marty <nicolas.marty@zuehlke.com>
This migrates all the current iterable section usages to the external
API, dropping the "Z_" prefix:
Z_ITERABLE_SECTION_ROM
Z_ITERABLE_SECTION_ROM_GC_ALLOWED
Z_ITERABLE_SECTION_RAM
Z_ITERABLE_SECTION_RAM_GC_ALLOWED
Z_STRUCT_SECTION_ITERABLE
Z_STRUCT_SECTION_ITERABLE_ALTERNATE
Z_STRUCT_SECTION_FOREACH
Signed-off-by: Fabio Baltieri <fabiobaltieri@google.com>
By default ICMP desination unreachable error packets are generated when
input packets target ports that are not in a listening state. This not
only reveals the presence of the host on the network which may be
considered a security vulnerability depending on the application, it
also ends up triggering ARP lookups to respond to the sending host. With
a small ARP table and a network where there may be broadcast (or
multicast) service discovery traffic such as mDNS or uPnP, ARP table
thrashing can occur impacting network stack performance.
Signed-off-by: Berend Ozceri <berend@recogni.com>
Socket CAN does not require interface link address to be
assigned, check is not applicable for socket CAN
interfaces. As this address is NULL for socket CAN interface
it results in assertion.
Signed-off-by: Ramesh Babu B <ramesh.babu.b@intel.com>
The verb tense for the suspended state was not consistent with other
states. The likely reason: state was being used as a command/action.
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
This adds the ability to create Ethernet bridges for connecting
separate Ethernet segments together to appear as a single
Ethernet network.
This mimics the Linux functionality of the same name.
Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
Introduce a helper function for being able to remove any arbitrary
length from tail of packet. This is handy in cases when removing
unneeded data, like CRC once it was verified.
Signed-off-by: Marcin Niestroj <m.niestroj@emb.dev>
The callback is not used anymore, so just delete it from the pm_control
callback signature.
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
When tcp_send_data() is called to resend data, but there is no data
to resend, zero length packet is allocated and NULL net_buf is passed
to net_buf_frag_insert() in which assertion fails.
Fixes#36578
Signed-off-by: Chih Hung Yu <chyu313@gmail.com>
There is a small window between when socket is created and
before it is bound to a local address, where the local address
pointer might be NULL.
Fixes#36276
Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
TCP unacked_len can be set to zero in tcp_resend_data(),
and then be minus by len_acked when ACK is received,
resulting in a negative unacked_len value.
Fixes#36390
Signed-off-by: Chih Hung Yu <chyu313@gmail.com>
In case both, static IP address configuration and DHCP were used, and no
DHCP server was avaliable in the network, clearing the gateway address
rendered the network interface unusable as it's gateway configuration
was cleared.
Prevent this by removing the gateway clearing during the DHCP
inititalization. If the DHCP server is available in the network, the
gateway address will be overwriten after receiving the DHCP OFFER
message or cleared if there's no Router option is avaiable in the
DHCP OFFER message.
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
This commit allows to add callbacks to NET_EVENT_IF_UP events before
the network initialization.
Signed-off-by: Pieter De Gendt <pieter.degendt@basalte.be>
If we receive any data in FIN_WAIT_1, then ack it even if we
are discarding it.
Fixes#33986
Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
Signed-off-by: Jim Paris <jim@jim.sh>
If there are no sockets in the system, then do not drop the
packet immediately as there can be other L2 network handlers
like gPTP in the system. This will also allow ICMP messages
to pass to local handler.
Fixes#34865
Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
When application calls TCP connect(), the call is blocked
by a semaphore which is then released when the connection
is established. Unfortunately the semaphore release was done
before the connection was marked as established. Depending
on the configuration options set, it is possible that after
the semaphore release, the thread that is waiting on connect()
is run immediately. Because of this, the connection bookeeping
still thought that the connection was not established even if
it was. A simple solution is to release the semaphore after
the connection is marked as established.
Fixes#35390
Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>