Subj. Start the (*pru_usrreq)() split. bluhm@ pointed, that many KASSERT()s are not welcomed, so I didn't insert them into newly introduced handlers. Anyway except the tcp(4) protocol, `so_pcb' cant be NULL here. But the socket lock assertion looks reasonable.
Some unp_*() functions could be merged with newly introduced uipc_*(), but I want to do this after (*pru_usrreq)() split finished. Index: sys/kern/uipc_usrreq.c =================================================================== RCS file: /cvs/src/sys/kern/uipc_usrreq.c,v retrieving revision 1.168 diff -u -p -r1.168 uipc_usrreq.c --- sys/kern/uipc_usrreq.c 15 Aug 2022 09:11:38 -0000 1.168 +++ sys/kern/uipc_usrreq.c 19 Aug 2022 21:34:26 -0000 @@ -130,6 +130,7 @@ const struct pr_usrreqs uipc_usrreqs = { .pru_usrreq = uipc_usrreq, .pru_attach = uipc_attach, .pru_detach = uipc_detach, + .pru_bind = uipc_bind, }; void @@ -222,10 +223,6 @@ uipc_usrreq(struct socket *so, int req, switch (req) { - case PRU_BIND: - error = unp_bind(unp, nam, p); - break; - case PRU_LISTEN: if (unp->unp_vnode == NULL) error = EINVAL; @@ -535,6 +532,14 @@ uipc_detach(struct socket *so) unp_detach(unp); return (0); +} + +int +uipc_bind(struct socket *so, struct mbuf *nam, struct proc *p) +{ + struct unpcb *unp = sotounpcb(so); + + return unp_bind(unp, nam, p); } int Index: sys/net/pfkeyv2.c =================================================================== RCS file: /cvs/src/sys/net/pfkeyv2.c,v retrieving revision 1.235 diff -u -p -r1.235 pfkeyv2.c --- sys/net/pfkeyv2.c 15 Aug 2022 09:11:38 -0000 1.235 +++ sys/net/pfkeyv2.c 19 Aug 2022 21:34:26 -0000 @@ -171,6 +171,7 @@ void pfkey_init(void); int pfkeyv2_attach(struct socket *, int); int pfkeyv2_detach(struct socket *); +int pfkeyv2_bind(struct socket *, struct mbuf *, struct proc *); int pfkeyv2_usrreq(struct socket *, int, struct mbuf *, struct mbuf *, struct mbuf *, struct proc *); int pfkeyv2_output(struct mbuf *, struct socket *, struct sockaddr *, @@ -203,6 +204,7 @@ const struct pr_usrreqs pfkeyv2_usrreqs .pru_usrreq = pfkeyv2_usrreq, .pru_attach = pfkeyv2_attach, .pru_detach = pfkeyv2_detach, + .pru_bind = pfkeyv2_bind, }; const struct protosw pfkeysw[] = { @@ -333,6 +335,12 @@ pfkeyv2_detach(struct socket *so) } int +pfkeyv2_bind(struct socket *so, struct mbuf *nam, struct proc *p) +{ + return (EOPNOTSUPP); +} + +int pfkeyv2_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam, struct mbuf *control, struct proc *p) { @@ -358,7 +366,6 @@ pfkeyv2_usrreq(struct socket *so, int re switch (req) { /* no connect, bind, accept. Socket is connected from the start */ case PRU_CONNECT: - case PRU_BIND: case PRU_CONNECT2: case PRU_LISTEN: case PRU_ACCEPT: Index: sys/net/rtsock.c =================================================================== RCS file: /cvs/src/sys/net/rtsock.c,v retrieving revision 1.335 diff -u -p -r1.335 rtsock.c --- sys/net/rtsock.c 15 Aug 2022 09:11:38 -0000 1.335 +++ sys/net/rtsock.c 19 Aug 2022 21:34:26 -0000 @@ -114,6 +114,7 @@ int route_output(struct mbuf *, struct s int route_ctloutput(int, struct socket *, int, int, struct mbuf *); int route_usrreq(struct socket *, int, struct mbuf *, struct mbuf *, struct mbuf *, struct proc *); +int route_bind(struct socket *, struct mbuf *, struct proc *); void route_input(struct mbuf *m0, struct socket *, sa_family_t); int route_arp_conflict(struct rtentry *, struct rt_addrinfo *); int route_cleargateway(struct rtentry *, void *, unsigned int); @@ -234,7 +235,6 @@ route_usrreq(struct socket *so, int req, switch (req) { /* no connect, bind, accept. Socket is connected from the start */ case PRU_CONNECT: - case PRU_BIND: case PRU_CONNECT2: case PRU_LISTEN: case PRU_ACCEPT: @@ -367,6 +367,12 @@ route_detach(struct socket *so) } int +route_bind(struct socket *so, struct mbuf *nam, struct proc *p) +{ + return (EOPNOTSUPP); +} + +int route_ctloutput(int op, struct socket *so, int level, int optname, struct mbuf *m) { @@ -2405,6 +2411,7 @@ const struct pr_usrreqs route_usrreqs = .pru_usrreq = route_usrreq, .pru_attach = route_attach, .pru_detach = route_detach, + .pru_bind = route_bind, }; const struct protosw routesw[] = { Index: sys/netinet/ip_divert.c =================================================================== RCS file: /cvs/src/sys/netinet/ip_divert.c,v retrieving revision 1.69 diff -u -p -r1.69 ip_divert.c --- sys/netinet/ip_divert.c 15 Aug 2022 09:11:39 -0000 1.69 +++ sys/netinet/ip_divert.c 19 Aug 2022 21:34:26 -0000 @@ -66,6 +66,7 @@ const struct pr_usrreqs divert_usrreqs = .pru_usrreq = divert_usrreq, .pru_attach = divert_attach, .pru_detach = divert_detach, + .pru_bind = divert_bind, }; int divbhashsize = DIVERTHASHSIZE; @@ -274,10 +275,6 @@ divert_usrreq(struct socket *so, int req } switch (req) { - case PRU_BIND: - error = in_pcbbind(inp, addr, p); - break; - case PRU_SHUTDOWN: socantsendmore(so); break; @@ -362,6 +359,15 @@ divert_detach(struct socket *so) in_pcbdetach(inp); return (0); +} + +int +divert_bind(struct socket *so, struct mbuf *addr, struct proc *p) +{ + struct inpcb *inp = sotoinpcb(so); + + soassertlocked(so); + return in_pcbbind(inp, addr, p); } int Index: sys/netinet/ip_divert.h =================================================================== RCS file: /cvs/src/sys/netinet/ip_divert.h,v retrieving revision 1.16 diff -u -p -r1.16 ip_divert.h --- sys/netinet/ip_divert.h 15 Aug 2022 09:11:39 -0000 1.16 +++ sys/netinet/ip_divert.h 19 Aug 2022 21:34:26 -0000 @@ -74,5 +74,6 @@ int divert_usrreq(struct socket *, int, struct mbuf *, struct mbuf *, struct mbuf *, struct proc *); int divert_attach(struct socket *, int); int divert_detach(struct socket *); +int divert_bind(struct socket *, struct mbuf *, struct proc *); #endif /* _KERNEL */ #endif /* _IP_DIVERT_H_ */ Index: sys/netinet/ip_gre.c =================================================================== RCS file: /cvs/src/sys/netinet/ip_gre.c,v retrieving revision 1.75 diff -u -p -r1.75 ip_gre.c --- sys/netinet/ip_gre.c 15 Aug 2022 09:11:39 -0000 1.75 +++ sys/netinet/ip_gre.c 19 Aug 2022 21:34:26 -0000 @@ -65,6 +65,7 @@ const struct pr_usrreqs gre_usrreqs = { .pru_usrreq = gre_usrreq, .pru_attach = rip_attach, .pru_detach = rip_detach, + .pru_bind = rip_bind, }; int Index: sys/netinet/ip_var.h =================================================================== RCS file: /cvs/src/sys/netinet/ip_var.h,v retrieving revision 1.97 diff -u -p -r1.97 ip_var.h --- sys/netinet/ip_var.h 15 Aug 2022 09:11:39 -0000 1.97 +++ sys/netinet/ip_var.h 19 Aug 2022 21:34:26 -0000 @@ -260,6 +260,7 @@ int rip_usrreq(struct socket *, int, struct mbuf *, struct mbuf *, struct mbuf *, struct proc *); int rip_attach(struct socket *, int); int rip_detach(struct socket *); +int rip_bind(struct socket *so, struct mbuf *, struct proc *); #ifdef MROUTING extern struct socket *ip_mrouter[]; /* multicast routing daemon */ #endif Index: sys/netinet/raw_ip.c =================================================================== RCS file: /cvs/src/sys/netinet/raw_ip.c,v retrieving revision 1.130 diff -u -p -r1.130 raw_ip.c --- sys/netinet/raw_ip.c 15 Aug 2022 09:11:39 -0000 1.130 +++ sys/netinet/raw_ip.c 19 Aug 2022 21:34:26 -0000 @@ -107,6 +107,7 @@ const struct pr_usrreqs rip_usrreqs = { .pru_usrreq = rip_usrreq, .pru_attach = rip_attach, .pru_detach = rip_detach, + .pru_bind = rip_bind, }; /* @@ -485,23 +486,6 @@ rip_usrreq(struct socket *so, int req, s in_pcbdetach(inp); break; - case PRU_BIND: - { - struct sockaddr_in *addr; - - if ((error = in_nam2sin(nam, &addr))) - break; - if (!((so->so_options & SO_BINDANY) || - addr->sin_addr.s_addr == INADDR_ANY || - addr->sin_addr.s_addr == INADDR_BROADCAST || - in_broadcast(addr->sin_addr, inp->inp_rtableid) || - ifa_ifwithaddr(sintosa(addr), inp->inp_rtableid))) { - error = EADDRNOTAVAIL; - break; - } - inp->inp_laddr = addr->sin_addr; - break; - } case PRU_CONNECT: { struct sockaddr_in *addr; @@ -635,5 +619,29 @@ rip_detach(struct socket *so) #endif in_pcbdetach(inp); + return (0); +} + +int +rip_bind(struct socket *so, struct mbuf *nam, struct proc *p) +{ + struct inpcb *inp = sotoinpcb(so); + struct sockaddr_in *addr; + int error; + + soassertlocked(so); + + if ((error = in_nam2sin(nam, &addr))) + return (error); + + if (!((so->so_options & SO_BINDANY) || + addr->sin_addr.s_addr == INADDR_ANY || + addr->sin_addr.s_addr == INADDR_BROADCAST || + in_broadcast(addr->sin_addr, inp->inp_rtableid) || + ifa_ifwithaddr(sintosa(addr), inp->inp_rtableid))) + return (EADDRNOTAVAIL); + + inp->inp_laddr = addr->sin_addr; + return (0); } Index: sys/netinet/tcp_usrreq.c =================================================================== RCS file: /cvs/src/sys/netinet/tcp_usrreq.c,v retrieving revision 1.188 diff -u -p -r1.188 tcp_usrreq.c --- sys/netinet/tcp_usrreq.c 15 Aug 2022 14:44:18 -0000 1.188 +++ sys/netinet/tcp_usrreq.c 19 Aug 2022 21:34:26 -0000 @@ -115,6 +115,7 @@ const struct pr_usrreqs tcp_usrreqs = { .pru_usrreq = tcp_usrreq, .pru_attach = tcp_attach, .pru_detach = tcp_detach, + .pru_bind = tcp_bind, }; static int pr_slowhz = PR_SLOWHZ; @@ -212,13 +213,6 @@ tcp_usrreq(struct socket *so, int req, s switch (req) { /* - * Give the socket an address. - */ - case PRU_BIND: - error = in_pcbbind(inp, nam, p); - break; - - /* * Prepare to accept connections. */ case PRU_LISTEN: @@ -777,6 +771,32 @@ tcp_detach(struct socket *so) if (otp) tcp_trace(TA_USER, ostate, tp, otp, NULL, PRU_DETACH, 0); + return (error); +} + +/* + * Give the socket an address. + */ +int +tcp_bind(struct socket *so, struct mbuf *nam, struct proc *p) +{ + struct inpcb *inp; + struct tcpcb *tp; + int error; + short ostate; + + soassertlocked(so); + + if ((error = tcp_sogetpcb(so, &inp, &tp))) + return (error); + + if (so->so_options & SO_DEBUG) + ostate = tp->t_state; + + error = in_pcbbind(inp, nam, p); + + if (so->so_options & SO_DEBUG) + tcp_trace(TA_USER, ostate, tp, tp, NULL, PRU_BIND, 0); return (error); } Index: sys/netinet/tcp_var.h =================================================================== RCS file: /cvs/src/sys/netinet/tcp_var.h,v retrieving revision 1.141 diff -u -p -r1.141 tcp_var.h --- sys/netinet/tcp_var.h 15 Aug 2022 09:11:39 -0000 1.141 +++ sys/netinet/tcp_var.h 19 Aug 2022 21:34:26 -0000 @@ -714,6 +714,7 @@ int tcp_usrreq(struct socket *, int, struct mbuf *, struct mbuf *, struct mbuf *, struct proc *); int tcp_attach(struct socket *, int); int tcp_detach(struct socket *); +int tcp_bind(struct socket *, struct mbuf *, struct proc *); void tcp_xmit_timer(struct tcpcb *, int); void tcpdropoldhalfopen(struct tcpcb *, u_int16_t); void tcp_sack_option(struct tcpcb *,struct tcphdr *,u_char *,int); Index: sys/netinet/udp_usrreq.c =================================================================== RCS file: /cvs/src/sys/netinet/udp_usrreq.c,v retrieving revision 1.282 diff -u -p -r1.282 udp_usrreq.c --- sys/netinet/udp_usrreq.c 15 Aug 2022 09:11:39 -0000 1.282 +++ sys/netinet/udp_usrreq.c 19 Aug 2022 21:34:26 -0000 @@ -126,6 +126,7 @@ const struct pr_usrreqs udp_usrreqs = { .pru_usrreq = udp_usrreq, .pru_attach = udp_attach, .pru_detach = udp_detach, + .pru_bind = udp_bind, }; const struct sysctl_bounded_args udpctl_vars[] = { @@ -1074,10 +1075,6 @@ udp_usrreq(struct socket *so, int req, s */ switch (req) { - case PRU_BIND: - error = in_pcbbind(inp, addr, p); - break; - case PRU_LISTEN: error = EOPNOTSUPP; break; @@ -1273,6 +1270,15 @@ udp_detach(struct socket *so) in_pcbdetach(inp); return (0); +} + +int +udp_bind(struct socket *so, struct mbuf *addr, struct proc *p) +{ + struct inpcb *inp = sotoinpcb(so); + + soassertlocked(so); + return in_pcbbind(inp, addr, p); } /* Index: sys/netinet/udp_var.h =================================================================== RCS file: /cvs/src/sys/netinet/udp_var.h,v retrieving revision 1.38 diff -u -p -r1.38 udp_var.h --- sys/netinet/udp_var.h 15 Aug 2022 09:11:39 -0000 1.38 +++ sys/netinet/udp_var.h 19 Aug 2022 21:34:26 -0000 @@ -143,5 +143,6 @@ int udp_usrreq(struct socket *, int, struct mbuf *, struct mbuf *, struct mbuf *, struct proc *); int udp_attach(struct socket *, int); int udp_detach(struct socket *); +int udp_bind(struct socket *, struct mbuf *, struct proc *); #endif /* _KERNEL */ #endif /* _NETINET_UDP_VAR_H_ */ Index: sys/netinet6/ip6_divert.c =================================================================== RCS file: /cvs/src/sys/netinet6/ip6_divert.c,v retrieving revision 1.68 diff -u -p -r1.68 ip6_divert.c --- sys/netinet6/ip6_divert.c 15 Aug 2022 09:11:39 -0000 1.68 +++ sys/netinet6/ip6_divert.c 19 Aug 2022 21:34:26 -0000 @@ -67,6 +67,7 @@ const struct pr_usrreqs divert6_usrreqs .pru_usrreq = divert6_usrreq, .pru_attach = divert6_attach, .pru_detach = divert6_detach, + .pru_bind = divert6_bind, }; int divb6hashsize = DIVERTHASHSIZE; @@ -280,10 +281,6 @@ divert6_usrreq(struct socket *so, int re } switch (req) { - case PRU_BIND: - error = in_pcbbind(inp, addr, p); - break; - case PRU_SHUTDOWN: socantsendmore(so); break; @@ -369,6 +366,15 @@ divert6_detach(struct socket *so) in_pcbdetach(inp); return (0); +} + +int +divert6_bind(struct socket *so, struct mbuf *addr, struct proc *p) +{ + struct inpcb *inp = sotoinpcb(so); + + soassertlocked(so); + return in_pcbbind(inp, addr, p); } int Index: sys/netinet6/ip6_divert.h =================================================================== RCS file: /cvs/src/sys/netinet6/ip6_divert.h,v retrieving revision 1.14 diff -u -p -r1.14 ip6_divert.h --- sys/netinet6/ip6_divert.h 15 Aug 2022 09:11:39 -0000 1.14 +++ sys/netinet6/ip6_divert.h 19 Aug 2022 21:34:27 -0000 @@ -74,6 +74,7 @@ int divert6_usrreq(struct socket *, int, struct mbuf *, struct mbuf *, struct mbuf *, struct proc *); int divert6_attach(struct socket *, int); int divert6_detach(struct socket *); +int divert6_bind(struct socket *, struct mbuf *, struct proc *); #endif /* _KERNEL */ #endif /* _IP6_DIVERT_H_ */ Index: sys/netinet6/ip6_var.h =================================================================== RCS file: /cvs/src/sys/netinet6/ip6_var.h,v retrieving revision 1.95 diff -u -p -r1.95 ip6_var.h --- sys/netinet6/ip6_var.h 15 Aug 2022 09:11:39 -0000 1.95 +++ sys/netinet6/ip6_var.h 19 Aug 2022 21:34:27 -0000 @@ -355,6 +355,7 @@ int rip6_usrreq(struct socket *, int, struct mbuf *, struct mbuf *, struct mbuf *, struct proc *); int rip6_attach(struct socket *, int); int rip6_detach(struct socket *); +int rip6_bind(struct socket *, struct mbuf *, struct proc *); int rip6_sysctl(int *, u_int, void *, size_t *, void *, size_t); int dest6_input(struct mbuf **, int *, int, int); Index: sys/netinet6/raw_ip6.c =================================================================== RCS file: /cvs/src/sys/netinet6/raw_ip6.c,v retrieving revision 1.150 diff -u -p -r1.150 raw_ip6.c --- sys/netinet6/raw_ip6.c 15 Aug 2022 09:11:39 -0000 1.150 +++ sys/netinet6/raw_ip6.c 19 Aug 2022 21:34:27 -0000 @@ -109,6 +109,7 @@ const struct pr_usrreqs rip6_usrreqs = { .pru_usrreq = rip6_usrreq, .pru_attach = rip6_attach, .pru_detach = rip6_detach, + .pru_bind = rip6_bind, }; /* @@ -604,25 +605,6 @@ rip6_usrreq(struct socket *so, int req, in_pcbdetach(in6p); break; - case PRU_BIND: - { - struct sockaddr_in6 *addr; - - if ((error = in6_nam2sin6(nam, &addr))) - break; - /* - * Make sure to not enter in_pcblookup_local(), local ports - * are non-sensical for raw sockets. - */ - addr->sin6_port = 0; - - if ((error = in6_pcbaddrisavail(in6p, addr, 0, p))) - break; - - in6p->inp_laddr6 = addr->sin6_addr; - break; - } - case PRU_CONNECT: { struct sockaddr_in6 *addr; @@ -772,6 +754,31 @@ rip6_detach(struct socket *so) in_pcbdetach(in6p); + return (0); +} + +int +rip6_bind(struct socket *so, struct mbuf *nam, struct proc *p) +{ + struct inpcb *in6p = sotoinpcb(so); + struct sockaddr_in6 *addr; + int error; + + soassertlocked(so); + + if ((error = in6_nam2sin6(nam, &addr))) + return (error); + + /* + * Make sure to not enter in_pcblookup_local(), local ports + * are non-sensical for raw sockets. + */ + addr->sin6_port = 0; + + if ((error = in6_pcbaddrisavail(in6p, addr, 0, p))) + return (error); + + in6p->inp_laddr6 = addr->sin6_addr; return (0); } Index: sys/sys/protosw.h =================================================================== RCS file: /cvs/src/sys/sys/protosw.h,v retrieving revision 1.37 diff -u -p -r1.37 protosw.h --- sys/sys/protosw.h 15 Aug 2022 09:11:39 -0000 1.37 +++ sys/sys/protosw.h 19 Aug 2022 21:34:27 -0000 @@ -66,6 +66,7 @@ struct pr_usrreqs { int (*pru_attach)(struct socket *, int); int (*pru_detach)(struct socket *); + int (*pru_bind)(struct socket *, struct mbuf *, struct proc *); }; struct protosw { @@ -264,8 +265,7 @@ pru_detach(struct socket *so) static inline int pru_bind(struct socket *so, struct mbuf *nam, struct proc *p) { - return (*so->so_proto->pr_usrreqs->pru_usrreq)(so, - PRU_BIND, NULL, nam, NULL, p); + return (*so->so_proto->pr_usrreqs->pru_bind)(so, nam, p); } static inline int Index: sys/sys/unpcb.h =================================================================== RCS file: /cvs/src/sys/sys/unpcb.h,v retrieving revision 1.27 diff -u -p -r1.27 unpcb.h --- sys/sys/unpcb.h 15 Aug 2022 09:11:39 -0000 1.27 +++ sys/sys/unpcb.h 19 Aug 2022 21:34:27 -0000 @@ -113,6 +113,7 @@ int uipc_usrreq(struct socket *, int , s struct mbuf *, struct mbuf *, struct proc *); int uipc_attach(struct socket *, int); int uipc_detach(struct socket *); +int uipc_bind(struct socket *, struct mbuf *, struct proc *); void unp_init(void); int unp_bind(struct unpcb *, struct mbuf *, struct proc *);