summaryrefslogtreecommitdiff
path: root/sys/netinet
diff options
context:
space:
mode:
authorAlexander Bluhm <bluhm@cvs.openbsd.org>2017-12-14 14:26:51 +0000
committerAlexander Bluhm <bluhm@cvs.openbsd.org>2017-12-14 14:26:51 +0000
commit180e58c91ba2c116ad7da261ab12aa3ab6995859 (patch)
tree7aac0ed766ba2023dec49e6a79b62d5af69f503b /sys/netinet
parent90d0c98dce164ac8e0de0b86b92b04a2547c7430 (diff)
The pf code marks ICMP packets belonging to an TCP or UDP divert
state as diverted. This is necessary for IP input to accept the packet as ours. But it must not be used to match the ICMP packet to a raw socket. Clear the PF_TAG_DIVERTED mbuf pf flag for the special ICMP and ICMP6 packets in icmp_input_if() and icmp6_input(). The m_tag_delete_chain() caused an inconsistent PF_TAG_DIVERTED mbuf pf flag and PACKET_TAG_PF_DIVERT mbuf tag which triggered an assert in rip_input(). Deleting all mbuf tags can have undesired side effects and is not necessary anymore since icmp_reflect() calls m_resethdr(). Do not touch the mbuf tags and adjust the mbuf pf flags for the correct behavior of rip_input() and rip6_input(). reported by Chris Eidem, James Turner, vicviq, Scott Vanderbilt OK mpi@
Diffstat (limited to 'sys/netinet')
-rw-r--r--sys/netinet/ip_icmp.c30
1 files changed, 12 insertions, 18 deletions
diff --git a/sys/netinet/ip_icmp.c b/sys/netinet/ip_icmp.c
index f218b6f428e..b71e8738da2 100644
--- a/sys/netinet/ip_icmp.c
+++ b/sys/netinet/ip_icmp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_icmp.c,v 1.173 2017/10/18 17:01:14 bluhm Exp $ */
+/* $OpenBSD: ip_icmp.c,v 1.174 2017/12/14 14:26:50 bluhm Exp $ */
/* $NetBSD: ip_icmp.c,v 1.19 1996/02/13 23:42:22 christos Exp $ */
/*
@@ -378,6 +378,12 @@ icmp_input_if(struct ifnet *ifp, struct mbuf **mp, int *offp, int proto, int af)
#if NPF > 0
if (m->m_pkthdr.pf.flags & PF_TAG_DIVERTED) {
switch (icp->icmp_type) {
+ /*
+ * As pf_icmp_mapping() considers redirects belonging to a
+ * diverted connection, we must include it here.
+ */
+ case ICMP_REDIRECT:
+ /* FALLTHROUGH */
/*
* These ICMP types map to other connections. They must be
* delivered to pr_ctlinput() also for diverted connections.
@@ -386,12 +392,11 @@ icmp_input_if(struct ifnet *ifp, struct mbuf **mp, int *offp, int proto, int af)
case ICMP_TIMXCEED:
case ICMP_PARAMPROB:
case ICMP_SOURCEQUENCH:
- break;
- /*
- * Although pf_icmp_mapping() considers redirects belonging
- * to a diverted connection, we must process it here anyway.
- */
- case ICMP_REDIRECT:
+ /*
+ * Do not use the divert-to property of the TCP or UDP
+ * rule when doing the PCB lookup for the raw socket.
+ */
+ m->m_pkthdr.pf.flags &=~ PF_TAG_DIVERTED;
break;
default:
goto raw;
@@ -454,10 +459,6 @@ icmp_input_if(struct ifnet *ifp, struct mbuf **mp, int *offp, int proto, int af)
goto badcode;
code = PRC_QUENCH;
deliver:
- /* Free packet atttributes */
- if (m->m_flags & M_PKTHDR)
- m_tag_delete_chain(m);
-
/*
* Problem with datagram; advise higher level routines.
*/
@@ -585,10 +586,6 @@ reflect:
&ip->ip_dst.s_addr, 1))
goto freeit;
#endif
- /* Free packet atttributes */
- if (m->m_flags & M_PKTHDR)
- m_tag_delete_chain(m);
-
icmpstat_inc(icps_reflect);
icmpstat_inc(icps_outhist + icp->icmp_type);
if (!icmp_reflect(m, &opts, NULL)) {
@@ -604,9 +601,6 @@ reflect:
struct sockaddr_in ssrc;
struct rtentry *newrt = NULL;
- /* Free packet atttributes */
- if (m->m_flags & M_PKTHDR)
- m_tag_delete_chain(m);
if (icmp_rediraccept == 0 || ipforwarding == 1)
goto freeit;
if (code > 3)