-
Notifications
You must be signed in to change notification settings - Fork 7.3k
net: core: Rework l3 handling #89248
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
0e4900b
to
77e4245
Compare
f5ddfc9
to
0f13367
Compare
0f13367
to
81dd7ff
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR reworks L3 packet handling, moving IPv4/IPv6 (and IEEE802.15.4) processing from the Ethernet L2 driver into the centralized net_core module to support virtual interfaces and new handler registration. Key changes include:
- Adding loopback flags and associated helper functions in net_pkt.
- Introducing dedicated L3 handlers for IPv4, IPv6, and IEEE802.15.4.
- Adjusting tests to explicitly set link layer protocol types for fragmented packet handling.
Reviewed Changes
Copilot reviewed 9 out of 11 changed files in this pull request and generated no comments.
Show a summary per file
File | Description |
---|---|
tests/net/lib/mdns_responder/src/main.c | Updates IPv6 packet allocation parameters and explicitly sets link layer protocol type. |
tests/net/ipv6_fragment/src/main.c | Ensures IPv6 fragments have the correct ll protocol type. |
tests/net/ipv4_fragment/src/main.c | Sets the IPv4 link layer protocol type in multiple test cases. |
subsys/net/l2/ieee802154/ieee802154.c | Introduces a dedicated L3 handler registration for IEEE802.15.4. |
subsys/net/l2/ethernet/ethernet.c | Removes legacy L3 dispatch logic from the Ethernet driver, reflecting the centralized processing. |
subsys/net/ip/net_core.c | Centralizes L3 processing logic and refactors handling of loopback and reassembled packets. |
subsys/net/ip/ipv6.c & ipv4.c | Add new L3 handler functions for IPv6 and IPv4, including protocol-specific error checks. |
include/zephyr/net/net_pkt.h | Adds the loopback flag field and helper functions, plus updates to interface management macros. |
Files not reviewed (2)
- doc/releases/release-notes-4.2.rst: Language not supported
- subsys/net/l2/ethernet/Kconfig: Language not supported
Comments suppressed due to low confidence (2)
subsys/net/ip/net_core.c:125
- [nitpick] The condition used to determine the correct L3 handler is complex. Consider refactoring it (e.g. by using temporary variables or a helper function) to improve readability and maintainability.
if (l3->ptype != net_pkt_ll_proto_type(pkt) || (l3->l2 != NULL && l3->l2 != (net_pkt_iface(pkt)->if_dev->l2 == &NET_L2_GET_NAME(VIRTUAL) ? net_pkt_orig_iface(pkt)->if_dev->l2 : net_pkt_iface(pkt)->if_dev->l2)) || l3->handler == NULL) {
subsys/net/ip/net_core.c:440
- [nitpick] The change removes the is_loopback parameter from the process_data function and now sets the loopback flag externally. Please verify that this change maintains consistent loopback processing semantics across all packet reception paths.
net_pkt_set_loopback(pkt, true);
There are now multiple PRs changing things in this area and at least I have some difficulty keeping track of the changes. zephyr/subsys/net/l2/ethernet/vlan.c Line 256 in e55a505
|
@go2sh BTW, I just wonder what is the use case where VLAN would not be run directly on top of Ethernet because VLAN is basically Ethernet header + couple extra bytes in header. This does not sound very standard like behavior. What is the macsec layer doing? |
@jukkar General remark for MACsec. MACsec is a layer 2 authentication and encryption standard, which operates on a point to point bases. Example: An ECU and a switch communicate via MACsec, usually all traffic between those two is either authenticated or encrypted through a symmetric cypher (usually AES-GCM). Each point-to-point link in the network has its on key pair. Depending on the system configuration also the VLAN header is part of the authenticated/encrypted data, sometimes outside, sometimes there is a q-in-q setting. Depending on the requirement of the vehicle architecture. This pull request should enable a l2 macsec interface to feed packets into the l3 handlers the sameway a ethernet l2 or vlan l2 would do. The other pull request (#89291) should allow to layer l2 device depending on the network requirement. This would also make it easy to enable q-in-q (s-vlan and c-vlan) support in zephyr. Maybe on general remark on how I see virtual interfaces here: My idea is to have a tree of virtual interfaces similar to what linux does (eth0, macsec0@eth0, vlan1@macesc0, vlan2@macsec0 and so on). During receiving, the processing goes from the root (ethernet l2) towards an end node depending on the protocol header (vlan and macesec header give guidance which interface to select next). During sending, the processing goes from edge node towards the root node (l2 Ethernet). Here the route is clear from the configuration of each interface. Each layer (either ethernet l2 or virtual l2) removes or inserts the header required for its protocol. With that you have complete freedom how to layer the different protocols (except l2 ethernet is always start or end). And by the way: This layering could also be used for the bridging. |
BTW: This PR doesn't change any observable behavior for the current use cases. The changes to the tests a negatable. |
This article seems to describe the working well |
After reading the article it looks like the macsec works similar way as Ethernet extension protocol like LLDP, to me it does not look like a virtual network interface.
Sorry for stupid questions, just trying to understand how the macsec works to figure out how it can be bolt into network packet processing pipeline. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Generally looks pretty reasonable, however it seems all L2s other than Ethernet need to be aligned to set ll_proto_type
accordingly. After a brief check it seems that only Ethernet L2 does this, all other L2s relied on the net_core behavior which checked the IP header.
Chaning the l3 processing from the ethernet l2 driver to the net_core l3 processing. This allows to have a more generic l3 processing also in conjunction with other l2 drivers. Signed-off-by: Christoph Seitz <christoph.seitz@infineon.com>
Adding a loopback flag allows to process this information in l3 handlers. Signed-off-by: Christoph Seitz <christoph.seitz@infineon.com>
Adding l3 handler for ieee802154 packets to not get droped during l3 processing before packet sockets. Signed-off-by: Christoph Seitz <christoph.seitz@infineon.com>
Add a dedicated l3 handler to support more flexible interface architecture. Signed-off-by: Christoph Seitz <christoph.seitz@infineon.com>
Adding a dedicated ipv6 l3 handler makes processing from interfaces easier. Signed-off-by: Christoph Seitz <christoph.seitz@infineon.com>
The length update for ip and ipv6 is done in the respecive protocol functions. Signed-off-by: Christoph Seitz <christoph.seitz@infineon.com>
I run all test and added the missing l3 handler, which was only IEEE802.15.4. The CAN L3 handler is in a separat PR. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR refactors the l3 packet handling by moving responsibilities from the ethernet l2 driver into net_core. Key changes include introducing a loopback flag in net_pkt, creating dedicated l3 handlers for IPv4, IPv6, and IEEE802.15.4, and allowing l3 handlers to operate independently of an l2 layer for DUMMY and VIRTUAL interfaces.
Reviewed Changes
Copilot reviewed 10 out of 12 changed files in this pull request and generated no comments.
Show a summary per file
File | Description |
---|---|
tests/net/lib/mdns_responder/src/main.c | Updated pkt allocation to explicitly use AF_INET6 and set LL protocol |
tests/net/ipv6_fragment/src/main.c & tests/net/ipv4_fragment/src/main.c | Added ll protocol type setting in packet tests |
subsys/net/l2/ieee802154/ieee802154.c | Introduced a dedicated l3 handler for IEEE802.15.4 via NET_L3_REGISTER |
subsys/net/l2/ethernet/ethernet.c | Removed internal l3 registration loop and ethernet_update_length helper |
subsys/net/ip/net_pkt.c | Ensured that loopback flag is propagated when cloning packets |
subsys/net/ip/net_core.c | Refactored process_data to eliminate the is_loopback parameter and updated L3 handling |
subsys/net/ip/ipv6.c & subsys/net/ip/ipv4.c | Introduced dedicated l3 handlers for IPv6 and IPv4 respectively |
include/zephyr/net/net_pkt.h | Added a new loopback bitfield and updated the interface for orig_iface handling |
Files not reviewed (2)
- doc/releases/release-notes-4.2.rst: Language not supported
- subsys/net/l2/ethernet/Kconfig: Language not supported
Comments suppressed due to low confidence (4)
subsys/net/l2/ethernet/ethernet.c:118
- Ensure that the removal of the internal l3 registration loop and the ethernet_update_length helper is intentional and that all L3 handling is now properly routed via net_core.
/* Removed ethernet_update_length and L3 registration loop */
tests/net/lib/mdns_responder/src/main.c:299
- [nitpick] The allocation now explicitly uses AF_INET6 instead of AF_UNSPEC; please confirm that all test cases expecting an IPv6 packet allocation are updated accordingly.
pkt = net_pkt_alloc_with_buffer(iface1, NET_IPV6UDPH_LEN + len, AF_INET6, 0, K_FOREVER);
subsys/net/ip/net_core.c:67
- Confirm that eliminating the is_loopback parameter in process_data and relying on net_pkt_set_loopback() does not inadvertently affect loopback packet processing.
static inline enum net_verdict process_data(struct net_pkt *pkt)
include/zephyr/net/net_pkt.h:247
- Double-check that adding the loopback bitfield does not disrupt the existing bitfield alignment or conflicts with other flags in the net_pkt structure.
uint8_t loopback: 1; /** Set to 1 if this packet is a loopback packet */
@@ -244,6 +244,8 @@ struct net_pkt { | |||
uint8_t tx_timestamping : 1; /** Timestamp transmitted packet */ | |||
uint8_t rx_timestamping : 1; /** Timestamp received packet */ | |||
#endif | |||
uint8_t loopback: 1; /** Set to 1 if this packet is a loopback packet */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Previous nit comment not addressed
uint8_t loopback: 1; /** Set to 1 if this packet is a loopback packet */ | |
uint8_t loopback : 1; /** Set to 1 if this packet is a loopback packet */ |
|
I wasn't referring to L3 handlers - my point is, that not all L2 implementations currently set the packet proto type to either OpenThread L2 diffdiff --git a/subsys/net/l2/openthread/openthread.c b/subsys/net/l2/openthread/openthread.c
index c82dfdea2d2..00290b7fde3 100644
--- a/subsys/net/l2/openthread/openthread.c
+++ b/subsys/net/l2/openthread/openthread.c
@@ -7,6 +7,7 @@
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(net_l2_openthread, CONFIG_OPENTHREAD_L2_LOG_LEVEL);
+#include <zephyr/net/ethernet.h>
#include <zephyr/net/net_core.h>
#include <zephyr/net/net_pkt.h>
#include <zephyr/net/net_mgmt.h>
@@ -307,6 +308,8 @@ static void ot_receive_handler(otMessage *aMessage, void *context)
}
}
+ net_pkt_set_ll_proto_type(pkt, PKT_IS_IPv4(pkt) ? ETH_P_IP : ETH_P_IPV6);
+
if (!pkt_list_is_full(ot_context)) {
if (pkt_list_add(ot_context, pkt) != 0) {
NET_ERR("pkt_list_add failed"); or for 802.15.4 6lowpan compression: 802.15.4 L2 diffdiff --git a/subsys/net/ip/6lo.c b/subsys/net/ip/6lo.c
index 6a0dfa66758..6d9e48d9fd4 100644
--- a/subsys/net/ip/6lo.c
+++ b/subsys/net/ip/6lo.c
@@ -13,6 +13,7 @@
LOG_MODULE_REGISTER(net_6lo, CONFIG_NET_6LO_LOG_LEVEL);
#include <errno.h>
+#include <zephyr/net/ethernet.h>
#include <zephyr/net/net_core.h>
#include <zephyr/net/net_if.h>
#include <zephyr/net/net_stats.h>
@@ -1420,6 +1421,7 @@ static bool uncompress_IPHC_header(struct net_pkt *pkt)
/* Version is always 6 */
ipv6->vtc = 0x60;
net_pkt_set_ip_hdr_len(pkt, NET_IPV6H_LEN);
+ net_pkt_set_ll_proto_type(pkt, ETH_P_IPV6);
/* Uncompress Traffic class and Flow label */
cursor = uncompress_tfl(iphc, cursor, ipv6);
@@ -1556,6 +1558,7 @@ static inline bool uncompress_ipv6_header(struct net_pkt *pkt)
/* Pull off IPv6 dispatch header and adjust data and length */
net_buf_pull(pkt->buffer, 1U);
net_pkt_cursor_init(pkt);
+ net_pkt_set_ll_proto_type(pkt, ETH_P_IPV6);
return true;
} PPP L2 likely (haven't tested this) need to set respective proto type somewhere in: zephyr/subsys/net/l2/ppp/ppp_l2.c Line 107 in f7a2b4e
Not sure about dummy L2 - it's mostly used for loopback so probably it's not an issue in this case. |
This PR rework the l3 handling from the ethernet l2 driver into the net_core. For that it does:
The idea is to allow virutal intefaces to go throug the l3 handlers. So for example (a potential macsec l2 inteface), the flow could look like: l2 ethernet -> l2 macsec ->l2 vlan -> l3 handler.