Skip to content

Conversation

@shrek-wang
Copy link
Contributor

@shrek-wang shrek-wang commented Sep 13, 2024

Deadloop happens when CONFIG_NET_ROUTING and VLAN are enabled. In function net_ipv6_prepare_for_send(), pkt->iface will be updated with net_pkt_set_iface(pkt, iface) in 2 scenarios:

  1. ip_hdr->dst is onlink
  2. check_route or nbr_lookup

VLAN is virtual-iface which attaches to a physical-iface. Each time a packet being sent to a VLAN port will invoke twice of the net_send_data(). The 1st time, pkt->iface is set to virtual iface and the 2nd time to physical iface. However in above 2 scenarios, at the 2nd time of calling the net_send_data(), the pkt-iface will be changed back to virtual iface. The system runs into a deadloop. This can be proved by enabling CONFIG_NET_ROUTING with the VLAN sample.
The main purpose for net_ipv6_prepare_for_send() is to set the right ll_dst address. If the ll_dst address is already set, then no need to go through it again. If the packet has done with the forwarding and set the ll_dst, then no need to check_route again. And, the pkt->iface will not be changed back to virtual iface.

Fixes: #77402

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The net_ipv6_prepare_for_send() is also responsible for fragmentation, I'm not entirely sure if it's ok to skip it.

But anyway, inside net_ipv6_prepare_for_send() we already have a lengthy if condition, which verifies if the L2 MAC address is present, and decides whether to quit early:

if ((net_pkt_lladdr_dst(pkt)->addr &&

I think it'd make more sense to fix that condition if it's wrong for VLAN case (maybe it should quit early for virtual interfaces?) instead of introducing similar check elsewhere.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right, @rlubos. I forgot the fragmentation case.
I will investigate where to add the right checks in the place you mentioned.

@shrek-wang shrek-wang marked this pull request as draft September 13, 2024 10:59
@shrek-wang shrek-wang force-pushed the fix_net_ipv6_deadloop branch from bc09594 to b10f995 Compare September 14, 2024 03:38
@shrek-wang shrek-wang changed the title net: Add DMAC-addr check before IPv6-prepare net: Add onlink and forwarding check to IPv6-prepare Sep 14, 2024
@shrek-wang shrek-wang marked this pull request as ready for review September 14, 2024 03:45
Copy link
Member

@jukkar jukkar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would like to also see in the commit message mentioned why this change is needed.

Deadloop happens when CONFIG_NET_ROUTING and VLAN are enabled.
In function net_ipv6_prepare_for_send(), pkt->iface will be
updated with net_pkt_set_iface(pkt, iface) in 2 scenarios:
1. ip_hdr->dst is onlink
2. check_route or nbr_lookup
VLAN is virtual-iface which attaches to a physical-iface. Each
time a packet being sent to a VLAN port will invoke twice of
the net_send_data(). The 1st time, pkt->iface is set to virtual
iface and the 2nd time to physical iface.
However in above 2 scenarios, at the 2nd time of calling the
net_send_data(), the pkt-iface will be changed back to virtual
iface. The system runs into a deadloop. This can be proved by
enabling CONFIG_NET_ROUTING with the VLAN sample.
The main purpose for net_ipv6_prepare_for_send() is to set the
right ll_dst address. If the ll_dst address is already set, then
no need to go through it again. If the packet has done with the
forwarding and set the ll_dst, then no need to check_route again.
And, the pkt->iface will not be changed back to virtual iface.

Fixes: zephyrproject-rtos#77402

Signed-off-by: Shrek Wang <[email protected]>
@shrek-wang shrek-wang force-pushed the fix_net_ipv6_deadloop branch from b10f995 to 794121f Compare September 14, 2024 14:13
@shrek-wang
Copy link
Contributor Author

Thanks, @jukkar.
I have added some words to describe the reason, though I believe there are more details to say.

Copy link
Member

@jukkar jukkar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, the commit message looks very good and thorough.

@nashif nashif merged commit 0b24b96 into zephyrproject-rtos:main Sep 18, 2024
@shrek-wang shrek-wang deleted the fix_net_ipv6_deadloop branch September 18, 2024 02:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Enabling IPv6-forwarding on VLAN-based interface triggers deadloop & hang

5 participants