git: 605284b89474 - main - Enforce net epoch in in6_selectsrc().

Alexander V. Chernikov melifaro at FreeBSD.org
Mon Feb 15 22:33:30 UTC 2021


The branch main has been updated by melifaro:

URL: https://cgit.FreeBSD.org/src/commit/?id=605284b894748d23136b30a202689493d8f8af52

commit 605284b894748d23136b30a202689493d8f8af52
Author:     Alexander V. Chernikov <melifaro at FreeBSD.org>
AuthorDate: 2021-02-13 14:32:10 +0000
Commit:     Alexander V. Chernikov <melifaro at FreeBSD.org>
CommitDate: 2021-02-15 22:33:12 +0000

    Enforce net epoch in in6_selectsrc().
    
    in6_selectsrc() may call fib6_lookup() in some cases, which requires
     epoch. Wrap in6_selectsrc* calls into epoch inside its users.
    Mark it as requiring epoch by adding NET_EPOCH_ASSERT().
    
    MFC after:      1 weeek
    Differential Revision:  https://reviews.freebsd.org/D28647
---
 sys/fs/nfsclient/nfs_clport.c | 3 +++
 sys/netinet6/icmp6.c          | 3 +++
 sys/netinet6/in6_pcb.c        | 3 +++
 sys/netinet6/in6_src.c        | 1 +
 sys/netinet6/nd6_nbr.c        | 4 ++++
 sys/netinet6/raw_ip6.c        | 5 +++++
 sys/netinet6/send.c           | 3 +++
 7 files changed, 22 insertions(+)

