From 1d3b3d6ee306456e17986bdc6a0006e0722a5a0a Mon Sep 17 00:00:00 2001 From: bluhm Date: Wed, 10 Feb 2021 18:28:06 +0000 Subject: [PATCH] If pf changes the routing table when sending packets, the kernel could get stuck in an endless recursion during TCP path MTU discovery. Create a dynamic host route in ip_output() that can be used by tcp_mtudisc() to store the MTU. Reported by Peter Mueller and Sebastian Sturm OK claudio@ --- sys/netinet/ip_output.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c index b32adb453fe..374c768cb30 100644 --- a/sys/netinet/ip_output.c +++ b/sys/netinet/ip_output.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_output.c,v 1.364 2021/02/06 13:15:37 bluhm Exp $ */ +/* $OpenBSD: ip_output.c,v 1.365 2021/02/10 18:28:06 bluhm Exp $ */ /* $NetBSD: ip_output.c,v 1.28 1996/02/13 23:43:07 christos Exp $ */ /* @@ -108,7 +108,10 @@ ip_output(struct mbuf *m0, struct mbuf *opt, struct route *ro, int flags, struct sockaddr_in *dst; struct tdb *tdb = NULL; u_long mtu; -#if defined(MROUTING) +#if NPF > 0 + u_int orig_rtableid; +#endif +#ifdef MROUTING int rv; #endif @@ -151,6 +154,7 @@ ip_output(struct mbuf *m0, struct mbuf *opt, struct route *ro, int flags, } #if NPF > 0 + orig_rtableid = m->m_pkthdr.ph_rtableid; reroute: #endif @@ -480,6 +484,15 @@ sendit: ipsec_adjust_mtu(m, ifp->if_mtu); #endif error = EMSGSIZE; +#if NPF > 0 + /* pf changed routing table, use orig rtable for path MTU */ + if (ro->ro_tableid != orig_rtableid) { + rtfree(ro->ro_rt); + ro->ro_tableid = orig_rtableid; + ro->ro_rt = icmp_mtudisc_clone( + satosin(&ro->ro_dst)->sin_addr, ro->ro_tableid, 0); + } +#endif /* * This case can happen if the user changed the MTU * of an interface after enabling IP on it. Because -- 2.20.1