Module Name: src
Committed By: rtr
Date: Wed Jul 30 06:53:53 UTC 2014
Modified Files:
src/sys/netinet: tcp_usrreq.c
Log Message:
put boilerplate extraction of inpcb or in6pcb and tcpcb performed in tcp
usrreqs into a function that can be called instead of cut & pasting it
to every single usrreq function.
tcp_getpcb(struct socket *, struct inpcb **, struct in6pcb **, struct tcpcb **)
* examines the family of the provided socket and fills in either inpcb
or in6pcb and tcpcb.
* if the pcb is not present for the family of the socket EINVAL is
returned, if the family is not AF_INET{,6} EAFNOSUPPORT is returned.
signature provided by and patch reviewed by rmind
To generate a diff of this commit:
cvs rdiff -u -r1.191 -r1.192 src/sys/netinet/tcp_usrreq.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/netinet/tcp_usrreq.c
diff -u src/sys/netinet/tcp_usrreq.c:1.191 src/sys/netinet/tcp_usrreq.c:1.192
--- src/sys/netinet/tcp_usrreq.c:1.191 Thu Jul 24 16:02:19 2014
+++ src/sys/netinet/tcp_usrreq.c Wed Jul 30 06:53:53 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: tcp_usrreq.c,v 1.191 2014/07/24 16:02:19 rtr Exp $ */
+/* $NetBSD: tcp_usrreq.c,v 1.192 2014/07/30 06:53:53 rtr Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -99,7 +99,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tcp_usrreq.c,v 1.191 2014/07/24 16:02:19 rtr Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tcp_usrreq.c,v 1.192 2014/07/30 06:53:53 rtr Exp $");
#include "opt_inet.h"
#include "opt_ipsec.h"
@@ -177,6 +177,41 @@ tcp_debug_trace(struct socket *so, struc
#endif
}
+static int
+tcp_getpcb(struct socket *so, struct inpcb **inp,
+ struct in6pcb **in6p, struct tcpcb **tp)
+{
+ /*
+ * When a TCP is attached to a socket, then there will be
+ * a (struct inpcb) pointed at by the socket, and this
+ * structure will point at a subsidary (struct tcpcb).
+ */
+ switch (so->so_proto->pr_domain->dom_family) {
+#ifdef INET
+ case PF_INET:
+ *inp = sotoinpcb(so);
+ if (*inp == NULL)
+ return EINVAL;
+ *tp = intotcpcb(*inp);
+ break;
+#endif
+#ifdef INET6
+ case PF_INET6:
+ *in6p = sotoin6pcb(so);
+ if (*in6p == NULL)
+ return EINVAL;
+ *tp = in6totcpcb(*in6p);
+ break;
+#endif
+ default:
+ return EAFNOSUPPORT;
+ }
+
+ KASSERT(tp != NULL);
+
+ return 0;
+}
+
/*
* Process a TCP user request for TCP tb. If this is a send request
* then m is the mbuf chain of send data. If this is a timer expiration
@@ -186,15 +221,12 @@ static int
tcp_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
struct mbuf *control, struct lwp *l)
{
- struct inpcb *inp;
-#ifdef INET6
- struct in6pcb *in6p;
-#endif
+ struct inpcb *inp = NULL;
+ struct in6pcb *in6p = NULL;
struct tcpcb *tp = NULL;
int s;
int error = 0;
int ostate = 0;
- int family; /* family of the socket */
KASSERT(req != PRU_ATTACH);
KASSERT(req != PRU_DETACH);
@@ -208,13 +240,11 @@ tcp_usrreq(struct socket *so, int req, s
KASSERT(req != PRU_RCVOOB);
KASSERT(req != PRU_SENDOOB);
- family = so->so_proto->pr_domain->dom_family;
-
s = splsoftnet();
if (req == PRU_PURGEIF) {
mutex_enter(softnet_lock);
- switch (family) {
+ switch (so->so_proto->pr_domain->dom_family) {
#ifdef INET
case PF_INET:
in_pcbpurgeif0(&tcbtable, (struct ifnet *)control);
@@ -241,57 +271,17 @@ tcp_usrreq(struct socket *so, int req, s
KASSERT(solocked(so));
- switch (family) {
-#ifdef INET
- case PF_INET:
- inp = sotoinpcb(so);
-#ifdef INET6
- in6p = NULL;
-#endif
- break;
-#endif
-#ifdef INET6
- case PF_INET6:
- inp = NULL;
- in6p = sotoin6pcb(so);
- break;
-#endif
- default:
+ if ((error = tcp_getpcb(so, &inp, &in6p, &tp)) != 0) {
splx(s);
- return EAFNOSUPPORT;
+ return error;
}
+
+ ostate = tcp_debug_capture(tp, req);
+
KASSERT(!control || req == PRU_SEND);
#ifdef INET6
/* XXX: KASSERT((inp != NULL) ^ (in6p != NULL)); */
#endif
- /*
- * When a TCP is attached to a socket, then there will be
- * a (struct inpcb) pointed at by the socket, and this
- * structure will point at a subsidary (struct tcpcb).
- */
- if (inp == NULL
-#ifdef INET6
- && in6p == NULL
-#endif
- )
- {
- error = EINVAL;
- goto release;
- }
-#ifdef INET
- if (inp) {
- tp = intotcpcb(inp);
- /* WHAT IF TP IS 0? */
- ostate = tcp_debug_capture(tp, req);
- }
-#endif
-#ifdef INET6
- if (in6p) {
- tp = in6totcpcb(in6p);
- /* WHAT IF TP IS 0? */
- ostate = tcp_debug_capture(tp, req);
- }
-#endif
switch (req) {
@@ -435,10 +425,9 @@ tcp_usrreq(struct socket *so, int req, s
}
tcp_debug_trace(so, tp, ostate, req);
-
-release:
splx(s);
- return (error);
+
+ return error;
}
static void
@@ -462,7 +451,6 @@ change_keepalive(struct socket *so, stru
TCP_TIMER_ARM(tp, TCPT_2MSL, tp->t_maxidle);
}
-
int
tcp_ctloutput(int op, struct socket *so, struct sockopt *sopt)
{
@@ -788,35 +776,17 @@ out:
static void
tcp_detach(struct socket *so)
{
- struct inpcb *inp;
-#ifdef INET6
- struct in6pcb *in6p;
-#endif
+ struct inpcb *inp = NULL;
+ struct in6pcb *in6p = NULL;
struct tcpcb *tp = NULL;
- int s, family;
+ int s;
KASSERT(solocked(so));
- s = splsoftnet();
- family = so->so_proto->pr_domain->dom_family;
- switch (family) {
-#ifdef INET
- case PF_INET:
- inp = sotoinpcb(so);
- tp = intotcpcb(inp);
- break;
-#endif
-#ifdef INET6
- case PF_INET6:
- in6p = sotoin6pcb(so);
- tp = in6totcpcb(in6p);
- break;
-#endif
- default:
- splx(s);
+ if (tcp_getpcb(so, &inp, &in6p, &tp) != 0)
return;
- }
- KASSERT(tp != NULL);
+
+ s = splsoftnet();
(void)tcp_disconnect(tp);
splx(s);
}
@@ -825,42 +795,17 @@ static int
tcp_accept(struct socket *so, struct mbuf *nam)
{
struct inpcb *inp = NULL;
-#ifdef INET6
struct in6pcb *in6p = NULL;
-#endif
struct tcpcb *tp = NULL;
int ostate = 0;
+ int error = 0;
KASSERT(solocked(so));
- switch (so->so_proto->pr_domain->dom_family) {
-#ifdef INET
- case PF_INET:
- inp = sotoinpcb(so);
- break;
-#endif
-#ifdef INET6
- case PF_INET6:
- in6p = sotoin6pcb(so);
- break;
-#endif
- default:
- return EAFNOSUPPORT;
- }
+ if ((error = tcp_getpcb(so, &inp, &in6p, &tp)) != 0)
+ return error;
- /*
- * When a TCP is attached to a socket, then there will be
- * a (struct inpcb) pointed at by the socket, and this
- * structure will point at a subsidary (struct tcpcb).
- */
- if (inp == NULL
-#ifdef INET6
- && in6p == NULL
-#endif
- )
- {
- return EINVAL;
- }
+ ostate = tcp_debug_capture(tp, PRU_ACCEPT);
/*
* Accept a connection. Essentially all the work is
@@ -869,94 +814,41 @@ tcp_accept(struct socket *so, struct mbu
*/
#ifdef INET
if (inp) {
- tp = intotcpcb(inp);
- KASSERT(tp != NULL);
- ostate = tcp_debug_capture(tp, PRU_ACCEPT);
in_setpeeraddr(inp, nam);
}
#endif
#ifdef INET6
if (in6p) {
- tp = in6totcpcb(in6p);
- KASSERT(tp != NULL);
- ostate = tcp_debug_capture(tp, PRU_ACCEPT);
in6_setpeeraddr(in6p, nam);
}
#endif
tcp_debug_trace(so, tp, ostate, PRU_ACCEPT);
+
return 0;
}
static int
tcp_bind(struct socket *so, struct mbuf *nam)
{
- struct inpcb *inp;
-#ifdef INET6
- struct in6pcb *in6p;
-#endif
+ struct inpcb *inp = NULL;
+ struct in6pcb *in6p = NULL;
struct tcpcb *tp = NULL;
int s;
int error = 0;
int ostate = 0;
- int family; /* family of the socket */
KASSERT(solocked(so));
+ if ((error = tcp_getpcb(so, &inp, &in6p, &tp)) != 0)
+ return error;
- s = splsoftnet();
-
- family = so->so_proto->pr_domain->dom_family;
- switch (family) {
-#ifdef INET
- case PF_INET:
- inp = sotoinpcb(so);
-#ifdef INET6
- in6p = NULL;
-#endif
- break;
-#endif
-#ifdef INET6
- case PF_INET6:
- inp = NULL;
- in6p = sotoin6pcb(so);
- break;
-#endif
- default:
- splx(s);
- return EAFNOSUPPORT;
- }
-
- /*
- * When a TCP is attached to a socket, then there will be
- * a (struct inpcb) pointed at by the socket, and this
- * structure will point at a subsidary (struct tcpcb).
- */
- if (inp == NULL
-#ifdef INET6
- && in6p == NULL
-#endif
- )
- {
- error = EINVAL;
- goto release;
- }
-#ifdef INET
- if (inp) {
- tp = intotcpcb(inp);
- ostate = tcp_debug_capture(tp, PRU_BIND);
- }
-#endif
-#ifdef INET6
- if (in6p) {
- tp = in6totcpcb(in6p);
- ostate = tcp_debug_capture(tp, PRU_BIND);
- }
-#endif
+ ostate = tcp_debug_capture(tp, PRU_BIND);
/*
* Give the socket an address.
*/
- switch (family) {
+ s = splsoftnet();
+ switch (so->so_proto->pr_domain->dom_family) {
#ifdef INET
case PF_INET:
error = in_pcbbind(inp, nam);
@@ -977,80 +869,32 @@ tcp_bind(struct socket *so, struct mbuf
}
tcp_debug_trace(so, tp, ostate, PRU_BIND);
-
-release:
splx(s);
- return (error);
+
+ return error;
}
static int
tcp_listen(struct socket *so)
{
- struct inpcb *inp;
-#ifdef INET6
- struct in6pcb *in6p;
-#endif
+ struct inpcb *inp = NULL;
+ struct in6pcb *in6p = NULL;
struct tcpcb *tp = NULL;
int s;
int error = 0;
int ostate = 0;
- int family; /* family of the socket */
KASSERT(solocked(so));
- s = splsoftnet();
-
- family = so->so_proto->pr_domain->dom_family;
- switch (family) {
-#ifdef INET
- case PF_INET:
- inp = sotoinpcb(so);
-#ifdef INET6
- in6p = NULL;
-#endif
- break;
-#endif
-#ifdef INET6
- case PF_INET6:
- inp = NULL;
- in6p = sotoin6pcb(so);
- break;
-#endif
- default:
- splx(s);
- return EAFNOSUPPORT;
- }
+ if ((error = tcp_getpcb(so, &inp, &in6p, &tp)) != 0)
+ return error;
- /*
- * When a TCP is attached to a socket, then there will be
- * a (struct inpcb) pointed at by the socket, and this
- * structure will point at a subsidary (struct tcpcb).
- */
- if (inp == NULL
-#ifdef INET6
- && in6p == NULL
-#endif
- )
- {
- error = EINVAL;
- goto release;
- }
-#ifdef INET
- if (inp) {
- tp = intotcpcb(inp);
- ostate = tcp_debug_capture(tp, PRU_LISTEN);
- }
-#endif
-#ifdef INET6
- if (in6p) {
- tp = in6totcpcb(in6p);
- ostate = tcp_debug_capture(tp, PRU_LISTEN);
- }
-#endif
+ ostate = tcp_debug_capture(tp, PRU_LISTEN);
/*
* Prepare to accept connections.
*/
+ s = splsoftnet();
#ifdef INET
if (inp && inp->inp_lport == 0) {
error = in_pcbbind(inp, NULL);
@@ -1067,11 +911,11 @@ tcp_listen(struct socket *so)
#endif
tp->t_state = TCPS_LISTEN;
- tcp_debug_trace(so, tp, ostate, PRU_LISTEN);
-
release:
+ tcp_debug_trace(so, tp, ostate, PRU_LISTEN);
splx(s);
- return (error);
+
+ return error;
}
static int
@@ -1104,47 +948,23 @@ static int
tcp_peeraddr(struct socket *so, struct mbuf *nam)
{
struct inpcb *inp = NULL;
-#ifdef INET6
struct in6pcb *in6p = NULL;
-#endif
struct tcpcb *tp = NULL;
int ostate = 0;
+ int error = 0;
- switch (so->so_proto->pr_domain->dom_family) {
-#ifdef INET
- case PF_INET:
- inp = sotoinpcb(so);
- break;
-#endif
-#ifdef INET6
- case PF_INET6:
- in6p = sotoin6pcb(so);
- break;
-#endif
- default:
- return EAFNOSUPPORT;
- }
+ if ((error = tcp_getpcb(so, &inp, &in6p, &tp)) != 0)
+ return error;
- if (inp == NULL
-#ifdef INET6
- && in6p == NULL
-#endif
- )
- return EINVAL;
+ ostate = tcp_debug_capture(tp, PRU_PEERADDR);
#ifdef INET
- if (inp) {
- tp = intotcpcb(inp);
- ostate = tcp_debug_capture(tp, PRU_PEERADDR);
+ if (inp)
in_setpeeraddr(inp, nam);
- }
#endif
#ifdef INET6
- if (in6p) {
- tp = in6totcpcb(in6p);
- ostate = tcp_debug_capture(tp, PRU_PEERADDR);
+ if (in6p)
in6_setpeeraddr(in6p, nam);
- }
#endif
tcp_debug_trace(so, tp, ostate, PRU_PEERADDR);
@@ -1156,47 +976,23 @@ static int
tcp_sockaddr(struct socket *so, struct mbuf *nam)
{
struct inpcb *inp = NULL;
-#ifdef INET6
struct in6pcb *in6p = NULL;
-#endif
struct tcpcb *tp = NULL;
int ostate = 0;
+ int error = 0;
- switch (so->so_proto->pr_domain->dom_family) {
-#ifdef INET
- case PF_INET:
- inp = sotoinpcb(so);
- break;
-#endif
-#ifdef INET6
- case PF_INET6:
- in6p = sotoin6pcb(so);
- break;
-#endif
- default:
- return EAFNOSUPPORT;
- }
+ if ((error = tcp_getpcb(so, &inp, &in6p, &tp)) != 0)
+ return error;
- if (inp == NULL
-#ifdef INET6
- && in6p == NULL
-#endif
- )
- return EINVAL;
+ ostate = tcp_debug_capture(tp, PRU_SOCKADDR);
#ifdef INET
- if (inp) {
- tp = intotcpcb(inp);
- ostate = tcp_debug_capture(tp, PRU_SOCKADDR);
+ if (inp)
in_setsockaddr(inp, nam);
- }
#endif
#ifdef INET6
- if (in6p) {
- tp = in6totcpcb(in6p);
- ostate = tcp_debug_capture(tp, PRU_SOCKADDR);
+ if (in6p)
in6_setsockaddr(in6p, nam);
- }
#endif
tcp_debug_trace(so, tp, ostate, PRU_SOCKADDR);
@@ -1208,46 +1004,15 @@ static int
tcp_recvoob(struct socket *so, struct mbuf *m, int flags)
{
struct inpcb *inp = NULL;
-#ifdef INET6
struct in6pcb *in6p = NULL;
-#endif
struct tcpcb *tp = NULL;
int ostate = 0;
+ int error = 0;
- switch (so->so_proto->pr_domain->dom_family) {
-#ifdef INET
- case PF_INET:
- inp = sotoinpcb(so);
- break;
-#endif
-#ifdef INET6
- case PF_INET6:
- in6p = sotoin6pcb(so);
- break;
-#endif
- default:
- return EAFNOSUPPORT;
- }
-
- if (inp == NULL
-#ifdef INET6
- && in6p == NULL
-#endif
- )
- return EINVAL;
+ if ((error = tcp_getpcb(so, &inp, &in6p, &tp)) != 0)
+ return error;
-#ifdef INET
- if (inp) {
- tp = intotcpcb(inp);
- ostate = tcp_debug_capture(tp, PRU_RCVOOB);
- }
-#endif
-#ifdef INET6
- if (in6p) {
- tp = in6totcpcb(in6p);
- ostate = tcp_debug_capture(tp, PRU_RCVOOB);
- }
-#endif
+ ostate = tcp_debug_capture(tp, PRU_RCVOOB);
if ((so->so_oobmark == 0 &&
(so->so_state & SS_RCVATMARK) == 0) ||
@@ -1272,47 +1037,15 @@ static int
tcp_sendoob(struct socket *so, struct mbuf *m, struct mbuf *control)
{
struct inpcb *inp = NULL;
-#ifdef INET6
struct in6pcb *in6p = NULL;
-#endif
struct tcpcb *tp = NULL;
int ostate = 0;
int error = 0;
- switch (so->so_proto->pr_domain->dom_family) {
-#ifdef INET
- case PF_INET:
- inp = sotoinpcb(so);
- break;
-#endif
-#ifdef INET6
- case PF_INET6:
- in6p = sotoin6pcb(so);
- break;
-#endif
- default:
- return EAFNOSUPPORT;
- }
-
- if (inp == NULL
-#ifdef INET6
- && in6p == NULL
-#endif
- )
- return EINVAL;
+ if ((error = tcp_getpcb(so, &inp, &in6p, &tp)) != 0)
+ return error;
-#ifdef INET
- if (inp) {
- tp = intotcpcb(inp);
- ostate = tcp_debug_capture(tp, PRU_SENDOOB);
- }
-#endif
-#ifdef INET6
- if (in6p) {
- tp = in6totcpcb(in6p);
- ostate = tcp_debug_capture(tp, PRU_SENDOOB);
- }
-#endif
+ ostate = tcp_debug_capture(tp, PRU_SENDOOB);
if (sbspace(&so->so_snd) < -512) {
m_freem(m);