-/* $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 $ */
/*
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;
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);
if_put(destifp);
}
}
-#endif /*IPSEC*/
ipstat_inc(ips_cantfrag);
+ if (destmtu == 0)
+ goto freecopy;
break;
case EACCES:
* packet back since pf(4) takes care of it.
*/
goto freecopy;
+
case ENOBUFS:
/*
* a router should not generate ICMP_SOURCEQUENCH as
* 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);
-/* $OpenBSD: ip6_forward.c,v 1.101 2021/10/14 17:39:42 bluhm Exp $ */
+/* $OpenBSD: ip6_forward.c,v 1.102 2021/11/22 13:47:10 bluhm Exp $ */
/* $KAME: ip6_forward.c,v 1.75 2001/06/29 12:42:13 jinmei Exp $ */
/*
struct sockaddr_in6 *sin6;
struct route_in6 ro;
struct ifnet *ifp = NULL;
- int error = 0, type = 0, code = 0;
+ int error = 0, type = 0, code = 0, destmtu = 0;
struct mbuf *mcopy = NULL;
#ifdef IPSEC
struct tdb *tdb = NULL;
#endif
if (mcopy == NULL)
goto out;
+
switch (error) {
case 0:
if (type == ND_REDIRECT) {
goto freecopy;
case EMSGSIZE:
- /* xxx MTU is constant in PPP? */
+ type = ICMP6_PACKET_TOO_BIG;
+ code = 0;
+ if (rt != NULL) {
+ if (rt->rt_mtu) {
+ destmtu = rt->rt_mtu;
+ } else {
+ struct ifnet *destifp;
+
+ destifp = if_get(rt->rt_ifidx);
+ if (destifp != NULL)
+ destmtu = destifp->if_mtu;
+ if_put(destifp);
+ }
+ }
+ ip6stat_inc(ip6s_cantfrag);
+ if (destmtu == 0)
+ goto freecopy;
+ break;
+
+ case EACCES:
+ /*
+ * pf(4) blocked the packet. There is no need to send an ICMP
+ * packet back since pf(4) takes care of it.
+ */
goto freecopy;
case ENOBUFS:
code = ICMP6_DST_UNREACH_ADDR;
break;
}
- icmp6_error(mcopy, type, code, 0);
+ icmp6_error(mcopy, type, code, destmtu);
goto out;
freecopy: