summaryrefslogtreecommitdiffstats
path: root/sys/netinet/ip_output.c
diff options
context:
space:
mode:
authorae <ae@FreeBSD.org>2014-02-06 10:48:55 +0000
committerae <ae@FreeBSD.org>2014-02-06 10:48:55 +0000
commit88938f44a008c777d8811442d0121c4edd7c943d (patch)
treedd679f50bed1fd304bd3220b83a55fcba1493720 /sys/netinet/ip_output.c
parentd65cbb18772b973f3f49fb98b7dfa730f38b8aac (diff)
downloadFreeBSD-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/ip_output.c')
-rw-r--r--sys/netinet/ip_output.c8
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));
OpenPOWER on IntegriCloud