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]