git: 20dbc462b200 - stable/15 - icmp: Limit routing table updates to the FIB of the redirect

From: Mark Johnston <markj_at_FreeBSD.org>
Date: Thu, 22 Oct 2026 17:32:03 UTC
The branch stable/15 has been updated by markj:

URL: https://cgit.FreeBSD.org/src/commit/?id=20dbc462b200c2d1582c37527a5e42ae43dd8e2a

commit 20dbc462b200c2d1582c37527a5e42ae43dd8e2a
Author:     Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2026-09-17 13:14:49 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2026-10-22 15:45:41 +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 fc0848b2c944..2d769f1d7f9b 100644
--- a/sys/netinet/ip_icmp.c
+++ b/sys/netinet/ip_icmp.c
@@ -464,7 +464,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();
 
@@ -730,12 +729,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 9f2e44f3f6e0..ec2e5a22aa33 100644
--- a/sys/netinet6/icmp6.c
+++ b/sys/netinet6/icmp6.c
@@ -2326,7 +2326,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));
@@ -2345,10 +2344,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: