Fix ipfw fwd for IPv4 traffic broken by r249894.

Problem case:
Original lookup returns route with GW set, so gw points to
rte->rt_gateway.
After that we're changing dst and performing lookup another time.
Since fwd host is most probably directly reachable, resulting
rte does not contain rt_gateway, so gw is not set. Finally, we
end with packet transmitted to proper interface but wrong
link-layer address.

Found by:	lstewart
Discussed with:	ae,lstewart
MFC after:	2 weeks
Sponsored by:	Yandex LLC
This commit is contained in:
Alexander V. Chernikov 2014-01-16 11:50:00 +00:00
parent 0b6a0ca072
commit 054692a4bd
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=260702

View File

@ -202,6 +202,13 @@ ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro, int flags,
hlen = ip->ip_hl << 2;
}
/*
* dst/gw handling:
*
* dst can be rewritten but always point to &ro->ro_dst
* gw is readonly but can be pointed either to dst OR rt_gatewy
* therefore we need restore GW if we're re-doing lookup
*/
gw = dst = (struct sockaddr_in *)&ro->ro_dst;
again:
ia = NULL;
@ -221,6 +228,7 @@ ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro, int flags,
RO_RTFREE(ro);
ro->ro_lle = NULL;
rte = NULL;
gw = dst;
}
if (rte == NULL && fwd_tag == NULL) {
bzero(dst, sizeof(*dst));