The branch main has been updated by markj:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=196874ce2e97e3e6425493b1d501e716b356bc36

commit 196874ce2e97e3e6425493b1d501e716b356bc36
Author:     Mark Johnston <[email protected]>
AuthorDate: 2026-08-04 13:35:35 +0000
Commit:     Mark Johnston <[email protected]>
CommitDate: 2026-08-05 13:09:08 +0000

    rawip: Fix handling of checksums in rip6_input()
    
    A v6 raw socket may ask the kernel to validate the checksum of an
    inbound packet.  If it does, and the validation fails, we discard the
    packet, but this isn't really right: other raw sockets may wish to
    receive a copy of the packet anyway.
    
    Rework checksum handling to address this problem, and use a flag to
    avoid computing the checksum more than once for a given packet.
    
    Fixes:          de2d47842e880281 ("SMR protection for inpcbs")
    Reviewed by:    pouria, glebius
    Reported by:    Yunzhi Ke
    MFC after:      1 week
    Sponsored by:   The FreeBSD Foundation
    Differential Revision:  https://reviews.freebsd.org/D58559
---
 sys/netinet6/raw_ip6.c | 26 +++++++++++++++-----------
 1 file changed, 15 insertions(+), 11 deletions(-)

diff --git a/sys/netinet6/raw_ip6.c b/sys/netinet6/raw_ip6.c
index 8c503f70af0f..dcf3db251629 100644
--- a/sys/netinet6/raw_ip6.c
+++ b/sys/netinet6/raw_ip6.c
@@ -190,7 +190,8 @@ rip6_input(struct mbuf **mp, int *offp, int proto)
        struct rip6_inp_match_ctx ctx = { .ip6 = ip6, .proto = proto };
        struct inpcb_iterator inpi = INP_ITERATOR(&V_ripcbinfo,
            INPLOOKUP_RLOCKPCB, rip6_inp_match, &ctx);
-       int delivered = 0, fib;
+       int cksum, delivered = 0, fib;
+       bool cksum_computed = false;
 
        M_ASSERTPKTHDR(m);
        NET_EPOCH_ASSERT();
@@ -230,19 +231,22 @@ rip6_input(struct mbuf **mp, int *offp, int proto)
                         */
                        continue;
                if (inp->in6p_cksum != -1) {
-                       RIP6STAT_INC(rip6s_isum);
-                       if (m->m_pkthdr.len - (*offp + inp->in6p_cksum) < 2 ||
-                           in6_cksum(m, proto, *offp,
-                           m->m_pkthdr.len - *offp)) {
-                               RIP6STAT_INC(rip6s_badsum);
+                       if (m->m_pkthdr.len - (*offp + inp->in6p_cksum) < 2)
+                               continue;
+                       if (!cksum_computed) {
+                               cksum = in6_cksum(m, proto, *offp,
+                                   m->m_pkthdr.len - *offp);
+                               cksum_computed = true;
+                               RIP6STAT_INC(rip6s_isum);
+                               if (cksum != 0)
+                                       RIP6STAT_INC(rip6s_badsum);
+                       }
+                       if (cksum != 0) {
                                /*
-                                * Drop the received message, don't send an
-                                * ICMP6 message. Set proto to IPPROTO_NONE
-                                * to achieve that.
+                                * Drop the packet, don't send an ICMP6 message.
                                 */
-                               INP_RUNLOCK(inp);
                                proto = IPPROTO_NONE;
-                               break;
+                               continue;
                        }
                }
                /*

Reply via email to