diff --git a/sys/fs/nfsclient/nfs_clport.c b/sys/fs/nfsclient/nfs_clport.c
index 9c0ac5c4364e..81a0e05c3234 100644
--- a/sys/fs/nfsclient/nfs_clport.c
+++ b/sys/fs/nfsclient/nfs_clport.c
@@ -1006,15 +1006,18 @@ nfscl_getmyip(struct nfsmount *nmp, struct in6_addr *paddr, int *isinet6p)
 #endif
 #ifdef INET6
 	if (nmp->nm_nam->sa_family == AF_INET6) {
+		struct epoch_tracker et;
 		struct sockaddr_in6 *sin6;
 		int error;
 
 		sin6 = (struct sockaddr_in6 *)nmp->nm_nam;
 
+		NET_EPOCH_ENTER(et);
 		CURVNET_SET(CRED_TO_VNET(nmp->nm_sockreq.nr_cred));
 		error = in6_selectsrc_addr(fibnum, &sin6->sin6_addr,
 		    sin6->sin6_scope_id, NULL, paddr, NULL);
 		CURVNET_RESTORE();
+		NET_EPOCH_EXIT(et);
 		if (error != 0)
 			return (NULL);
 
diff --git a/sys/netinet6/icmp6.c b/sys/netinet6/icmp6.c
index 1a08dad7de64..6208b7be78a2 100644
--- a/sys/netinet6/icmp6.c
+++ b/sys/netinet6/icmp6.c
@@ -260,6 +260,7 @@ icmp6_error(struct mbuf *m, int type, int code, int param)
 {
 	struct ip6_hdr *oip6, *nip6;
 	struct icmp6_hdr *icmp6;
+	struct epoch_tracker et;
 	u_int preplen;
 	int off;
 	int nxt;
@@ -379,7 +380,9 @@ icmp6_error(struct mbuf *m, int type, int code, int param)
 	icmp6->icmp6_pptr = htonl((u_int32_t)param);
 
 	ICMP6STAT_INC(icp6s_outhist[type]);
+	NET_EPOCH_ENTER(et);
 	icmp6_reflect(m, sizeof(struct ip6_hdr)); /* header order: IPv6 - ICMPv6 */
+	NET_EPOCH_EXIT(et);
 
 	return;
 
diff --git a/sys/netinet6/in6_pcb.c b/sys/netinet6/in6_pcb.c
index 567a7918f159..5fce9fcafa33 100644
--- a/sys/netinet6/in6_pcb.c
+++ b/sys/netinet6/in6_pcb.c
@@ -352,6 +352,7 @@ in6_pcbladdr(struct inpcb *inp, struct sockaddr *nam,
 	int error = 0;
 	int scope_ambiguous = 0;
 	struct in6_addr in6a;
+	struct epoch_tracker et;
 
 	INP_WLOCK_ASSERT(inp);
 	INP_HASH_WLOCK_ASSERT(inp->inp_pcbinfo);	/* XXXRW: why? */
@@ -379,8 +380,10 @@ in6_pcbladdr(struct inpcb *inp, struct sockaddr *nam,
 	if ((error = prison_remote_ip6(inp->inp_cred, &sin6->sin6_addr)) != 0)
 		return (error);
 
+	NET_EPOCH_ENTER(et);
 	error = in6_selectsrc_socket(sin6, inp->in6p_outputopts,
 	    inp, inp->inp_cred, scope_ambiguous, &in6a, NULL);
+	NET_EPOCH_EXIT(et);
 	if (error)
 		return (error);
 
diff --git a/sys/netinet6/in6_src.c b/sys/netinet6/in6_src.c
index 7a756030f01c..2224d568e121 100644
--- a/sys/netinet6/in6_src.c
+++ b/sys/netinet6/in6_src.c
@@ -191,6 +191,7 @@ in6_selectsrc(uint32_t fibnum, struct sockaddr_in6 *dstsock,
 	int error;
 	struct ip6_moptions *mopts;
 
+	NET_EPOCH_ASSERT();
 	KASSERT(srcp != NULL, ("%s: srcp is NULL", __func__));
 
 	dst = dstsock->sin6_addr; /* make a copy for local operation */
diff --git a/sys/netinet6/nd6_nbr.c b/sys/netinet6/nd6_nbr.c
index ab55c4dfc697..42e901bdd2a4 100644
--- a/sys/netinet6/nd6_nbr.c
+++ b/sys/netinet6/nd6_nbr.c
@@ -413,6 +413,8 @@ nd6_ns_output_fib(struct ifnet *ifp, const struct in6_addr *saddr6,
 	int maxlen;
 	caddr_t mac;
 
+	NET_EPOCH_ASSERT();
+
 	if (IN6_IS_ADDR_MULTICAST(taddr6))
 		return;
 
@@ -947,6 +949,8 @@ nd6_na_output_fib(struct ifnet *ifp, const struct in6_addr *daddr6_0,
 	struct in6_addr daddr6, dst6, src6;
 	uint32_t scopeid;
 
+	NET_EPOCH_ASSERT();
+
 	int icmp6len, maxlen, error;
 	caddr_t mac = NULL;
 
diff --git a/sys/netinet6/raw_ip6.c b/sys/netinet6/raw_ip6.c
index aea99add4391..8d71c40455a1 100644
--- a/sys/netinet6/raw_ip6.c
+++ b/sys/netinet6/raw_ip6.c
@@ -478,8 +478,10 @@ rip6_output(struct mbuf *m, struct socket *so, ...)
 	/*
 	 * Source address selection.
 	 */
+	NET_EPOCH_ENTER(et);
 	error = in6_selectsrc_socket(dstsock, optp, inp, so->so_cred,
 	    scope_ambiguous, &in6a, &hlim);
+	NET_EPOCH_EXIT(et);
 
 	if (error)
 		goto bad;
@@ -795,6 +797,7 @@ rip6_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
 	struct inpcb *inp;
 	struct sockaddr_in6 *addr = (struct sockaddr_in6 *)nam;
 	struct in6_addr in6a;
+	struct epoch_tracker et;
 	int error = 0, scope_ambiguous = 0;
 
 	inp = sotoinpcb(so);
@@ -823,8 +826,10 @@ rip6_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
 	INP_INFO_WLOCK(&V_ripcbinfo);
 	INP_WLOCK(inp);
 	/* Source address selection. XXX: need pcblookup? */
+	NET_EPOCH_ENTER(et);
 	error = in6_selectsrc_socket(addr, inp->in6p_outputopts,
 	    inp, so->so_cred, scope_ambiguous, &in6a, NULL);
+	NET_EPOCH_EXIT(et);
 	if (error) {
 		INP_WUNLOCK(inp);
 		INP_INFO_WUNLOCK(&V_ripcbinfo);
diff --git a/sys/netinet6/send.c b/sys/netinet6/send.c
index bc9880c82267..fbe53924c91f 100644
--- a/sys/netinet6/send.c
+++ b/sys/netinet6/send.c
@@ -115,6 +115,7 @@ send_output(struct mbuf *m, struct ifnet *ifp, int direction)
 	struct ip6_hdr *ip6;
 	struct sockaddr_in6 dst;
 	struct icmp6_hdr *icmp6;
+	struct epoch_tracker et;
 	int icmp6len;
 
 	/*
@@ -150,7 +151,9 @@ send_output(struct mbuf *m, struct ifnet *ifp, int direction)
 		 */
 		switch (icmp6->icmp6_type) {
 		case ND_NEIGHBOR_SOLICIT:
+			NET_EPOCH_ENTER(et);
 			nd6_ns_input(m, sizeof(struct ip6_hdr), icmp6len);
+			NET_EPOCH_EXIT(et);
 			break;
 		case ND_NEIGHBOR_ADVERT:
 			nd6_na_input(m, sizeof(struct ip6_hdr), icmp6len);


More information about the dev-commits-src-main mailing list