git: 01a95394abfd - main - icmp: Limit routing table updates to the FIB of the redirect

From: Mark Johnston <markj_at_FreeBSD.org>
Date: Thu, 17 Sep 2026 13:18:39 UTC
The branch main has been updated by markj:

URL: https://cgit.FreeBSD.org/src/commit/?id=01a95394abfdef2adb3216e74d88b9c33321260e

commit 01a95394abfdef2adb3216e74d88b9c33321260e
Author:     Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2026-09-17 13:14:49 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2026-09-17 13:17:49 +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
---
 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 fd1a3cd24c8f..ef7b931e1d93 100644
--- a/sys/netinet/ip_icmp.c
+++ b/sys/netinet/ip_icmp.c
@@ -463,7 +463,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();
 
@@ -729,12 +728,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 e92a433c21b1..4cb00603e6b0 100644
--- a/sys/netinet6/icmp6.c
+++ b/sys/netinet6/icmp6.c
@@ -2328,7 +2328,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));
@@ -2347,10 +2346,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: