Module Name: src
Committed By: kardel
Date: Thu Nov 12 13:13:45 UTC 2020
Modified Files:
src/sys/netinet: ip_mroute.c
Log Message:
PR kern/55779:
restore non-desctructive guarantee of ip_mforward() mbuf
argument. This avoids generation invalid UDP checksums
on multicast packets in ip_output().
XXX the root cause of the misguided fix in 2008 should be
XXX investigated
To generate a diff of this commit:
cvs rdiff -u -r1.163 -r1.164 src/sys/netinet/ip_mroute.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/netinet/ip_mroute.c
diff -u src/sys/netinet/ip_mroute.c:1.163 src/sys/netinet/ip_mroute.c:1.164
--- src/sys/netinet/ip_mroute.c:1.163 Fri Sep 14 05:09:51 2018
+++ src/sys/netinet/ip_mroute.c Thu Nov 12 13:13:45 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: ip_mroute.c,v 1.163 2018/09/14 05:09:51 maxv Exp $ */
+/* $NetBSD: ip_mroute.c,v 1.164 2020/11/12 13:13:45 kardel Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -93,7 +93,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ip_mroute.c,v 1.163 2018/09/14 05:09:51 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip_mroute.c,v 1.164 2020/11/12 13:13:45 kardel Exp $");
#ifdef _KERNEL_OPT
#include "opt_inet.h"
@@ -225,6 +225,8 @@ static int tbf_dq_sel(struct vif *, stru
static void tbf_send_packet(struct vif *, struct mbuf *);
static void tbf_update_tokens(struct vif *);
static int priority(struct vif *, struct ip *);
+static int ip_mforward_real(struct mbuf *, struct ifnet *);
+
/*
* Bandwidth monitoring
@@ -1268,6 +1270,34 @@ socket_send(struct socket *s, struct mbu
int
ip_mforward(struct mbuf *m, struct ifnet *ifp)
{
+ int rc;
+ /*
+ * save csum_flags to uphold the
+ * "unscathed" guarantee.
+ * ip_output() relies on that and
+ * without it we send out
+ * multicast packets with an invalid
+ * checksum
+ *
+ * see PR kern/55779
+ */
+ int csum_flags = m->m_pkthdr.csum_flags;
+
+ /*
+ * Temporarily clear any in-bound checksum flags for this packet.
+ */
+ m->m_pkthdr.csum_flags = 0;
+
+ rc = ip_mforward_real(m, ifp);
+
+ m->m_pkthdr.csum_flags = csum_flags;
+
+ return rc;
+}
+
+static int
+ip_mforward_real(struct mbuf *m, struct ifnet *ifp)
+{
struct ip *ip = mtod(m, struct ip *);
struct mfc *rt;
static int srctun = 0;
@@ -1305,11 +1335,6 @@ ip_mforward(struct mbuf *m, struct ifnet
}
/*
- * Clear any in-bound checksum flags for this packet.
- */
- m->m_pkthdr.csum_flags = 0;
-
- /*
* Don't forward a packet with time-to-live of zero or one,
* or a packet destined to a local-only group.
*/