git: 43d39ca7e518 - main - netinet*: de-void control input IP protocol methods

From: Gleb Smirnoff <glebius_at_FreeBSD.org>
Date: Tue, 04 Oct 2022 03:57:31 UTC
The branch main has been updated by glebius:

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

commit 43d39ca7e5180d4a04ae50996a542f69b4609402
Author:     Gleb Smirnoff <glebius@FreeBSD.org>
AuthorDate: 2022-10-04 03:53:04 +0000
Commit:     Gleb Smirnoff <glebius@FreeBSD.org>
CommitDate: 2022-10-04 03:53:04 +0000

    netinet*: de-void control input IP protocol methods
    
    After decoupling of protosw(9) and IP wire protocols in 78b1fc05b205 for
    IPv4 we got vector ip_ctlprotox[] that is executed only and only from
    icmp_input() and respectively for IPv6 we got ip6_ctlprotox[] executed
    only and only from icmp6_input().  This allows to use protocol specific
    argument types in these methods instead of struct sockaddr and void.
    
    Reviewed by:            melifaro
    Differential revision:  https://reviews.freebsd.org/D36727
---
 sys/netinet/ip_icmp.c       |  4 +--
 sys/netinet/ip_var.h        |  7 ++---
 sys/netinet/raw_ip.c        |  4 +--
 sys/netinet/sctp_usrreq.c   | 11 ++++----
 sys/netinet/sctp_var.h      |  2 +-
 sys/netinet/tcp_subr.c      | 64 ++++++++++++++++++++++-----------------------
 sys/netinet/tcp_var.h       |  2 --
 sys/netinet/udp_usrreq.c    | 26 +++++++++---------
 sys/netinet6/icmp6.c        |  5 ++--
 sys/netinet6/in6_pcb.c      | 14 +++++-----
 sys/netinet6/in6_pcb.h      |  4 +--
 sys/netinet6/ip6_var.h      |  9 ++++---
 sys/netinet6/raw_ip6.c      | 19 +++++---------
 sys/netinet6/sctp6_usrreq.c | 16 ++----------
 sys/netinet6/sctp6_var.h    |  2 +-
 sys/netinet6/tcp6_var.h     |  6 -----
 sys/netinet6/udp6_usrreq.c  | 39 ++++++++++++---------------
 sys/netinet6/udp6_var.h     |  4 ---
 18 files changed, 98 insertions(+), 140 deletions(-)

diff --git a/sys/netinet/ip_icmp.c b/sys/netinet/ip_icmp.c
index 1cc8d7c09391..709f920106cc 100644
--- a/sys/netinet/ip_icmp.c
+++ b/sys/netinet/ip_icmp.c
@@ -573,8 +573,8 @@ icmp_input(struct mbuf **mp, int *offp, int proto)
 		 *   ICMP_ADVLENPREF. See its definition in ip_icmp.h.
 		 */
 		if (ip_ctlprotox[icp->icmp_ip.ip_p] != NULL)
-			ip_ctlprotox[icp->icmp_ip.ip_p](code,
-			    (struct sockaddr *)&icmpsrc, &icp->icmp_ip);
+			ip_ctlprotox[icp->icmp_ip.ip_p](code, &icmpsrc,
+			    &icp->icmp_ip);
 		break;
 
 	badcode:
diff --git a/sys/netinet/ip_var.h b/sys/netinet/ip_var.h
index 70afa5e1bce8..070c82677150 100644
--- a/sys/netinet/ip_var.h
+++ b/sys/netinet/ip_var.h
@@ -228,8 +228,6 @@ void	ip_savecontrol(struct inpcb *, struct mbuf **, struct ip *,
 	    struct mbuf *);
 void	ip_fillid(struct ip *);
 int	rip_ctloutput(struct socket *, struct sockopt *);
-void	rip_ctlinput(int, struct sockaddr *, void *);
-int	rip_input(struct mbuf **, int *, int);
 int	ipip_input(struct mbuf **, int *, int);
 int	rsvp_input(struct mbuf **, int *, int);
 
@@ -240,7 +238,7 @@ extern void	(*ip_rsvp_force_done)(struct socket *);
 extern int	(*rsvp_input_p)(struct mbuf **, int *, int);
 
 typedef int	ipproto_input_t(struct mbuf **, int *, int);
-typedef void	ipproto_ctlinput_t(int, struct sockaddr *, void *);
+typedef void	ipproto_ctlinput_t(int, struct sockaddr_in *, struct ip *);
 int	ipproto_register(uint8_t, ipproto_input_t, ipproto_ctlinput_t);
 int	ipproto_unregister(uint8_t);
 #define	IPPROTO_REGISTER(prot, input, ctl)	do {			\
@@ -249,6 +247,9 @@ int	ipproto_unregister(uint8_t);
 	MPASS(error == 0);						\
 } while (0)
 
+ipproto_input_t		rip_input;
+ipproto_ctlinput_t	rip_ctlinput;
+
 VNET_DECLARE(struct pfil_head *, inet_pfil_head);
 #define	V_inet_pfil_head	VNET(inet_pfil_head)
 #define	PFIL_INET_NAME		"inet"
diff --git a/sys/netinet/raw_ip.c b/sys/netinet/raw_ip.c
index fb5628324020..fb692e0822cf 100644
--- a/sys/netinet/raw_ip.c
+++ b/sys/netinet/raw_ip.c
@@ -804,14 +804,14 @@ rip_ctloutput(struct socket *so, struct sockopt *sopt)
 }
 
 void
-rip_ctlinput(int cmd, struct sockaddr *sa, void *vip)
+rip_ctlinput(int cmd, struct sockaddr_in *sin, struct ip *ip)
 {
 
 	switch (cmd) {
 #if defined(IPSEC) || defined(IPSEC_SUPPORT)
 	case PRC_MSGSIZE:
 		if (IPSEC_ENABLED(ipv4))
-			IPSEC_CTLINPUT(ipv4, cmd, sa, vip);
+			IPSEC_CTLINPUT(ipv4, cmd, (struct sockaddr *)sin, ip);
 		break;
 #endif
 	}
diff --git a/sys/netinet/sctp_usrreq.c b/sys/netinet/sctp_usrreq.c
index 58a9d610b003..e5ddac897d47 100644
--- a/sys/netinet/sctp_usrreq.c
+++ b/sys/netinet/sctp_usrreq.c
@@ -260,7 +260,7 @@ sctp_notify(struct sctp_inpcb *inp,
 }
 
 void
-sctp_ctlinput(int cmd, struct sockaddr *sa, void *vip)
+sctp_ctlinput(int cmd, struct sockaddr_in *sin, struct ip *ip)
 {
 	struct ip *outer_ip;
 	struct ip *inner_ip;
@@ -272,17 +272,16 @@ sctp_ctlinput(int cmd, struct sockaddr *sa, void *vip)
 	struct sctp_init_chunk *ch;
 	struct sockaddr_in src, dst;
 
-	if (sa->sa_family != AF_INET ||
-	    ((struct sockaddr_in *)sa)->sin_addr.s_addr == INADDR_ANY) {
+	if (sin->sin_addr.s_addr == INADDR_ANY) {
 		return;
 	}
 	if (PRC_IS_REDIRECT(cmd)) {
-		vip = NULL;
+		ip = NULL;
 	} else if ((unsigned)cmd >= PRC_NCMDS || inetctlerrmap[cmd] == 0) {
 		return;
 	}
-	if (vip != NULL) {
-		inner_ip = (struct ip *)vip;
+	if (ip != NULL) {
+		inner_ip = ip;
 		icmp = (struct icmp *)((caddr_t)inner_ip -
 		    (sizeof(struct icmp) - sizeof(struct ip)));
 		outer_ip = (struct ip *)((caddr_t)icmp - sizeof(struct ip));
diff --git a/sys/netinet/sctp_var.h b/sys/netinet/sctp_var.h
index 3675ba4443a4..77516db37773 100644
--- a/sys/netinet/sctp_var.h
+++ b/sys/netinet/sctp_var.h
@@ -322,7 +322,7 @@ struct sctphdr;
 
 void sctp_close(struct socket *so);
 int sctp_disconnect(struct socket *so);
-void sctp_ctlinput(int, struct sockaddr *, void *);
+void sctp_ctlinput(int, struct sockaddr_in *, struct ip *);
 int sctp_ctloutput(struct socket *, struct sockopt *);
 void sctp_input_with_port(struct mbuf *, int, uint16_t);
 int sctp_input(struct mbuf **, int *, int);
diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c
index b9c5be5592f5..0b02f9b66651 100644
--- a/sys/netinet/tcp_subr.c
+++ b/sys/netinet/tcp_subr.c
@@ -109,9 +109,6 @@ __FBSDID("$FreeBSD$");
 #include <netinet/tcp_syncache.h>
 #include <netinet/tcp_hpts.h>
 #include <netinet/cc/cc.h>
-#ifdef INET6
-#include <netinet6/tcp6_var.h>
-#endif
 #include <netinet/tcpip.h>
 #include <netinet/tcp_fastopen.h>
 #ifdef TCPPCAP
@@ -125,6 +122,9 @@ __FBSDID("$FreeBSD$");
 #endif
 #include <netinet/udp.h>
 #include <netinet/udp_var.h>
+#ifdef INET6
+#include <netinet6/tcp6_var.h>
+#endif
 
 #include <netipsec/ipsec_support.h>
 
@@ -133,6 +133,9 @@ __FBSDID("$FreeBSD$");
 
 #include <security/mac/mac_framework.h>
 
+static ip6proto_ctlinput_t tcp6_ctlinput;
+static udp_tun_icmp_t tcp6_ctlinput_viaudp;
+
 VNET_DEFINE(int, tcp_mssdflt) = TCP_MSS;
 #ifdef INET6
 VNET_DEFINE(int, tcp_v6mssdflt) = TCP6_MSS;
@@ -372,6 +375,8 @@ static struct inpcb *tcp_mtudisc_notify(struct inpcb *, int);
 static struct inpcb *tcp_mtudisc(struct inpcb *, int);
 static char *	tcp_log_addr(struct in_conninfo *inc, struct tcphdr *th,
 		    const void *ip4hdr, const void *ip6hdr);
+static ipproto_ctlinput_t	tcp_ctlinput;
+static udp_tun_icmp_t		tcp_ctlinput_viaudp;
 
 static struct tcp_function_block tcp_def_funcblk = {
 	.tfb_tcp_block_name = "freebsd",
@@ -2849,11 +2854,10 @@ tcp_next_pmtu(const struct icmp *icp, const struct ip *ip)
 }
 
 static void
-tcp_ctlinput_with_port(int cmd, struct sockaddr *sa, void *vip, uint16_t port)
+tcp_ctlinput_with_port(int cmd, struct sockaddr_in *sin, struct ip *ip,
+    uint16_t port)
 {
-	struct ip *ip = vip;
 	struct tcphdr *th;
-	struct in_addr faddr;
 	struct inpcb *inp;
 	struct tcpcb *tp;
 	struct inpcb *(*notify)(struct inpcb *, int) = tcp_notify;
@@ -2862,8 +2866,7 @@ tcp_ctlinput_with_port(int cmd, struct sockaddr *sa, void *vip, uint16_t port)
 	tcp_seq icmp_tcp_seq;
 	int mtu;
 
-	faddr = ((struct sockaddr_in *)sa)->sin_addr;
-	if (sa->sa_family != AF_INET || faddr.s_addr == INADDR_ANY)
+	if (sin->sin_addr.s_addr == INADDR_ANY)
 		return;
 
 	if (cmd == PRC_MSGSIZE)
@@ -2884,13 +2887,14 @@ tcp_ctlinput_with_port(int cmd, struct sockaddr *sa, void *vip, uint16_t port)
 		return;
 
 	if (ip == NULL) {
-		in_pcbnotifyall(&V_tcbinfo, faddr, inetctlerrmap[cmd], notify);
+		in_pcbnotifyall(&V_tcbinfo, sin->sin_addr, inetctlerrmap[cmd],
+		    notify);
 		return;
 	}
 
 	icp = (struct icmp *)((caddr_t)ip - offsetof(struct icmp, icmp_ip));
 	th = (struct tcphdr *)((caddr_t)ip + (ip->ip_hl << 2));
-	inp = in_pcblookup(&V_tcbinfo, faddr, th->th_dport, ip->ip_src,
+	inp = in_pcblookup(&V_tcbinfo, sin->sin_addr, th->th_dport, ip->ip_src,
 	    th->th_sport, INPLOOKUP_WLOCKPCB, NULL);
 	if (inp != NULL && PRC_IS_REDIRECT(cmd)) {
 		/* signal EHOSTDOWN, as it flushes the cached route */
@@ -2933,7 +2937,7 @@ tcp_ctlinput_with_port(int cmd, struct sockaddr *sa, void *vip, uint16_t port)
 					if (mtu < tp->t_maxseg +
 					    sizeof(struct tcpiphdr)) {
 						bzero(&inc, sizeof(inc));
-						inc.inc_faddr = faddr;
+						inc.inc_faddr = sin->sin_addr;
 						inc.inc_fibnum =
 						    inp->inp_inc.inc_fibnum;
 						tcp_hc_updatemtu(&inc, mtu);
@@ -2948,7 +2952,7 @@ tcp_ctlinput_with_port(int cmd, struct sockaddr *sa, void *vip, uint16_t port)
 		bzero(&inc, sizeof(inc));
 		inc.inc_fport = th->th_dport;
 		inc.inc_lport = th->th_sport;
-		inc.inc_faddr = faddr;
+		inc.inc_faddr = sin->sin_addr;
 		inc.inc_laddr = ip->ip_src;
 		syncache_unreach(&inc, icmp_tcp_seq, port);
 	}
@@ -2957,13 +2961,13 @@ out:
 		INP_WUNLOCK(inp);
 }
 
-void
-tcp_ctlinput(int cmd, struct sockaddr *sa, void *vip)
+static void
+tcp_ctlinput(int cmd, struct sockaddr_in *sin, struct ip *ip)
 {
-	tcp_ctlinput_with_port(cmd, sa, vip, htons(0));
+	tcp_ctlinput_with_port(cmd, sin, ip, htons(0));
 }
 
-void
+static void
 tcp_ctlinput_viaudp(int cmd, struct sockaddr *sa, void *vip, void *unused)
 {
 	/* Its a tunneled TCP over UDP icmp */
@@ -2998,7 +3002,7 @@ tcp_ctlinput_viaudp(int cmd, struct sockaddr *sa, void *vip, void *unused)
 	o_len -= sizeof(struct udphdr);
 	outer_ip->ip_len = htons(o_len);
 	/* Now call in to the normal handling code */
-	tcp_ctlinput_with_port(cmd, sa, vip, port);
+	tcp_ctlinput_with_port(cmd, (struct sockaddr_in *)sa, vip, port);
 }
 #endif /* INET */
 
@@ -3018,7 +3022,8 @@ tcp6_next_pmtu(const struct icmp6_hdr *icmp6)
 }
 
 static void
-tcp6_ctlinput_with_port(int cmd, struct sockaddr *sa, void *d, uint16_t port)
+tcp6_ctlinput_with_port(int cmd, struct sockaddr_in6 *sin6,
+    struct ip6ctlparam *ip6cp, uint16_t port)
 {
 	struct in6_addr *dst;
 	struct inpcb *(*notify)(struct inpcb *, int) = tcp_notify;
@@ -3027,7 +3032,6 @@ tcp6_ctlinput_with_port(int cmd, struct sockaddr *sa, void *d, uint16_t port)
 	struct inpcb *inp;
 	struct tcpcb *tp;
 	struct icmp6_hdr *icmp6;
-	struct ip6ctlparam *ip6cp = NULL;
 	const struct sockaddr_in6 *sa6_src = NULL;
 	struct in_conninfo inc;
 	struct tcp_ports {
@@ -3038,13 +3042,8 @@ tcp6_ctlinput_with_port(int cmd, struct sockaddr *sa, void *d, uint16_t port)
 	unsigned int mtu;
 	unsigned int off;
 
-	if (sa->sa_family != AF_INET6 ||
-	    sa->sa_len != sizeof(struct sockaddr_in6))
-		return;
-
 	/* if the parameter is from icmp6, decode it. */
-	if (d != NULL) {
-		ip6cp = (struct ip6ctlparam *)d;
+	if (ip6cp != NULL) {
 		icmp6 = ip6cp->ip6c_icmp6;
 		m = ip6cp->ip6c_m;
 		ip6 = ip6cp->ip6c_ip6;
@@ -3077,9 +3076,8 @@ tcp6_ctlinput_with_port(int cmd, struct sockaddr *sa, void *d, uint16_t port)
 		return;
 
 	if (ip6 == NULL) {
-		in6_pcbnotify(&V_tcbinfo, sa, 0,
-			      (const struct sockaddr *)sa6_src,
-			      0, cmd, NULL, notify);
+		in6_pcbnotify(&V_tcbinfo, sin6, 0, sa6_src, 0, cmd, NULL,
+		    notify);
 		return;
 	}
 
@@ -3168,13 +3166,13 @@ out:
 		INP_WUNLOCK(inp);
 }
 
-void
-tcp6_ctlinput(int cmd, struct sockaddr *sa, void *d)
+static void
+tcp6_ctlinput(int cmd, struct sockaddr_in6 *sin6, struct ip6ctlparam *ctl)
 {
-	tcp6_ctlinput_with_port(cmd, sa, d, htons(0));
+	tcp6_ctlinput_with_port(cmd, sin6, ctl, htons(0));
 }
 
-void
+static void
 tcp6_ctlinput_viaudp(int cmd, struct sockaddr *sa, void *d, void *unused)
 {
 	struct ip6ctlparam *ip6cp;
@@ -3197,7 +3195,7 @@ tcp6_ctlinput_viaudp(int cmd, struct sockaddr *sa, void *d, void *unused)
 		ip6cp->ip6c_m->m_pkthdr.len -= sizeof(struct udphdr);
 	}
 	/* Now call in to the normal handling code */
-	tcp6_ctlinput_with_port(cmd, sa, d, port);
+	tcp6_ctlinput_with_port(cmd, (struct sockaddr_in6 *)sa, ip6cp, port);
 }
 
 #endif /* INET6 */
diff --git a/sys/netinet/tcp_var.h b/sys/netinet/tcp_var.h
index a7d1206ee982..ec6818648746 100644
--- a/sys/netinet/tcp_var.h
+++ b/sys/netinet/tcp_var.h
@@ -1084,9 +1084,7 @@ void	 tcp_discardcb(struct tcpcb *);
 bool	 tcp_freecb(struct tcpcb *);
 void	 tcp_twstart(struct tcpcb *);
 void	 tcp_twclose(struct tcptw *, int);
-void	 tcp_ctlinput(int, struct sockaddr *, void *);
 int	 tcp_ctloutput(struct socket *, struct sockopt *);
-void 	 tcp_ctlinput_viaudp(int, struct sockaddr *, void *, void *);
 void	 tcp_fini(void *);
 char	*tcp_log_addrs(struct in_conninfo *, struct tcphdr *, const void *,
 	    const void *);
diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c
index 112e343853bc..68de037ada1a 100644
--- a/sys/netinet/udp_usrreq.c
+++ b/sys/netinet/udp_usrreq.c
@@ -740,21 +740,18 @@ udp_notify(struct inpcb *inp, int errno)
 
 #ifdef INET
 static void
-udp_common_ctlinput(int cmd, struct sockaddr *sa, void *vip,
+udp_common_ctlinput(int cmd, struct sockaddr_in *sin, struct ip *ip,
     struct inpcbinfo *pcbinfo)
 {
-	struct ip *ip = vip;
 	struct udphdr *uh;
-	struct in_addr faddr;
 	struct inpcb *inp;
 
-	faddr = ((struct sockaddr_in *)sa)->sin_addr;
-	if (sa->sa_family != AF_INET || faddr.s_addr == INADDR_ANY)
+	if (sin->sin_addr.s_addr == INADDR_ANY)
 		return;
 
 	if (PRC_IS_REDIRECT(cmd)) {
 		/* signal EHOSTDOWN, as it flushes the cached route */
-		in_pcbnotifyall(pcbinfo, faddr, EHOSTDOWN, udp_notify);
+		in_pcbnotifyall(pcbinfo, sin->sin_addr, EHOSTDOWN, udp_notify);
 		return;
 	}
 
@@ -770,7 +767,7 @@ udp_common_ctlinput(int cmd, struct sockaddr *sa, void *vip,
 		return;
 	if (ip != NULL) {
 		uh = (struct udphdr *)((caddr_t)ip + (ip->ip_hl << 2));
-		inp = in_pcblookup(pcbinfo, faddr, uh->uh_dport,
+		inp = in_pcblookup(pcbinfo, sin->sin_addr, uh->uh_dport,
 		    ip->ip_src, uh->uh_sport, INPLOOKUP_WLOCKPCB, NULL);
 		if (inp != NULL) {
 			INP_WLOCK_ASSERT(inp);
@@ -779,7 +776,7 @@ udp_common_ctlinput(int cmd, struct sockaddr *sa, void *vip,
 			}
 			INP_WUNLOCK(inp);
 		} else {
-			inp = in_pcblookup(pcbinfo, faddr, uh->uh_dport,
+			inp = in_pcblookup(pcbinfo, sin->sin_addr, uh->uh_dport,
 					   ip->ip_src, uh->uh_sport,
 					   INPLOOKUP_WILDCARD | INPLOOKUP_RLOCKPCB, NULL);
 			if (inp != NULL) {
@@ -792,26 +789,27 @@ udp_common_ctlinput(int cmd, struct sockaddr *sa, void *vip,
 				func = up->u_icmp_func;
 				INP_RUNLOCK(inp);
 				if (func != NULL)
-					(*func)(cmd, sa, vip, ctx);
+					(*func)(cmd, (struct sockaddr *)sin,
+					    ip, ctx);
 			}
 		}
 	} else
-		in_pcbnotifyall(pcbinfo, faddr, inetctlerrmap[cmd],
+		in_pcbnotifyall(pcbinfo, sin->sin_addr, inetctlerrmap[cmd],
 		    udp_notify);
 }
 
 static void
-udp_ctlinput(int cmd, struct sockaddr *sa, void *vip)
+udp_ctlinput(int cmd, struct sockaddr_in *sin, struct ip *ip)
 {
 
-	return (udp_common_ctlinput(cmd, sa, vip, &V_udbinfo));
+	return (udp_common_ctlinput(cmd, sin, ip, &V_udbinfo));
 }
 
 static void
-udplite_ctlinput(int cmd, struct sockaddr *sa, void *vip)
+udplite_ctlinput(int cmd, struct sockaddr_in *sin, struct ip *ip)
 {
 
-	return (udp_common_ctlinput(cmd, sa, vip, &V_ulitecbinfo));
+	return (udp_common_ctlinput(cmd, sin, ip, &V_ulitecbinfo));
 }
 #endif /* INET */
 
diff --git a/sys/netinet6/icmp6.c b/sys/netinet6/icmp6.c
index 0d8786907716..5f49b2215cde 100644
--- a/sys/netinet6/icmp6.c
+++ b/sys/netinet6/icmp6.c
@@ -113,7 +113,7 @@ __FBSDID("$FreeBSD$");
 #include <netinet6/nd6.h>
 #include <netinet6/send.h>
 
-extern ipproto_ctlinput_t	*ip6_ctlprotox[];
+extern ip6proto_ctlinput_t	*ip6_ctlprotox[];
 
 VNET_PCPUSTAT_DEFINE(struct icmp6stat, icmp6stat);
 VNET_PCPUSTAT_SYSINIT(icmp6stat);
@@ -1086,8 +1086,7 @@ icmp6_notify_error(struct mbuf **mp, int off, int icmp6len, int code)
 		}
 
 		if (ip6_ctlprotox[nxt] != NULL)
-			ip6_ctlprotox[nxt](code, (struct sockaddr *)&icmp6dst,
-			    &ip6cp);
+			ip6_ctlprotox[nxt](code, &icmp6dst, &ip6cp);
 	}
 	*mp = m;
 	return (0);
diff --git a/sys/netinet6/in6_pcb.c b/sys/netinet6/in6_pcb.c
index 2d76a8b3db77..9a055dcb0563 100644
--- a/sys/netinet6/in6_pcb.c
+++ b/sys/netinet6/in6_pcb.c
@@ -681,30 +681,29 @@ inp_match6(const struct inpcb *inp, void *v __unused)
 	return ((inp->inp_vflag & INP_IPV6) != 0);
 }
 void
-in6_pcbnotify(struct inpcbinfo *pcbinfo, struct sockaddr *dst,
-    u_int fport_arg, const struct sockaddr *src, u_int lport_arg,
+in6_pcbnotify(struct inpcbinfo *pcbinfo, struct sockaddr_in6 *sa6_dst,
+    u_int fport_arg, const struct sockaddr_in6 *src, u_int lport_arg,
     int cmd, void *cmdarg,
     struct inpcb *(*notify)(struct inpcb *, int))
 {
 	struct inpcb_iterator inpi = INP_ITERATOR(pcbinfo, INPLOOKUP_WLOCKPCB,
 	    inp_match6, NULL);
 	struct inpcb *inp;
-	struct sockaddr_in6 sa6_src, *sa6_dst;
+	struct sockaddr_in6 sa6_src;
 	u_short	fport = fport_arg, lport = lport_arg;
 	u_int32_t flowinfo;
 	int errno;
 
-	if ((unsigned)cmd >= PRC_NCMDS || dst->sa_family != AF_INET6)
+	if ((unsigned)cmd >= PRC_NCMDS)
 		return;
 
-	sa6_dst = (struct sockaddr_in6 *)dst;
 	if (IN6_IS_ADDR_UNSPECIFIED(&sa6_dst->sin6_addr))
 		return;
 
 	/*
 	 * note that src can be NULL when we get notify by local fragmentation.
 	 */
-	sa6_src = (src == NULL) ? sa6_any : *(const struct sockaddr_in6 *)src;
+	sa6_src = (src == NULL) ? sa6_any : *src;
 	flowinfo = sa6_src.sin6_flowinfo;
 
 	/*
@@ -733,8 +732,7 @@ in6_pcbnotify(struct inpcbinfo *pcbinfo, struct sockaddr *dst,
 		 * XXX: should we avoid to notify the value to TCP sockets?
 		 */
 		if (cmd == PRC_MSGSIZE && cmdarg != NULL)
-			ip6_notify_pmtu(inp, (struct sockaddr_in6 *)dst,
-					*(u_int32_t *)cmdarg);
+			ip6_notify_pmtu(inp, sa6_dst, *(uint32_t *)cmdarg);
 
 		/*
 		 * Detect if we should notify the error. If no source and
diff --git a/sys/netinet6/in6_pcb.h b/sys/netinet6/in6_pcb.h
index ec12c9c1654a..09907e2c397c 100644
--- a/sys/netinet6/in6_pcb.h
+++ b/sys/netinet6/in6_pcb.h
@@ -94,8 +94,8 @@ struct	inpcb *
 	in6_pcblookup_mbuf(struct inpcbinfo *, struct in6_addr *,
 			   u_int, struct in6_addr *, u_int, int,
 			   struct ifnet *ifp, struct mbuf *);
-void	in6_pcbnotify(struct inpcbinfo *, struct sockaddr *,
-			   u_int, const struct sockaddr *, u_int, int, void *,
+void	in6_pcbnotify(struct inpcbinfo *, struct sockaddr_in6 *, u_int,
+			   const struct sockaddr_in6 *, u_int, int, void *,
 			   struct inpcb *(*)(struct inpcb *, int));
 struct inpcb *
 	in6_rtchange(struct inpcb *, int);
diff --git a/sys/netinet6/ip6_var.h b/sys/netinet6/ip6_var.h
index 2b15443fc4d6..7696597b5111 100644
--- a/sys/netinet6/ip6_var.h
+++ b/sys/netinet6/ip6_var.h
@@ -394,8 +394,6 @@ int	frag6_input(struct mbuf **, int *, int);
 void	frag6_drain(void);
 
 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_usrreq(struct socket *,
 	    int, struct mbuf *, struct mbuf *, struct mbuf *, struct thread *);
@@ -444,7 +442,8 @@ struct ip6ctlparam {
 };
 
 typedef int	ip6proto_input_t(struct mbuf **, int *, int);
-typedef void	ip6proto_ctlinput_t(int, struct sockaddr *, void *);
+typedef void	ip6proto_ctlinput_t(int, struct sockaddr_in6 *,
+		    struct ip6ctlparam *);
 int	ip6proto_register(uint8_t, ip6proto_input_t, ip6proto_ctlinput_t);
 int	ip6proto_unregister(uint8_t);
 #define	IP6PROTO_REGISTER(prot, input, ctl)	do {			\
@@ -452,6 +451,10 @@ int	ip6proto_unregister(uint8_t);
 	error = ip6proto_register(prot, input, ctl);			\
 	MPASS(error == 0);						\
 } while (0)
+
+ip6proto_input_t	rip6_input;
+ip6proto_ctlinput_t	rip6_ctlinput;
+
 #endif /* _KERNEL */
 
 #endif /* !_NETINET6_IP6_VAR_H_ */
diff --git a/sys/netinet6/raw_ip6.c b/sys/netinet6/raw_ip6.c
index b1cf9fc68a59..fe303254e861 100644
--- a/sys/netinet6/raw_ip6.c
+++ b/sys/netinet6/raw_ip6.c
@@ -323,31 +323,25 @@ rip6_input(struct mbuf **mp, int *offp, int proto)
 }
 
 void
-rip6_ctlinput(int cmd, struct sockaddr *sa, void *d)
+rip6_ctlinput(int cmd, struct sockaddr_in6 *sin6, struct ip6ctlparam *ip6cp)
 {
-	struct ip6ctlparam *ip6cp = NULL;
-	const struct sockaddr_in6 *sa6_src = NULL;
+	const struct sockaddr_in6 *sa6_src;
 	void *cmdarg;
 	struct inpcb *(*notify)(struct inpcb *, int) = in6_rtchange;
 
-	if (sa->sa_family != AF_INET6 ||
-	    sa->sa_len != sizeof(struct sockaddr_in6))
-		return;
-
 	if ((unsigned)cmd >= PRC_NCMDS)
 		return;
 	if (PRC_IS_REDIRECT(cmd))
-		notify = in6_rtchange, d = NULL;
+		notify = in6_rtchange, ip6cp = NULL;
 	else if (cmd == PRC_HOSTDEAD)
-		d = NULL;
+		ip6cp = NULL;
 	else if (inet6ctlerrmap[cmd] == 0)
 		return;
 
 	/*
 	 * If the parameter is from icmp6, decode it.
 	 */
-	if (d != NULL) {
-		ip6cp = (struct ip6ctlparam *)d;
+	if (ip6cp != NULL) {
 		cmdarg = ip6cp->ip6c_cmdarg;
 		sa6_src = ip6cp->ip6c_src;
 	} else {
@@ -355,8 +349,7 @@ rip6_ctlinput(int cmd, struct sockaddr *sa, void *d)
 		sa6_src = &sa6_any;
 	}
 
-	(void) in6_pcbnotify(&V_ripcbinfo, sa, 0,
-	    (const struct sockaddr *)sa6_src, 0, cmd, cmdarg, notify);
+	in6_pcbnotify(&V_ripcbinfo, sin6, 0, sa6_src, 0, cmd, cmdarg, notify);
 }
 
 /*
diff --git a/sys/netinet6/sctp6_usrreq.c b/sys/netinet6/sctp6_usrreq.c
index b14d7d10451a..5a771b19bdb8 100644
--- a/sys/netinet6/sctp6_usrreq.c
+++ b/sys/netinet6/sctp6_usrreq.c
@@ -248,34 +248,22 @@ sctp6_notify(struct sctp_inpcb *inp,
 }
 
 void
-sctp6_ctlinput(int cmd, struct sockaddr *pktdst, void *d)
+sctp6_ctlinput(int cmd, struct sockaddr_in6 *pktdst, struct ip6ctlparam *ip6cp)
 {
-	struct ip6ctlparam *ip6cp;
 	struct sctp_inpcb *inp;
 	struct sctp_tcb *stcb;
 	struct sctp_nets *net;
 	struct sctphdr sh;
 	struct sockaddr_in6 src, dst;
 
-	if (pktdst->sa_family != AF_INET6 ||
-	    pktdst->sa_len != sizeof(struct sockaddr_in6)) {
-		return;
-	}
-
 	if ((unsigned)cmd >= PRC_NCMDS) {
 		return;
 	}
 	if (PRC_IS_REDIRECT(cmd)) {
-		d = NULL;
+		ip6cp = NULL;
 	} else if (inet6ctlerrmap[cmd] == 0) {
 		return;
 	}
-	/* If the parameter is from icmp6, decode it. */
-	if (d != NULL) {
-		ip6cp = (struct ip6ctlparam *)d;
-	} else {
-		ip6cp = (struct ip6ctlparam *)NULL;
-	}
 
 	if (ip6cp != NULL) {
 		/*
diff --git a/sys/netinet6/sctp6_var.h b/sys/netinet6/sctp6_var.h
index 74a24f425cea..a5df12a30f26 100644
--- a/sys/netinet6/sctp6_var.h
+++ b/sys/netinet6/sctp6_var.h
@@ -48,7 +48,7 @@ int sctp6_input_with_port(struct mbuf **, int *, uint16_t);
 int
 sctp6_output(struct sctp_inpcb *, struct mbuf *, struct sockaddr *,
     struct mbuf *, struct proc *);
-void sctp6_ctlinput(int, struct sockaddr *, void *);
+ip6proto_ctlinput_t	sctp6_ctlinput;
 void
 sctp6_notify(struct sctp_inpcb *, struct sctp_tcb *, struct sctp_nets *,
     uint8_t, uint8_t, uint32_t);
diff --git a/sys/netinet6/tcp6_var.h b/sys/netinet6/tcp6_var.h
index 141070b44ca7..49e1591294d5 100644
--- a/sys/netinet6/tcp6_var.h
+++ b/sys/netinet6/tcp6_var.h
@@ -72,14 +72,8 @@ VNET_DECLARE(int, tcp_v6mssdflt);	/* XXX */
 #define	V_tcp_v6mssdflt			VNET(tcp_v6mssdflt)
 #endif
 
-struct	ip6_hdr;
-void	tcp6_ctlinput(int, struct sockaddr *, void *);
-void 	tcp6_ctlinput_viaudp(int, struct sockaddr *, void *, void *);
 int	tcp6_input(struct mbuf **, int *, int);
 int	tcp6_input_with_port(struct mbuf **, int *, int, uint16_t);
-
-extern struct	pr_usrreqs tcp6_usrreqs;
-
 #endif /* _KERNEL */
 
 #endif /* _NETINET_TCP6_VAR_H_ */
diff --git a/sys/netinet6/udp6_usrreq.c b/sys/netinet6/udp6_usrreq.c
index 4c06e5ea9433..f7f737f7e051 100644
--- a/sys/netinet6/udp6_usrreq.c
+++ b/sys/netinet6/udp6_usrreq.c
@@ -547,14 +547,13 @@ badunlocked:
 }
 
 static void
-udp6_common_ctlinput(int cmd, struct sockaddr *sa, void *d,
-    struct inpcbinfo *pcbinfo)
+udp6_common_ctlinput(int cmd, struct sockaddr_in6 *sin6,
+    struct ip6ctlparam *ip6cp, struct inpcbinfo *pcbinfo)
 {
 	struct udphdr uh;
 	struct ip6_hdr *ip6;
 	struct mbuf *m;
 	int off = 0;
-	struct ip6ctlparam *ip6cp = NULL;
 	const struct sockaddr_in6 *sa6_src = NULL;
 	void *cmdarg;
 	struct inpcb *(*notify)(struct inpcb *, int) = udp_notify;
@@ -563,22 +562,17 @@ udp6_common_ctlinput(int cmd, struct sockaddr *sa, void *d,
 		u_int16_t uh_dport;
 	} *uhp;
 
-	if (sa->sa_family != AF_INET6 ||
-	    sa->sa_len != sizeof(struct sockaddr_in6))
-		return;
-
 	if ((unsigned)cmd >= PRC_NCMDS)
 		return;
 	if (PRC_IS_REDIRECT(cmd))
-		notify = in6_rtchange, d = NULL;
+		notify = in6_rtchange, ip6cp = NULL;
 	else if (cmd == PRC_HOSTDEAD)
-		d = NULL;
+		ip6cp = NULL;
 	else if (inet6ctlerrmap[cmd] == 0)
 		return;
 
 	/* if the parameter is from icmp6, decode it. */
-	if (d != NULL) {
-		ip6cp = (struct ip6ctlparam *)d;
+	if (ip6cp != NULL) {
 		m = ip6cp->ip6c_m;
 		ip6 = ip6cp->ip6c_ip6;
 		off = ip6cp->ip6c_off;
@@ -619,7 +613,7 @@ udp6_common_ctlinput(int cmd, struct sockaddr *sa, void *d,
 					/* Yes it is. */
 					INP_RUNLOCK(inp);
 					(*up->u_icmp_func)(cmd, (struct sockaddr *)ip6cp->ip6c_src,
-					      d, up->u_tun_ctx);
+					      ip6cp, up->u_tun_ctx);
 					return;
 				} else {
 					/* Can't find it. */
@@ -627,26 +621,25 @@ udp6_common_ctlinput(int cmd, struct sockaddr *sa, void *d,
 				}
 			}
 		}
-		(void)in6_pcbnotify(pcbinfo, sa, uh.uh_dport,
-		    (struct sockaddr *)ip6cp->ip6c_src, uh.uh_sport, cmd,
-		    cmdarg, notify);
+		in6_pcbnotify(pcbinfo, sin6, uh.uh_dport, ip6cp->ip6c_src,
+		    uh.uh_sport, cmd, cmdarg, notify);
 	} else
-		(void)in6_pcbnotify(pcbinfo, sa, 0,
-		    (const struct sockaddr *)sa6_src, 0, cmd, cmdarg, notify);
+		in6_pcbnotify(pcbinfo, sin6, 0, sa6_src, 0, cmd, cmdarg,
+		    notify);
 }
 
-void
-udp6_ctlinput(int cmd, struct sockaddr *sa, void *d)
+static void
+udp6_ctlinput(int cmd, struct sockaddr_in6 *sin6, struct ip6ctlparam *ctl)
 {
 
-	return (udp6_common_ctlinput(cmd, sa, d, &V_udbinfo));
+	return (udp6_common_ctlinput(cmd, sin6, ctl, &V_udbinfo));
 }
 
-void
-udplite6_ctlinput(int cmd, struct sockaddr *sa, void *d)
+static void
+udplite6_ctlinput(int cmd, struct sockaddr_in6 *sin6, struct ip6ctlparam *ctl)
 {
 
-	return (udp6_common_ctlinput(cmd, sa, d, &V_ulitecbinfo));
+	return (udp6_common_ctlinput(cmd, sin6, ctl, &V_ulitecbinfo));
 }
 
 static int
diff --git a/sys/netinet6/udp6_var.h b/sys/netinet6/udp6_var.h
index 93e226d6a4b3..5d2c793bee0c 100644
--- a/sys/netinet6/udp6_var.h
+++ b/sys/netinet6/udp6_var.h
@@ -68,10 +68,6 @@
 #ifdef _KERNEL
 SYSCTL_DECL(_net_inet6_udp6);
 
-extern struct pr_usrreqs	udp6_usrreqs;
-
-void	udp6_ctlinput(int, struct sockaddr *, void *);
-void	udplite6_ctlinput(int, struct sockaddr *, void *);
 int	udp6_input(struct mbuf **, int *, int);
 #endif