yifan xu wrote:
The problem is for an IPv6 packets being forwarded and queued in nce->nce_qd_mp 
in case no ire cache has found, when neighbour discovery gets done, it will be 
sent to its destination carrying incorrect tcp/udp checksums. See CR 6446106.

The cause is ndp_process() sends those packets through a wrong path:
ndp_process -> put -> ip_wput_v6 -> ip_output_v6 -> ip_wput_ire_v6 (briefly)
That should be the path only for locally originated packets. ip_wput_ire_v6 
will recalculate the checksum and thus causes the problem.
For externally originated packets, the path should be:
ndp_process -> put -> ip_rput_v6 -> ip_rput_data_v6 -> ip_xmit_v6 (briefly)

The reason that ndp_process() makes the incorrect verdict for packets being forwarded is 
that it determines whether packets are externally originated depending on mp->b_prev 
which is used to store phyint_ifindex in ip_rput_data_v6(). But when the packet arrives 
ndp_process(), the mblk has been prepended an M_CTL type message by ndp_prepend_zone() to 
store zoneid. So in ndp_process() it is mp->b_cont->b_prev which should be examined 
instead of mp->b_prev.

What I am not sure about is the resolution.
1) Modifying ndp_process() to get rid of the prepended M_CTL mblk is the most 
simple way to fix the problem, making the packets going through the right path.
2) But since this prepended message and the zone id stored in it will never be used for 
packets being forwarded(the zone id will not be used when doing ire lookup or 
ip_newroute_v6, they use "ALL_ZONES" in ip_rput_data_v6), it seems not calling 
ndp_prepend_zone() in ndp_resolver() for forwarding packets is a more reasonable 
resolution.
3) And one might expect a more complete change, to make the forwarding packets 
also make use of the zone id, just like the locally originated packets do.

Any suggestions?

Doing #2 sounds best as the short-term fix.

Longer term we want to apply what Surya did to IPv4 forwarding to IPv4 origination and and IPv6, which would mean that when the packet is queued for ARP/NDP resolution, the rest of IP is done with everything we need to do and all that remains is filling in the L2 header.

That way when resultion is complete we'd always go to ip_xmit_v* and the code will be much simpler.

   Erik
_______________________________________________
networking-discuss mailing list
[email protected]

Reply via email to