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

📄 route.c

📁 VXWORKS 源码
💻 C
📖 第 1 页 / 共 4 页
字号:
 */voidrtalloc(ro)	register struct route *ro;{	if (ro->ro_rt && ro->ro_rt->rt_ifp && (ro->ro_rt->rt_flags & RTF_UP))		return;				 /* XXX */	ro->ro_rt = rtalloc1(&ro->ro_dst, 1);}struct rtentry *rtalloc1(dst, report)	register struct sockaddr *dst;	int report;{	register struct radix_node_head *rnh = rt_tables[dst->sa_family];	register struct rtentry *rt;	register struct radix_node *rn;	struct rtentry *newrt = 0;	struct rt_addrinfo info;	u_long tosRtMask;	/* TOS route mask */	u_long newRtMask;	/* TOS 0 route mask */	int  s = splnet(), err = 0, msgtype = RTM_MISS;	struct rtentry *   tosRt = NULL;        u_char     savedTos;      /*        * save original tos since we overwrite it temporarily in the        * dst socketaddr       */       savedTos = TOS_GET (dst);       /*	* The Type of Service octet consists of three fields:	*	*       0     1     2     3     4     5     6     7	*     +-----+-----+-----+-----+-----+-----+-----+-----+	*     |                 |                       |     |	*     |   PRECEDENCE    |          TOS          | MBZ |	*     |                 |                       |     |	*     +-----+-----+-----+-----+-----+-----+-----+-----+	*	* Precedence bits should not be considered when searching	* the table.  An existing matching route would not be found	* and if a new route were created, since dst is copied to 	* generate the key, precedence bits would be part	* of the new route's TOS field which is wrong.  This	* would create a leak if this wrong route were created	* for a local address.  ARP would hold on to a packet,	* while it resolves the local address.  When the reply	* comes back, since ARP does not look for routes with	* TOS set, the packet would never be sent.	*	*/	TOS_SET(dst, savedTos & 0x1f);match:	if (rnh && (rn = rnh->rnh_matchaddr((caddr_t)dst, rnh)) &&	    ((rn->rn_flags & RNF_ROOT) == 0)) {		newrt = rt = (struct rtentry *)rn;                if ( (dst->sa_family == AF_INET) && (rt->rt_refcnt == 0) &&                    (rt->rt_flags & RTF_DELETE) && !(rt->rt_flags & RTF_STATIC))                    {                    /*                     * Reusing a (cloned) route to a remote destination.                     * Remove deletion tag and reset timer.                     *                     * NOTE: All manually added proxy ARP entries include                     * the RTF_ANNOUNCE flag which uses the same value as                     * the RTF_DELETE flag. The preceding test for RTF_STATIC                     * preserves the flag settings for those ARP entries,                     * even though the removal of RTF_ANNOUNCE should be                     * harmless since its only purpose is to trigger the                     * gratuitous ARP request when the entry is created.                     */                    rt->rt_flags &= ~RTF_DELETE;                    rt->rt_rmx.rmx_expire = 0;                    }		if (report && (rt->rt_flags & RTF_CLONING)) {#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_INFO event */            WV_NET_MARKER_2 (NET_AUX_EVENT, WV_NET_INFO, 17, 9,                             WV_NETEVENT_RTALLOC_CLONE,                         ((struct sockaddr_in *)rt_key (rt))->sin_addr.s_addr,                          ((struct sockaddr_in *)dst)->sin_addr.s_addr)#endif  /* INCLUDE_WVNET */#endif			err = rtrequest(RTM_RESOLVE, dst, SA(0),					      SA(0), 0, &newrt);			if (err) {				newrt = rt;				rt->rt_refcnt++;				goto miss;			}			if ((rt = newrt) && (rt->rt_flags & RTF_XRESOLVE)) {				msgtype = RTM_RESOLVE;				goto miss;			}		} else                      {#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_INFO event */        WV_NET_DSTADDROUT_MARKER_1 (NET_AUX_EVENT, WV_NET_INFO, 18, 10,                               ((struct sockaddr_in *)dst)->sin_addr.s_addr,                                    WV_NETEVENT_RTALLOC_SEARCHGOOD,                               ((struct sockaddr_in *)dst)->sin_addr.s_addr)#endif  /* INCLUDE_WVNET */#endif                      rt->rt_refcnt++;                      }	} else {		rtstat.rts_unreach++;	miss:#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_CRITICAL event */        WV_NET_MARKER_1 (NET_AUX_EVENT, WV_NET_CRITICAL, 26, 5,                         WV_NETEVENT_RTALLOC_SEARCHFAIL,                         ((struct sockaddr_in *)dst)->sin_addr.s_addr)#endif  /* INCLUDE_WVNET */#endif                if (report) {			bzero((caddr_t)&info, sizeof(info));			info.rti_info[RTAX_DST] = dst;                        if (rtMissMsgHook)                            (*rtMissMsgHook) (msgtype, &info, 0, err);		}	}        /*         *  RFC 1583 Section 11.1:         *         * "Select the routing table entry whose value matches the TOS found         *  in the packet header.  If there is no routing table entry for         *  this TOS, select the routing table entry for TOS 0.  In other         *  words, packets requesting TOS X are routed along the TOS 0         *  path if a TOS X path does not exist."	 *  See also RFC 1349, Appendix B.4.         */        if (TOS_GET (dst) != 0)            {            TOS_SET (dst, 0);            tosRt = newrt;            newrt = NULL;            goto match;            }        /*         * tosRt is the TOS route match, if any. If none exists, tosRt is the         * default route ("0.0.0.0"), if any.  Otherwise, tosRt is NULL.         * newrt is the TOS 0 route.         */        if (tosRt != NULL)            {            if (newrt != NULL)                {                /*                 * Host route entries created by ARP have null masks with                 * implied mask = 0xffffffff                 */                tosRtMask =  (rt_mask (tosRt) == NULL) ? 0xffffffff :                    ((struct sockaddr_in *) rt_mask (tosRt))->sin_addr.s_addr;#ifdef RTALLOC_DEBUG                printf("\nBEST MATCHING TOS ROUTE:\n");                 routeEntryDebugShow ((struct radix_node *)tosRt);                printf("\nTOS 0 ROUTE:\n");                 routeEntryDebugShow ((struct radix_node *)newrt);#endif /* RTALLOC_DEBUG */                newRtMask =  (rt_mask (newrt) == NULL) ? 0xffffffff :                    ((struct sockaddr_in *) rt_mask (newrt))->sin_addr.s_addr;                /*                 * select the route with longest netmask. we assume                 * contiguous masks starting at the same bit position.                 * The default route has a mask = 0x00000000                 */                if (tosRtMask >= newRtMask)                    {                    RTFREE (newrt);                    newrt = tosRt;                    }                else                    {                    /* newrt is more specific: keep it */                    RTFREE (tosRt);                   }                }            else /* newrt is NULL */                {                /*                 * Restore previously found TOS route.  Can happen if there is a                 * route entered with TOS set, but no default route exists nor                 * route match with 0 TOS.                 */                newrt = tosRt;                }            }#ifdef RTALLOC_DEBUG	if (savedTos && newrt != NULL)	    {	    printf ("\nSELECTED ROUTE:\n");	    routeEntryDebugShow ((struct radix_node *)newrt);	    }#endif /* RTALLOC_DEBUG */       /* Restore the saved TOS. */        TOS_SET (dst, savedTos);       splx(s);       return (newrt);}    /*     * This version of the route search routine is specifically designed     * for retrieving a route when forwarding packets. Unlike the original     * case, this route search never clones routes to remote destinations.     * Those cloned routes are necessary for path MTU discovery, but should     * only exist when the Internet host originates the traffic, not when     * it forwards it as a router.     */struct rtentry *rtalloc2(dst)	register struct sockaddr *dst;{	register struct radix_node_head *rnh = rt_tables[dst->sa_family];	register struct rtentry *rt;	register struct radix_node *rn;	struct rtentry *newrt = 0;	struct rt_addrinfo info;	int  s = splnet(), err = 0, msgtype = RTM_MISS;	struct rtentry *   tosRt = NULL;        u_long tosRtMask;       /* TOS route mask */        u_long newRtMask;       /* TOS 0 route mask */        u_char     savedTos;      /*        * save original tos since we overwrite it temporarily in the        * dst socketaddr       */       savedTos = TOS_GET (dst);match:	if (rnh && (rn = rnh->rnh_matchaddr((caddr_t)dst, rnh)) &&	    ((rn->rn_flags & RNF_ROOT) == 0)) {		newrt = rt = (struct rtentry *)rn;                if ( (dst->sa_family == AF_INET) && (rt->rt_refcnt == 0) &&                    (rt->rt_flags & RTF_DELETE) && !(rt->rt_flags & RTF_STATIC))                    {                    /*                     * Reusing a (cloned) route to a remote destination.                     * Remove deletion tag and reset timer.                     *                     * NOTE: All manually added proxy ARP entries include                     * the RTF_ANNOUNCE flag which uses the same value as                     * the RTF_DELETE flag. The preceding test for RTF_STATIC                     * preserves the flag settings for those ARP entries,                     * even though the removal of RTF_ANNOUNCE should be                     * harmless since its only purpose is to trigger the                     * gratuitous ARP request when the entry is created.                     */                    rt->rt_flags &= ~RTF_DELETE;                    rt->rt_rmx.rmx_expire = 0;                    }                /*                 * Disable cloning when forwarding data to a remote                 * destination. This search will still create a                  * cloned entry if the destination is directly reachable                 * to hold the ARP information for the target host.                 */		if ( !(rt->rt_flags & RTF_GATEWAY) &&                    (rt->rt_flags & RTF_CLONING)) {			err = rtrequest(RTM_RESOLVE, dst, SA(0),					      SA(0), 0, &newrt);			if (err) {				newrt = rt;				rt->rt_refcnt++;				goto miss;			}			if ((rt = newrt) && (rt->rt_flags & RTF_XRESOLVE)) {				msgtype = RTM_RESOLVE;				goto miss;			}		} else			rt->rt_refcnt++;	} else {		rtstat.rts_unreach++;	miss:		bzero((caddr_t)&info, sizeof(info));		info.rti_info[RTAX_DST] = dst;                if (rtMissMsgHook)                    (*rtMissMsgHook) (msgtype, &info, 0, err);	}    /*     *  RFC 1583 Section 11.1:     *     * "Select the routing table entry whose value matches the TOS found     *  in the packet header.  If there is no routing table entry for     *  this TOS, select the routing table entry for TOS 0.  In other     *  words, packets requesting TOS X are routed along the TOS 0     *  path if a TOS X path does not exist."     *  See also RFC 1349, Appendix B.4.     */    if (TOS_GET (dst) != 0)           {        TOS_SET (dst, 0);        tosRt = newrt;        newrt = NULL;        goto match;        }    /*     * tosRt is the TOS route match, if any. If none exists, tosRt is the     * default route ("0.0.0.0"), if any.  Otherwise, tosRt is NULL.     * newrt is the TOS 0 route.     */    if (tosRt != NULL)        {        if (newrt != NULL)            {            /*             * Host route entries created by ARP have null masks with             * implied mask = 0xffffffff             */            tosRtMask =  (rt_mask (tosRt) == NULL) ? 0xffffffff :                ((struct sockaddr_in *) rt_mask (tosRt))->sin_addr.s_addr;            newRtMask =  (rt_mask (newrt) == NULL) ? 0xffffffff :                ((struct sockaddr_in *) rt_mask (newrt))->sin_addr.s_addr;            /*             * select the route with longest netmask. we assume             * contiguous masks starting at the same bit position.             * The default route has a mask = 0x00000000             */            if (tosRtMask >= newRtMask)                {                RTFREE (newrt);                newrt = tosRt;                }            else                {                /* newrt is more specific: keep it */                RTFREE (tosRt);               }            }        else /* newrt is NULL */            {            /*             * Restore previously found TOS route.  Can happen if there is a             * route entered with TOS set, but no default route exists nor             * route match with 0 TOS.             */            newrt = tosRt;            }        }       /*         * restore the saved tos. is redundant but harmless in case tos        * was default to  start with.        */        TOS_SET (dst, savedTos);        splx(s);        return (newrt);    }voidrtfree(rt)	register struct rtentry *rt;{	register struct ifaddr *ifa;#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_INFO event */    if (rt)        {        WV_NET_MARKER_2 (NET_AUX_EVENT, WV_NET_INFO, 19, 11,                         WV_NETEVENT_RTFREE_START,                         ((struct sockaddr_in *)rt_key (rt))->sin_addr.s_addr,                         rt->rt_refcnt)        }    else        {        WV_NET_MARKER_2 (NET_AUX_EVENT, WV_NET_INFO, 19, 11,                         WV_NETEVENT_RTFREE_START, 0, 0)        }#endif  /* INCLUDE_WVNET */#endif	if (rt == 0)            {#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_EMERGENCY event */            WV_NET_MARKER_0 (NET_AUX_EVENT, WV_NET_EMERGENCY, 21, 1,                     WV_NETEVENT_RTFREE_PANIC)#endif  /* INCLUDE_WVNET */#endif            panic("rtfree");            }	rt->rt_refcnt--;        if (rt_key(rt)->sa_family == AF_INET)            {            /*             * If route was cloned for path MTU results, mark for later             * removal (if not reused) instead of deleting immediately.             */            if ( (rt->rt_refcnt == 0) && (rt->rt_flags & RTF_UP) &&                (rt->rt_flags & RTF_HOST) && !(rt->rt_flags & RTF_LLINFO) &&                (rt->rt_flags & RTF_CLONED))                {                rt->rt_flags |= RTF_DELETE;                if (rt->rt_rmx.rmx_expire == 0)    /* Not yet assigned. */                    rt->rt_rmx.rmx_expire = tickGet() + routePendInterval;                }            }	if (rt->rt_refcnt <= 0 && (rt->rt_flags & RTF_UP) == 0) {		if (rt->rt_nodes->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, 21, 1,                                     WV_NETEVENT_RTFREE_PANIC)#endif  /* INCLUDE_WVNET */#endif                    panic ("rtfree 2");                    }		rttrash--;		if (rt->rt_refcnt < 0) {#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_ALERT event */                    WV_NET_MARKER_0 (NET_AUX_EVENT, WV_NET_ALERT, 8, 4,                                     WV_NETEVENT_RTFREE_BADREFCNT)#endif  /* INCLUDE_WVNET */#endif                    logMsg ("rtfree: %x not freed (neg refs)\n", (int)rt,                            0, 0, 0, 0, 0);                    return;                    }		ifa = rt->rt_ifa;		IFAFREE(ifa);                if (rt->rt_parent)                    {                    RTFREE (rt->rt_parent)                    }		Free(rt_key(rt));#ifdef ROUTER_STACK                /*                 * Entries which are not directly attached to the                 * tree use a different free routine since the netmask                 * information is stored in a uniquely allocated buffer,                 * not shared among multiple route entries.                 */

⌨️ 快捷键说明

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