⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 route.c

📁 VXWORKS 源码
💻 C
📖 第 1 页 / 共 4 页
字号:
		if ( ((ROUTE_ENTRY*)rt)->primaryRouteFlag == FALSE)		    routeEntryFree ((ROUTE_ENTRY*)rt, FALSE);                else		    Free ((ROUTE_ENTRY*)rt);#else                Free (rt);#endif /* ROUTER_STACK */	}}/* * Force a routing table entry to the specified * destination to go through the given gateway. * Normally called as a result of a routing redirect * message from the network layer. * * N.B.: must be called at splnet * */intrtredirect(dst, gateway, netmask, flags, src, rtp)	struct sockaddr *dst, *gateway, *netmask, *src;	int flags;	struct rtentry **rtp;{	register struct rtentry *rt;	int error = 0;	short *stat = 0;	struct rt_addrinfo info;	struct ifaddr *ifa;	/* verify the gateway is directly reachable */	if ((ifa = ifa_ifwithnet(gateway)) == 0) {		error = ENETUNREACH;		goto out;	}	rt = rtalloc1(dst, 0);	/*	 * If the redirect isn't from our current router for this dst,	 * it's either old or wrong.  If it redirects us to ourselves,	 * we have a routing loop, perhaps as a result of an interface	 * going down recently.	 */#define	equal(a1, a2) (bcmp((caddr_t)(a1), (caddr_t)(a2), (a1)->sa_len) == 0)	if (!(flags & RTF_DONE) && rt &&	     (!equal(src, rt->rt_gateway) || rt->rt_ifa != ifa))		error = EINVAL;	else if (ifa_ifwithaddr(gateway))		error = EHOSTUNREACH;	if (error)		goto done;	/*	 * Create a new entry if we just got back a wildcard entry	 * or the the lookup failed.  This is necessary for hosts	 * which use routing redirects generated by smart gateways	 * to dynamically build the routing tables.	 */	if ((rt == 0) || (rt_mask(rt) && rt_mask(rt)->sa_len < 2))		goto create;	/*	 * Don't listen to the redirect if it's	 * for a route to an interface. 	 */	if (rt->rt_flags & RTF_GATEWAY) {		if (((rt->rt_flags & RTF_HOST) == 0) && (flags & RTF_HOST)) {			/*			 * Changing from route to net => route to host.			 * Create new route, rather than smashing route to net.			 */		create:			flags |=  RTF_GATEWAY | RTF_DYNAMIC;                        /*                         * Create the new route entry using the default                         * weight. Do not report the change since the                         * later hook generates both types of messages.                         */                        error = rtrequestAddEqui (dst, netmask, gateway, flags,                                                  M2_ipRouteProto_icmp, 0,                                                  FALSE, FALSE, NULL);			/* error = rtrequest((int)RTM_ADD, dst, gateway,				    netmask, flags,				    (struct rtentry **)0);                        */			stat = &rtstat.rts_dynamic;		} else {			/*			 * Smash the current notion of the gateway to			 * this destination.  Should check about netmask!!!			 */			if (!(error = rt_setgate (rt, rt_key(rt), gateway)))			    {			    rt->rt_flags |= RTF_MODIFIED;			    flags |= RTF_MODIFIED;			    stat = &rtstat.rts_newgateway;			    rt->rt_mod = tickGet(); 	    /* last modified */			    rtmodified++; 			    }		}	} else		error = EHOSTUNREACH;done:	if (rt) {		if (rtp && !error)			*rtp = rt;		else			rtfree(rt);	}out:	if (error)            {#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_CRITICAL event */            WV_NET_MARKER_2 (NET_AUX_EVENT, WV_NET_CRITICAL, 27, 6,                             WV_NETEVENT_RTRESET_BADDEST,                             error,                              ((struct sockaddr_in *)gateway)->sin_addr.s_addr)#endif  /* INCLUDE_WVNET */#endif            rtstat.rts_badredirect++;            }	else if (stat != NULL)		(*stat)++;	bzero((caddr_t)&info, sizeof(info));	info.rti_info[RTAX_DST] = dst;	info.rti_info[RTAX_GATEWAY] = gateway;	info.rti_info[RTAX_NETMASK] = netmask;	info.rti_info[RTAX_AUTHOR] = src;        if (rtMissMsgHook)            (*rtMissMsgHook) (RTM_REDIRECT, &info, flags, error);#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_VERBOSE event */        WV_NET_MARKER_4 (NET_AUX_EVENT, WV_NET_VERBOSE, 34, 14,                         WV_NETEVENT_RTRESET_STATUS,                         error,                          ((struct sockaddr_in *)dst)->sin_addr.s_addr,                          ((struct sockaddr_in *)gateway)->sin_addr.s_addr,                          ((struct sockaddr_in *)netmask)->sin_addr.s_addr)#endif  /* INCLUDE_WVNET */#endif	return (error); }/** Routing table ioctl interface.** WRS MODS support for this function is being for backward compatibility.* This function has be moved else where because the routing code has * nothing to do with internet specific addresses since routing is independent* of the sockaddress family.*/intrtioctl(req, data)	int req;	caddr_t data;{	struct ortentry * pORE = NULL;	struct sockaddr netMask;	struct sockaddr * pNetMask = &netMask; 	register u_long i; 	register u_long net;	register struct in_ifaddr *ia;#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_INFO event */    WV_NET_MARKER_1 (NET_AUX_EVENT, WV_NET_INFO, 20, 12,                     WV_NETEVENT_RTIOCTL_START, req)#endif  /* INCLUDE_WVNET */#endif        if (req != SIOCADDRT && req != SIOCDELRT)            {#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_ERROR event */            WV_NET_MARKER_1 (NET_AUX_EVENT, WV_NET_ERROR, 37, 8,                             WV_NETEVENT_RTIOCTL_BADREQ, req)#endif  /* INCLUDE_WVNET */#endif            return (EINVAL);            }	pORE = (struct ortentry *)data;	/* BSD4.3 to BSD4.4 conversion */	if (req == SIOCADDRT)	    req = RTM_ADD;	else	    req = RTM_DELETE;	/* 	 * Set the netmask to the netmask of the interface address.	 * This has to be removed if provision is made with routeAdd	 * to add the network mask. 	 */	bzero ((caddr_t)&netMask, sizeof (struct sockaddr));	/* check for default gateway address */	if (((struct sockaddr_in *)(&pORE->rt_dst))->sin_addr.s_addr 	    != INADDR_ANY )	    {	    i = ntohl(((struct sockaddr_in*)&pORE->rt_dst)->sin_addr.s_addr);			    pNetMask->sa_family = AF_INET; 	    pNetMask->sa_len    = 8;	    if (IN_CLASSA(i))		{		((struct sockaddr_in *)pNetMask)->sin_addr.s_addr = 		    htonl(IN_CLASSA_NET);		net = i & IN_CLASSA_NET;		}	    else if (IN_CLASSB(i))		{		((struct sockaddr_in *)pNetMask)->sin_addr.s_addr = 		    htonl(IN_CLASSB_NET);		net = i & IN_CLASSB_NET;		}	    else if (IN_CLASSC(i))		{		((struct sockaddr_in *)pNetMask)->sin_addr.s_addr = 		    htonl(IN_CLASSC_NET);		net = i & IN_CLASSC_NET;		}	    else		{		((struct sockaddr_in *)pNetMask)->sin_addr.s_addr = 		    htonl(IN_CLASSD_NET);		net = i & IN_CLASSD_NET;		}	    /*	     * Check whether network is a subnet;	     * if so, return subnet number.	     */#ifdef VIRTUAL_STACK	    for (ia = _in_ifaddr; ia; ia = ia->ia_next)#else	    for (ia = in_ifaddr; ia; ia = ia->ia_next)#endif /* VIRTUAL_STACK */		if (net == ia->ia_net)		    ((struct sockaddr_in *)pNetMask)->sin_addr.s_addr =			htonl(ia->ia_subnetmask); 	    in_socktrim ((struct sockaddr_in *)pNetMask); 	    }       pORE->rt_flags |= RTF_GATEWAY;       if(pORE->rt_flags & RTF_HOST)	   pNetMask=0; #ifdef DEBUG       logMsg("rtIoctl:before rtrequestAddEqui/DelEqui\n",0,0,0,0,0,0);#endif        /*         * Add the requested route using the default weight value or delete         * the matching entry. In either case, report the change using both         * routing socket messages and direct callbacks.         */       if(req==RTM_ADD)	   return (rtrequestAddEqui (&pORE->rt_dst, pNetMask,                                     &pORE->rt_gateway, pORE->rt_flags,                                     M2_ipRouteProto_other, 0,                                     TRUE, TRUE, NULL));       else	   return (rtrequestDelEqui (&pORE->rt_dst, pNetMask,                                     &pORE->rt_gateway, pORE->rt_flags,                                     M2_ipRouteProto_other, TRUE, TRUE, NULL));}#define ROUNDUP(a) (a>0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))int rt_fixdelete (struct radix_node *, void *);static int rt_fixchange (struct radix_node *, void *);intrtrequest(req, dst, gateway, netmask, flags, ret_nrt)	int req, flags;	struct sockaddr *dst, *gateway, *netmask;	struct rtentry **ret_nrt;{	int s = splnet(); int error = 0;	register struct rtentry *rt;	register struct radix_node *rn;	register struct radix_node_head *rnh;	struct ifaddr *ifa;	struct sockaddr *ndst;#define senderr(x) { error = x ; goto bad; }	if ((rnh = rt_tables[dst->sa_family]) == 0)		senderr(ESRCH);	if (flags & RTF_HOST)            {            netmask = 0;	    }        if (netmask)	    {	    TOS_SET (netmask, 0x1f);  /* set the 5 bits in the mask corresponding					 to the TOS bits */	    }	switch (req) {	case RTM_DELETE:		if ((rn = rnh->rnh_deladdr(dst, netmask, rnh)) == 0)			senderr(ESRCH);		if (rn->rn_flags & (RNF_ACTIVE | RNF_ROOT))                    {#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_EMERGENCY event */                    WV_NET_MARKER_0 (NET_AUX_EVENT, WV_NET_EMERGENCY, 22, 2,                                     WV_NETEVENT_RTREQ_PANIC)#endif  /* INCLUDE_WVNET */#endif                    panic ("rtrequest delete");                    }		rt = (struct rtentry *)rn;                /*                 * Search the appropriate subtree to remove any children                 * (created for path MTU results). This cleanup must occur                 * before clearing the RTF_UP flag or the system might                 * release the current node's memory prematurely if the                 * search deletes the last reference.                 */                if (dst->sa_family == AF_INET &&                    (rt->rt_flags & RTF_CLONING) && netmask)                    {                    rn_walksubtree (rnh, dst, netmask, rt_fixdelete, rt);                    }		rt->rt_flags &= ~RTF_UP;		if (rt->rt_gwroute) {			rt = rt->rt_gwroute; RTFREE(rt);			(rt = (struct rtentry *)rn)->rt_gwroute = 0;		}		if ((ifa = rt->rt_ifa) && ifa->ifa_rtrequest)			ifa->ifa_rtrequest(RTM_DELETE, rt, SA(0));		rttrash++;		if (ret_nrt)			*ret_nrt = rt;		else if (rt->rt_refcnt <= 0) {			rt->rt_refcnt++;			rtfree(rt);		}		rtmodified++;		break;	case RTM_RESOLVE:		if (ret_nrt == 0 || (rt = *ret_nrt) == 0)                        {#ifdef DEBUG                        logMsg("rtrequest: RTM_RESOLVE, EINVAL error\n",0,0,0,0,0,0);#endif			senderr(EINVAL);                        }		ifa = rt->rt_ifa;		flags = rt->rt_flags & ~RTF_CLONING;		gateway = rt->rt_gateway;		if ((netmask = rt->rt_genmask) == 0)			{			flags |= RTF_HOST;			}		goto makeroute;	case RTM_ADD:		if ((ifa = ifa_ifwithroute(flags, dst, gateway)) == 0)			senderr(ENETUNREACH);	makeroute:		R_Malloc(rt, struct rtentry *, sizeof(ROUTE_ENTRY));		if (rt == 0)			senderr(ENOBUFS);		Bzero(rt, sizeof (ROUTE_ENTRY));		rt->rt_flags = RTF_UP | flags;		if (rt_setgate(rt, dst, gateway)) {			Free(rt);			senderr(ENOBUFS);		}		ndst = rt_key(rt);		if (netmask) {			rt_maskedcopy(dst, ndst, netmask);		} else			Bcopy(dst, ndst, dst->sa_len);            /* Set IP routes to create children (for path MTU results). */            if (ndst->sa_family == AF_INET &&                !IN_MULTICAST                    (ntohl ( ((struct sockaddr_in *)ndst)->sin_addr.s_addr)) &&                ! (rt->rt_flags & RTF_HOST))                {                if (((struct sockaddr_in *)netmask)->sin_addr.s_addr                          != 0xffffffff)                    {                    rt->rt_flags |= RTF_CLONING;                    }                }		rn = rnh->rnh_addaddr((caddr_t)ndst, (caddr_t)netmask,					rnh, rt->rt_nodes);		/* update proto field of rt entry, in the gateway sockaddr */		if ((req == RTM_ADD) && (gateway->sa_family == AF_INET))		    RT_PROTO_SET (ndst, RT_PROTO_GET (dst));                if (rn == 0 && (rt->rt_flags & RTF_HOST))                    {                    /* Replace matching (cloned) entry if possible. */                    rn = routeSwap (rnh, rt, ndst, netmask);                    }		if (rn == 0) {			if (rt->rt_gwroute)				rtfree(rt->rt_gwroute);			Free(rt_key(rt));			Free(rt);			senderr(EEXIST);		}		ifa->ifa_refcnt++;		rt->rt_ifa = ifa;		rt->rt_ifp = ifa->ifa_ifp;		if (req == RTM_RESOLVE)                    {                    rt->rt_rmx = (*ret_nrt)->rt_rmx; /* copy metrics */                    rt->rt_parent = (*ret_nrt);   /* record source route */                    (*ret_nrt)->rt_refcnt++;                    rt->rt_flags |= RTF_CLONED;                                        /*                     * Mark the cloned route as a representative route                     * so that when it is deleted, Fastpath is called with                     * ROUTE_REP_DEL operation and the entry gets removed                     * from the Fastpath cache                     */                     ((ROUTE_ENTRY*)rt)->primaryRouteFlag = TRUE;                    }                if (rt->rt_ifp->if_type == IFT_PMP)                    {                    /*                     * Point-to-multipoint devices do not use a common                     * MTU value for all destinations or perform address                     * resolution, so cloning the interface route to store                     * that information is not necessary.                     */                    rt->rt_flags &= ~RTF_CLONING;                    }                /* Assign initial path MTU estimate, if enabled for route. */                if (!rt->rt_rmx.rmx_mtu && !(rt->rt_rmx.rmx_locks & RTV_MTU)                    && rt->rt_ifp)                    rt->rt_rmx.rmx_mtu = rt->rt_ifp->if_mtu;		if (ifa->ifa_rtrequest)			ifa->ifa_rtrequest(req, rt, SA(ret_nrt ? *ret_nrt : 0));                if (ndst->sa_family == AF_INET)                    {                    /*                     * Remove any cloned routes which a new                     * network route overrides.                     */                    if (!(rt->rt_flags & RTF_HOST) && rt_mask (rt) != 0)                        {                        rn_walksubtree (rnh, ndst, netmask, rt_fixchange, rt);                        }                    }		if (ret_nrt) {			*ret_nrt = rt;			rt->rt_refcnt++;		}		rt->rt_mod = tickGet(); 	/* last modified */		rtmodified++;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -