routeCommonLib.c
上传用户:nvosite88
上传日期:2007-01-17
资源大小:4983k
文件大小:16k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* routeCommonLib.c - route interface shared code library */
  2. /* Copyright 1984 - 2002 Wind River Systems, Inc. */
  3. /*
  4. modification history
  5. --------------------
  6. 01f,09may02,niq  Moved routeAgeSet and routeMetric from routeEntryLib.c
  7. 01e,18mar02,vvv  fixed rtrequestAddEqui to set errno and return correct
  8.  value in case of error (SPR #74250)
  9. 01d,06mar02,vvv  set protocol id in route for host stack (SPR #73148)
  10. 01c,06aug01,spm  fixed netmask value for internal host-specific routes
  11. 01b,01aug01,spm  cleanup: removed unused prototype
  12. 01a,31jul01,spm  extracted from version 03s of routeEntryLib.c module
  13. */
  14. /*
  15. DESCRIPTION
  16. This library contains the shared functions which both the host and router
  17. versions of the network stack use internally to add and delete route entries.
  18. The router stack product creates expanded versions of these routines which
  19. create and send the internal callback messages for registered users. That
  20. product also sends routing socket messages (if appropriate) when adding or
  21. removing routes.
  22. None of the routines in this library are published or available to customers.
  23. INTERNAL
  24. Various network libraries use these add and delete routines to insert and
  25. remove route entries. The interfaces mimic the original rtrequest() entry
  26. point from the BSD code, with some additions for features of the router
  27. stack product.
  28. NOMANUAL
  29. */
  30. /* includes */
  31. #include "vxWorks.h"
  32. #include "routeEnhLib.h"
  33. /* forward declarations */
  34. #ifdef ROUTER_STACK
  35. IMPORT STATUS _routeEntryAdd (ROUTE_DESC *, ROUTE_ENTRY **);
  36. IMPORT STATUS _routeEntryDel (ROUTE_DESC *, ROUTE_ENTRY **);
  37. IMPORT void routeCallBackSend (int, void *);
  38. IMPORT STATUS routeSocketMessageSend (int, ROUTE_DESC *);
  39. #endif /* ROUTER_STACK */
  40. /*******************************************************************************
  41. *
  42. * rtrequestAddEqui - internal common entry point for route creation
  43. *
  44. * This routine replaces all references to the internal rtrequest() routine
  45. * which the network stack used to generate routes when necessary. That
  46. * routine allowed the stack to create internal routes for the local 
  47. * interfaces (with the rtinit() routine) and to create routes in response
  48. * to ICMP redirect messages. It also handled the add operation of routing
  49. * sockets.
  50. *
  51. * All the previous published interfaces for creating static routes now use
  52. * this routine as well. If available, it uses the router stack features to
  53. * create a visible route or a duplicate entry as appropriate. Otherwise,
  54. * it simply creates the initial route entry, or fails if that entry
  55. * already exists.
  56. *
  57. * The router stack features use the <weight> parameter to determine the
  58. * location of the new entry relative to any existing duplicate routes. If
  59. * that weight is the minimum value, the new route will replace the current
  60. * visible route, if any. The router stack also uses the <socketFlag> and
  61. * <notifyFlag> parameters to determine which types of reports to send.
  62. * The host stack variant does not use any of these parameters.
  63. *
  64. * When used within the routing socket output processing, the <socketFlag> is
  65. * FALSE since that code generates the socket messages independently.
  66. *
  67. * When the routing table changes because an interface address is added or
  68. * removed, both the <socketFlag> and <notifyFlag> parameters are FALSE 
  69. * since the network stack calls the address update hook which generates both
  70. * message types.
  71. *
  72. * In all other cases, both parameters are TRUE since the published routines
  73. * for adding and deleting static routes must generate the routing socket
  74. * messages and the callback notifications.
  75. *
  76. * RETURNS: OK on success, ERROR on failure
  77. *
  78. * NOMANUAL
  79. */
  80. STATUS rtrequestAddEqui
  81.     (
  82.     struct sockaddr * pDstAddr, /* destination address for route */
  83.     struct sockaddr* pNetMask,  /* trimmed netmask, or 0 for host route */
  84.     struct sockaddr* pGateway,  /* gateway address for new route */
  85.     short flags,  /* RTF_HOST and RTF_GATEWAY if needed */
  86.     short protoId,  /* source of routing entry, from m2Lib.h */
  87.     UCHAR weight,  /* administrative weight */
  88.     BOOL notifyFlag,        /* TRUE: send callback message */
  89.     BOOL socketFlag,        /* TRUE: send socket message */
  90.     ROUTE_ENTRY** ppRouteEntry  /* direct access to new route for caller */
  91.     )
  92.     {
  93. #ifdef ROUTER_STACK                          /* original version */
  94.     STATUS result;
  95.     struct sockaddr dstAddr;
  96.     struct sockaddr gateway;
  97.     ROUTE_DESC routeDesc;
  98.     bzero((char*)&routeDesc,sizeof(ROUTE_DESC));
  99.     bcopy ( (char *)pDstAddr, (char *)&dstAddr, sizeof (struct sockaddr));
  100.     bcopy ( (char *)pGateway, (char *)&gateway, sizeof (struct sockaddr));
  101. #ifdef DEBUG
  102.     logMsg("rtrequestAddEqui:startingn",0,0,0,0,0,0);
  103. #endif
  104.     /*
  105.      * Setup the descriptor so the original arguments are not modified.
  106.      * The add operation changes the descriptor contents to create the
  107.      * update messages.
  108.      */
  109.     routeDesc.pDstAddr = &dstAddr;
  110.     routeDesc.pNetmask = pNetMask;
  111.     routeDesc.pGateway = &gateway;
  112.     routeDesc.flags = flags;
  113.     routeDesc.protoId = protoId;
  114.     if (weight == 0)
  115.         routeDesc.weight = 100;   /* XXX: configure default value */
  116.     else
  117.         routeDesc.weight = weight;
  118.     /*
  119.      * Use the correct netmask for a host specific route. The rtinit()
  120.      * routine supplies the interface's mask instead of this value.
  121.      */
  122.     if (flags & RTF_HOST)
  123.         routeDesc.pNetmask = 0;
  124.     /*
  125.      * Create the route entry. If successful, the descriptor contains
  126.      * the actual destination address of the route (with the netmask applied)
  127.      * and the corresponding interface, as well as a flag setting which
  128.      * indicates whether the new route is a duplicate entry. The gateway
  129.      * address is not changed until after the routine completes.
  130.      */
  131.     result = _routeEntryAdd (&routeDesc, ppRouteEntry);
  132.     if (result == ERROR)
  133.         return (result);
  134.     /* Announce the new route to any registered users, if appropriate. */
  135.     if (notifyFlag)
  136.         routeCallBackSend (ROUTE_ADD, &routeDesc);
  137.     /*
  138.      * Save the routing protocol's identifier in the gateway address
  139.      * for any routing socket message.
  140.      */
  141.     RT_PROTO_SET(&gateway, protoId);
  142.     /*
  143.      * Transmit a routing socket message. This operation might occur
  144.      * within the add routine if it is limited to representative nodes
  145.      * which the routing sockets are currently able to modify.
  146.      */
  147.     if (socketFlag)    /* Transmit routing socket message? */
  148.         {
  149.         routeSocketMessageSend (RTM_ADD, &routeDesc);
  150.         }
  151.     /* XXX: should it return ERROR if a message isn't sent? */
  152.     return (OK);
  153. #else                                   /* Host version */
  154.     struct sockaddr dstAddr;
  155.     int    status;
  156.     bcopy ((char *) pDstAddr, (char *) &dstAddr, sizeof (struct sockaddr));
  157.     RT_PROTO_SET (&dstAddr, protoId);
  158.     if ((status = rtrequest ((int)RTM_ADD, &dstAddr, pGateway, pNetMask, flags,
  159.                              (struct rtentry **) ppRouteEntry)) != OK)
  160.         {
  161. errno = status;
  162. return (ERROR);
  163. }
  164.     return (OK);
  165. #endif ROUTER_STACK
  166.     }
  167. /*******************************************************************************
  168. *
  169. * rtrequestDelEqui - internal common entry point for route deletion
  170. *
  171. * This routine replaces all references to the internal rtrequest() routine
  172. * which the network stack used to remove routes when necessary. That
  173. * routine allowed the stack to delete internal routes for the local 
  174. * interfaces (with the rtinit() routine) when an address changed.
  175. * It also handled the delete operation of routing sockets.
  176. *
  177. * All the previous published interfaces for deleting static routes now
  178. * use this routine as well. If available, it uses the router stack features
  179. * to delete the visible route or a duplicate entry as appropriate. Otherwise,
  180. * it simply removes the initial route entry, or fails if that entry does
  181. * not exist.
  182. *
  183. * The router stack features use the <socketFlag> and <notifyFlag> parameters
  184. * to determine which types of reports to send. The host stack variant does
  185. * not use either of those parameters.
  186. *
  187. * When used within the routing socket output processing, the <socketFlag> is
  188. * FALSE since that code generates the socket messages independently.
  189. *
  190. * When the routing table changes because an interface address is added or
  191. * removed, both the <socketFlag> and <notifyFlag> parameters are FALSE
  192. * since the network stack calls the address update hook which generates both
  193. * message types.
  194. *
  195. * In all other cases, both parameters are TRUE since the published routines
  196. * for adding and deleting static routes must generate the routing socket
  197. * messages and the callback notifications.
  198. *
  199. * RETURNS: OK on success, ERROR on failure
  200. *
  201. * NOMANUAL
  202. */
  203. STATUS rtrequestDelEqui
  204.     (
  205.     struct sockaddr* pDstAddr,  /* destination address for route */
  206.     struct sockaddr* pNetMask,  /* trimmed netmask, or 0 for host route */
  207.     struct sockaddr* pGateway,  /* gateway address for route, 0 for any */
  208.     short flags,  /* RTF_HOST or RTF_GATEWAY, if appropriate */
  209.     short protoId,  /* source of specific route, 0 for any */
  210.     BOOL notifyFlag,        /* TRUE: send callback message */
  211.     BOOL socketFlag,        /* TRUE: send socket message */
  212.     ROUTE_ENTRY** ppRouteEntry  /* direct access to (detached) route entry */
  213.     )
  214.     {
  215. #ifdef ROUTER_STACK                          /* original version */
  216.     STATUS result;
  217.     struct sockaddr dstAddr;
  218.     struct sockaddr gateway;
  219.     ROUTE_DESC routeDesc;
  220.     /*
  221.      * Setup the descriptor so the original arguments are not modified.
  222.      * The delete operation changes the descriptor contents to create the
  223.      * update messages.
  224.      */
  225.     bzero ( (char*)&routeDesc, sizeof (ROUTE_DESC));
  226.     bcopy ( (char *)pDstAddr, (char *)&dstAddr, sizeof (struct sockaddr));
  227.     if (pGateway)    /* Set gateway to zero if not specified. */
  228.         bcopy ( (char *)pGateway, (char *)&gateway, sizeof (struct sockaddr));
  229.     else
  230.         bzero ( (char*)&gateway, sizeof (struct sockaddr));
  231.     routeDesc.pDstAddr = &dstAddr;
  232.     routeDesc.pNetmask = pNetMask;
  233.     routeDesc.pGateway = &gateway;
  234.     routeDesc.flags = flags;
  235.     routeDesc.protoId = protoId;
  236.     /*
  237.      * Use the correct netmask for a host specific route. The rtinit()
  238.      * routine supplies the interface's mask instead of this value.
  239.      */
  240.     if (flags & RTF_HOST)
  241.         routeDesc.pNetmask = 0;
  242.     /*
  243.      * Delete the matching route. If successful, the descriptor contains
  244.      * the actual destination (generated from the netmask), matching gateway,
  245.      * and all the metric values and additional information from the deleted
  246.      * route entry. It also includes a flag setting which indicates whether
  247.      * the deleted route was a duplicate entry.
  248.      */
  249.     result = _routeEntryDel (&routeDesc, ppRouteEntry);
  250.     if (result == ERROR)
  251.         return (result);
  252.     /* Announce the route deletion to any registered users, if appropriate. */
  253.     if (notifyFlag)
  254.         routeCallBackSend (ROUTE_DEL, &routeDesc);
  255.     /*
  256.      * Save the routing protocol's identifier in the gateway address
  257.      * for any routing socket message.
  258.      */
  259.     RT_PROTO_SET(&gateway, protoId);
  260.     /*
  261.      * Transmit a routing socket message. This operation might occur
  262.      * within the preceding delete routine if it is limited to
  263.      * representative nodes which the routing sockets are currently
  264.      * able to modify.
  265.      */
  266.     if (socketFlag)    /* Transmit routing socket message? */
  267.         {
  268.         routeSocketMessageSend (RTM_DELETE, &routeDesc);
  269.         }
  270.     /* XXX: should it return ERROR if a message isn't sent? */
  271.     return (OK);
  272. #else                                   /* Host version */
  273.     return (rtrequest((int)RTM_DELETE, pDstAddr, pGateway, pNetMask,flags,
  274.                       (struct rtentry **)ppRouteEntry));
  275. #endif ROUTER_STACK
  276.     }
  277. /******************************************************************************
  278. *
  279. * routeAgeSet - Set the age of the route entry
  280. *
  281. * This routine searches the routing table for an entry which matches the
  282. * specified destination address. (For a Router stack, the protocol ID
  283. * is also checked for a match; it is ignored for a Host stack).
  284. * If the netmask is specified, the selected route also matches that value.
  285. *
  286. * Once a route is chosen, this routine sets the route age to the value
  287. * specified by <newTime>.
  288. *
  289. * RETURNS: OK if a route is found and time set, or ERROR otherwise.
  290. *
  291. * NOMANUAL
  292. *
  293. * INTERNAL: This routine is currently called only by RIP
  294. */
  295. STATUS routeAgeSet
  296.     (
  297.     struct sockaddr * pDstAddr, /* Destination address */
  298.     struct sockaddr * pNetmask, /* Netmask */
  299.     int protoId, /* Protocol ID */
  300.     int newTime /* New time to set */
  301.     )
  302.     {
  303.     int s;
  304. #ifndef ROUTER_STACK
  305.     register struct rtentry * pRoute;
  306.     struct radix_node_head * rnh;
  307.     /* First validate the parameters */
  308.     if (pDstAddr == NULL)
  309.         return (ERROR);
  310.     s = splnet ();
  311.     if ((rnh = rt_tables[pDstAddr->sa_family]) == 0) 
  312.         {
  313.         splx (s);
  314.         return (ERROR);
  315.         }
  316.     if (pNetmask)
  317. {
  318. in_socktrim ((struct sockaddr_in *)pNetmask);
  319. TOS_SET (pNetmask, 0x1f);
  320. }
  321.     if ((pRoute = (struct rtentry *) rnh->rnh_lookup(pDstAddr, 
  322.                                                      pNetmask, rnh)))
  323.             pRoute->rt_refcnt++;
  324. #else
  325.     ROUTE_ENTRY *  pRoute;    /* Matching route, if any. */
  326.     ULONG  netmask;
  327.     ULONG *  pMask;
  328.     /* First validate the parameters */
  329.     if (pDstAddr == NULL || protoId == 0)
  330.         return (ERROR);
  331.     if (pNetmask)
  332.         {
  333.         netmask = ((struct sockaddr_in *)(pNetmask))->sin_addr.s_addr;
  334.         pMask = &netmask;
  335.         }
  336.     else
  337.         pMask = NULL;
  338.     s = splnet ();
  339.     semTake (routeTableLock, WAIT_FOREVER);
  340.     pRoute = routeLookup (pDstAddr, pMask, protoId);
  341.     semGive (routeTableLock);
  342. #endif /* ROUTER_STACK */
  343.     splx (s);
  344.     if (pRoute == NULL)
  345.         return (ERROR);
  346.     /* Now set the age of the route */
  347.     
  348. #ifdef ROUTER_STACK
  349.     pRoute->rtEntry.rt_mod = newTime;
  350. #else
  351.     pRoute->rt_mod = newTime;
  352. #endif /* ROUTER_STACK */
  353.     /* Release the reference when finished. */
  354.     s = splnet ();
  355.     rtfree ( (struct rtentry *)pRoute);
  356.     splx (s);
  357.     return (OK);
  358.     }
  359. /******************************************************************************
  360. *
  361. * routeMetricSet - Set the metric for the specified route entry
  362. *
  363. * This routine searches the routing table for an entry which matches the
  364. * specified destination address. (For a Router stack, the protocol ID
  365. * is also checked for a match; it is ignored for a Host stack).
  366. * If the netmask is specified, the selected route also matches that value.
  367. *
  368. * Once a route is chosen, this routine sets the route metric to the value
  369. * specified by <metric>.
  370. *
  371. * RETURNS: OK if a route is found and time set, or ERROR otherwise.
  372. *
  373. * NOMANUAL
  374. *
  375. * INTERNAL: This routine is currently called only by RIP
  376. */
  377. STATUS routeMetricSet
  378.     (
  379.     struct sockaddr * pDstAddr, /* Destination address */
  380.     struct sockaddr * pNetmask, /* Netmask */
  381.     int protoId, /* Protocol ID */
  382.     int metric /* metric to set */
  383.     )
  384.     {
  385.     int s;
  386. #ifndef ROUTER_STACK
  387.     register struct rtentry * pRoute;
  388.     struct radix_node_head * rnh;
  389.     /* First validate the parameters */
  390.     if (pDstAddr == NULL)
  391.         return (ERROR);
  392.     s = splnet ();
  393.     if ((rnh = rt_tables[pDstAddr->sa_family]) == 0) 
  394.         {
  395.         splx (s);
  396.         return (ERROR);
  397.         }
  398.     if (pNetmask)
  399. {
  400. in_socktrim ((struct sockaddr_in *)pNetmask);
  401. TOS_SET (pNetmask, 0x1f);
  402. }
  403.     if ((pRoute = (struct rtentry *) rnh->rnh_lookup(pDstAddr, 
  404.                                                      pNetmask, rnh)))
  405.             pRoute->rt_refcnt++;
  406. #else
  407.     ROUTE_ENTRY *  pRoute;    /* Matching route, if any. */
  408.     ULONG  netmask;
  409.     ULONG *  pMask;
  410.     /* First validate the parameters */
  411.     if (pDstAddr == NULL || protoId == 0)
  412.         return (ERROR);
  413.     if (pNetmask)
  414.         {
  415.         netmask = ((struct sockaddr_in *)(pNetmask))->sin_addr.s_addr;
  416.         pMask = &netmask;
  417.         }
  418.     else
  419.         pMask = NULL;
  420.     s = splnet ();
  421.     semTake (routeTableLock, WAIT_FOREVER);
  422.     pRoute = routeLookup (pDstAddr, pMask, protoId);
  423.     semGive (routeTableLock);
  424. #endif /* ROUTER_STACK */
  425.     splx (s);
  426.     if (pRoute == NULL)
  427.         return (ERROR);
  428.     /* Now set the metric of the route */
  429.     
  430. #ifdef ROUTER_STACK
  431.     pRoute->rtEntry.rt_rmx.rmx_hopcount = metric;
  432. #else
  433.     pRoute->rt_rmx.rmx_hopcount = metric;
  434. #endif /* ROUTER_STACK */
  435.     /* Release the reference when finished. */
  436.     s = splnet ();
  437.     rtfree ( (struct rtentry *)pRoute);
  438.     splx (s);
  439.     return (OK);
  440.     }