summaryrefslogtreecommitdiffstats
path: root/sys/netinet/ip_divert.c
diff options
context:
space:
mode:
authorrwatson <rwatson@FreeBSD.org>2006-04-01 16:20:54 +0000
committerrwatson <rwatson@FreeBSD.org>2006-04-01 16:20:54 +0000
commita7c2bca553bef1485f864043c190482cc9c6fdd4 (patch)
tree60c6d1ae13c348075601004daade9dd8338f72a3 /sys/netinet/ip_divert.c
parent71cc03392bbc78f93765e5550fc35f98c373df04 (diff)
downloadFreeBSD-src-a7c2bca553bef1485f864043c190482cc9c6fdd4.zip
FreeBSD-src-a7c2bca553bef1485f864043c190482cc9c6fdd4.tar.gz
Update in_pcb-derived basic socket types following changes to
pru_abort(), pru_detach(), and in_pcbdetach(): - Universally support and enforce the invariant that so_pcb is never NULL, converting dozens of unnecessary NULL checks into assertions, and eliminating dozens of unnecessary error handling cases in protocol code. - In some cases, eliminate unnecessary pcbinfo locking, as it is no longer required to ensure so_pcb != NULL. For example, in protocol shutdown methods, and in raw IP send. - Abort and detach protocol switch methods no longer return failures, nor attempt to free sockets, as the socket layer does this. - Invoke in_pcbfree() after in_pcbdetach() in order to free the detached in_pcb structure for a socket. MFC after: 3 months
Diffstat (limited to 'sys/netinet/ip_divert.c')
-rw-r--r--sys/netinet/ip_divert.c49
1 files changed, 15 insertions, 34 deletions
diff --git a/sys/netinet/ip_divert.c b/sys/netinet/ip_divert.c
index bb31630..89aa4e4 100644
--- a/sys/netinet/ip_divert.c
+++ b/sys/netinet/ip_divert.c
@@ -394,21 +394,14 @@ div_attach(struct socket *so, int proto, struct thread *td)
struct inpcb *inp;
int error;
- INP_INFO_WLOCK(&divcbinfo);
inp = sotoinpcb(so);
- if (inp != 0) {
- INP_INFO_WUNLOCK(&divcbinfo);
- return EINVAL;
- }
- if (td && (error = suser(td)) != 0) {
- INP_INFO_WUNLOCK(&divcbinfo);
+ KASSERT(inp == NULL, ("div_attach: inp != NULL"));
+ if (td && (error = suser(td)) != 0)
return error;
- }
error = soreserve(so, div_sendspace, div_recvspace);
- if (error) {
- INP_INFO_WUNLOCK(&divcbinfo);
+ if (error)
return error;
- }
+ INP_INFO_WLOCK(&divcbinfo);
error = in_pcballoc(so, &divcbinfo, "divinp");
if (error) {
INP_INFO_WUNLOCK(&divcbinfo);
@@ -429,14 +422,12 @@ div_detach(struct socket *so)
{
struct inpcb *inp;
- INP_INFO_WLOCK(&divcbinfo);
inp = sotoinpcb(so);
- if (inp == 0) {
- INP_INFO_WUNLOCK(&divcbinfo);
- return;
- }
+ KASSERT(inp != NULL, ("div_detach: inp == NULL"));
+ INP_INFO_WLOCK(&divcbinfo);
INP_LOCK(inp);
in_pcbdetach(inp);
+ in_pcbfree(inp);
INP_INFO_WUNLOCK(&divcbinfo);
}
@@ -446,12 +437,8 @@ div_bind(struct socket *so, struct sockaddr *nam, struct thread *td)
struct inpcb *inp;
int error;
- INP_INFO_WLOCK(&divcbinfo);
inp = sotoinpcb(so);
- if (inp == 0) {
- INP_INFO_WUNLOCK(&divcbinfo);
- return EINVAL;
- }
+ KASSERT(inp == NULL, ("div_bind: inp == NULL"));
/* in_pcbbind assumes that nam is a sockaddr_in
* and in_pcbbind requires a valid address. Since divert
* sockets don't we need to make sure the address is
@@ -460,13 +447,12 @@ div_bind(struct socket *so, struct sockaddr *nam, struct thread *td)
* and should probably have its own family.
*/
if (nam->sa_family != AF_INET)
- error = EAFNOSUPPORT;
- else {
- ((struct sockaddr_in *)nam)->sin_addr.s_addr = INADDR_ANY;
- INP_LOCK(inp);
- error = in_pcbbind(inp, nam, td->td_ucred);
- INP_UNLOCK(inp);
- }
+ return EAFNOSUPPORT;
+ ((struct sockaddr_in *)nam)->sin_addr.s_addr = INADDR_ANY;
+ INP_INFO_WLOCK(&divcbinfo);
+ INP_LOCK(inp);
+ error = in_pcbbind(inp, nam, td->td_ucred);
+ INP_UNLOCK(inp);
INP_INFO_WUNLOCK(&divcbinfo);
return error;
}
@@ -476,14 +462,9 @@ div_shutdown(struct socket *so)
{
struct inpcb *inp;
- INP_INFO_RLOCK(&divcbinfo);
inp = sotoinpcb(so);
- if (inp == 0) {
- INP_INFO_RUNLOCK(&divcbinfo);
- return EINVAL;
- }
+ KASSERT(inp != NULL, ("div_shutdown: inp == NULL"));
INP_LOCK(inp);
- INP_INFO_RUNLOCK(&divcbinfo);
socantsendmore(so);
INP_UNLOCK(inp);
return 0;
OpenPOWER on IntegriCloud