Rework the IPv4-related code to avoid casting. Use raw variants of
IPv4-related functions whenever possible (especially on the critical
data path).
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
Rework the rest of the IPv6-related code to avoid casting. Use raw
variants of IPv6-related functions whenever possible (especially on the
critical data path). For the routing case, use a copy of the address to
avoid massive rework of the routing module.
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
In order to be able to receive packets on unbound packet sockets (which
should collect packet from all interfaces in such case), it's needed to
register receive callback at the socket layer as soon as the socket is
created.
In additional to that, the default binding for packet sockets need to be
revisited. Packet socket should not be bound to the default interface,
as this way the socket would only be receiving packets from that
particular interface. Instead, leave the interface unspecified in such
case.
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
Allow to update the local address on a registered connection when
rebinding.
This is needed for packet sockets, as by default packet socket
will be bound to "any" interface (interface index 0), and interface
index is part of the local address registered for packet socket.
In order to be able to explicitly bind to a specific interface later, it
needs to be possible to update the local address registered for the
connection, as we need to update the interface index, which is used
by net_conn_packet_input() for packet filtering.
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
Part of the socket matching criteria for AF_PACKET family took place
inside conn_raw_socket() function, and some of it was redundant with
what already was checked in net_conn_packet_input(). Moreover, if the
packet cloning for packet socket failed for whatever reason, the packet
was reported as NET_DROP, which was confusing.
Finally, conn_raw_socket() updated network stats, which didn't really
work as net stats are only collected for UDP/TCP protocols and not for
L2 level protocols.
Therefore, cleanup the processing by:
* Moving all socket matching criteria into net_conn_packet_input()
for clarity,
* Drop unneeded net stats functions,
* Clarify NET_DROP strategy for packet socket input.
net_conn_packet_input() should only be responsible for delivering
packets to respective packet sockets, it should not decide whether
to drop the packet or not - it's L2/L3 processing code
responsibility. Therefore, assume this function forwards packet for
further processing by default, and only allow small optimization to
return NET_OK if the packet socket was really the only endpoint in
the system.
* And finally, since now conn_raw_socket() responsibility was to clone
the packet for the respective socket, and was almost identical to a
corresponding function for raw IP sockets, unify the two functions.
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
The current implementation of net_conn_input() can accept different
packet types, with completely different processing code, resulting in a
function which is pretty bloated, sliced with conditionally enabled code
and hard to understand and therefore maintain.
This commit splits that function into smaller ones, specialized for
different packet types (and entry levels). The following functions have
been extracted from the original one:
- net_conn_packet_input() for early packet processing (covering
AF_PACKET family sockets)
- net_conn_raw_ip_input() for raw IP packets processing (covering
AF_INET(6)/SOCK_RAW sockets)
- net_conn_can_input() for CAN packets processing (covering AF_CAN
family sockets)
The net_conn_input() function stripped from above cases now only takes
care of packets that have been processed by respective L4 and are
intended for regular TCP/UDP sockets.
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
According to AF_PACKET man pages protocol number 0 is allowed, however
in such case the socket is only capable of transmitting packets then:
"If protocol is set to zero, no packets are received."
Therefore, allow to create sockets with such protocol, and at the
connection.c level filter out such sockets from data reception.
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
As the network packet filter drops packets without any indication
that the packet is dropped, it can be difficult to monitor what
is going on in the system when receiving data. The user can
now monitor the statistics and see if packets are being dropped
because of packet filter activity.
Signed-off-by: Jukka Rissanen <jukka.rissanen@nordicsemi.no>
IPPROTO_RAW is not a valid protocol type for AF_PACKET sockets, which
should only use IEEE 802.3 protocol numbers. Therefore remove support
for this type of sockets.
As an alternative, users can use AF_PACKET/SOCK_DGRAM or
AF_INET(6)/SOCK_RAW, depending on the actual use case.
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
Introduce changes in the networking stack which allow to create raw IP
sockets, so that applications can send and receive raw IP datagrams.
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
Register connection type along with family and protocol, so that it's
possible to differentiate between connection listening for raw IP
datagrams and TCP/UDP/other packets.
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
Add CONFIG_NET_CONN_PACKET_CLONE_TIMEOUT to allow for longer
timeouts. This can be used to prevent dropping packets when
transmitting large amounts of data (with PPP).
Signed-off-by: Markus Lassila <markus.lassila@nordicsemi.no>
Utilize a code spell-checking tool to scan for and correct spelling errors
in all files within the `subsys/net/ip` directory.
Signed-off-by: Pisit Sawangvonganan <pisit@ndrsolution.com>
Supplicant create AF_PACKET proto ETH_P_PAE socket but receive other
frames like ICMP, UDP and causes following issues.
1. When frame len exceeds MTU, net_pkt_clone cannot clone pkt.
Thus dropped it and print warning log.
2. It will lower throughput performance as every packet is cloned.
Fix it by conn_raw_socket does not deliver pkts protocol not macted,
after l2 processed, unless conn is all packets.
Signed-off-by: Fengming Ye <frank.ye@nxp.com>
Running out of connection contexts is most likely due to app
misconfiguration, therefore it's useful to get an explicit information
that context allocation failed.
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
This commit adds the new internal function for update the callback,
user data, remote address, and port for a registered connection
handle.
Signed-off-by: Takuya Sasaki <takuya.sasaki@spacecubics.com>
This commit adds the new static function for change the remote
address and port to connection, and replaces the changing process
for remote address and port in net_conn_register().
Signed-off-by: Takuya Sasaki <takuya.sasaki@spacecubics.com>
The net_conn_change_callback() is not currently being called by
anyone, so this commit moves to static function, and replaces
the change callback parameter process in net_conn_register().
Signed-off-by: Takuya Sasaki <takuya.sasaki@spacecubics.com>
Iterating over connection list w/o mutex lock could lead to a crash on
constant incoming packet flow. Fix this by:
1. Adding mutex lock when iterating over an active connection list, to
prevent list corruption.
2. Create a copy of the callback and user data pointers before releasing
lock, to prevent NULL pointer dereference in case connection is
released before callback is executed.
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
We should use the NET_CONN_RANK() macro when printing the
current rank value as that macro masks the rank values properly.
Signed-off-by: Jukka Rissanen <jukka.rissanen@nordicsemi.no>
This allows IPv4 and IPv6 share the same port space.
User can still control the behavior of the v4-mapping-to-v6
by using the IPV6_V6ONLY socket option at runtime.
Currently the IPv4 mapping to IPv6 is turned off by
default, and also the IPV6_V6ONLY is true by default which
means that IPv4 and IPv6 do not share the port space.
Only way to use v4-mapping-to-v6 is to enable the Kconfig
option and turn off the v6only socket option.
Signed-off-by: Jukka Rissanen <jukka.rissanen@nordicsemi.no>
Add Kconfig option to control TCP RST behavior on connection attempts on
unbound ports. If enabled, TCP stack will reply with RST packet (enabled
by default).
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
Send RST as a reply for unexpected TCP packets in the following
scenarios:
1) Unexpected ACK value received during handshake (connection still open
on the peer side),
2) Unexpected data packet on a listening port (accepted connection
closed),
3) SYN received on a closed port.
This allows the other end to detect that the connection is no longer
valid (for example due to reboot) and release the resources.
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
This commits adds support for the SO_REUSEPORT socket option.
The implementation follows the behavior of BSD and tries to also follow
the specific additional features of linux with the following
limitations:
* SO_REUSEADDR and SO_REUSEPORT are not "the same" for client sockets,
as we do not have a trivial way so identify a socket as "client"
during binding. To get the Linux behavior, one has to use SO_REUSEPORT
with Zephyr
* No prevention of "port hijacking"
* No support for the load balancing stuff for incoming
packets/connections
There is also a new Kconfig option to control this feature, which is
enabled by default if TCP or UDP is enabled.
Signed-off-by: Tobias Frauenschläger <t.frauenschlaeger@me.com>
The additional hooks provide infrastructure to construct
rules on another network stack levels. Main benefit of this
approach is packets are pre-parsed and e.g. IP filter is
easier to implement. These hooks are equivalent of prerouting
and local_in in linux's netfilter.
Signed-off-by: Marcin Gasiorek <marcin.gasiorek@nordicsemi.no>
When testing on qemu_x86_64 with e1000 Ethernet driver, there are
several crashes due to list management simultaneously executing on
different cores. Add mutexes similar to other parts on networking
stack, for example tcp_lock.
Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
The net_core:process_data() and connection:net_conn_input() methods are
the central network packet reception pipeline which:
1) guide network packets through all network layers,
2) decode, validate and filter packages along the way and
3) distribute packages to connections/sockets on all layers.
This code seems to have grown complex and rather cluttered over time as
all protocols, layers and socket implementations meet there in one single
place.
The code also reveals its origin as a pure IP stack which makes it hard
to introduce non-IP protocols and their supporting socket infrastructure
in a modularized way.
For an outside contributor it seems almost impossible to add another
protocol, protocol layer, filter rule or socket implementation without
breaking things.
This change doesn't try to solve all issues at once. It focuses
exclusively on aspects that maintain backwards compatibility:
* Improve modularization and encapsulation on implementation level by
disentangling code that mixes up layers, protocols and socket
implementations.
* Make IP just one protocol among others by removing assymmetry in
protocol handling logic and introduce preprocessor markup so that
IP-specific code can be eliminated by the preprocessor if not needed.
* Use preprocessor markup to delineate hook points for future
modularization or expansion without introducing structural changes (as
this would almost certainly break the API).
* Reduce cyclomatic complexity, use positive rather than negative logic,
improve variable naming, replace if/elseif/else blocks with switches,
reduce variable span, introduce inline comments where code does not
speak for itself, etc. as much as possible to make the code overall
more human-friendly.
Background: These are preparative steps for the introduction of IEEE
802.15.RAW sockets, DGRAM sockets and sockets bound to PAN IDs and device
addresses similar to what the Linux kernel does.
Signed-off-by: Florian Grandel <jerico.dev@gmail.com>
Rename the SocketCAN header from socket_can.h to socketcan.h to better
match the naming of the functionality.
Signed-off-by: Henrik Brix Andersen <hebad@vestas.com>
Logging v1 has been removed and log_strdup wrapper function is no
longer needed. Removing the function and its use in the tree.
Signed-off-by: Krzysztof Chruscinski <krzysztof.chruscinski@nordicsemi.no>
Datagram AF_PACKET sockets were not processed properly by the net stack.
Instead of receving a packet already processed L2, and thus with L2
header trimmed, it was receiving a raw, unprocessed packet.
Fix this by calling net_packet_socket_input() for the second time, after
L2 has processed the packet. An updated connection handler module will
forward the packet correctly based on the corresponding socket type and
packet L2 processing status.
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
In order to bring consistency in-tree, migrate all subsystems code to
the new prefix <zephyr/...>. Note that the conversion has been scripted,
refer to zephyrproject-rtos#45388 for more details.
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
Replace unpacked in6_addr structures with raw buffers in net_ipv6_hdr
struct, to prevent compiler warnings about unaligned access.
Remove __packed parameter from `struct net_6lo_context` since the
structure isn't really serialized.
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
Replace unpacked in_addr structures with raw buffers in net_ipv4_hdr
struct, to prevent compiler warnings about unaligned access.
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
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>
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>
Implement SO_BINDTODEVICE socket option which allows to bind an open
socket to a particular network interface. Once bound, the socket will
only send and receive packets through that interface.
For the TX path, simply avoid overwriting the interface pointer by
net_context_bind() in case it's already bound to an interface with an
option. For the RX path, drop the packet in case the connection handler
detects that the net_context associated with that connection is bound to
a different interface that the packet origin interface.
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
With these changes, dial up Zephyr application/driver can use
socket(AF_PACKET, SOCK_RAW, IPPROTO_RAW) for creating
a socket for sending/receiving data to/from ppp net link, i.e.
packet is going to/from PPP L2.
Signed-off-by: Jani Hirsimäki <jani.hirsimaki@nordicsemi.no>
This patch brings support for AF_PACKET and SOCK_RAW type of sockets.
In net_conn_input() function the new flag has been introduced -
'raw_pkt_continue' to indicate if there are other than AF_PACKET
connections registered.
If we do not have other connections than AF_PACKET, the packet is
solely handled in net_conn_input() (or to be more specific in its
helper function - conn_raw_socket()).
Otherwise, it is passed back to net_conn_input in IPv4/6 processing.
Signed-off-by: Lukasz Majewski <lukma@denx.de>
The new function - namely conn_raw_socket(); has been introduced to
handle raw sockets processing. Its code, up till now, only was
executed when IS_ENABLED(CONFIG_NET_SOCKETS_PACKET) was defined.
After this change it can be reused when one would like to handle
raw sockets also when CONFIG_NET_{UDP|TCP} are enabled.
Signed-off-by: Lukasz Majewski <lukma@denx.de>
If there is no handler for IPv4 broadcast packet, then ignore it
instead of trying to send an ARP message to resolve the senders
address.
Fixes#21016
Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
Allow user to create SOCK_DGRAM type AF_PACKET socket. This
allows user to send raw IP packets without specifying
L2 (like Ethernet) headers.
Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
If we have multiple network interfaces and we are waiting incoming
network packets, make sure to honor the bind of the socket so that
correct socket will receive data in certain network interface.
Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
If the system has more than one network interface, then it should
be possible to bind a AF_PACKET socket to each interface if the
network interface index is set when bind() is called. This was
not possible earlier as the code was always using default network
interface with AF_PACKET socket bind().
Fixes#23153
Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
If we receive a multicast IPv4 or IPv6 packet, then we need to
deliver it to all sockets that have installed a handler for it.
Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>