monitube-mgmt_config.c

Go to the documentation of this file.
00001 /*
00002  * $Id: monitube-mgmt_config.c 358766 2010-01-20 16:37:38Z jamesk $
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) 2008, Juniper Networks, Inc.
00011  * All rights reserved.
00012  */
00013 
00021 #include <sync/common.h>
00022 #include <ddl/dax.h>
00023 #include <jnx/pconn.h>
00024 #include "monitube-mgmt_config.h"
00025 #include "monitube-mgmt_conn.h"
00026 #include "monitube-mgmt_logging.h"
00027 
00028 #include MONITUBE_OUT_H
00029 
00030 /*** Constants ***/
00031 
00032 #define MAX_FLOW_AGE 300  
00033 
00034 
00035 /*** Data Structures ***/
00036 
00037 
00038 static patroot     monitors_conf;     
00039 static patroot     mirrors_conf;      
00040 static monitor_t * current_monitor = NULL; 
00041 static uint8_t     replication_interval;   
00042 static evContext   m_ctx;                  
00043 
00044 /*** STATIC/INTERNAL Functions ***/
00045 
00050 PATNODE_TO_STRUCT(mon_entry, monitor_t, node)
00051 
00052 
00053 
00057 PATNODE_TO_STRUCT(mir_entry, mirror_t, node)
00058 
00059 
00064 PATNODE_TO_STRUCT(address_entry, address_t, node)
00065 
00066 
00071 PATNODE_TO_STRUCT(fs_entry, flowstat_t, node)
00072 
00073 
00083 static void
00084 update_address(in_addr_t addr, in_addr_t mask)
00085 {
00086     address_t * address = NULL;
00087     struct in_addr paddr;
00088     char * tmp;
00089 
00090     INSIST_ERR(current_monitor != NULL);
00091 
00092     junos_trace(MONITUBE_TRACEFLAG_CONF, "%s", __func__);
00093 
00094     address = calloc(1, sizeof(address_t));
00095     INSIST(address != NULL);
00096 
00097     address->address = addr;
00098     address->mask = mask;
00099 
00100     // Add to patricia tree
00101 
00102     if(!patricia_add(current_monitor->addresses, &address->node)) {
00103         free(address);
00104         paddr.s_addr = addr;
00105         tmp = strdup(inet_ntoa(paddr));
00106         paddr.s_addr = mask;
00107         LOG(TRACE_LOG_ERR, "%s: Cannot add address %s/%s as it conflicts with "
00108                 "another address in the same monitored-networks group (%s)",
00109                 __func__, tmp, inet_ntoa(paddr), current_monitor->name);
00110         free(tmp);
00111     }
00112 
00113     notify_address_update(current_monitor->name, addr, mask);
00114 }
00115 
00116 
00129 static monitor_t *
00130 update_monitor(const char * name, uint32_t rate)
00131 {
00132     monitor_t * mon;
00133 
00134     junos_trace(MONITUBE_TRACEFLAG_CONF, "%s", __func__);
00135 
00136     mon = mon_entry(patricia_get(&monitors_conf, strlen(name) + 1, name));
00137 
00138     if(mon == NULL) {
00139         mon = calloc(1, sizeof(monitor_t));
00140         INSIST(mon != NULL);
00141         strncpy(mon->name, name, MAX_MON_NAME);
00142 
00143         // Add to patricia tree
00144         patricia_node_init_length(&mon->node, strlen(name) + 1);
00145 
00146         if(!patricia_add(&monitors_conf, &mon->node)) {
00147             LOG(TRACE_LOG_ERR, "%s: Failed to add "
00148                     "monitor to configuration", __func__);
00149             free(mon);
00150             return NULL;
00151         }
00152 
00153         // init addresses
00154         mon->addresses = patricia_root_init(NULL, FALSE, sizeof(in_addr_t), 0);
00155 
00156         // init flow_stats
00157         mon->flow_stats = patricia_root_init(NULL, FALSE,
00158                 sizeof(in_addr_t) + (3 * sizeof(uint16_t)), 0);
00159     }
00160 
00161     if(mon->rate != rate) {
00162         mon->rate = rate;
00163         notify_monitor_update(name, rate);
00164     }
00165 
00166     return mon;
00167 }
00168 
00169 
00179 static void
00180 update_mirror(in_addr_t from, in_addr_t to)
00181 {
00182     mirror_t * mir;
00183 
00184     junos_trace(MONITUBE_TRACEFLAG_CONF, "%s", __func__);
00185 
00186     mir = mir_entry(patricia_get(&mirrors_conf, sizeof(from), &from));
00187 
00188     if(mir == NULL) {
00189         mir = calloc(1, sizeof(mirror_t));
00190         INSIST(mir != NULL);
00191         mir->original = from;
00192 
00193         if(!patricia_add(&mirrors_conf, &mir->node)) {
00194             LOG(TRACE_LOG_ERR, "%s: Failed to add "
00195                     "mirror to configuration", __func__);
00196             free(mir);
00197             return;
00198         }
00199     }
00200 
00201     // always true until we add more to a mirror...
00202     if(mir->redirect != to) {
00203         mir->redirect = to;
00204         notify_mirror_update(from, to);
00205     }
00206 }
00207 
00208 
00215 static void
00216 delete_all_addresses(boolean notify)
00217 {
00218     address_t * add = NULL;
00219 
00220     INSIST_ERR(current_monitor != NULL);
00221 
00222     junos_trace(MONITUBE_TRACEFLAG_CONF, "%s", __func__);
00223 
00224     while(NULL != (add =
00225         address_entry(patricia_find_next(current_monitor->addresses, NULL)))) {
00226 
00227         if(!patricia_delete(current_monitor->addresses, &add->node)) {
00228             LOG(TRACE_LOG_ERR, "%s: Deleting address failed", __func__);
00229             continue;
00230         }
00231 
00232         free(add);
00233     }
00234 
00235     if(notify) {
00236         // treat as a monitor delete since without any address a
00237         // monitor is useless to the data component
00238         notify_monitor_delete(current_monitor->name);
00239     }
00240 }
00241 
00242 
00249 static void
00250 delete_all_flowstats(monitor_t * mon)
00251 {
00252     flowstat_t * fs = NULL;
00253 
00254     INSIST_ERR(mon != NULL);
00255 
00256     junos_trace(MONITUBE_TRACEFLAG_CONF, "%s", __func__);
00257 
00258     while(NULL != (fs = fs_entry(patricia_find_next(mon->flow_stats, NULL)))) {
00259 
00260         if(evTestID(fs->timer_id)) {
00261            evClearTimer(m_ctx, fs->timer_id);
00262         }
00263 
00264         if(!patricia_delete(mon->flow_stats, &fs->node)) {
00265             LOG(TRACE_LOG_ERR, "%s: Deleting flowstat failed", __func__);
00266             continue;
00267         }
00268 
00269         free(fs);
00270     }
00271 }
00272 
00273 
00277 static void
00278 delete_all_monitors(void)
00279 {
00280     monitor_t * mon;
00281 
00282     junos_trace(MONITUBE_TRACEFLAG_CONF, "%s", __func__);
00283 
00284     while(NULL != (mon = mon_entry(patricia_find_next(&monitors_conf, NULL)))) {
00285 
00286         current_monitor = mon;
00287         delete_all_addresses(FALSE);
00288         patricia_root_delete(mon->addresses);
00289         delete_all_flowstats(mon);
00290         patricia_root_delete(mon->flow_stats);
00291 
00292         if(!patricia_delete(&monitors_conf, &mon->node)) {
00293             LOG(TRACE_LOG_ERR, "%s: Deleting monitor failed", __func__);
00294             continue;
00295         }
00296 
00297         free(mon);
00298     }
00299 
00300     current_monitor = NULL;
00301 
00302     notify_delete_all_monitors();
00303 }
00304 
00305 
00309 static void
00310 delete_all_mirrors(void)
00311 {
00312     mirror_t * mir;
00313 
00314     junos_trace(MONITUBE_TRACEFLAG_CONF, "%s", __func__);
00315 
00316     while(NULL != (mir = mir_entry(patricia_find_next(&mirrors_conf, NULL)))) {
00317 
00318         if(!patricia_delete(&mirrors_conf, &mir->node)) {
00319             LOG(TRACE_LOG_ERR, "%s: Deleting mirror failed", __func__);
00320             continue;
00321         }
00322 
00323         free(mir);
00324     }
00325 
00326     notify_delete_all_mirrors();
00327 }
00328 
00329 
00339 static void
00340 delete_address(in_addr_t addr, in_addr_t mask)
00341 {
00342     address_t * address = NULL;
00343 
00344     INSIST_ERR(current_monitor != NULL);
00345 
00346     junos_trace(MONITUBE_TRACEFLAG_CONF, "%s", __func__);
00347 
00348     address = address_entry(patricia_get(current_monitor->addresses,
00349                     sizeof(in_addr_t), &addr));
00350 
00351     if(address == NULL) {
00352         LOG(TRACE_LOG_ERR, "%s: Could not find address to delete",__func__);
00353         return;
00354     }
00355 
00356     notify_address_delete(current_monitor->name, addr, mask);
00357 
00358     if(!patricia_delete(current_monitor->addresses, &address->node)) {
00359         LOG(TRACE_LOG_ERR, "%s: Deleting address failed", __func__);
00360         return;
00361     }
00362 
00363     free(address);
00364 
00365 
00366 }
00367 
00368 
00375 static void
00376 delete_monitor(monitor_t * mon)
00377 {
00378     junos_trace(MONITUBE_TRACEFLAG_CONF, "%s", __func__);
00379 
00380     current_monitor = mon;
00381     delete_all_addresses(FALSE);
00382     patricia_root_delete(mon->addresses);
00383     delete_all_flowstats(mon);
00384     patricia_root_delete(mon->flow_stats);
00385     current_monitor = NULL;
00386 
00387     notify_monitor_delete(mon->name);
00388 
00389     if(!patricia_delete(&monitors_conf, &mon->node)) {
00390         LOG(TRACE_LOG_ERR, "%s: Deleting monitor failed", __func__);
00391         return;
00392     }
00393 
00394     free(mon);
00395 }
00396 
00397 
00404 static void
00405 delete_mirror(in_addr_t from)
00406 {
00407     mirror_t * mir;
00408 
00409     junos_trace(MONITUBE_TRACEFLAG_CONF, "%s", __func__);
00410 
00411     mir = mir_entry(patricia_get(&mirrors_conf, sizeof(from), &from));
00412 
00413     if(mir == NULL) {
00414         LOG(TRACE_LOG_ERR, "%s: Could not find mirror to delete", __func__);
00415         return;
00416     }
00417 
00418     notify_mirror_delete(from);
00419 
00420     if(!patricia_delete(&mirrors_conf, &mir->node)) {
00421         LOG(TRACE_LOG_ERR, "%s: Deleting mirror failed", __func__);
00422         return;
00423     }
00424 
00425     free(mir);
00426 }
00427 
00428 
00448 static int
00449 parse_addresses(dax_walk_data_t * dwd,
00450                 ddl_handle_t * dop,
00451                 int action,
00452                 void * data)
00453 {
00454     char ip_str[32], * tmpstr, *tmpip;
00455     struct in_addr tmp;
00456     in_addr_t addr, prefix;
00457     int check = *((int *)data), mask;
00458 
00459     junos_trace(MONITUBE_TRACEFLAG_CONF, "%s", __func__);
00460 
00461     if(action == DAX_ITEM_DELETE_ALL) {
00462         // All servers were deleted
00463         delete_all_addresses(TRUE);
00464         return DAX_WALK_OK;
00465     }
00466 
00467     INSIST(dop != NULL);
00468 
00469     switch(action) {
00470 
00471     case DAX_ITEM_DELETE:
00472         // an address was deleted
00473 
00474         // get the (deleted) address
00475         // for deleted items we can only get a string form:
00476         if(!dax_get_stringr_by_dwd_ident(dwd, NULL, 0, ip_str, sizeof(ip_str))){
00477             dax_error(dop, "Failed to parse IP address and prefix on delete");
00478             return DAX_WALK_ABORT;
00479         }
00480 
00481         // break off prefix
00482         tmpip = strdup(ip_str);
00483         tmpstr = strtok(tmpip, "/");
00484 
00485         if(inet_aton(tmpstr, &tmp) != 1) { // if failed
00486             dax_error(dop, "Failed to parse prefix address portion: %s",
00487                     ip_str);
00488             return DAX_WALK_ABORT;
00489         }
00490         addr = tmp.s_addr;
00491 
00492         // parse prefix
00493         tmpstr = strtok(NULL, "/");
00494 
00495         errno = 0;
00496         mask = (int)strtol(tmpstr, (char **)NULL, 10);
00497         if(errno) {
00498             dax_error(dop, "Failed to parse prefix mask portion: %s", ip_str);
00499             return DAX_WALK_ABORT;
00500         }
00501         if(mask < 0 || mask > 32) {
00502             dax_error(dop, "Mask bits must be in range of 0-32: %s", ip_str);
00503             return DAX_WALK_ABORT;
00504         }
00505 
00506         if(mask == 32) {
00507             prefix = 0xFFFFFFFF;
00508         } else {
00509             prefix = (1 << mask) - 1;
00510             prefix = htonl(prefix);
00511         }
00512 
00513         free(tmpip);
00514 
00515         if(!check) {
00516             delete_address(addr, prefix);
00517         }
00518 
00519         break;
00520 
00521     case DAX_ITEM_CHANGED:
00522         // a server was added
00523 
00524         if(!dax_get_ipv4prefixmandatory_by_name(dop,
00525                 DDLNAME_MONITORED_NETWORKS_ADDRESS, &addr, &prefix)) {
00526             dax_error(dop, "Failed to parse IP address and prefix");
00527             return DAX_WALK_ABORT;
00528         }
00529 
00530         if(((~prefix) & addr) != 0) {
00531             dax_error(dop, "Host bits in address must be zero");
00532             return DAX_WALK_ABORT;
00533         }
00534 
00535         if(!check) {
00536             update_address(addr, prefix);
00537         }
00538 
00539         break;
00540 
00541     case DAX_ITEM_UNCHANGED:
00542         junos_trace(MONITUBE_TRACEFLAG_CONF,
00543                 "%s: DAX_ITEM_UNCHANGED observed", __func__);
00544         break;
00545 
00546     default:
00547         break;
00548     }
00549 
00550     return DAX_WALK_OK;
00551 }
00552 
00553 
00572 static int
00573 parse_monitors(dax_walk_data_t * dwd,
00574                ddl_handle_t * dop,
00575                int action,
00576                void * data)
00577 {
00578     char monitor_name[MAX_MON_NAME];
00579     uint32_t rate;
00580     monitor_t * mon;
00581     ddl_handle_t * mon_nets_dop;
00582     int check = *((int *)data);
00583 
00584     junos_trace(MONITUBE_TRACEFLAG_CONF, "%s", __func__);
00585 
00586     switch (action) {
00587 
00588     case DAX_ITEM_DELETE_ALL:
00589 
00590         // All monitors were deleted
00591         delete_all_monitors();
00592         return DAX_WALK_OK;
00593 
00594         break;
00595 
00596     case DAX_ITEM_DELETE:
00597 
00598         // get the (deleted) monitor name
00599         if (!dax_get_stringr_by_dwd_ident(dwd, NULL, 0,
00600                 monitor_name, sizeof(monitor_name))) {
00601             dax_error(dop, "Failed to parse a monitor name");
00602             return DAX_WALK_ABORT;
00603         }
00604 
00605         if(check) {
00606             break; // nothing to do
00607         }
00608 
00609         mon = mon_entry(patricia_get(&monitors_conf,
00610                     strlen(monitor_name) + 1, monitor_name));
00611         if(mon != NULL) {
00612             delete_monitor(mon);
00613         }
00614 
00615         break;
00616 
00617     case DAX_ITEM_CHANGED:
00618 
00619         INSIST_ERR(dop != NULL);
00620 
00621         // get the monitor name
00622 
00623         if (!dax_get_stringr_by_name(dop, DDLNAME_MONITOR_MONITOR_NAME,
00624                 monitor_name, sizeof(monitor_name))) {
00625             dax_error(dop, "Failed to parse monitor name");
00626             return DAX_WALK_ABORT;
00627         }
00628 
00629         // read in some of the attributes
00630 
00631         if (!dax_get_uint_by_name(dop, DDLNAME_MONITOR_RATE, &rate)) {
00632             dax_error(dop, "Failed to parse rate");
00633             return DAX_WALK_ABORT;
00634         }
00635 
00636         if(!dax_get_object_by_name(dop, DDLNAME_MONITORED_NETWORKS,
00637                 &mon_nets_dop, FALSE)) {
00638 
00639             dax_error(dop, "Failed to parse monitored-networks (required)");
00640             return DAX_WALK_ABORT;
00641 
00642         } else {
00643 
00644             // update
00645             if(!check) {
00646                 current_monitor = update_monitor(monitor_name, rate);
00647                 if(current_monitor == NULL) {
00648                     dax_release_object(&mon_nets_dop);
00649                     return DAX_WALK_ABORT;
00650                 }
00651             }
00652 
00653             if(dax_walk_list(mon_nets_dop, DAX_WALK_DELTA, parse_addresses,data)
00654                         != DAX_WALK_OK) {
00655 
00656                 dax_release_object(&mon_nets_dop);
00657                 current_monitor = NULL;
00658                 return DAX_WALK_ABORT;
00659             }
00660         }
00661 
00662         current_monitor = NULL;
00663         dax_release_object(&mon_nets_dop);
00664 
00665         break;
00666 
00667     case DAX_ITEM_UNCHANGED:
00668         junos_trace(MONITUBE_TRACEFLAG_CONF,
00669                 "%s: DAX_ITEM_UNCHANGED observed", __func__);
00670         break;
00671 
00672     default:
00673         break;
00674     }
00675 
00676     return DAX_WALK_OK;
00677 }
00678 
00679 
00680 
00699 static int
00700 parse_mirrors(dax_walk_data_t * dwd,
00701               ddl_handle_t * dop,
00702               int action,
00703               void * data)
00704 {
00705     in_addr_t mirror_from;
00706     in_addr_t mirror_to;
00707     char ip_str[INET_ADDRSTRLEN];
00708     struct in_addr tmp;
00709     int check = *((int *)data);
00710     int addr_fam;
00711 
00712     junos_trace(MONITUBE_TRACEFLAG_CONF, "%s", __func__);
00713 
00714     switch (action) {
00715 
00716     case DAX_ITEM_DELETE_ALL:
00717 
00718         // All mirrors were deleted
00719         delete_all_mirrors();
00720         return DAX_WALK_OK;
00721 
00722         break;
00723 
00724     case DAX_ITEM_DELETE:
00725 
00726         // get the (deleted) mirror name (only available as a string)
00727         if (!dax_get_stringr_by_dwd_ident(dwd, NULL, 0,
00728                 ip_str, sizeof(ip_str))) {
00729             dax_error(dop, "Failed to parse mirror address");
00730             return DAX_WALK_ABORT;
00731         }
00732         if(inet_aton(ip_str, &tmp) != 1) { // if failed
00733             dax_error(dop, "Failed to parse mirror IP from: %s", ip_str);
00734             return DAX_WALK_ABORT;
00735         }
00736         mirror_from = tmp.s_addr;
00737 
00738         if(!check) {
00739             delete_mirror(mirror_from);
00740         }
00741 
00742         break;
00743 
00744     case DAX_ITEM_CHANGED:
00745 
00746         INSIST_ERR(dop != NULL);
00747 
00748         // get the mirror info
00749 
00750         if(!dax_get_ipaddr_by_name(dop, DDLNAME_MIRROR_MIRRORED_ADDRESS,
00751                 &addr_fam, &mirror_from, sizeof(mirror_from)) ||
00752                 addr_fam != AF_INET) {
00753             dax_error(dop, "Failed to parse mirror IP");
00754             return DAX_WALK_ABORT;
00755         }
00756 
00757         if(!dax_get_ipaddr_by_name(dop, DDLNAME_MIRROR_DESTINATION,
00758                 &addr_fam, &mirror_to, sizeof(mirror_to)) ||
00759                 addr_fam != AF_INET) {
00760             dax_error(dop, "Failed to parse mirror destination IP");
00761             return DAX_WALK_ABORT;
00762         }
00763 
00764         // update
00765         if(!check) {
00766             update_mirror(mirror_from, mirror_to);
00767         }
00768 
00769         break;
00770 
00771     case DAX_ITEM_UNCHANGED:
00772         junos_trace(MONITUBE_TRACEFLAG_CONF,
00773                 "%s: DAX_ITEM_UNCHANGED observed", __func__);
00774         break;
00775 
00776     default:
00777         break;
00778     }
00779 
00780     return DAX_WALK_OK;
00781 }
00782 
00783 
00799 static void
00800 age_out_flow_stat(evContext ctx __unused, void * uap,
00801             struct timespec due __unused, struct timespec inter __unused)
00802 {
00803     flowstat_t * fs = (flowstat_t *)uap;
00804 
00805     INSIST_ERR(fs != NULL);
00806 
00807     junos_trace(MONITUBE_TRACEFLAG_CONF, "%s", __func__);
00808 
00809     if(evTestID(fs->timer_id)) {
00810        evClearTimer(m_ctx, fs->timer_id);
00811     }
00812 
00813     if(!patricia_delete(fs->mon->flow_stats, &fs->node)) {
00814         LOG(TRACE_LOG_ERR, "%s: Deleting flowstat failed", __func__);
00815         return;
00816     }
00817 
00818     free(fs);
00819 }
00820 
00821 
00822 /*** GLOBAL/EXTERNAL Functions ***/
00823 
00824 
00828 void
00829 init_config(evContext ctx)
00830 {
00831     m_ctx = ctx;
00832     replication_interval = 0;
00833 
00834     patricia_root_init(&monitors_conf, FALSE, MAX_MON_NAME, 0);
00835     patricia_root_init(&mirrors_conf, FALSE, sizeof(in_addr_t), 0);
00836 }
00837 
00838 
00842 void
00843 clear_config(void)
00844 {
00845     delete_all_monitors();
00846     delete_all_mirrors();
00847 }
00848 
00849 
00860 int
00861 monitube_config_read(int check)
00862 {
00863     const char * monitube_config[] =
00864         {DDLNAME_SYNC, DDLNAME_SYNC_MONITUBE, NULL};
00865 
00866     ddl_handle_t * top = NULL, * mon_dop = NULL, * mir_dop = NULL;
00867     uint8_t old_ri;
00868 
00869     junos_trace(MONITUBE_TRACEFLAG_CONF, "%s: Starting monitube "
00870             "configuration load", __func__);
00871 
00872     // Load the main configuration under sync monitube (if changed)...
00873 
00874     if (!dax_get_object_by_path(NULL, monitube_config, &top, FALSE))  {
00875 
00876         junos_trace(MONITUBE_TRACEFLAG_CONF,
00877                 "%s: Cleared monitube configuration", __func__);
00878 
00879         clear_config();
00880         return SUCCESS;
00881     } else {
00882         if(dax_get_object_by_name(top, DDLNAME_MONITOR, &mon_dop, FALSE)) {
00883             if(dax_walk_list(mon_dop, DAX_WALK_DELTA, parse_monitors, &check)
00884                     != DAX_WALK_OK) {
00885     
00886                 junos_trace(MONITUBE_TRACEFLAG_CONF, "%s: walk monitors "
00887                     "list in sampling configuration failed", __func__);
00888                 goto failed;
00889             }
00890         } else {
00891             delete_all_monitors();
00892         }
00893     
00894         if(dax_get_object_by_name(top, DDLNAME_MIRROR, &mir_dop, FALSE)) {
00895             if(dax_walk_list(mir_dop, DAX_WALK_DELTA, parse_mirrors, &check)
00896                     != DAX_WALK_OK) {
00897                 junos_trace(MONITUBE_TRACEFLAG_CONF, "%s: walk mirrors list in "
00898                         "sampling configuration failed", __func__);
00899                 goto failed;
00900             }
00901         } else {
00902             delete_all_mirrors();
00903         }
00904     
00905         if(mon_dop == NULL && mir_dop == NULL) {
00906             dax_error(top, "Cannot have empty monitube service configuration");
00907             goto failed;
00908         }
00909     
00910         old_ri = replication_interval;
00911     
00912         dax_get_ubyte_by_name(top,
00913                 DDLNAME_SYNC_MONITUBE_REPLICATION_INTERVAL,
00914                 &replication_interval);
00915     
00916         if(old_ri != replication_interval) {
00917             notify_replication_interval(replication_interval);
00918         }
00919         
00920         dax_release_object(&top);
00921     }
00922 
00923 
00924     if(!check) {
00925         // send to the PIC(s)
00926         process_notifications();
00927     }
00928 
00929     junos_trace(MONITUBE_TRACEFLAG_CONF,
00930             "%s: Loaded monitube configuration", __func__);
00931 
00932     return SUCCESS;
00933 
00934 failed:
00935 
00936     if(mon_dop)
00937         dax_release_object(&mon_dop);
00938 
00939     if(mir_dop)
00940         dax_release_object(&mir_dop);
00941 
00942     if(top)
00943         dax_release_object(&top);
00944 
00945     return EFAIL;
00946 }
00947 
00948 
00954 uint8_t
00955 get_replication_interval(void)
00956 {
00957     return replication_interval;
00958 }
00959 
00968 monitor_t *
00969 next_monitor(monitor_t * data)
00970 {
00971     return mon_entry(
00972             patricia_find_next(&monitors_conf, (data ? &(data->node) : NULL)));
00973 }
00974 
00975 
00984 mirror_t *
00985 next_mirror(mirror_t * data)
00986 {
00987     return mir_entry(
00988             patricia_find_next(&mirrors_conf, (data ? &(data->node) : NULL)));
00989 }
00990 
00991 
01004 address_t *
01005 next_address(monitor_t * mon, address_t * data)
01006 {
01007     return address_entry(patricia_find_next(mon->addresses,
01008                                     (data ? &(data->node) : NULL)));
01009 }
01010 
01011 
01024 flowstat_t *
01025 next_flowstat(monitor_t * mon, flowstat_t * data)
01026 {
01027     return fs_entry(patricia_find_next(mon->flow_stats,
01028                                     (data ? &(data->node) : NULL)));
01029 }
01030 
01031 
01040 monitor_t *
01041 find_monitor(char * name)
01042 {
01043     return mon_entry(patricia_get(&monitors_conf, strlen(name) + 1, name));
01044 }
01045 
01046 
01071 void
01072 set_flow_stat(uint16_t fpc_slot,
01073               uint16_t pic_slot,
01074               const char * name,
01075               in_addr_t flow_addr,
01076               uint16_t flow_port,
01077               double mdi_df,
01078               uint32_t mdi_mlr)
01079 {
01080     monitor_t * mon;
01081     flowstat_t * fs;
01082     struct anp {
01083         uint16_t  fpc;
01084         uint16_t  pic;
01085         in_addr_t address;
01086         uint16_t  port;
01087     } key;
01088 
01089     // get monitor
01090     mon = mon_entry(patricia_get(&monitors_conf, strlen(name) + 1, name));
01091 
01092     if(mon == NULL) {
01093         LOG(TRACE_LOG_WARNING, "%s: statistic received for a flow in a monitor "
01094                 "that is not configured (ignored)", __func__);
01095         return;
01096     }
01097 
01098     // get flow stat
01099 
01100     key.fpc = fpc_slot;
01101     key.pic = pic_slot;
01102     key.address = flow_addr;
01103     key.port = flow_port;
01104 
01105     fs = fs_entry(patricia_get(mon->flow_stats, sizeof(in_addr_t) +
01106             (3 * sizeof(uint16_t)), &key));
01107 
01108     if(fs == NULL) { // gotta create it
01109         fs = calloc(1, sizeof(flowstat_t));
01110         INSIST(fs != NULL);
01111         fs->fpc_slot = fpc_slot;
01112         fs->pic_slot = pic_slot;
01113         fs->flow_addr = flow_addr;
01114         fs->flow_port = flow_port;
01115         fs->mon = mon;
01116 
01117         if(!patricia_add(mon->flow_stats, &fs->node)) {
01118             LOG(TRACE_LOG_ERR, "%s: Failed to add a flow stat to configuration",
01119                     __func__);
01120             free(fs);
01121             return;
01122         }
01123 
01124         junos_trace(MONITUBE_TRACEFLAG_CONF, "%s: Added a new flow statistic "
01125                 "for monitor %s", __func__, name);
01126 
01127     } else { // it already exists
01128         if(evTestID(fs->timer_id)) {
01129            evClearTimer(m_ctx, fs->timer_id);
01130         }
01131     }
01132 
01133     fs->last_mdi_df[fs->window_position] = mdi_df;
01134     fs->last_mdi_mlr[fs->window_position] = mdi_mlr;
01135     fs->reports++;
01136     fs->window_position++;
01137     if(fs->window_position == STATS_BASE_WINDOW) {
01138         fs->window_position = 0;
01139     }
01140 
01141     // reset age timer
01142 
01143     if(evSetTimer(m_ctx, age_out_flow_stat, fs,
01144             evAddTime(evNowTime(), evConsTime(MAX_FLOW_AGE, 0)),
01145             evConsTime(0, 0), &fs->timer_id)) {
01146 
01147         LOG(LOG_EMERG, "%s: evSetTimer() failed! Will not be "
01148                 "able to age out flow statistics", __func__);
01149     }
01150 }
01151 
01152 
01156 void
01157 clear_all_flowstats(void)
01158 {
01159     monitor_t * mon;
01160 
01161     junos_trace(MONITUBE_TRACEFLAG_CONF, "%s", __func__);
01162 
01163     mon = next_monitor(NULL);
01164     while(mon != NULL) {
01165 
01166         delete_all_flowstats(mon);
01167 
01168         mon = next_monitor(mon);
01169     }
01170 }
01171 
01172 
01182 int
01183 clear_flowstats(char * mon_name)
01184 {
01185     monitor_t * mon;
01186 
01187     junos_trace(MONITUBE_TRACEFLAG_CONF, "%s", __func__);
01188 
01189     // get monitor
01190     mon = mon_entry(patricia_get(&monitors_conf, strlen(mon_name)+1, mon_name));
01191 
01192     if(mon == NULL) {
01193         return -1;
01194     }
01195 
01196     delete_all_flowstats(mon);
01197     return 0;
01198 }

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:03 2010 for SDK Your Net Corporation Monitube IPTV Monitoring Example: monitube-mgmt 1.0 by Doxygen 1.5.1