From 4794d48d5e9a5f90324c105094e45544d2a1b6a7 Mon Sep 17 00:00:00 2001 From: kardel Date: Thu, 12 Nov 2020 13:13:45 +0000 Subject: [PATCH] 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 --- sys/netinet/ip_mroute.c | 39 ++++++++++++++++++++++++++++++++------- 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/sys/netinet/ip_mroute.c b/sys/netinet/ip_mroute.c index 78c10978cd2b..33237440f63e 100644 --- a/sys/netinet/ip_mroute.c +++ b/sys/netinet/ip_mroute.c @@ -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 -__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 *, struct ip *); 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 @@ -1267,6 +1269,34 @@ socket_send(struct socket *s, struct mbuf *mm, struct sockaddr_in *src) 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; @@ -1304,11 +1334,6 @@ ip_mforward(struct mbuf *m, struct ifnet *ifp) return EOPNOTSUPP; } - /* - * 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.