📄 rrtask.c
字号:
/** Copyright (c) 1998-2001 by NETsilicon Inc.** This software is copyrighted by and is the sole property of* NETsilicon. All rights, title, ownership, or other interests* in the software remain the property of NETsilicon. This* software may only be used in accordance with the corresponding* license agreement. Any unauthorized use, duplication, transmission,* distribution, or disclosure of this software is expressly forbidden.** This Copyright notice may not be removed or modified without prior* written consent of NETsilicon.** NETsilicon, reserves the right to modify this software* without notice.** NETsilicon* 411 Waverley Oaks Road USA 781.647.1234* Suite 227 http://www.netsilicon.com* Waltham, MA 02452 AmericaSales@netsilicon.com*************************************************************************** $Source: M:/psisrc/routing/common/rcs/rrtask.c $*************************************************************************** File Description: Router main task for when INLINE_ROUTER is NOT defined.* The user must start an OS task to run the function* fns_router. This file should be omitted from your* build if you have INLINE_ROUTER defined or you are* not using RIP or OSPF.***************************************************************************/#include "config.h"#if !defined(INLINE_ROUTER) && (defined(RIP_PROTOCOL) || defined(OSPF_PROTOCOL))#define __RRTASK_C__#include "fnsproto.h"#include "rconst.h" /* for RIP_PORT */#include "os_const.h" /* for AUTH_TYPE_NONE */#include "rribd.h"#include "rrtypes.h"#include "ip_types.h"#ifdef OSPF_PROTOCOL#include "ospf.h"#endif#include "iprtypes.h" /* for IPRT_LOCAL */#ifdef RIP_PROTOCOL#include "fnsrip.h"#endif#include "rrtask.h"#define __FNSRR_C__#include "fnsrr.h"#undef __FNSRR_C__#include "flags.h"#include "in.h"#include "fns_mem.h"#include "nerrno.h"#include "debug.h"#include "icmp.h"#ifdef OSPF_PROTOCOL#include "fnsospf.h"#endifimport netdev ** ndp_tbl;#ifdef TRACEimport boolean fr_trace;#endif#ifdef DEBUGimport boolean fr_debug;#endifexport int send_2_router(int message_type, netdev * ndp, void *msg, void *ret1 );#define MAX_ROUTES 8 /* Maximum outstanding Local or Static routes messages */typedef struct route_intf { u16 route_msgtype; /* ADD_STATIC_ROUTE, ADD_LOCAL_ROUTE * etc. plus flag for message in use. */ netdev * route_ndp; /* ndp */ void * inmsg; /* Input message */ void * rmsg; /* Return message */ int route_status; /* Error return */} router_route_intf;static router_route_intf route_list[MAX_ROUTES];extern int ip_add_lroute_circuit (netdev * ndp, IPNA * ipnap, u32 ospfarea);extern int ip_del_lroute_circuit (netdev * ndp, IPNA * ipnap);static boolean router_initialized = false;extern int router_flags;import tcb router_tcb;/* router_state flags */#define R_WAIT (char)0 /* Router task in wait state */#define R_RUN (char)1 /* Router task running */static char router_state = R_WAIT; /* router state (see above) */char router_events = 0;gq router_r_gq; /* queue for incoming RIP or OSPF packets */static int router_msgs = 0; /* how many outstanding route messages to the router */import int RtrDisc_clock;import u32 nc_hsize;static int router_enabled = 0;#ifdef USE_ROUTER_STOPstatic int stop_router = 1;#endif/****************************************************************************** * * send_2_router * * Post a message to the router task input queue. The router code is * non-reentrant so we must perform all activities via this thread-safe * mechanism except for ipGetNextHop which, in a preemptive multi-tasking * system, requires critical section protection between it and the * code to add/delete routes (ipFwdLockMem etc.) * */export intsend_2_router(int message_type, netdev * ndp, void *inmsg, void *rmsg ){ int err; fns_route_msg *rrmsg; int savpri = os_critical(); /* Must go critical */ /*** Send to the router task ******/ if (router_enabled) { int i; trace1(fr_trace, "sending to router %d\n", message_type); /* find a free entry */ for (i = 0; i < MAX_ROUTES; i++) { if (route_list[i].route_msgtype == 0) break; } if (i == MAX_ROUTES) { os_normal(savpri); return FNS_ENOBUFS; } route_list[i].route_msgtype = R_MSG_IN_USE; /* mark the entry as used */ /* fill up the entry*/ route_list[i].route_ndp = ndp; route_list[i].inmsg = inmsg; route_list[i].rmsg = rmsg; route_list[i].route_status = 0; router_msgs++; route_list[i].route_msgtype |= message_type; router_events |= R_ROUTE; /* tell the router task to process the entry */ os_wakeup(&router_events); /* wait for the router task to process the entry */ while (1) { if( (route_list[i].route_msgtype & R_MSG_MASK) == 0 ) break; os_sleep((char *)&route_list[i].route_status); } route_list[i].route_msgtype = 0; /* free the entry */ err = route_list[i].route_status; } else { if( message_type == ADD_LOCAL_ROUTE ) { rrmsg = (fns_route_msg *)inmsg; err = ip_add_lroute_circuit(ndp, &rrmsg->ipna, rrmsg->ospf_area ); /* After the first interface has been configured start the router timer and * let the router task (INLINE_ROUTER not defined) run. */ router_start(); }else { err = FNS_ENETDOWN; } } os_normal(savpri); return err;}/******************************************************************************* * * router_task_riprx * * Upcall to give the router task a RIP. Dups the message so processing * can continue in the receive task without interruption. * */int router_task_rx( m *mp ){ int err; m *mrip = m_dup(mp); if ((err = gq_in(&router_r_gq, mrip)) != 0) { return err; } router_events |= R_INCOMING; os_wakeup(&router_events); return 0;}/* INLINE_ROUTER needs to be defined when the all of Fusion including * the router code is to be run in a single thread or non-RTOS (polling * loop) environment. * * If INLINE_ROUTER is not defined then the user needs to create * a router task. We use a router receive guarded queue. For OSPF, * ospf_up directly called from Fusion ip_up will queue the * OSPF packets in that queue. Similaryly for RIP, rip_up directly * called from Fusion udp_up will queue the RIP packets in the same * guarded queue. * * The router process will wait on that queue, and get the RIP/OSPF data * and then call riprx/ospf_received for each RIP/OSPF packet on that queue. * The limit on that receive queue is ROUTER_RQ_MAX. */export void fns_router (void * param){ int err; int count;#ifdef RIP_PROTOCOL u16 sport;#endif netdev * ndp, ** ndpp; int cid; u32 snethost; m * mp; fns_route_msg *rrmsg; fns_rleak_msg *rlmsg;#ifdef OSPF_PROTOCOL u32 dnethost;#endif int i; router_route_intf * rlp; use_critical; trace0(fr_trace, "fns_router_task starting\n"); router_state = R_WAIT; while (1) { err = 0; critical; while (router_events == (char)0 || !router_enabled) { router_state = R_WAIT;#ifdef USE_ROUTER_STOP if (stop_router) os_wakeup(&router_state); /* FNS is waiting for the router to stop */#endif os_sleep(&router_events); } router_state = R_RUN; normal; if (router_events & R_ROUTE) { for (rlp = &route_list[0], i=0; i < MAX_ROUTES; i++, rlp++) { switch (rlp->route_msgtype & R_MSG_MASK) { case ADD_LOCAL_ROUTE: trace0(fr_trace, "ADD_LOCAL_ROUTE\n"); rrmsg = (fns_route_msg *)rlp->inmsg; rlp->route_status = ip_add_lroute_circuit( rlp->route_ndp, &rrmsg->ipna, rrmsg->ospf_area ); break; case ADD_STATIC_ROUTE: trace0(fr_trace, "ADD_STATIC_ROUTE\n"); rrmsg = (fns_route_msg *)rlp->inmsg; if( rlp->route_ndp ) { cid = ndp_2_cid(rlp->route_ndp); }else { /* ipAddStaticRoute will look up the interface */ cid = 0; } rlp->route_status = ipAddStaticRoute( &rrmsg->ipna,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -