dpm-ctrl_config.c

Go to the documentation of this file.
00001 /*
00002  * $Id: dpm-ctrl_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 
00023 #include "dpm-ctrl_main.h"
00024 #include <jnx/vrf_util_pub.h>
00025 #include <jnx/rt_shared_pub.h>
00026 #include <jnx/ipc_types.h>
00027 #include <jnx/ipc_msp_pub.h>
00028 #include "dpm-ctrl_dfw.h"
00029 #include "dpm-ctrl_http.h"
00030 #include "dpm-ctrl_config.h"
00031 
00032 
00033 /*** Constants ***/
00034 
00035 #ifndef VRFINDEX_ERROR
00036 #define VRFINDEX_ERROR -1 
00037 #endif
00038 
00039 /*** Data structures ***/
00040 
00045 typedef struct policer_s {
00046     patnode        node;         
00047     policer_info_t policer __attribute__ ((packed));      
00048 } policer_t;
00049 
00050 
00055 typedef struct int_pol_s {
00056     patnode  node;                         
00057     char     ifl_name[MAX_INT_NAME + 1];   
00058     patnode  node2;                        
00059     uint32_t index;                        
00060     char     input_pol[MAX_POL_NAME + 1];  
00061     char     output_pol[MAX_POL_NAME + 1]; 
00062 } int_pol_t;
00063 
00064 
00069 typedef struct subscriber_s {
00070     patnode    node;        
00071     sub_info_t subscriber;  
00072     policer_t  * policer;   
00073 } subscriber_t;
00074 
00075 
00080 typedef struct user_s {
00081     patnode       node;        
00082     in_addr_t     address;     
00083     subscriber_t  * sub;       
00084     int_pol_t     * interface; 
00085 } user_t;
00086 
00087 extern msp_fdb_handle_t fdb_handle; 
00088 static uint8_t use_classic_filters; 
00089 static int     vrf_default;         
00090 static patroot sub_conf;            
00091 static patroot user_conf;           
00092 static patroot pol_conf;            
00093 
00098 static patroot int_conf;
00099 
00104 static patroot int_conf2;
00105 
00106 
00107 /*** STATIC/INTERNAL Functions ***/
00108 
00113 PATNODE_TO_STRUCT(pol_entry, policer_t, node)
00114 
00115 
00116 
00122 PATNODE_TO_STRUCT(int_entry, int_pol_t, node)
00123 
00124 
00131 PATNODE_TO_STRUCT(int_entry2, int_pol_t, node2)
00132 
00133 
00138 PATNODE_TO_STRUCT(sub_entry, subscriber_t, node)
00139 
00140 
00145 PATNODE_TO_STRUCT(user_entry, user_t, node)
00146 
00147 
00148 /*** GLOBAL/EXTERNAL Functions ***/
00149 
00150 
00157 status_t
00158 init_configuration(void)
00159 {
00160     use_classic_filters = 0;
00161     
00162     patricia_root_init(&pol_conf, FALSE, MAX_POL_NAME + 1, 0);
00163     patricia_root_init(&int_conf, FALSE, MAX_INT_NAME + 1, 0);
00164     patricia_root_init(&int_conf2, FALSE, sizeof(uint32_t), 0);
00165     patricia_root_init(&sub_conf, FALSE, MAX_SUB_NAME + 1, 0);
00166     patricia_root_init(&user_conf, FALSE, sizeof(in_addr_t), 0);
00167     
00168     vrf_default = vrf_getindexbyvrfname(
00169                     JUNOS_SDK_TABLE_DEFAULT_NAME, NULL, AF_INET);
00170     
00171     if(vrf_default == VRFINDEX_ERROR) {
00172         LOG(LOG_EMERG, "%s: Failed to retrieve VRF index for %s due to %m",
00173             __func__, JUNOS_SDK_TABLE_DEFAULT_NAME);
00174     }
00175     
00176     return SUCCESS;
00177 }
00178 
00179 
00183 void
00184 clear_configuration(void)
00185 {
00186     policer_t    * pol;
00187     int_pol_t    * ip;
00188     subscriber_t * sub;
00189     user_t       * user;
00190     
00191     use_classic_filters = 0;
00192     
00193     while(NULL != (pol = pol_entry(patricia_find_next(&pol_conf, NULL)))) {
00194 
00195         if(!patricia_delete(&pol_conf, &pol->node)) {
00196             LOG(LOG_ERR, "%s: Deleting policer failed", __func__);
00197             continue;
00198         }
00199         free(pol);
00200     }
00201     
00202     while(NULL != (ip = int_entry(patricia_find_next(&int_conf, NULL)))) {
00203 
00204         if(!patricia_delete(&int_conf, &ip->node)) {
00205             LOG(LOG_ERR, "%s: Deleting interface policy failed", __func__);
00206             continue;
00207         }
00208         
00209         if(!patricia_delete(&int_conf2, &ip->node2)) {
00210             LOG(LOG_ERR, "%s: Deleting interface policy2 failed", __func__);
00211             continue;
00212         }
00213         free(ip);
00214     }
00215     
00216     while(NULL != (sub = sub_entry(patricia_find_next(&sub_conf, NULL)))) {
00217 
00218         if(!patricia_delete(&sub_conf, &sub->node)) {
00219             LOG(LOG_ERR, "%s: Deleting subscriber failed", __func__);
00220             continue;
00221         }
00222         free(sub);
00223     }
00224     
00225     while(NULL != (user = user_entry(patricia_find_next(&user_conf, NULL)))) {
00226 
00227         if(!patricia_delete(&user_conf, &user->node)) {
00228             LOG(LOG_ERR, "%s: Deleting user failed", __func__);
00229             continue;
00230         }
00231         free(user);
00232     }
00233 }
00234 
00235 
00239 void
00240 reset_configuration(uint8_t filter_mode)
00241 {
00242     suspend_http_server();
00243     clear_configuration();
00244     use_classic_filters = filter_mode;
00245 }
00246 
00247 
00251 void
00252 configuration_complete(void)
00253 {
00254     policer_t * pol;
00255     int_pol_t * ip;
00256     
00257     reset_all_filters(use_classic_filters);
00258     
00259     // Create all policiers thru dfw module
00260     
00261     pol = pol_entry(patricia_find_next(&pol_conf, NULL));
00262     while(pol != NULL) {
00263         create_policer(&pol->policer);
00264         pol = pol_entry(patricia_find_next(&pol_conf, &pol->node));
00265     }
00266 
00267     // Apply managed interfaces' default policiers thru dfw module
00268     
00269     ip = int_entry(patricia_find_next(&int_conf, NULL));
00270     while(ip != NULL) {
00271         apply_default_int_policy(ip->ifl_name, ip->input_pol, ip->output_pol);
00272         pol = pol_entry(patricia_find_next(&pol_conf, &pol->node));
00273     }
00274     
00275     resume_http_server(); 
00276 }
00277 
00278 
00285 void
00286 configure_policer(policer_info_t * policer)
00287 {
00288     policer_t * pol = NULL;
00289     
00290     INSIST_ERR(policer != NULL);
00291     
00292     pol = calloc(1, sizeof(policer_t));
00293     INSIST_ERR(pol != NULL);
00294 
00295     // copy to new policer_t
00296     memcpy(&pol->policer, policer, sizeof(policer_info_t));
00297     
00298     // add it to the configuration
00299     patricia_node_init_length(&pol->node, strlen(pol->policer.name) + 1);
00300 
00301     if(!patricia_add(&pol_conf, &pol->node)) {
00302         LOG(LOG_ERR, "%s: Failed to add policer to configuration",
00303                 __func__);
00304         free(pol);
00305     }
00306 }
00307 
00308 
00316 void
00317 configure_managed_interface(int_info_t * interface)
00318 {
00319     int_pol_t * intpol;
00320     
00321     INSIST_ERR(interface != NULL);
00322     
00323     intpol = calloc(1, sizeof(int_pol_t));
00324     INSIST_ERR(intpol != NULL);
00325     
00326     // copy data to new int_pol_t
00327     sprintf(intpol->ifl_name, "%s.%d",
00328             interface->name, interface->subunit);
00329     
00330     intpol->index = interface->index;
00331             
00332     strcpy(intpol->input_pol, interface->input_pol);
00333     strcpy(intpol->output_pol, interface->output_pol);
00334     
00335     // add it to the configuration
00336     patricia_node_init_length(&intpol->node, strlen(intpol->ifl_name) + 1);
00337 
00338     // tree by name
00339     if(!patricia_add(&int_conf, &intpol->node)) {
00340         LOG(LOG_ERR, "%s: Failed to add interface default policy "
00341                 "to configuration", __func__);
00342         free(intpol);
00343     }
00344     
00345     // tree by index
00346     if(!patricia_add(&int_conf2, &intpol->node2)) {
00347         LOG(LOG_ERR, "%s: Failed to add interface default policy "
00348                 "to configuration (2)", __func__);
00349         
00350         if(!patricia_delete(&int_conf, &intpol->node)) {
00351             LOG(LOG_ERR, "%s: Deleting interface policy failed", __func__);
00352         }
00353         free(intpol);
00354     }
00355 }
00356 
00357 
00365 void
00366 configure_subscriber(sub_info_t * subscriber)
00367 {
00368     subscriber_t * sub = NULL;
00369     
00370     INSIST_ERR(subscriber != NULL);
00371     
00372     sub = calloc(1, sizeof(subscriber_t));
00373     INSIST_ERR(sub != NULL);
00374     
00375     // copy to new subscriber_t
00376     memcpy(&sub->subscriber, subscriber, sizeof(sub_info_t));
00377     
00378     // find the policer to point to directly
00379     sub->policer = pol_entry(patricia_get(&pol_conf,
00380             strlen(sub->subscriber.policer) + 1, sub->subscriber.policer));
00381     
00382     if(sub->policer == NULL) {
00383         LOG(LOG_ERR, "%s: Failed to find policer %s for subscriber %s",
00384                 __func__, sub->subscriber.policer, sub->subscriber.name);
00385         free(sub);
00386         return;
00387     }
00388     
00389     // add it to the configuration
00390     patricia_node_init_length(&sub->node, strlen(sub->subscriber.name) + 1);
00391 
00392     if(!patricia_add(&sub_conf, &sub->node)) {
00393         LOG(LOG_ERR, "%s: Failed to add subscriber to configuration",
00394                 __func__);
00395         free(sub);
00396     }
00397 }
00398 
00399 
00411 boolean
00412 validate_credentials(char * username, char * password)
00413 {
00414     subscriber_t * sub = NULL;
00415 
00416     // find the subscriber
00417     sub = sub_entry(patricia_get(&sub_conf, strlen(username) + 1, username));
00418     
00419     if(sub != NULL && strcmp(password, sub->subscriber.password) == 0) {
00420         return TRUE;
00421     }
00422     
00423     return FALSE;
00424 }
00425 
00426 
00435 boolean
00436 user_logged_in(in_addr_t address)
00437 {
00438     return (patricia_get(&user_conf, sizeof(in_addr_t), &address) != NULL);
00439 }
00440 
00441 
00453 status_t
00454 apply_policy(char * username, in_addr_t address)
00455 {
00456     subscriber_t * sub = NULL;
00457     user_t * user = NULL;
00458     int_pol_t * ip;
00459     msp_fdb_rt_query_t rt_query;
00460     msp_fdb_rt_info_t rt_res;
00461     
00462     // find the subscriber
00463     sub = sub_entry(patricia_get(&sub_conf, strlen(username) + 1, username));
00464     
00465     if(sub == NULL) {
00466         LOG(LOG_ERR, "%s: Cannot find subscriber", __func__);
00467         return EFAIL;
00468     }
00469     if(sub->policer) {
00470         LOG(LOG_ERR, "%s: Cannot find subscriber's policy", __func__);
00471         return EFAIL;
00472     }
00473     
00474     INSIST_ERR(user != NULL);
00475     
00476     user = calloc(1, sizeof(user_t));
00477     INSIST_ERR(user != NULL);
00478     
00479     // copy to new user_t
00480     user->address = address;
00481     user->sub = sub;
00482     
00483     if(!patricia_add(&user_conf, &user->node)) {
00484         LOG(LOG_ERR, "%s: Failed to add user to configuration", __func__);
00485         free(user);
00486         return EFAIL;
00487     }
00488     
00489     // Find the output interface index associated with the IP address
00490     
00491     rt_query.rt_addr_family = PROTO_IPV4;
00492     rt_query.rt_vrf_key_type = MSP_FDB_RT_QUERY_KEY_RT_INDEX;
00493     rt_query.rt_vrf.rt_idx = vrf_default;
00494     memcpy(rt_query.rt_dest_addr, &address, sizeof(address));
00495 
00496     msp_fdb_get_route_record(fdb_handle, &rt_query, &rt_res);
00497     
00498     LOG(LOG_INFO, "%s: Found output interface index %d",
00499             __func__, rt_res.rt_oif);
00500     
00501     // Check this IFL matches one of the default IFLs
00502     ip = int_entry2(patricia_get(&int_conf2, sizeof(uint32_t), &rt_res.rt_oif));
00503     if(ip == NULL) {
00504         if(!patricia_delete(&user_conf, &user->node)) {
00505             LOG(LOG_ERR, "%s: Deleting user from configuration failed",
00506                     __func__);
00507         }
00508         free(user);
00509         return EFAIL;
00510     }
00511     
00512     user->interface = ip;
00513     
00514     // Apply this subscriber's policy (policier)
00515     // Filter is applied to the IFL that his traffic gets routed through
00516     if(apply_subscriber_policer(ip->ifl_name, sub->subscriber.name,
00517             address, sub->policer->policer.name)) {
00518         LOG(LOG_ERR, "%s: Could not apply subscriber policy", __func__);
00519         return EFAIL;
00520     }
00521     
00522     return SUCCESS;
00523 }
00524 
00525 
00532 void
00533 remove_policy(in_addr_t address)
00534 {
00535     user_t * user = NULL;
00536 
00537     // find the user
00538     user = user_entry(patricia_get(&user_conf, sizeof(in_addr_t), &address));
00539     
00540     if(user != NULL) {
00541         if(!patricia_delete(&user_conf, &user->node)) {
00542             LOG(LOG_ERR, "%s: Deleting user failed", __func__);
00543             return;
00544         }
00545         
00546         // Revoke this subscriber's policy (policier)
00547         // Filter is applied to the IFL that his traffic gets routed through
00548         if(revoke_subscriber_policer(user->interface->ifl_name, 
00549                 user->sub->subscriber.name)) {
00550             LOG(LOG_ERR, "%s: Could not revoke subscriber policy",__func__);
00551         }
00552         
00553         free(user);
00554     } else {
00555         LOG(LOG_ERR, "%s: Cannot find user", __func__);
00556     }
00557 }
00558 

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:26:54 2010 for SDK Your Net Corporation Dynamic Policy Manager Example: dpm-ctrl 1.0 by Doxygen 1.5.1