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? Yifan This message posted from opensolaris.org _______________________________________________ networking-discuss mailing list [email protected]
