diff options
author | Alexander Bluhm <bluhm@cvs.openbsd.org> | 2021-11-22 13:47:11 +0000 |
---|---|---|
committer | Alexander Bluhm <bluhm@cvs.openbsd.org> | 2021-11-22 13:47:11 +0000 |
commit | 8a1afef19e586ffa3115066680455751d81e9166 (patch) | |
tree | 29fe0adc2904e515b03822c0f25cf5b108bb8f34 /sys/netinet/ip_input.c | |
parent | a64a5a717fb37c5b53c8bc732b4a21ce8d022f3b (diff) |
Copy code from ip_forward() to ip6_forward() to fix Path MTU discovery
in IPsec IPv6 tunnel. Implement sending ICMP6 packet too big
messages. Also implement the pf error case in ip6_forward(). While
there, do some cleanup and make the IPv4 and IPv6 code look similar.
OK tobhe@
Diffstat (limited to 'sys/netinet/ip_input.c')
-rw-r--r-- | sys/netinet/ip_input.c | 34 |
1 files changed, 16 insertions, 18 deletions
diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c index 3915225657e..9e7e20af30b 100644 --- a/sys/netinet/ip_input.c +++ b/sys/netinet/ip_input.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_input.c,v 1.363 2021/06/21 22:09:14 jca Exp $ */ +/* $OpenBSD: ip_input.c,v 1.364 2021/11/22 13:47:10 bluhm Exp $ */ /* $NetBSD: ip_input.c,v 1.30 1996/03/16 23:53:58 christos Exp $ */ /* @@ -1436,7 +1436,7 @@ ip_forward(struct mbuf *m, struct ifnet *ifp, struct rtentry *rt, int srcrt) struct ip *ip = mtod(m, struct ip *); struct sockaddr_in *sin; struct route ro; - int error, type = 0, code = 0, destmtu = 0, fake = 0, len; + int error = 0, type = 0, code = 0, destmtu = 0, fake = 0, len; u_int32_t dest; dest = 0; @@ -1535,29 +1535,17 @@ ip_forward(struct mbuf *m, struct ifnet *ifp, struct rtentry *rt, int srcrt) goto freecopy; switch (error) { - case 0: /* forwarded, but need redirect */ /* type, code set above */ break; - case ENETUNREACH: /* shouldn't happen, checked above */ - case EHOSTUNREACH: - case ENETDOWN: - case EHOSTDOWN: - default: - type = ICMP_UNREACH; - code = ICMP_UNREACH_HOST; - break; - case EMSGSIZE: type = ICMP_UNREACH; code = ICMP_UNREACH_NEEDFRAG; - -#ifdef IPSEC if (rt != NULL) { - if (rt->rt_mtu) + if (rt->rt_mtu) { destmtu = rt->rt_mtu; - else { + } else { struct ifnet *destifp; destifp = if_get(rt->rt_ifidx); @@ -1566,8 +1554,9 @@ ip_forward(struct mbuf *m, struct ifnet *ifp, struct rtentry *rt, int srcrt) if_put(destifp); } } -#endif /*IPSEC*/ ipstat_inc(ips_cantfrag); + if (destmtu == 0) + goto freecopy; break; case EACCES: @@ -1576,6 +1565,7 @@ ip_forward(struct mbuf *m, struct ifnet *ifp, struct rtentry *rt, int srcrt) * packet back since pf(4) takes care of it. */ goto freecopy; + case ENOBUFS: /* * a router should not generate ICMP_SOURCEQUENCH as @@ -1584,8 +1574,16 @@ ip_forward(struct mbuf *m, struct ifnet *ifp, struct rtentry *rt, int srcrt) * or the underlying interface is rate-limited. */ goto freecopy; - } + case ENETUNREACH: /* shouldn't happen, checked above */ + case EHOSTUNREACH: + case ENETDOWN: + case EHOSTDOWN: + default: + type = ICMP_UNREACH; + code = ICMP_UNREACH_HOST; + break; + } mcopy = m_copym(&mfake, 0, len, M_DONTWAIT); if (mcopy) icmp_error(mcopy, type, code, dest, destmtu); |