git: e0b405003a2a - main - raw ip6: merge rip6_output() into rip6_send()

From: Gleb Smirnoff <glebius_at_FreeBSD.org>
Date: Thu, 11 Aug 2022 16:20:18 UTC
The branch main has been updated by glebius:

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

commit e0b405003a2adb9f0b065a20eed7fc751001af36
Author:     Gleb Smirnoff <glebius@FreeBSD.org>
AuthorDate: 2022-08-11 16:19:37 +0000
Commit:     Gleb Smirnoff <glebius@FreeBSD.org>
CommitDate: 2022-08-11 16:19:37 +0000

    raw ip6: merge rip6_output() into rip6_send()
    
    While here remove some code that was compat legacy back in 2005, added
    in a1f7e5f8ee7fe.
    
    Reviewed by:            melifaro
    Differential revision:  https://reviews.freebsd.org/D36128
---
 sys/netinet6/ip6_var.h |   1 -
 sys/netinet6/raw_ip6.c | 124 +++++++++++++++++++------------------------------
 2 files changed, 48 insertions(+), 77 deletions(-)

diff --git a/sys/netinet6/ip6_var.h b/sys/netinet6/ip6_var.h
index 76aa304288bf..9717230fb160 100644
--- a/sys/netinet6/ip6_var.h
+++ b/sys/netinet6/ip6_var.h
@@ -402,7 +402,6 @@ void	rip6_init(void);
 int	rip6_input(struct mbuf **, int *, int);
 void	rip6_ctlinput(int, struct sockaddr *, void *);
 int	rip6_ctloutput(struct socket *, struct sockopt *);
-int	rip6_output(struct mbuf *, struct socket *, ...);
 int	rip6_usrreq(struct socket *,
 	    int, struct mbuf *, struct mbuf *, struct mbuf *, struct thread *);
 
diff --git a/sys/netinet6/raw_ip6.c b/sys/netinet6/raw_ip6.c
index ab0b6771fe99..678121b0ca32 100644
--- a/sys/netinet6/raw_ip6.c
+++ b/sys/netinet6/raw_ip6.c
@@ -364,32 +364,62 @@ rip6_ctlinput(int cmd, struct sockaddr *sa, void *d)
  * Generate IPv6 header and pass packet to ip6_output.  Tack on options user
  * may have setup with control call.
  */
-int
-rip6_output(struct mbuf *m, struct socket *so, ...)
+static int
+rip6_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam,
+    struct mbuf *control, struct thread *td)
 {
 	struct epoch_tracker et;
-	struct mbuf *control;
+	struct inpcb *inp;
+	struct sockaddr_in6 tmp, *dstsock;
 	struct m_tag *mtag;
-	struct sockaddr_in6 *dstsock;
 	struct ip6_hdr *ip6;
-	struct inpcb *inp;
 	u_int	plen = m->m_pkthdr.len;
-	int error = 0;
 	struct ip6_pktopts opt, *optp;
 	struct ifnet *oifp = NULL;
+	int error;
 	int type = 0, code = 0;		/* for ICMPv6 output statistics only */
 	int scope_ambiguous = 0;
 	int use_defzone = 0;
 	int hlim = 0;
 	struct in6_addr in6a;
-	va_list ap;
-
-	va_start(ap, so);
-	dstsock = va_arg(ap, struct sockaddr_in6 *);
-	control = va_arg(ap, struct mbuf *);
-	va_end(ap);
 
 	inp = sotoinpcb(so);
+	KASSERT(inp != NULL, ("rip6_send: inp == NULL"));
+
+	/* Always copy sockaddr to avoid overwrites. */
+	/* Unlocked read. */
+	if (so->so_state & SS_ISCONNECTED) {
+		if (nam) {
+			error = EISCONN;
+			goto release;
+		}
+		tmp = (struct sockaddr_in6 ){
+			.sin6_family = AF_INET6,
+			.sin6_len = sizeof(struct sockaddr_in6),
+		};
+		INP_RLOCK(inp);
+		bcopy(&inp->in6p_faddr, &tmp.sin6_addr,
+		    sizeof(struct in6_addr));
+		INP_RUNLOCK(inp);
+		dstsock = &tmp;
+	} else {
+		if (nam == NULL)
+			error = ENOTCONN;
+		else if (nam->sa_family != AF_INET6)
+			error = EAFNOSUPPORT;
+		else if (nam->sa_len != sizeof(struct sockaddr_in6))
+			error = EINVAL;
+		else
+			error = 0;
+		if (error != 0)
+			goto release;
+		dstsock = (struct sockaddr_in6 *)nam;
+		if (dstsock->sin6_family != AF_INET6) {
+			error = EAFNOSUPPORT;
+			goto release;
+		}
+	}
+
 	INP_WLOCK(inp);
 
 	if (control != NULL) {
@@ -555,6 +585,12 @@ rip6_output(struct mbuf *m, struct socket *so, ...)
 	}
 	INP_WUNLOCK(inp);
 	return (error);
+
+release:
+	if (control != NULL)
+		m_freem(control);
+	m_freem(m);
+	return (error);
 }
 
 /*
@@ -833,70 +869,6 @@ rip6_shutdown(struct socket *so)
 	return (0);
 }
 
-static int
-rip6_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam,
-    struct mbuf *control, struct thread *td)
-{
-	struct inpcb *inp;
-	struct sockaddr_in6 tmp;
-	struct sockaddr_in6 *dst;
-	int error;
-
-	inp = sotoinpcb(so);
-	KASSERT(inp != NULL, ("rip6_send: inp == NULL"));
-
-	/* Always copy sockaddr to avoid overwrites. */
-	/* Unlocked read. */
-	if (so->so_state & SS_ISCONNECTED) {
-		if (nam) {
-			error = EISCONN;
-			goto release;
-		}
-		/* XXX */
-		bzero(&tmp, sizeof(tmp));
-		tmp.sin6_family = AF_INET6;
-		tmp.sin6_len = sizeof(struct sockaddr_in6);
-		INP_RLOCK(inp);
-		bcopy(&inp->in6p_faddr, &tmp.sin6_addr,
-		    sizeof(struct in6_addr));
-		INP_RUNLOCK(inp);
-		dst = &tmp;
-	} else {
-		error = 0;
-		if (nam == NULL)
-			error = ENOTCONN;
-		else if (nam->sa_family != AF_INET6)
-			error = EAFNOSUPPORT;
-		else if (nam->sa_len != sizeof(struct sockaddr_in6))
-			error = EINVAL;
-		if (error != 0)
-			goto release;
-		tmp = *(struct sockaddr_in6 *)nam;
-		dst = &tmp;
-
-		if (dst->sin6_family == AF_UNSPEC) {
-			/*
-			 * XXX: we allow this case for backward
-			 * compatibility to buggy applications that
-			 * rely on old (and wrong) kernel behavior.
-			 */
-			log(LOG_INFO, "rip6 SEND: address family is "
-			    "unspec. Assume AF_INET6\n");
-			dst->sin6_family = AF_INET6;
-		} else if (dst->sin6_family != AF_INET6) {
-			error = EAFNOSUPPORT;
-			goto release;
-		}
-	}
-	return (rip6_output(m, so, dst, control));
-
-release:
-	if (control != NULL)
-		m_freem(control);
-	m_freem(m);
-	return (error);
-}
-
 struct pr_usrreqs rip6_usrreqs = {
 	.pru_abort =		rip6_abort,
 	.pru_attach =		rip6_attach,