ped_policy_table.c

Go to the documentation of this file.
00001 /*
00002  * $Id: ped_policy_table.c 366303 2010-03-05 13:14:01Z taoliu $
00003  *
00004  * This code is provided as is by Juniper Networks SDK Developer Support.
00005  * It is provided with no warranties or guarantees, and Juniper Networks
00006  * will not provide support or maintenance of this code in any fashion.
00007  * The code is provided only to help a developer better understand how
00008  * the SDK can be used.
00009  *
00010  * Copyright (c) 2007-2008, Juniper Networks, Inc.
00011  * All rights reserved.
00012  */
00013 
00023 #include <sync/common.h>
00024 #include <hashtable.h>
00025 #include <hashtable_itr.h>
00026 #include "ped_policy_table.h"
00027 #include "ped_filter.h"
00028 #include "ped_ssd.h"
00029 
00030 #include PE_OUT_H
00031 
00032 /*** Constants ***/
00033 
00034 
00035 /*** Data Structures ***/
00036 
00040 static struct hashtable *if_table = NULL; 
00041 
00042 
00046 static struct hashtable_itr *itr = NULL;
00047 
00048 
00052 static boolean itr_broken = TRUE;
00053 
00057 static uint32_t changes_pending = 0;
00058 
00062 static boolean clean_table = FALSE;
00063 
00064 // HASHTABLE STUFF (key and value)
00065 
00069 typedef struct key_s {
00070     char       ifname[MAX_IF_NAME_LEN + 1]; 
00071     uint8_t    af;                          
00072 } hash_key_t;
00073 
00074 
00075 /*** STATIC/INTERNAL Functions ***/
00076 
00077 
00078 // Define functions ht_insert, ht_get, and ht_remove
00079 
00083 static DEFINE_HASHTABLE_INSERT(ht_insert, hash_key_t, policy_table_entry_t);
00084 
00088 static DEFINE_HASHTABLE_SEARCH(ht_get, hash_key_t, policy_table_entry_t);
00089 
00093 static DEFINE_HASHTABLE_REMOVE(ht_remove, hash_key_t, policy_table_entry_t);
00094 
00095 
00104 static unsigned int
00105 hashFromKey(void * ky)
00106 {
00107     hash_key_t *k = (hash_key_t *)ky;    
00108     unsigned int hashcode = 0, c;
00109     char *str;
00110     
00111     INSIST(k != NULL);
00112     str = k->ifname;
00113 
00114     while((c = *str++)) // requires str to be '\0' terminated
00115         hashcode = c + (hashcode << 6) + (hashcode << 16) - hashcode;
00116 
00117     hashcode += k->af;
00118 
00119     return hashcode;
00120 }
00121 
00122 
00134 static int
00135 equalKeys(void * k1, void * k2)
00136 {
00137     INSIST(k1 != NULL);
00138     INSIST(k2 != NULL);
00139 
00140     return(((hash_key_t *)k1)->af == ((hash_key_t *)k2)->af &&
00141             (0 == strcmp(((hash_key_t *)k1)->ifname, ((hash_key_t *)k2)->ifname)));
00142 }
00143 
00144 
00156 static boolean
00157 equalRoutes(policy_route_msg_t * r1, policy_route_msg_t * r2)
00158 { 
00159     return((r1->route_addr == r2->route_addr) &&
00160            (r1->preferences == r2->preferences));
00161 }
00162 
00163 
00175 static policy_table_entry_t *
00176 get_or_create_policy(char * ifname, uint8_t af)
00177 {
00178     hash_key_t * k;
00179     policy_table_entry_t * v;
00180     
00181     // Create key
00182     k = (hash_key_t *)malloc(sizeof(hash_key_t));
00183     INSIST(k != NULL);
00184     
00185     // Copy interface name and address family.
00186     strcpy(k->ifname, ifname);
00187     k->af = af;
00188     
00189     if((v = ht_get(if_table, k)) == NULL) {
00190         v = (policy_table_entry_t *)malloc(sizeof(policy_table_entry_t));
00191         INSIST(v != NULL);
00192         bzero(v, sizeof(policy_table_entry_t));
00193         strcpy(v->ifname, ifname);
00194         v->af = af;
00195         ht_insert(if_table, k, v);
00196     } else {
00197         free(k);
00198     }
00199     
00200     return v;
00201 }
00202 
00203 
00218 static boolean
00219 mark_route(policy_route_msg_t * route, policy_route_status_e status)
00220 {
00221     hash_key_t k;
00222     policy_table_entry_t * pol;
00223     ped_policy_route_t * r;
00224 
00225     INSIST(if_table != NULL);
00226     INSIST(route != NULL);
00227     INSIST(strlen(route->ifname) <= MAX_IF_NAME_LEN);
00228     
00229     junos_trace(PED_TRACEFLAG_HT, "%s", __func__);
00230 
00231     strcpy(k.ifname, route->ifname);
00232     k.af = route->af;
00233 
00234     pol = ht_get(if_table, &k);
00235 
00236     if(pol) { // if policy exists
00237         
00238         // Search routes for route
00239         
00240         for(r = pol->route; pol != NULL; r = r->next) {
00241             if(equalRoutes(route, &r->route_data)) {
00242                 if(r->status == ROUTE_PENDING && status != ROUTE_PENDING) {
00243                     --changes_pending;
00244                 }
00245                 if(status == ROUTE_FAILED) {
00246                     // break it but don't delete it
00247                     // because we could get more info coming in for this policy
00248                     // and we have to know that it is broken
00249                     pol->broken = TRUE;
00250                     clean_table = TRUE;
00251                 }
00252                 r->status = status;
00253                 return TRUE;
00254             }
00255         }
00256     }
00257     
00258     return FALSE;
00259 }
00260 
00261 
00276 static void
00277 ssd_request_status(ssd_reply_e reply, void * user_data)
00278 {
00279     policy_route_msg_t * route_data;
00280     struct in_addr  addr; // for printing nicely
00281     
00282     route_data = (policy_route_msg_t *)user_data;
00283     
00284     if(route_data)
00285         addr.s_addr = route_data->route_addr;
00286     
00287     // process reply
00288     
00289     switch(reply) {
00290 
00291     case ADD_SUCCESS:
00292         
00293         INSIST(route_data != NULL);
00294             
00295         junos_trace(PED_TRACEFLAG_NORMAL,
00296             "%s: route %s/%d was successfully added through SSD",
00297             __func__, inet_ntoa(addr), route_data->route_addr_prefix);
00298             
00299         mark_route(route_data, ROUTE_ADDED);
00300 
00301         break;
00302         
00303     case ADD_FAILED:
00304     
00305         INSIST(route_data != NULL);
00306     
00307         junos_trace(PED_TRACEFLAG_NORMAL,
00308             "%s: route %s/%d was not successfully added through SSD, "
00309             "so policy will be marked for removal.",
00310             __func__, inet_ntoa(addr), route_data->route_addr_prefix);
00311         
00312         // we need to mark this policy and route as bad
00313         // we can't delete it because it could be re-created, but without 
00314         // this route meaning it would be incorrect
00315         
00316         mark_route(route_data, ROUTE_FAILED);
00317         
00318         // we are breaking a policy so it should be cleaned up eventually
00319         // when our ssd module becomes idle or else future req on this policy
00320         // won't work because the broken policy will still be around
00321         clean_table = TRUE;
00322 
00323         break;
00324         
00325     case DELETE_SUCCESS:
00326             
00327         if(route_data == NULL) {
00328             // route deleted from a broken policy
00329             junos_trace(PED_TRACEFLAG_NORMAL,
00330                 "%s: route was successfully deleted through SSD", __func__);
00331         } else {
00332             junos_trace(PED_TRACEFLAG_NORMAL,
00333                 "%s: route %s/%d was successfully deleted through SSD",
00334                 __func__, inet_ntoa(addr), route_data->route_addr_prefix);
00335         }
00336             
00337         // nothing to do on policy table because the policy 
00338         // no longer stores this route anyway
00339             
00340         break;
00341         
00342     case DELETE_FAILED:
00343 
00344         if(route_data == NULL) {
00345             // route deleted from a broken policy
00346             
00347             ERRMSG(PED, TRACE_LOG_WARNING,
00348                 "%s: Request to delete a route from a broken policy FAILED. "
00349                 "WARNING: may have a dangling route if this route was " 
00350                 "previously installed (may not if route was not installed).",
00351                 __func__);
00352         } else {
00353             // route deleted from a policy because route 
00354             // is no longer part of the policy
00355             
00356             ERRMSG(PED, TRACE_LOG_WARNING,
00357                 "%s: Request to delete route %s/%d from a policy FAILED. "
00358                 "WARNING: may have a dangling route if this route was " 
00359                 "previously installed (may not if route was not installed). "
00360                 "Retrying delete without SSD confirmation",
00361                 __func__, inet_ntoa(addr), route_data->route_addr_prefix);
00362 
00363             // try again without confirmation
00364             // (unreliable but better than nothing)
00365             ssd_client_del_route_request(route_data, NULL, NULL);
00366         }
00367 
00368         break;
00369         
00370     default:
00371     
00372         ERRMSG(PED, TRACE_LOG_ERR,
00373             "%s: Didn't understand the type of reply", __func__);
00374     }
00375     
00376     if(route_data)
00377         free(route_data);
00378 }
00379 
00380 
00392 static boolean
00393 add_route(policy_route_msg_t * route_data)
00394 {
00395     policy_route_msg_t * route;
00396     
00397     // make a copy of the route data passed in
00398     
00399     route = (policy_route_msg_t *)malloc(sizeof(policy_route_msg_t));
00400     INSIST(route != NULL);
00401     memcpy(route, route_data, sizeof(policy_route_msg_t));
00402     
00403     if(!ssd_client_add_route_request(route_data, ssd_request_status, route)) {
00404             
00405         ERRMSG(PED, TRACE_LOG_ERR,
00406             "%s: SSD did not accept request to add a route.", __func__);
00407             
00408         // Request to add route was NOT accepted
00409         return FALSE;            
00410     }
00411     
00412     return TRUE;
00413 }
00414 
00415 
00423 static void
00424 remove_route(ped_policy_route_t * route)
00425 {
00426     policy_route_msg_t * route_data;
00427         
00428     route_data = (policy_route_msg_t *)malloc(sizeof(policy_route_msg_t));
00429     INSIST(route_data != NULL);
00430     memcpy(route_data, &route->route_data, sizeof(policy_route_msg_t));
00431     
00432     // Delete route from SSD
00433     if(!ssd_client_del_route_request(
00434         &route->route_data, ssd_request_status, route_data)) {
00435 
00436         // try without confirmation
00437         // (unreliable but better than nothing)
00438         ssd_client_del_route_request(
00439             &route->route_data, NULL, NULL);
00440 
00441         ERRMSG(PED, TRACE_LOG_WARNING,
00442             "%s: Cannot remove route because request to delete "
00443             "the route with confirmation was not accepted. "
00444             "Trying without, but route may be left dangling "
00445             "if operation fails.", __func__);
00446 
00447         free(route_data);
00448     }
00449 }
00450 
00451 
00452 /*** GLOBAL/EXTERNAL Functions ***/
00453 
00454 
00462 void
00463 policy_table_add_filter(policy_filter_msg_t * filter_data)
00464 {
00465     policy_table_entry_t * policy;
00466 
00467     INSIST(if_table != NULL);
00468     INSIST(filter_data != NULL);
00469     INSIST(strlen(filter_data->ifname) <= MAX_IF_NAME_LEN);
00470 
00471     junos_trace(PED_TRACEFLAG_HT, "%s: %s, af: %d", __func__,
00472         filter_data->ifname, filter_data->af);
00473 
00474     policy = get_or_create_policy(filter_data->ifname, filter_data->af);
00475 
00476     if(policy->broken) {
00477         // if the policy is broken then this whole policy 
00478         // will be deleted because something's wrong with it
00479         // ...So, don't add the filter
00480         return;
00481     }
00482     
00483     if(!policy->pfd_filter) {
00484         policy->pfd_filter = apply_pfd_filter_to_interface(policy->ifname);
00485     }
00486     
00487     if(!policy->filter) {
00488         // Create filter if it doesn't exist
00489         policy->filter = (ped_policy_filter_t *)malloc(sizeof(ped_policy_filter_t));
00490         INSIST(policy->filter != NULL);
00491     }
00492 
00493     // Update filter data
00494     memcpy(&(policy->filter->filter_data), filter_data,
00495             sizeof(policy_filter_msg_t));
00496 
00497     policy->filter->status = FILTER_PENDING;
00498     
00499     if(apply_filters_to_interface(policy->ifname, policy->filter)) {
00500         policy->filter->status = FILTER_ADDED;
00501     } else {
00502         policy->filter->status = FILTER_FAILED;
00503         policy->broken = TRUE; // break it so it gets cleaned
00504         clean_table = TRUE;
00505         
00506         ERRMSG(PED, TRACE_LOG_ERR, "%s: Failed to apply filters"
00507             "on interface", __func__, policy->ifname);
00508     }
00509 }
00510 
00511 
00519 void
00520 policy_table_add_route(policy_route_msg_t * route_data)
00521 {
00522     policy_table_entry_t * policy;
00523     ped_policy_route_t *route = NULL;
00524     ped_policy_route_t *route_end = NULL;
00525 
00526     INSIST(if_table != NULL);
00527     INSIST(route_data != NULL);
00528     INSIST(strlen(route_data->ifname) <= MAX_IF_NAME_LEN);
00529 
00530     junos_trace(PED_TRACEFLAG_HT,
00531             "%s: %s, %d", __func__, route_data->ifname, route_data->af);
00532 
00533     policy = get_or_create_policy(route_data->ifname, route_data->af);
00534 
00535     if(policy->broken) {
00536         // if the policy is broken then this whole policy 
00537         // will be deleted because something's wrong with it
00538         // ...So, don't add the route
00539         return;
00540     }
00541     
00542     if(!policy->pfd_filter) {
00543         policy->pfd_filter = apply_pfd_filter_to_interface(policy->ifname);
00544     }
00545     
00546     // Search route list for same route
00547     route_end = route = policy->route;
00548     
00549     while(route) {
00550         if(equalRoutes(route_data, &route->route_data)) {
00551             break;
00552         }
00553         route_end = route;
00554         route = route->next;
00555     }
00556     
00557     if(!route) { // No match, so create route data
00558         route = (ped_policy_route_t *)malloc(sizeof(ped_policy_route_t));
00559         INSIST(route != NULL);
00560         route->next = NULL;
00561 
00562         // Add route data to the list.
00563         if(route_end) {
00564             route_end->next = route;
00565         } else {
00566             policy->route = route;
00567         }
00568     }
00569 
00570     // Copy in route data.
00571     memcpy(&(route->route_data), route_data, sizeof(policy_route_msg_t));
00572     
00573     // Add or change the route itself 
00574     if(add_route(route_data)) {
00575         route->status = ROUTE_PENDING;
00576         ++changes_pending;
00577     } else {
00578         route->status = ROUTE_FAILED;
00579         policy->broken = TRUE;
00580         clean_table = TRUE;
00581     }
00582 }
00583 
00584 
00596 void
00597 policy_table_clear_policy(char *ifname, uint8_t af)
00598 {
00599     policy_table_entry_t * policy;
00600     ped_policy_route_t  * route = NULL, * route_tmp = NULL;
00601 
00602     INSIST(if_table != NULL);
00603     INSIST(ifname != NULL);
00604     INSIST(strlen(ifname) <= MAX_IF_NAME_LEN);
00605     
00606     junos_trace(PED_TRACEFLAG_HT, "%s(%s, %d)", __func__, ifname, af);
00607 
00608     policy = get_or_create_policy(ifname, af);
00609 
00610     // just remove anything but the pfd filter
00611 
00612     if(policy->broken) {
00613         return;
00614     }
00615     
00616     if(policy->filter) {
00617         free(policy->filter);
00618         policy->filter = NULL;
00619     }
00620         
00621     if(!remove_filters_from_interface(ifname)) {
00622         policy->broken = TRUE; // break it so it gets cleaned
00623         
00624         ERRMSG(PED, TRACE_LOG_ERR, "%s: Failed to remove "
00625             "filters on interface ", __func__, ifname);
00626     }
00627     
00628     route = policy->route;
00629     policy->route = NULL;
00630     
00631     while(route) {
00632         route_tmp = route;      // Save pointer to current route
00633         route = route->next;    // Move to the next route
00634         remove_route(route_tmp);
00635         if(route->status == ROUTE_PENDING) {
00636             --changes_pending;
00637         }
00638         free(route_tmp);        // Free the current route data.
00639     }
00640 }
00641 
00642 
00656 void
00657 policy_table_delete_policy(char *ifname, uint8_t af, boolean interface_exists)
00658 {
00659     hash_key_t k;
00660     policy_table_entry_t * policy;
00661     ped_policy_route_t  * route = NULL, * route_tmp = NULL;
00662 
00663     INSIST(if_table != NULL);
00664     INSIST(ifname != NULL);
00665     INSIST(strlen(ifname) <= MAX_IF_NAME_LEN);
00666     
00667     junos_trace(PED_TRACEFLAG_HT, "%s(%s, %d)", __func__, ifname, af);
00668 
00669     strcpy(k.ifname, ifname);
00670     k.af = af;
00671 
00672     policy = ht_remove(if_table, &k); // frees the key
00673 
00674     if(policy == NULL) return;
00675      
00676     // remove and delete filters only if the interface still exists
00677     // (if interface is deleted so are all attached filters)
00678     if(interface_exists) {
00679         if(policy->filter) {
00680             remove_filters_from_interface(ifname);
00681             free(policy->filter);
00682         }
00683         
00684         if(policy->pfd_filter) {
00685             remove_pfd_filter_from_interface(policy->ifname);
00686             policy->pfd_filter = FALSE;
00687         }
00688     }
00689     
00690     // remove and delete routes
00691     
00692     route = policy->route;
00693     while(route) {
00694         route_tmp = route;      // Save pointer to current route.
00695         route = route->next;    // Move to the next route.
00696         if(route->status != ROUTE_FAILED) {
00697             remove_route(route_tmp);
00698             if(route->status == ROUTE_PENDING) {
00699                 --changes_pending;
00700             }
00701         }
00702         free(route_tmp);        // Free the current route data.
00703     }
00704 
00705     free(policy);
00706 }
00707 
00708 
00719 boolean
00720 policy_table_unverify_all(void)
00721 {
00722     policy_table_entry_t * pol = NULL;
00723     ped_policy_route_t * route = NULL;
00724     struct hashtable_itr * iterator = NULL;
00725     
00726     if(hashtable_count(if_table) < 1)
00727         return TRUE; // nothing to do
00728         
00729     if(changes_pending > 0)
00730         return FALSE; // don't do anything if there's still changes pending
00731 
00732     junos_trace(PED_TRACEFLAG_HT, "%s", __func__);
00733 
00734     iterator = hashtable_iterator(if_table); // mallocs
00735     INSIST(iterator != NULL);
00736 
00737     // go through all policies
00738     do {
00739         pol = hashtable_iterator_value(iterator);
00740         
00741         // for all filters and routes in route lists set status to UNVERIFIED
00742         
00743         if(!pol->broken) {
00744             if(pol->filter) {
00745                 pol->filter->status = FILTER_UNVERIFIED;
00746             }
00747             if((route = pol->route)) {
00748                 while(route) {
00749                     // changes_pending is wrong if this fails
00750                     INSIST(route->status != ROUTE_PENDING);
00751                     route->status = ROUTE_UNVERIFIED;
00752                     route = route->next;
00753                 }
00754             }
00755         }
00756         
00757     } while (hashtable_iterator_advance(iterator));
00758 
00759     free(iterator);
00760     
00761     clean_table = TRUE;
00762     
00763     return TRUE;
00764 }
00765 
00766 
00771 void
00772 policy_table_clean(void)
00773 {
00774     policy_table_entry_t * policy = NULL;
00775     ped_policy_route_t * route_tmp = NULL, * route = NULL;
00776     struct hashtable_itr * iterator = NULL;
00777     
00778     if(hashtable_count(if_table) < 1 || !clean_table ||
00779        !get_ssd_ready() || !get_ssd_idle()) {
00780         return; // nothing to do or don't clean yet
00781     }
00782     
00783     junos_trace(PED_TRACEFLAG_HT, "%s", __func__);
00784     
00785     iterator = hashtable_iterator(if_table); // mallocs
00786     INSIST(iterator != NULL);
00787 
00788     // go through all policies
00789     do {
00790         policy = hashtable_iterator_value(iterator);
00791         
00792         // if we have a broken policy, then remove it
00793         if(policy->broken) {
00794             
00795             // remove and delete filters
00796             if(policy->filter) {
00797                 remove_filters_from_interface(policy->ifname);
00798                 free(policy->filter);
00799             }
00800             
00801             if(policy->pfd_filter) {
00802                 remove_pfd_filter_from_interface(policy->ifname);
00803                 policy->pfd_filter = FALSE;
00804             }
00805             
00806             // remove and delete routes
00807             
00808             route = policy->route;
00809             while(route) {
00810                 route_tmp = route;      // Save pointer to current route.
00811                 route = route->next;    // Move to the next route.
00812                 if(route_tmp->status != ROUTE_FAILED) {
00813                     remove_route(route_tmp);
00814                     if(route->status == ROUTE_PENDING) {
00815                         --changes_pending;
00816                     }
00817                 }
00818                 free(route_tmp);        // Free the current route data.
00819             }
00820 
00821             free(policy);
00822             
00823             if(hashtable_iterator_remove(iterator))
00824                 continue;
00825             else
00826                 break;
00827         }
00828         
00829         // else: policy is not broken 
00830         // but we will check for routes or filters that don't belong
00831         
00832         
00833         // Check filter:
00834         if(policy->filter && policy->filter->status == FILTER_UNVERIFIED) {
00835             free(policy->filter);
00836             policy->filter = NULL;
00837             remove_filters_from_interface(policy->ifname);
00838         }
00839         
00840         if(!policy->pfd_filter) {
00841             policy->pfd_filter = apply_pfd_filter_to_interface(policy->ifname);
00842         }
00843 
00844         // Check route(s):        
00845         route = policy->route;
00846         route_tmp = NULL;
00847         policy->route = NULL;  // Detach route list temporarily
00848         
00849         while(route) {
00850             
00851             // check we don't get FAILED routes (in non-broken policies)
00852             if(route->status == ROUTE_FAILED) {
00853                 // log and crash because this shouldn't happen
00854                 ERRMSG(PED, TRACE_LOG_EMERG, 
00855                     "%s: Found a route with status=FAILED in a non-broken "
00856                     "policy. This should not happen.", __func__);
00857                 // abort() is called in the above ERRMSG
00858             }
00859             
00860             // its status should probably be ADDED...
00861             // unless it's not part of the PSD policy anymore it will be:
00862             // UNVERIFIED
00863             if(route->status == ROUTE_UNVERIFIED) {
00864                 // we've received all routes from the PSD, so it is  
00865                 // no longer part of the policy, and we need to delete it
00866                 
00867                 // copy route data into new mem to pass to callback
00868                 // we choose to do this only when policy is not broken
00869                 
00870                 if(route_tmp) { // route_tmp points to last kept route
00871 
00872                     route_tmp->next = route->next;
00873                     
00874                     remove_route(route);
00875                     free(route);
00876                     
00877                     // make route point to the next route (in tmp->next) and
00878                     route = route_tmp->next;
00879                     
00880                 } else {  // No previous routes that we've kept yet
00881                     
00882                     // use tmp ptr to save next
00883                     route_tmp = route->next;
00884                     
00885                     remove_route(route);
00886                     free(route);
00887                     
00888                     // restore route to next route (in tmp) and tmp to NULL
00889                     route = route_tmp;
00890                     route_tmp = NULL;
00891                 }
00892             } else { // a route we are keeping
00893 
00894                 if(policy->route == NULL) {
00895                     policy->route = route;  // First route in the new list
00896                 }
00897                 
00898                 route_tmp = route; // move route_tmp to end
00899                 route = route->next;
00900             }
00901         }
00902         
00903         // Done checking route(s)
00904         
00905     } while (hashtable_iterator_advance(iterator));
00906 
00907     free(iterator);
00908     
00909     clean_table = FALSE;
00910 }
00911 
00912 
00916 void
00917 init_table(void)
00918 {
00919     junos_trace(PED_TRACEFLAG_HT, "%s", __func__);
00920     
00921     if(if_table)
00922         destroy_table();
00923 
00924     if_table = create_hashtable(16, hashFromKey, equalKeys);
00925 
00926     INSIST(if_table != NULL);
00927 }
00928 
00929 
00933 void
00934 destroy_table(void)
00935 {
00936     junos_trace(PED_TRACEFLAG_HT, "%s", __func__);
00937     
00938     hashtable_destroy(if_table, TRUE);
00939     if_table = NULL;
00940 }
00941 
00942 
00948 int
00949 policy_table_entry_count(void)
00950 {
00951     INSIST(if_table != NULL);
00952     return hashtable_count(if_table);
00953 }
00954 
00955 
00960 void
00961 policy_table_iterator_reset(void)
00962 {
00963     itr_broken = TRUE;
00964 }
00965 
00966 
00977 policy_table_entry_t *
00978 policy_table_next(void)
00979 {
00980     policy_table_entry_t *v;
00981 
00982     INSIST(if_table != NULL);
00983     if(hashtable_count(if_table) < 1)
00984         return NULL;
00985 
00986     if(itr_broken) {
00987         if(itr)
00988             free(itr);
00989         itr = hashtable_iterator(if_table); // mallocs
00990         INSIST(itr != NULL);
00991         itr_broken = FALSE;
00992         // now it's at the first element
00993     } else if (!hashtable_iterator_advance(itr)){
00994         // no more
00995         free(itr);
00996         itr = NULL;
00997         itr_broken = TRUE; // will reset next time around
00998 
00999         return NULL;
01000     }
01001 
01002     v = hashtable_iterator_value(itr);
01003 
01004     return v;
01005 }

2007-2009 Juniper Networks, Inc. All rights reserved. The information contained herein is confidential information of Juniper Networks, Inc., and may not be used, disclosed, distributed, modified, or copied without the prior written consent of Juniper Networks, Inc. in an express license. This information is subject to change by Juniper Networks, Inc. Juniper Networks, the Juniper Networks logo, and JUNOS are registered trademarks of Juniper Networks, Inc. in the United States and other countries. All other trademarks, service marks, registered trademarks, or registered service marks are the property of their respective owners.
Generated on Sun May 30 20:27:06 2010 for SDK Your Net Corporation Policy Manager Example: Policy Enforcement Daemon 1.0 by Doxygen 1.5.1