summaryrefslogtreecommitdiffstats
path: root/sys/netinet6/raw_ip6.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/netinet6/raw_ip6.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/netinet6/raw_ip6.c')
-rw-r--r--sys/netinet6/raw_ip6.c35
1 files changed, 13 insertions, 22 deletions
diff --git a/sys/netinet6/raw_ip6.c b/sys/netinet6/raw_ip6.c
index 5b6daac..76fb495 100644
--- a/sys/netinet6/raw_ip6.c
+++ b/sys/netinet6/raw_ip6.c
@@ -549,27 +549,18 @@ rip6_attach(struct socket *so, int proto, struct thread *td)
struct icmp6_filter *filter;
int error, s;
- INP_INFO_WLOCK(&ripcbinfo);
inp = sotoinpcb(so);
- if (inp) {
- INP_INFO_WUNLOCK(&ripcbinfo);
- panic("rip6_attach");
- }
- if (td && (error = suser(td)) != 0) {
- INP_INFO_WUNLOCK(&ripcbinfo);
+ KASSERT(inp == NULL, ("rip6_attach: inp != NULL"));
+ if (td && (error = suser(td)) != 0)
return error;
- }
error = soreserve(so, rip_sendspace, rip_recvspace);
- if (error) {
- INP_INFO_WUNLOCK(&ripcbinfo);
+ if (error)
return error;
- }
MALLOC(filter, struct icmp6_filter *,
sizeof(struct icmp6_filter), M_PCB, M_NOWAIT);
- if (filter == NULL) {
- INP_INFO_WUNLOCK(&ripcbinfo);
+ if (filter == NULL)
return ENOMEM;
- }
+ INP_INFO_WLOCK(&ripcbinfo);
s = splnet();
error = in_pcballoc(so, &ripcbinfo, "raw6inp");
splx(s);
@@ -596,12 +587,8 @@ rip6_detach(struct socket *so)
{
struct inpcb *inp;
- INP_INFO_WLOCK(&ripcbinfo);
inp = sotoinpcb(so);
- if (inp == 0) {
- INP_INFO_WUNLOCK(&ripcbinfo);
- panic("rip6_detach");
- }
+ KASSERT(inp != NULL, ("rip6_detach: inp == NULL"));
/* xxx: RSVP */
if (so == ip6_mrouter)
ip6_mrouter_done();
@@ -609,8 +596,10 @@ rip6_detach(struct socket *so)
FREE(inp->in6p_icmp6filt, M_PCB);
inp->in6p_icmp6filt = NULL;
}
+ INP_INFO_WLOCK(&ripcbinfo);
INP_LOCK(inp);
in6_pcbdetach(inp);
+ in6_pcbfree(inp);
INP_INFO_WUNLOCK(&ripcbinfo);
}
@@ -630,7 +619,7 @@ rip6_disconnect(struct socket *so)
return ENOTCONN;
inp->in6p_faddr = in6addr_any;
rip6_abort(so);
- return 0;
+ return (0);
}
static int
@@ -641,6 +630,7 @@ rip6_bind(struct socket *so, struct sockaddr *nam, struct thread *td)
struct ifaddr *ia = NULL;
int error = 0;
+ KASSERT(inp != NULL, ("rip6_bind: inp == NULL"));
if (nam->sa_len != sizeof(*addr))
return EINVAL;
if (TAILQ_EMPTY(&ifnet) || addr->sin6_family != AF_INET6)
@@ -674,6 +664,7 @@ rip6_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
struct ifnet *ifp = NULL;
int error = 0, scope_ambiguous = 0;
+ KASSERT(inp != NULL, ("rip6_connect: inp == NULL"));
if (nam->sa_len != sizeof(*addr))
return EINVAL;
if (TAILQ_EMPTY(&ifnet))
@@ -726,10 +717,9 @@ rip6_shutdown(struct socket *so)
{
struct inpcb *inp;
- INP_INFO_RLOCK(&ripcbinfo);
inp = sotoinpcb(so);
+ KASSERT(inp != NULL, ("rip6_shutdown: inp == NULL"));
INP_LOCK(inp);
- INP_INFO_RUNLOCK(&ripcbinfo);
socantsendmore(so);
INP_UNLOCK(inp);
return 0;
@@ -744,6 +734,7 @@ rip6_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam,
struct sockaddr_in6 *dst;
int ret;
+ KASSERT(inp != NULL, ("rip6_send: inp == NULL"));
INP_INFO_WLOCK(&ripcbinfo);
/* always copy sockaddr to avoid overwrites */
/* Unlocked read. */
OpenPOWER on IntegriCloud