We need to use destination address stored in dst variable instead of IP header when doing route lookup.
Thus correct address will be used when PACKET_TAG_IPFORWARD is set by ipfw.
This code path is used when ip_output is called with NULL route pointer, in this case ro == &iproute and dst is initialized as ip->ip_dst. After ip_output_pfil dst value can be changed to the address from fwd_tag, but IP header keeps unchanged, thus we need to use dst variable in fib4_lookup.
IPv6 code is a bit different and patch seems hackish.
Probably we should just move block to be before again: label
if (ro == NULL || ro->ro_nh == NULL) { bzero(dst, sizeof(*dst)); dst->sin6_family = AF_INET6; dst->sin6_len = sizeof(*dst); dst->sin6_addr = ip6->ip6_dst; }
Regression was introduced in D19804 and D23886.
PR: 256828, 261697, 255705