Azinix

evlAct.c

Go to the documentation of this file.
00001 /** \file evlAct.c
00002 
00003   \brief Implement actions on packets.
00004 
00005 */
00006 
00007 
00008 
00009 #include "evl.h"
00010 
00011 /**AutomaticStart*************************************************************/
00012 
00013 /*---------------------------------------------------------------------------*/
00014 /* Static function prototypes                                                */
00015 /*---------------------------------------------------------------------------*/
00016 
00017 static int compareQueueNames (char *q1, char *q2);
00018 static int compareQueuePriorities (char *q1, char *q2);
00019 
00020 /**AutomaticEnd***************************************************************/
00021 
00022 
00023 /**
00024   * \brief Compare function for queues, uses names to 
00025   * impose order on queues.
00026   *
00027   */
00028 
00029 static int
00030 compareQueueNames (char *q1, char *q2)
00031 {
00032   return strcmp (((Q_Q_t *) q1)->name, ((Q_Q_t *) q2)->name);
00033 }
00034 
00035 
00036 /**
00037   * \brief  Create a heap of Q_Q_t's , whose priorities are given by the
00038   * currentPriority field.
00039   * 
00040   */
00041 
00042 Heap_t *
00043 Evl_AllocateQueueHeap (st_table * queueTable)
00044 {
00045   Heap_t *result;
00046 
00047   result = Heap_Init (compareQueuePriorities);
00048   st_generator *stGen;
00049   char *qName;
00050   Q_Q_t *aQ;
00051 
00052   // doing this to get a deterministic order for the
00053   // queues in the heap
00054   array_t *qArray = array_alloc (Q_Q_t *, 0);
00055 
00056   st_foreach_item (queueTable, stGen, (char **) &qName, (char **) &aQ)
00057   {
00058     array_insert_last (Q_Q_t *, qArray, aQ);
00059   }
00060   array_sort (qArray, ( int(*)() ) compareQueueNames);
00061   int i;
00062   for (i = 0; i < array_n (qArray); i++)
00063     {
00064       aQ = array_fetch (Q_Q_t *, qArray, i);
00065       Heap_Insert (result, (char *) aQ);
00066     }
00067   return result;
00068 }
00069 
00070 
00071 /**
00072   * \brief  Compare to Q_Q_t's based on currentPriority field
00073   * 
00074   * Compare to Q_Q_t's based on currentPriority field
00075   * 
00076   */
00077 
00078 static int
00079 compareQueuePriorities (char *q1, char *q2)
00080 {
00081   if (((Q_Q_t *) q1)->currentPriority < ((Q_Q_t *) q2)->currentPriority)
00082     {
00083       return 1;
00084     }
00085   return 0;
00086 }
00087 
00088 
00089 /**
00090   * \brief  Set the route for the packet
00091   */
00092 
00093 void
00094 Evl_RoutePkt (Evl_Action_t * action,
00095           Evl_Bridge_t * bridge, Pkt_ProcessPkt_t * pp)
00096 {
00097   assert (action->parsedAction->type == Rlp_ActionRoute_c);
00098   int i;
00099   if (action->outIf != NIL (Pkt_LibNet_t))
00100     {
00101       pp->outIf = action->outIf;
00102       return;
00103     }
00104 
00105   for (i = 0; i < array_n (bridge->outArray); i++)
00106     {
00107       Pkt_LibNet_t *outIf = array_fetch (Pkt_LibNet_t *, bridge->outArray, i);
00108       if (util_strequal (action->parsedAction->dest, outIf->interfaceName))
00109     {
00110       pp->outIf = outIf;
00111       action->outIf = outIf;
00112       return;
00113     }
00114     }
00115 
00116   return;
00117 }
00118 
00119 
00120 /**
00121   * \brief  Perform action desired by user, specified as a tcl proc.
00122   *
00123   *     Action is a tcl proc which takes two parameters, specifically
00124   * a mgr and a pointer to a packet (well the int ids that we're using 
00125   * in place of the pointers).
00126   */
00127 
00128 void
00129 Evl_UscriptAction (Rlp_Action_t * action,
00130            Evl_Manager_t * mgr, Pkt_ProcessPkt_t * pp)
00131 {
00132   assert (action->type == Rlp_ActionUscript_c);
00133   Pkt_EthernetHdr_t *pkt = pp->pkt;
00134 
00135   const int numArgsToTclFunction = 3;
00136   Tcl_Obj *tmpObjv[numArgsToTclFunction];
00137 
00138   char *tclRuleString = action->uscript;
00139   Tcl_Obj *tmpPtr = Tcl_NewStringObj (strdup (tclRuleString), -1);
00140   tmpObjv[0] = tmpPtr;
00141 
00142   int resultId = Nm_TclCDStorePtr ((Nm_TclCD_t *) mgr->cd, (void *) mgr);
00143   tmpObjv[1] = Tcl_NewIntObj (resultId);
00144 
00145   resultId = Nm_TclCDStorePtr ((Nm_TclCD_t *) mgr->cd, (void *) pkt);
00146   tmpObjv[2] = Tcl_NewIntObj (resultId);
00147 
00148   // three arguments, in the array of Tcl_Obj *s : one is the function's name, the
00149   // next is the "pointer" to the manager, then a pointer to the pkt 
00150   int retCode = Tcl_EvalObjv (mgr->interp, numArgsToTclFunction, tmpObjv,
00151                   TCL_EVAL_GLOBAL);
00152   if (retCode != TCL_OK)
00153     {
00154       printf ("Error in invoking script %s\n", action->uscript);
00155       printf ("\ttcl interp error message is: %s\n",
00156           Tcl_GetStringResult (mgr->interp));
00157     }
00158 
00159   return;
00160 }
00161 
00162 
00163 /**
00164   * \brief  Perform action desired by user, implemented by C code that's been
00165   * dynamically linked in previously.
00166   *
00167   *     Action is a C function which takes several parameters
00168   *   - a pointer to the manager
00169   *   - a pointer to the pp structure encapsulating the packet
00170   *   - a pointer to a pointer var that can be used to store state
00171   *   - a charstring argument
00172   */
00173 
00174 int
00175 Evl_UcodeAction (Rlp_Action_t * action,
00176          Evl_Manager_t * mgr, Pkt_ProcessPkt_t * pp)
00177 {
00178   assert (action->type == Rlp_ActionUcode_c);
00179 
00180   if ((action->ucodeFunction == 0))
00181     {
00182       if (!Hash_Lookup
00183       (mgr->ucodeNameToFunction, action->ucodeName,
00184        (char **) &action->ucodeFunction))
00185     {
00186       printf
00187         ("Error: did not find function with name %s, did you register it?\n",
00188          action->ucodeName);
00189       assert (0);
00190     }
00191     }
00192 
00193   // int retCode = ( ( int()( Evl_Manager_t *, Pkt_ProcessPkt_t *, void **, char * ) ) action->ucodeFunction ) (mgr, pp, &action->ucodeFunctionState, action->argument);
00194 
00195   int retCode = action->ucodeFunction ( (void*) mgr,  (void*) pp, &action->ucodeFunctionState, action->argument);
00196 
00197   return retCode;
00198 }