diff options
author | ae <ae@FreeBSD.org> | 2014-02-06 10:48:55 +0000 |
---|---|---|
committer | ae <ae@FreeBSD.org> | 2014-02-06 10:48:55 +0000 |
commit | 88938f44a008c777d8811442d0121c4edd7c943d (patch) | |
tree | dd679f50bed1fd304bd3220b83a55fcba1493720 /sys/netinet | |
parent | d65cbb18772b973f3f49fb98b7dfa730f38b8aac (diff) | |
download | FreeBSD-src-88938f44a008c777d8811442d0121c4edd7c943d.zip FreeBSD-src-88938f44a008c777d8811442d0121c4edd7c943d.tar.gz |
MFC r260702 (by melifaro):
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.
Diffstat (limited to 'sys/netinet')
-rw-r--r-- | sys/netinet/ip_output.c | 8 |
1 files changed, 8 insertions, 0 deletions
diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c index 2838e76..7764bc3 100644 --- a/sys/netinet/ip_output.c +++ b/sys/netinet/ip_output.c @@ -200,6 +200,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; @@ -219,6 +226,7 @@ again: RO_RTFREE(ro); ro->ro_lle = NULL; rte = NULL; + gw = dst; } if (rte == NULL && fwd_tag == NULL) { bzero(dst, sizeof(*dst)); |