summaryrefslogtreecommitdiffstats
path: root/sys/netinet/ip_output.c
diff options
context:
space:
mode:
authorclaudio <claudio@openbsd.org>2009-10-06 21:21:48 +0000
committerclaudio <claudio@openbsd.org>2009-10-06 21:21:48 +0000
commitf1638404ba0c53306d1b01045a1c7c17d655615f (patch)
tree933dd84fe5d7f7acc3b2f79cce5faee5d50aa3f3 /sys/netinet/ip_output.c
parentdisallow AUTH once a session is in progress, this prevents a fatal from (diff)
downloadwireguard-openbsd-f1638404ba0c53306d1b01045a1c7c17d655615f.tar.xz
wireguard-openbsd-f1638404ba0c53306d1b01045a1c7c17d655615f.zip
Redo the route lookup in the output (and IPv6 forwarding) path if the
destination of a packet was changed by pf. This allows for some evil games with rdr-to or nat-to but is mostly needed for better rdomain/rtable support. This is a first step and more work and cleanup is needed. Here a list of what works and what does not (needs a patched pfctl): pass out rdr-to: from local rdr-to local addr works (if state tracking on lo0 is done) from remote rdr-to local addr does NOT work from local rdr-to remote works from remote rdr-to remote works pass in nat-to: from remote nat-to local addr does NOT work from remote nat-to non-local addr works non-local is an IP that is routed to the FW but is not assigned on the FW. The non working cases need some magic to correctly rewrite the incomming packet since the rewriting would happen outbound which is too late. "time to get it in" deraadt@
Diffstat (limited to 'sys/netinet/ip_output.c')
-rw-r--r--sys/netinet/ip_output.c25
1 files changed, 23 insertions, 2 deletions
diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c
index 8247955acab..b59ffcaaf2d 100644
--- a/sys/netinet/ip_output.c
+++ b/sys/netinet/ip_output.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_output.c,v 1.194 2009/06/05 00:05:22 claudio Exp $ */
+/* $OpenBSD: ip_output.c,v 1.195 2009/10/06 21:21:48 claudio Exp $ */
/* $NetBSD: ip_output.c,v 1.28 1996/02/13 23:43:07 christos Exp $ */
/*
@@ -245,6 +245,10 @@ ip_output(struct mbuf *m0, ...)
ip->ip_src = ia->ia_addr.sin_addr;
}
+#if NPF > 0
+reroute:
+#endif
+
#ifdef IPSEC
if (!ipsec_in_use && inp == NULL)
goto done_spd;
@@ -594,6 +598,13 @@ sendit:
}
ip = mtod(m, struct ip *);
hlen = ip->ip_hl << 2;
+ /*
+ * PF_TAG_REROUTE handling or not...
+ * Packet is entering IPsec so the routing is
+ * already overruled by the IPsec policy.
+ * Until now the change was not reconsidered.
+ * What's the behaviour?
+ */
#endif
tdb = gettdb(sspi, &sdst, sproto);
@@ -703,9 +714,19 @@ sendit:
}
if (m == NULL)
goto done;
-
ip = mtod(m, struct ip *);
hlen = ip->ip_hl << 2;
+ if ((m->m_pkthdr.pf.flags & (PF_TAG_REROUTE | PF_TAG_GENERATED)) ==
+ (PF_TAG_REROUTE | PF_TAG_GENERATED))
+ /* already rerun the route lookup, go on */
+ m->m_pkthdr.pf.flags &= ~(PF_TAG_GENERATED | PF_TAG_REROUTE);
+ else if (m->m_pkthdr.pf.flags & PF_TAG_REROUTE) {
+ /* tag as generated to skip over pf_test on rerun */
+ m->m_pkthdr.pf.flags |= PF_TAG_GENERATED;
+ ro = NULL;
+ donerouting = 0;
+ goto reroute;
+ }
#endif
#ifdef IPSEC