When it comes to reference counting in the receiving path, route entries act as proxy for interface addresses. In other words you CANNOT dereference ``rt->rt_ifa'' after calling rtfree(9).
Diff below fixes that in icmp_reflect(), ok? Index: netmpls/mpls_input.c =================================================================== RCS file: /cvs/src/sys/netmpls/mpls_input.c,v retrieving revision 1.56 diff -u -p -r1.56 mpls_input.c --- netmpls/mpls_input.c 11 Jul 2016 09:23:06 -0000 1.56 +++ netmpls/mpls_input.c 22 Aug 2016 11:20:48 -0000 @@ -385,8 +385,9 @@ mpls_do_error(struct mbuf *m, int type, m_freem(m); return (NULL); } - rtfree(rt); + /* It is safe to dereference ``ia'' iff ``rt'' is valid. */ error = icmp_reflect(m, NULL, ia); + rtfree(rt); if (error) return (NULL); Index: netinet/ip_icmp.c =================================================================== RCS file: /cvs/src/sys/netinet/ip_icmp.c,v retrieving revision 1.151 diff -u -p -r1.151 ip_icmp.c --- netinet/ip_icmp.c 9 Dec 2015 09:27:40 -0000 1.151 +++ netinet/ip_icmp.c 22 Aug 2016 11:21:02 -0000 @@ -702,7 +702,7 @@ icmp_reflect(struct mbuf *m, struct mbuf struct ip *ip = mtod(m, struct ip *); struct mbuf *opts = NULL; struct sockaddr_in sin; - struct rtentry *rt; + struct rtentry *rt = NULL; int optlen = (ip->ip_hl << 2) - sizeof(struct ip); u_int rtableid; @@ -733,7 +733,6 @@ icmp_reflect(struct mbuf *m, struct mbuf if (rtisvalid(rt) && ISSET(rt->rt_flags, RTF_LOCAL|RTF_BROADCAST)) ia = ifatoia(rt->rt_ifa); - rtfree(rt); } /* @@ -742,6 +741,8 @@ icmp_reflect(struct mbuf *m, struct mbuf * drop the packet as there is no path to the host. */ if (ia == NULL) { + rtfree(rt); + memset(&sin, 0, sizeof(sin)); sin.sin_len = sizeof(sin); sin.sin_family = AF_INET; @@ -756,12 +757,14 @@ icmp_reflect(struct mbuf *m, struct mbuf } ia = ifatoia(rt->rt_ifa); - rtfree(rt); } ip->ip_dst = ip->ip_src; - ip->ip_src = ia->ia_addr.sin_addr; ip->ip_ttl = MAXTTL; + + /* It is safe to dereference ``ia'' iff ``rt'' is valid. */ + ip->ip_src = ia->ia_addr.sin_addr; + rtfree(rt); if (optlen > 0) { u_char *cp;