Exemplo n.º 1
0
void
in6_pcbdetach(struct in6pcb *in6p)
{
	struct socket *so = in6p->in6p_socket;
	int s;

	if (in6p->in6p_af != AF_INET6)
		return;

#if defined(IPSEC) || defined(FAST_IPSEC)
	ipsec6_delete_pcbpolicy(in6p);
#endif /* IPSEC */
	so->so_pcb = 0;
	if (in6p->in6p_options)
		m_freem(in6p->in6p_options);
	if (in6p->in6p_outputopts != NULL) {
		ip6_clearpktopts(in6p->in6p_outputopts, -1);
		free(in6p->in6p_outputopts, M_IP6OPT);
	}
	rtcache_free(&in6p->in6p_route);
	ip6_freemoptions(in6p->in6p_moptions);
	s = splnet();
	in6_pcbstate(in6p, IN6P_ATTACHED);
	LIST_REMOVE(&in6p->in6p_head, inph_lhash);
	CIRCLEQ_REMOVE(&in6p->in6p_table->inpt_queue, &in6p->in6p_head,
	    inph_queue);
	pool_put(&in6pcb_pool, in6p);
	splx(s);
	sofree(so);				/* drops the socket's lock */
	mutex_enter(softnet_lock);		/* reacquire it */
}
Exemplo n.º 2
0
Arquivo: in6_pcb.c Projeto: Prajna/xnu
void
in6_pcbdetach(
	struct inpcb *inp)
{
	struct socket *so = inp->inp_socket;
	struct inpcbinfo *ipi = inp->inp_pcbinfo;

#if IPSEC
	if (inp->in6p_sp != NULL) {
		ipsec6_delete_pcbpolicy(inp);
	}
#endif /* IPSEC */

	if (in_pcb_checkstate(inp, WNT_STOPUSING, 1) != WNT_STOPUSING)
		printf("in6_pcbdetach so=%p can't be marked dead ok\n", so);

	inp->inp_state = INPCB_STATE_DEAD;

	if ((so->so_flags & SOF_PCBCLEARING) == 0) {
		struct ip_moptions *imo;
		struct ip6_moptions *im6o;

		inp->inp_vflag = 0;
		so->so_flags |= SOF_PCBCLEARING;
		inp->inp_gencnt = ++ipi->ipi_gencnt;
		if (inp->in6p_options)
			m_freem(inp->in6p_options);
 		ip6_freepcbopts(inp->in6p_outputopts);
		if (inp->in6p_route.ro_rt) {
			rtfree(inp->in6p_route.ro_rt);
			inp->in6p_route.ro_rt = NULL;
		}
		/* Check and free IPv4 related resources in case of mapped addr */
		if (inp->inp_options)
			(void)m_free(inp->inp_options);

		im6o = inp->in6p_moptions;
		inp->in6p_moptions = NULL;
		if (im6o != NULL)
			IM6O_REMREF(im6o);

		imo = inp->inp_moptions;
		inp->inp_moptions = NULL;
		if (imo != NULL)
			IMO_REMREF(imo);
	}
}