git: 240680dfd4e2 - stable/14 - icmp: Limit routing table updates to the FIB of the redirect

From: Mark Johnston <markj_at_FreeBSD.org>
Date: Mon, 26 Oct 2026 19:46:55 UTC
The branch stable/14 has been updated by markj:

URL: https://cgit.FreeBSD.org/src/commit/?id=240680dfd4e2cbbe9737eb78d43db30c7ca8ef38

commit 240680dfd4e2cbbe9737eb78d43db30c7ca8ef38
Author:     Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2026-09-17 13:14:49 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2026-10-26 14:12:15 +0000

    icmp: Limit routing table updates to the FIB of the redirect
    
    When we receive an ICMP redirect, rib_add_redirect() is used to apply
    the redirect to all FIBs.  This has been the case since support for
    multiple FIBs was added.  However, it seems rather dubious: the new
    gateway might not be routable from all FIBs, and the validation done for
    v4 redirects in icmp_verify_redirect_gateway() is only applied to the
    FIB from which the redirect originated.
    
    Modify the handler to apply the redirect only in the originating FIB.
    
    Reported by:    Yuxiang Yang, Yizhou Zhao, Ao Wang, Xuewei Feng, Qi Li,
                    and Ke Xu from Tsinghua University using GLM-5.1 from Z.ai
    Reviewed by:    pouria, zlei, glebius, melifaro
    MFC after:      3 weeks
    Sponsored by:   The FreeBSD Foundation
    Differential Revision:  https://reviews.freebsd.org/D59567
    
    (cherry picked from commit 01a95394abfdef2adb3216e74d88b9c33321260e)
---
 sys/netinet/ip_icmp.c | 11 ++++-------
 sys/netinet6/icmp6.c  |  8 +++-----
 2 files changed, 7 insertions(+), 12 deletions(-)

diff --git a/sys/netinet/ip_icmp.c b/sys/netinet/ip_icmp.c
index 29ce294fefd2..14a0c67c5bbe 100644
--- a/sys/netinet/ip_icmp.c
+++ b/sys/netinet/ip_icmp.c
@@ -466,7 +466,6 @@ icmp_input(struct mbuf **mp, int *offp, int proto)
 	int hlen = *offp;
 	int icmplen = ntohs(ip->ip_len) - *offp;
 	int i, code;
-	int fibnum;
 
 	NET_EPOCH_ASSERT();
 
@@ -737,12 +736,10 @@ reflect:
 			break;
 		}
 
-		for ( fibnum = 0; fibnum < rt_numfibs; fibnum++) {
-			rib_add_redirect(fibnum, (struct sockaddr *)&icmpsrc,
-			    (struct sockaddr *)&icmpdst,
-			    (struct sockaddr *)&icmpgw, m->m_pkthdr.rcvif,
-			    RTF_GATEWAY, V_redirtimeout);
-		}
+		rib_add_redirect(M_GETFIB(m), (struct sockaddr *)&icmpsrc,
+		    (struct sockaddr *)&icmpdst,
+		    (struct sockaddr *)&icmpgw, m->m_pkthdr.rcvif,
+		    RTF_GATEWAY, V_redirtimeout);
 		break;
 
 	/*
diff --git a/sys/netinet6/icmp6.c b/sys/netinet6/icmp6.c
index 3fe0bec536e8..09eb49769dcb 100644
--- a/sys/netinet6/icmp6.c
+++ b/sys/netinet6/icmp6.c
@@ -2356,7 +2356,6 @@ icmp6_redirect_input(struct mbuf *m, int off)
 		struct sockaddr_in6 ssrc;
 		struct sockaddr *gw;
 		int rt_flags;
-		u_int fibnum;
 
 		bzero(&sdst, sizeof(sdst));
 		bzero(&ssrc, sizeof(ssrc));
@@ -2375,10 +2374,9 @@ icmp6_redirect_input(struct mbuf *m, int off)
 			rt_flags |= RTF_GATEWAY;
 		} else
 			gw = ifp->if_addr->ifa_addr;
-		for (fibnum = 0; fibnum < rt_numfibs; fibnum++)
-			rib_add_redirect(fibnum, (struct sockaddr *)&sdst, gw,
-			    (struct sockaddr *)&ssrc, ifp, rt_flags,
-			    V_icmp6_redirtimeout);
+		rib_add_redirect(M_GETFIB(m), (struct sockaddr *)&sdst, gw,
+		    (struct sockaddr *)&ssrc, ifp, rt_flags,
+		    V_icmp6_redirtimeout);
 	}
 
  freeit: