git: 2cf1e120c654 - main - Enter epoch when addding IPv4 multicast forwarding cache entry

From: Mike Karels <karels_at_FreeBSD.org>
Date: Tue, 22 Mar 2022 12:41:14 UTC
The branch main has been updated by karels:

URL: https://cgit.FreeBSD.org/src/commit/?id=2cf1e120c654df5d02b115dd8dc278dcfcb4a80d

commit 2cf1e120c654df5d02b115dd8dc278dcfcb4a80d
Author:     Mike Karels <karels@FreeBSD.org>
AuthorDate: 2022-03-21 14:50:08 +0000
Commit:     Mike Karels <karels@FreeBSD.org>
CommitDate: 2022-03-22 12:28:57 +0000

    Enter epoch when addding IPv4 multicast forwarding cache entry
    
    The code path from the IPv4 multicast setsockopt could call ip_output()
    without entering an epoch.  Specifically, the MRT_ADD_MFC setbsocopt
    would call add_mfc(), which in turn called ip_mdq() to send queued
    packets.  This resulted in an epoch assert failure in ip_output().
    Enter an epoch in add_mfc(), and add some epoch asserts to check
    for similar failures.
    
    Reviewed by:    kp, bz, wma, cy
    Differential Revision: https://reviews.freebsd.org/D34624
---
 sys/netinet/ip_mroute.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/sys/netinet/ip_mroute.c b/sys/netinet/ip_mroute.c
index 99ec2952de88..e6acfd4dcfc7 100644
--- a/sys/netinet/ip_mroute.c
+++ b/sys/netinet/ip_mroute.c
@@ -1124,6 +1124,7 @@ add_mfc(struct mfcctl2 *mfccp)
     struct rtdetq *rte;
     u_long hash = 0;
     u_short nstl;
+    struct epoch_tracker et;
 
     MRW_WLOCK();
     rt = mfc_find(&mfccp->mfcc_origin, &mfccp->mfcc_mcastgrp);
@@ -1144,6 +1145,7 @@ add_mfc(struct mfcctl2 *mfccp)
      */
     nstl = 0;
     hash = MFCHASH(mfccp->mfcc_origin, mfccp->mfcc_mcastgrp);
+    NET_EPOCH_ENTER(et);
     LIST_FOREACH(rt, &V_mfchashtbl[hash], mfc_hash) {
 	if (in_hosteq(rt->mfc_origin, mfccp->mfcc_origin) &&
 	    in_hosteq(rt->mfc_mcastgrp, mfccp->mfcc_mcastgrp) &&
@@ -1171,6 +1173,7 @@ add_mfc(struct mfcctl2 *mfccp)
 		}
 	}
     }
+    NET_EPOCH_EXIT(et);
 
     /*
      * It is possible that an entry is being inserted without an upcall
@@ -1548,6 +1551,7 @@ ip_mdq(struct mbuf *m, struct ifnet *ifp, struct mfc *rt, vifi_t xmt_vif)
     int plen = ntohs(ip->ip_len);
 
     MRW_LOCK_ASSERT();
+    NET_EPOCH_ASSERT();
 
     /*
      * If xmt_vif is not -1, send on only the requested vif.
@@ -1752,6 +1756,7 @@ send_packet(struct vif *vifp, struct mbuf *m)
 	int error __unused;
 
 	MRW_LOCK_ASSERT();
+	NET_EPOCH_ASSERT();
 
 	imo.imo_multicast_ifp  = vifp->v_ifp;
 	imo.imo_multicast_ttl  = mtod(m, struct ip *)->ip_ttl - 1;