예제 #1
0
/*
 * Check for alternatives when higher level complains
 * about service problems.  For now, invalidate cached
 * routing information.  If the route was created dynamically
 * (by a redirect), time to try a default gateway again.
 */
void
in6_losing(struct in6pcb *in6p)
{
	struct rtentry *rt;
	struct rt_addrinfo info;

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

	if ((rt = rtcache_validate(&in6p->in6p_route)) == NULL)
		return;

	memset(&info, 0, sizeof(info));
	info.rti_info[RTAX_DST] = rtcache_getdst(&in6p->in6p_route);
	info.rti_info[RTAX_GATEWAY] = rt->rt_gateway;
	info.rti_info[RTAX_NETMASK] = rt_mask(rt);
	rt_missmsg(RTM_LOSING, &info, rt->rt_flags, 0);
	if (rt->rt_flags & RTF_DYNAMIC) {
		(void)rtrequest(RTM_DELETE, rt_getkey(rt),
		    rt->rt_gateway, rt_mask(rt), rt->rt_flags, NULL);
	}
	/*
	 * A new route can be allocated
	 * the next time output is attempted.
	 */
	rtcache_free(&in6p->in6p_route);
}
예제 #2
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 */
}
예제 #3
0
/*
 * After a routing change, flush old routing.  A new route can be
 * allocated the next time output is attempted.
 */
void
in6_rtchange(struct in6pcb *in6p, int errno)
{
	if (in6p->in6p_af != AF_INET6)
		return;

	rtcache_free(&in6p->in6p_route);
	/*
	 * A new route can be allocated the next time
	 * output is attempted.
	 */
}
예제 #4
0
static int
gif_clone_destroy(struct ifnet *ifp)
{
	struct gif_softc *sc = (void *) ifp;

	gif_delete_tunnel(&sc->gif_if);
	LIST_REMOVE(sc, gif_list);
#ifdef INET6
	encap_detach(sc->encap_cookie6);
#endif
#ifdef INET
	encap_detach(sc->encap_cookie4);
#endif

	bpf_detach(ifp);
	if_detach(ifp);
	rtcache_free(&sc->gif_ro);

	free(sc, M_DEVBUF);

	return (0);
}