dpm-ctrl_dfw.c

Go to the documentation of this file.
00001 /*
00002  * $Id: dpm-ctrl_dfw.c 346460 2009-11-14 05:06:47Z ssiano $
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 
00022 #include "dpm-ctrl_main.h"
00023 #include <jnx/junos_dfw_api.h>
00024 #include <jnx/provider_info.h>
00025 #include "dpm-ctrl_dfw.h"
00026 #include <errno.h>
00027 #include <limits.h>
00028 
00029 
00030 /*** Constants ***/
00031 
00032 #define KB_BYTES        1024 
00033 
00034 #define FULL_PREFIX_LEN   32 
00035 
00036 /*** Data Structures ***/
00037 
00038 static junos_dfw_session_handle_t dfw_handle; 
00039 static junos_dfw_client_id_t      dpm_cid;    
00040 static boolean                    ready = FALSE;  
00041 static boolean                    use_classic_filters = FALSE;
00043 
00044 /*** STATIC/INTERNAL Functions ***/
00045 
00046 
00063 static void
00064 session_connect(junos_dfw_session_handle_t handle,
00065                 junos_dfw_session_connect_return_t code,
00066                 junos_dfw_client_id_t * client_id_list,
00067                 int num_client_ids)
00068 {
00069     INSIST_ERR(handle == dfw_handle);
00070     
00071     if(code == JUNOS_DFW_SC_SUCCESS) {
00072         
00073         if(num_client_ids > 1) {
00074             LOG(LOG_ERR, "%s: Found more than one client ID", __func__);            
00075         }
00076         
00077         if(client_id_list != NULL) {
00078             
00079             dpm_cid = client_id_list[0]; // get dynamic ID assigned 
00080             LOG(LOG_INFO, "%s: Connected to dfwd", __func__);
00081             
00082             if(junos_dfw_trans_purge(dfw_handle,
00083                     client_id_list, num_client_ids)) {
00084                 LOG(LOG_ERR, "%s: Failed to perform initial DFWD purge",
00085                         __func__);
00086             }
00087             
00088             ready = TRUE;
00089             return;
00090         } else {
00091             LOG(LOG_ERR, "%s: Found no client ID", __func__);
00092         }
00093     } else if(code == JUNOS_DFW_SC_FAILED_VERSION) {
00094         LOG(LOG_ERR, "%s: Connecting to dfwd failed. Bad libdfwd version",
00095                 __func__);
00096     } else {
00097         LOG(LOG_ERR, "%s: Connecting to dfwd failed", __func__);
00098     }
00099     ready = FALSE;
00100 }
00101 
00102 
00112 static void
00113 session_state_changed(junos_dfw_session_handle_t handle,
00114                       junos_dfw_session_state_t state)
00115 {
00116     INSIST_ERR(handle == dfw_handle);
00117     LOG(LOG_ALERT, "%s: DPM-CTRL Connection to DFWD going %s", __func__,
00118             (state == JUNOS_DFW_SS_DOWN) ? "DOWN" : "??");
00119     ready = FALSE;
00120     
00121     /*
00122      * release the session handle
00123      */
00124     junos_dfw_session_handle_free(handle);
00125 
00126     dfw_handle = NULL;
00127 
00128     // TODO start a retry timer
00129 }
00130 
00131 
00144 static void
00145 transaction_rejected(junos_dfw_session_handle_t handle, 
00146                      uint64_t ctx, 
00147                      junos_dfw_trans_reject_reason_info_t reason_info)
00148 {
00149     #define ERR_BUF_SIZE 256
00150     char errbuf[ERR_BUF_SIZE];
00151     
00152     INSIST_ERR(handle == dfw_handle);
00153     
00154     junos_dfw_trans_reject_reason_strerr(reason_info, errbuf, ERR_BUF_SIZE);
00155     
00156     LOG(LOG_WARNING, "%s: Context %lld failed: %s", __func__, ctx, errbuf);
00157 }
00158 
00159 
00172 static void
00173 transaction_accepted(junos_dfw_session_handle_t handle, 
00174                      uint64_t ctx,
00175                      uint32_t dfw_idx)
00176 {
00177     INSIST_ERR(handle == dfw_handle);
00178     
00179     LOG(LOG_INFO,"%s: Context %lld accepted as %d", __func__, ctx, dfw_idx);
00180 }
00181 
00182 
00183 /*** GLOBAL/EXTERNAL Functions ***/
00184 
00185 
00195 status_t
00196 init_dfw(evContext ctx)
00197 {
00198     int rc;
00199     junos_dfw_client_functions_t funcs;
00200     junos_dfw_conn_addr_t conn_addr;
00201     junos_dfw_sdk_app_id_t app_id;
00202 
00203     ready = FALSE;
00204     dfw_handle = NULL;
00205     
00206     funcs.session_connect_cb = session_connect;
00207     funcs.session_state_change_cb = session_state_changed;
00208     funcs.trans_rejected_cb = transaction_rejected;
00209     funcs.trans_accepted_cb = transaction_accepted;
00210 
00211     rc = junos_dfw_session_handle_alloc(&dfw_handle, &funcs);
00212     
00213     if(rc != 0) {
00214         LOG(LOG_ERR, "%s: Cannot allocate handle for a dynamic "
00215                 "firewall session (%m)", __func__);
00216         dfw_handle = NULL;
00217         return EFAIL;
00218     }
00219     
00220     conn_addr.addr_family = JUNOS_DFW_CONN_AF_INET;
00221     conn_addr.addr.dfwd_inet.dfwd_server_port = JUNOS_DFW_DEFAULT_PORT;
00222         
00223     conn_addr.addr.dfwd_inet.dfwd_host_name = 
00224         malloc(strlen(JUNOS_DFW_DEFAULT_LOCAL_ADDR) + 1);
00225     INSIST_ERR(conn_addr.addr.dfwd_inet.dfwd_host_name != NULL);
00226     strlcpy(conn_addr.addr.dfwd_inet.dfwd_host_name, 
00227             JUNOS_DFW_DEFAULT_LOCAL_ADDR,
00228             strlen(JUNOS_DFW_DEFAULT_LOCAL_ADDR) + 1);
00229     
00230     app_id = 1; // Would be origin ID if done in the RE SDK
00231     
00232     rc = junos_dfw_session_open(dfw_handle, &conn_addr, app_id, ctx);
00233     
00234     if(rc != 0) {
00235         if(errno == EISCONN) {
00236             LOG(LOG_INFO, "%s: Connection to DWFD established", __func__);
00237             ready = TRUE;            
00238         } else {
00239             LOG(LOG_ERR, "%s: Cannot setup dynamic firewall connection (%m)",
00240                     __func__);
00241             junos_dfw_session_handle_free(dfw_handle);
00242             dfw_handle = NULL;
00243             return EFAIL;
00244         }
00245     }
00246 
00247     return SUCCESS;
00248 }
00249 
00250 
00254 void
00255 shutdown_dfw(void)
00256 {
00257     ready = FALSE;
00258     
00259     if(dfw_handle) {
00260         junos_dfw_session_close(dfw_handle);
00261         junos_dfw_session_handle_free(dfw_handle);
00262         dfw_handle = NULL;
00263     }
00264 }
00265 
00266 
00272 boolean
00273 dfw_ready(void)
00274 {
00275     return ready;
00276 }
00277 
00278 
00285 void
00286 reset_all_filters(boolean new_filter_mode)
00287 {
00288     if(ready) {
00289         LOG(LOG_ERR, "%s: Purging all existing filters", __func__);
00290         
00291         use_classic_filters = new_filter_mode;
00292         
00293         if(junos_dfw_trans_purge(dfw_handle, &dpm_cid, 1)) {
00294             LOG(LOG_ERR, "%s: Failed to perform DFWD purge", __func__);
00295         }
00296     }
00297 }
00298 
00299 
00306 void
00307 create_policer(policer_info_t * policer)
00308 {
00309     junos_dfw_policer_info_t dpi;
00310     junos_dfw_trans_handle_t trans_hdl;
00311     junos_dfw_burst_size_unit_t burst_size_unit;
00312     junos_dfw_rate_unit_t rate_unit;
00313 
00314     bzero(&dpi, sizeof(dpi));
00315     strlcpy(dpi.namestr_key, policer->name, sizeof(dpi.namestr_key));
00316     dpi.owner_client_id = dpm_cid;
00317     dpi.filter_specific = FALSE;
00318 
00319     if(junos_dfw_policer_trans_alloc(&dpi, 
00320             JUNOS_DFW_POLICER_OP_ADD, &trans_hdl)) {
00321         LOG(LOG_ERR, "%s: junos_dfw_policer_trans_alloc failed", __func__);
00322         return;
00323     }
00324     
00325     // we have to squeeze this uint64_t burst_size_limit into a uint32_t
00326     burst_size_unit = JUNOS_DFW_BURST_SIZE_UNIT_BYTE;
00327     while(policer->if_exceeding.burst_size_limit > UINT_MAX) {
00328         ++burst_size_unit;
00329         policer->if_exceeding.burst_size_limit /= KB_BYTES;
00330     }
00331     if(burst_size_unit < JUNOS_DFW_BURST_SIZE_UNIT_GBYTE) {
00332         LOG(LOG_ERR, "%s: burst_size_limit of policer %s is too big",
00333                 __func__, policer->name);
00334         goto failed;
00335     }
00336     
00337     // configure policier depending on limit in percent or BPS
00338     
00339     if(policer->if_exceeding.bw_in_percent) {
00340         
00341         if (junos_dfw_policer_parameters(trans_hdl,
00342                 policer->if_exceeding.bw_u.bandwidth_percent,
00343                 JUNOS_DFW_RATE_UNIT_BANDWIDTH_PERCENT,
00344                 (uint32_t)policer->if_exceeding.burst_size_limit,
00345                 burst_size_unit)) {
00346             LOG(LOG_ERR,  "%s: junos_dfw_policer_parameters failed %m",
00347                     __func__);
00348             goto failed;
00349         }
00350     } else {
00351         
00352         // we have to squeeze this uint64_t bandwidth_limit into a uint32_t
00353         rate_unit = JUNOS_DFW_RATE_UNIT_BPS;
00354         while(policer->if_exceeding.burst_size_limit > UINT_MAX) {
00355             ++rate_unit;
00356             policer->if_exceeding.bw_u.bandwidth_limit /= KB_BYTES;
00357         }
00358         if(rate_unit < JUNOS_DFW_RATE_UNIT_GBPS) {
00359             LOG(LOG_ERR, "%s: bandwidth limit of policer %s is too high",
00360                     __func__, policer->name);
00361             goto failed;
00362         }
00363         
00364         if (junos_dfw_policer_parameters(trans_hdl,
00365                 (uint32_t)policer->if_exceeding.bw_u.bandwidth_limit,
00366                 rate_unit,
00367                 (uint32_t)policer->if_exceeding.burst_size_limit,
00368                 burst_size_unit)) {
00369             LOG(LOG_ERR, "%s: junos_dfw_policer_parameters failed %m",
00370                     __func__);
00371             goto failed;
00372         }
00373     }
00374 
00375     // Configure policier actions
00376     
00377     if(policer->action.discard) {
00378         if(junos_dfw_policer_action_discard(trans_hdl)) {
00379             LOG(LOG_ERR, "%s: junos_dfw_policer_action_discard failed",
00380                     __func__);
00381             goto failed;
00382         }        
00383     }
00384 
00385     if ((junos_dfw_trans_send(dfw_handle, trans_hdl, dpm_cid, 0))) {
00386         LOG(LOG_ERR, "%s: junos_dfw_trans_send failed", __func__);
00387         goto failed;
00388     }
00389 
00390 failed: // or done
00391     junos_dfw_trans_handle_free(trans_hdl);
00392 }
00393 
00394 
00408 void
00409 apply_default_int_policy(const char * int_name,
00410                          const char * ingress_pol,
00411                          const char * egress_pol)
00412 {
00413     junos_dfw_policer_info_t ingress_dpi, egress_dpi;
00414     junos_dfw_filter_info_t i_filter_info, e_filter_info;
00415     junos_dfw_term_info_t i_dti, e_dti;
00416     junos_dfw_filter_attach_info_t dfai;
00417     junos_dfw_trans_handle_t i_trans_hdl, e_trans_hdl;
00418     const char * tname = "SYNC-DPM_DEFAULT_TERM";
00419     char * tmp;
00420     
00421     // Create policer info
00422     
00423     bzero(&ingress_dpi, sizeof(ingress_dpi));
00424     strlcpy(ingress_dpi.namestr_key, ingress_pol, 
00425             sizeof(ingress_dpi.namestr_key));
00426     ingress_dpi.owner_client_id = dpm_cid;
00427     ingress_dpi.filter_specific = FALSE;
00428     
00429     bzero(&egress_dpi, sizeof(egress_dpi));
00430     strlcpy(egress_dpi.namestr_key, egress_pol, sizeof(egress_dpi.namestr_key));
00431     egress_dpi.owner_client_id = dpm_cid;
00432     egress_dpi.filter_specific = FALSE;
00433 
00434     // Create filter infos
00435     
00436     bzero(&i_filter_info, sizeof(i_filter_info));
00437     snprintf(i_filter_info.namestr_key, sizeof(i_filter_info.namestr_key),
00438             "SYNC-DPM_%s_INGRESS", int_name);
00439     i_filter_info.owner_client_id = dpm_cid;
00440     i_filter_info.addr_family = JUNOS_DFW_FILTER_AF_INET;
00441 
00442     // Check what filter to use Classic/FUF and program accordingly
00443     if (use_classic_filters) {
00444         i_filter_info.type = JUNOS_DFW_FILTER_TYPE_CLASSIC;
00445     } else {
00446         i_filter_info.type = JUNOS_DFW_FILTER_TYPE_FAST_UPDATE;
00447     }
00448     
00449     bzero(&e_filter_info, sizeof(e_filter_info));
00450     snprintf(e_filter_info.namestr_key, sizeof(e_filter_info.namestr_key), 
00451             "SYNC-DPM_%s_EGRESS", int_name);
00452     e_filter_info.owner_client_id = dpm_cid;
00453     e_filter_info.addr_family = JUNOS_DFW_FILTER_AF_INET;
00454     
00455     // Check what filter to use Classic/FUF and program accordingly
00456     if (use_classic_filters) {
00457         e_filter_info.type = JUNOS_DFW_FILTER_TYPE_CLASSIC;
00458     } else {
00459         e_filter_info.type = JUNOS_DFW_FILTER_TYPE_FAST_UPDATE;
00460     }
00461 
00462     // Create the filter add transaction 
00463     
00464     if(junos_dfw_filter_trans_alloc(&i_filter_info,
00465             JUNOS_DFW_FILTER_OP_ADD, &i_trans_hdl)) {
00466         LOG(LOG_ERR, "%s: junos_dfw_filter_trans_alloc failed (i)\n",
00467                 __func__);
00468         return;
00469     }
00470     if(junos_dfw_filter_trans_alloc(&e_filter_info,
00471             JUNOS_DFW_FILTER_OP_ADD, &e_trans_hdl)) {
00472         LOG(LOG_ERR, "%s: junos_dfw_filter_trans_alloc failed (e)\n",
00473                 __func__);
00474         junos_dfw_trans_handle_free(i_trans_hdl);
00475         return;
00476     }
00477 
00478     // For FUF we have to set the order of the fields
00479     if (!use_classic_filters) {
00480         junos_dfw_filter_field_type_t  field_list[5];    
00481 
00482         field_list[0] = JUNOS_DFW_FILTER_FIELD_IP_PROTO;
00483         field_list[1] = JUNOS_DFW_FILTER_FIELD_IP_SRC_ADDR;
00484         field_list[2] = JUNOS_DFW_FILTER_FIELD_IP_DEST_ADDR;
00485         field_list[3] = JUNOS_DFW_FILTER_FIELD_SRC_PORT;
00486         field_list[4] = JUNOS_DFW_FILTER_FIELD_DEST_PORT;
00487 
00488         if (junos_dfw_filter_prop_ordered_field_list(i_trans_hdl, 5, field_list) < 0) {
00489             LOG(LOG_ERR, "%s: junos_dfw_filter_prop_ordered_field_list failed (i) : %s\n",
00490                        __func__, strerror(errno));
00491             return;
00492         }
00493 
00494         if (junos_dfw_filter_prop_ordered_field_list(e_trans_hdl, 5, field_list) < 0) {
00495             LOG(LOG_ERR, "%s: junos_dfw_filter_prop_ordered_field_list failed (i) : %s\n",
00496                        __func__, strerror(errno));
00497             return;
00498         }
00499     }
00500  
00501     // Add a term to each filter
00502     
00503     bzero(&i_dti, sizeof(i_dti));
00504     strlcpy(i_dti.namestr_key, tname, sizeof(i_dti.namestr_key));
00505     if (use_classic_filters) {
00506         i_dti.type = JUNOS_DFW_TERM_TYPE_ORDERED;
00507         i_dti.property.order.term_adj_type = JUNOS_DFW_TERM_ADJ_PREV;
00508     } else {
00509         i_dti.type = JUNOS_DFW_TERM_TYPE_PRIORITISED;
00510         i_dti.property.priority = 0;
00511     }
00512 
00513     bzero(&e_dti, sizeof(e_dti));
00514     strlcpy(e_dti.namestr_key, tname, sizeof(e_dti.namestr_key));
00515     if (use_classic_filters) {
00516         e_dti.type = JUNOS_DFW_TERM_TYPE_ORDERED;
00517         e_dti.property.order.term_adj_type = JUNOS_DFW_TERM_ADJ_PREV;
00518     } else {
00519         e_dti.type = JUNOS_DFW_TERM_TYPE_PRIORITISED;
00520         e_dti.property.priority = 0;
00521     }
00522     
00523     if(junos_dfw_term_start(i_trans_hdl, &i_dti, JUNOS_DFW_TERM_OP_ADD)) {
00524         LOG(LOG_ERR, "%s: junos_dfw_term_start failed (i)", __func__);
00525         goto failed;
00526     }
00527     if(junos_dfw_term_start(e_trans_hdl, &e_dti, JUNOS_DFW_TERM_OP_ADD)) {
00528         LOG(LOG_ERR, "%s: junos_dfw_term_start failed (e)", __func__);
00529         goto failed;
00530     }
00531     
00532     // Specify term action as policer
00533     
00534     if(junos_dfw_term_action_policer(i_trans_hdl, &ingress_dpi)) {
00535         LOG(LOG_ERR, "%s: junos_dfw_term_action_policer failed (i)",
00536                 __func__);
00537         goto failed;
00538     }
00539     if(junos_dfw_term_action_policer(e_trans_hdl, &egress_dpi)) {
00540         LOG(LOG_ERR, "%s: junos_dfw_term_action_policer failed (e)",
00541                 __func__);
00542         goto failed;
00543     }
00544     
00545     if(junos_dfw_term_end(i_trans_hdl) < 0) {
00546         LOG(LOG_ERR, "%s: junos_dfw_term_end failed (i)", __func__);
00547         goto failed;
00548     }
00549     if(junos_dfw_term_end(e_trans_hdl) < 0) {
00550         LOG(LOG_ERR, "%s: junos_dfw_term_end failed (e)", __func__);
00551         goto failed;
00552     }
00553     
00554     // Send transaction to finish the filter add
00555     
00556     if(junos_dfw_trans_send(dfw_handle, i_trans_hdl, dpm_cid, 0)) {
00557         LOG(LOG_ERR, "%s: junos_dfw_trans_send failed (i)", __func__);
00558         goto failed;
00559     }
00560     if(junos_dfw_trans_send(dfw_handle, e_trans_hdl, dpm_cid, 0)) {
00561         LOG(LOG_ERR, "%s: junos_dfw_trans_send failed (e)", __func__);
00562         goto failed;
00563     }
00564     
00565     junos_dfw_trans_handle_free(i_trans_hdl);
00566     junos_dfw_trans_handle_free(e_trans_hdl);
00567     
00568     // Apply the filters to the interface
00569     
00570     dfai.attach_point = JUNOS_DFW_FILTER_ATTACH_POINT_INPUT_INTF;
00571     strlcpy(dfai.type.intf.ifd_name, int_name, sizeof(dfai.type.intf.ifd_name));
00572     tmp = dfai.type.intf.ifd_name;
00573     strsep(&tmp, "."); // replace '.' with a '\0'
00574     dfai.type.intf.sub_unit = strtol(strstr(int_name, ".")+1, (char **)NULL,10);
00575     
00576     // Ingress side
00577     
00578     if(junos_dfw_filter_attach_trans_alloc(&i_filter_info, &dfai,&i_trans_hdl)){
00579         LOG(LOG_ERR, "%s: junos_dfw_filter_attach_trans_alloc failed (i)",
00580                 __func__);
00581         goto failed;
00582     }
00583     if(junos_dfw_trans_send(dfw_handle, i_trans_hdl, dpm_cid, 0)) {
00584         LOG(LOG_ERR, "%s: junos_dfw_trans_send (attach) failed (i)",
00585                 __func__);
00586         goto failed;
00587     }
00588     
00589     // Egress side
00590     
00591     dfai.attach_point = JUNOS_DFW_FILTER_ATTACH_POINT_OUTPUT_INTF;
00592 
00593     if(junos_dfw_filter_attach_trans_alloc(&e_filter_info, &dfai,&e_trans_hdl)){
00594         LOG(LOG_ERR, "%s: junos_dfw_filter_attach_trans_alloc failed (e)",
00595                 __func__);
00596         goto failed;
00597     }
00598     if(junos_dfw_trans_send(dfw_handle, e_trans_hdl, dpm_cid, 0)) {
00599         LOG(LOG_ERR, "%s: junos_dfw_trans_send (attach) failed (e)",
00600                 __func__);
00601         goto failed;
00602     }
00603     
00604 failed: // or done
00605     junos_dfw_trans_handle_free(i_trans_hdl);
00606     junos_dfw_trans_handle_free(e_trans_hdl);
00607 }
00608 
00609 
00629 int
00630 apply_subscriber_policer(const char * int_name,
00631                          const char * sub_name,
00632                          in_addr_t address,
00633                          const char * pol_name)
00634 {
00635     junos_dfw_policer_info_t dpi;
00636     junos_dfw_filter_info_t i_filter_info, e_filter_info;
00637     junos_dfw_term_info_t i_dti, e_dti;
00638     junos_dfw_trans_handle_t i_trans_hdl, e_trans_hdl;
00639     int rc = -1;
00640     
00641     // Create policer info
00642     
00643     bzero(&dpi, sizeof(dpi));
00644     strlcpy(dpi.namestr_key, pol_name, sizeof(dpi.namestr_key));
00645     dpi.owner_client_id = dpm_cid;
00646     dpi.filter_specific = FALSE;
00647     
00648     // Create filter infos
00649     
00650     bzero(&i_filter_info, sizeof(i_filter_info));
00651     snprintf(i_filter_info.namestr_key, sizeof(i_filter_info.namestr_key), 
00652             "SYNC-DPM_%s_INGRESS", int_name);
00653     i_filter_info.owner_client_id = dpm_cid;
00654     i_filter_info.addr_family = JUNOS_DFW_FILTER_AF_INET;
00655     
00656     // Check what filter to use Classic/FUF and program accordingly
00657     if (use_classic_filters) {
00658         i_filter_info.type = JUNOS_DFW_FILTER_TYPE_CLASSIC;
00659     } else {
00660         i_filter_info.type = JUNOS_DFW_FILTER_TYPE_FAST_UPDATE;
00661     }
00662     
00663     bzero(&e_filter_info, sizeof(e_filter_info));
00664     snprintf(e_filter_info.namestr_key, sizeof(e_filter_info.namestr_key),
00665             "SYNC-DPM_%s_EGRESS", int_name);
00666     e_filter_info.owner_client_id = dpm_cid;
00667     e_filter_info.addr_family = JUNOS_DFW_FILTER_AF_INET;
00668     
00669     // Check what filter to use Classic/FUF and program accordingly
00670     if (use_classic_filters) {
00671         e_filter_info.type = JUNOS_DFW_FILTER_TYPE_CLASSIC;
00672     } else {
00673         e_filter_info.type = JUNOS_DFW_FILTER_TYPE_FAST_UPDATE;
00674     }
00675 
00676     // Create the filter change transaction
00677     
00678     if(junos_dfw_filter_trans_alloc(&i_filter_info,
00679             JUNOS_DFW_FILTER_OP_CHANGE, &i_trans_hdl)) {
00680         LOG(LOG_ERR, "%s: junos_dfw_filter_trans_alloc failed (i)\n",
00681                 __func__);
00682         return -1;
00683     }
00684     if(junos_dfw_filter_trans_alloc(&e_filter_info,
00685             JUNOS_DFW_FILTER_OP_CHANGE, &e_trans_hdl)) {
00686         LOG(LOG_ERR, "%s: junos_dfw_filter_trans_alloc failed (e)\n",
00687                 __func__);
00688         junos_dfw_trans_handle_free(i_trans_hdl);
00689         return -1;
00690     }
00691 
00692     // For FUF we don't have to set the order of the fields if it is
00693     // a filter change transaction
00694 
00695     // Add a term to each filter
00696     
00697     bzero(&i_dti, sizeof(i_dti));
00698     strlcpy(i_dti.namestr_key, sub_name, sizeof(i_dti.namestr_key));
00699     if (use_classic_filters) {
00700         i_dti.type = JUNOS_DFW_TERM_TYPE_ORDERED;
00701         i_dti.property.order.term_adj_type = JUNOS_DFW_TERM_ADJ_PREV;
00702     } else {
00703         i_dti.type = JUNOS_DFW_TERM_TYPE_PRIORITISED;
00704         i_dti.property.priority = 0;
00705     }
00706     // if we specify prev and dti.property.order.term_adj_namestr_key is empty
00707     // like this, then this term that we are adding becomes first in the filter
00708 
00709     bzero(&e_dti, sizeof(e_dti));
00710     strlcpy(e_dti.namestr_key, sub_name, sizeof(e_dti.namestr_key));
00711     if (use_classic_filters) {
00712         e_dti.type = JUNOS_DFW_TERM_TYPE_ORDERED;
00713         e_dti.property.order.term_adj_type = JUNOS_DFW_TERM_ADJ_PREV;
00714     } else {
00715         e_dti.type = JUNOS_DFW_TERM_TYPE_PRIORITISED;
00716         e_dti.property.priority = 0;
00717     }
00718     // if we specify prev and dti.property.order.term_adj_namestr_key is empty
00719     // like this, then this term that we are adding becomes first in the filter
00720     
00721     if(junos_dfw_term_start(i_trans_hdl, &i_dti, JUNOS_DFW_TERM_OP_ADD)) {
00722         LOG(LOG_ERR, "%s: junos_dfw_term_start failed (i)", __func__);
00723         goto failed;
00724     }
00725     if(junos_dfw_term_start(e_trans_hdl, &e_dti, JUNOS_DFW_TERM_OP_ADD)) {
00726         LOG(LOG_ERR, "%s: junos_dfw_term_start failed (e)", __func__);
00727         goto failed;
00728     }
00729     
00730     // Match this subscriber's traffic (src for ingress/dest for egress)
00731     
00732     if(junos_dfw_term_match_src_prefix(i_trans_hdl, 
00733             &address, FULL_PREFIX_LEN, JUNOS_DFW_FILTER_OP_MATCH)) {
00734         LOG(LOG_ERR, "%s: junos_dfw_term_match_src_prefix failed (i)",
00735                 __func__);
00736         goto failed;
00737     }
00738     if(junos_dfw_term_match_dest_prefix(e_trans_hdl, 
00739             &address, FULL_PREFIX_LEN, JUNOS_DFW_FILTER_OP_MATCH)) {
00740         LOG(LOG_ERR, "%s: junos_dfw_term_match_src_prefix failed (i)",
00741                 __func__);
00742         goto failed;
00743     }    
00744     
00745     // Specify term action as the policer for this subscriber
00746     
00747     if(junos_dfw_term_action_policer(i_trans_hdl, &dpi)) {
00748         LOG(LOG_ERR, "%s: junos_dfw_term_action_policer failed (i)",
00749                 __func__);
00750         goto failed;
00751     }
00752     if(junos_dfw_term_action_policer(e_trans_hdl, &dpi)) {
00753         LOG(LOG_ERR, "%s: junos_dfw_term_action_policer failed (e)",
00754                 __func__);
00755         goto failed;
00756     }
00757     
00758     if(junos_dfw_term_end(i_trans_hdl) < 0) {
00759         LOG(LOG_ERR, "%s: junos_dfw_term_end failed (i)", __func__);
00760         goto failed;
00761     }
00762     if(junos_dfw_term_end(e_trans_hdl) < 0) {
00763         LOG(LOG_ERR, "%s: junos_dfw_term_end failed (e)", __func__);
00764         goto failed;
00765     }
00766     
00767     // Send transaction to finish the filter add
00768     
00769     if(junos_dfw_trans_send(dfw_handle, i_trans_hdl, dpm_cid, 0)) {
00770         LOG(LOG_ERR, "%s: junos_dfw_trans_send failed (i)", __func__);
00771         goto failed;
00772     }
00773     if(junos_dfw_trans_send(dfw_handle, e_trans_hdl, dpm_cid, 0)) {
00774         LOG(LOG_ERR, "%s: junos_dfw_trans_send failed (e)", __func__);
00775         goto failed;
00776     }
00777 
00778     rc = 0;
00779     
00780 failed:
00781     junos_dfw_trans_handle_free(i_trans_hdl);
00782     junos_dfw_trans_handle_free(e_trans_hdl);
00783     
00784     return rc;
00785 }
00786 
00787 
00801 int
00802 revoke_subscriber_policer(const char * int_name,
00803                           const char * sub_name)
00804 {
00805     junos_dfw_filter_info_t i_filter_info, e_filter_info;
00806     junos_dfw_term_info_t i_dti, e_dti;
00807     junos_dfw_trans_handle_t i_trans_hdl, e_trans_hdl;
00808     int rc = -1;
00809     
00810     // Create filter infos
00811     
00812     bzero(&i_filter_info, sizeof(i_filter_info));
00813     snprintf(i_filter_info.namestr_key, sizeof(i_filter_info.namestr_key), 
00814             "SYNC-DPM_%s_INGRESS", int_name);
00815     i_filter_info.owner_client_id = dpm_cid;
00816     i_filter_info.addr_family = JUNOS_DFW_FILTER_AF_INET;
00817     
00818     // Check what filter to use Classic/FUF and program accordingly
00819     if (use_classic_filters) {
00820         i_filter_info.type = JUNOS_DFW_FILTER_TYPE_CLASSIC;
00821     } else {
00822         i_filter_info.type = JUNOS_DFW_FILTER_TYPE_FAST_UPDATE;
00823     }
00824 
00825     bzero(&e_filter_info, sizeof(e_filter_info));
00826     snprintf(e_filter_info.namestr_key, sizeof(e_filter_info.namestr_key),
00827             "SYNC-DPM_%s_EGRESS", int_name);
00828     e_filter_info.owner_client_id = dpm_cid;
00829     e_filter_info.addr_family = JUNOS_DFW_FILTER_AF_INET;
00830     
00831     // Check what filter to use Classic/FUF and program accordingly
00832     if (use_classic_filters) {
00833         e_filter_info.type = JUNOS_DFW_FILTER_TYPE_CLASSIC;
00834     } else {
00835         e_filter_info.type = JUNOS_DFW_FILTER_TYPE_FAST_UPDATE;
00836     }
00837 
00838     // Create the filter change transaction
00839     
00840     if(junos_dfw_filter_trans_alloc(&i_filter_info,
00841             JUNOS_DFW_FILTER_OP_CHANGE, &i_trans_hdl)) {
00842         LOG(LOG_ERR, "%s: junos_dfw_filter_trans_alloc failed (i)\n",
00843                 __func__);
00844         return -1;
00845     }
00846     if(junos_dfw_filter_trans_alloc(&e_filter_info,
00847             JUNOS_DFW_FILTER_OP_CHANGE, &e_trans_hdl)) {
00848         LOG(LOG_ERR, "%s: junos_dfw_filter_trans_alloc failed (e)\n",
00849                 __func__);
00850         junos_dfw_trans_handle_free(i_trans_hdl);
00851         return -1;
00852     }
00853 
00854     // Delete a term from each filter
00855     
00856     bzero(&i_dti, sizeof(i_dti));
00857     strlcpy(i_dti.namestr_key, sub_name, sizeof(i_dti.namestr_key));
00858     if (use_classic_filters) {
00859         i_dti.type = JUNOS_DFW_TERM_TYPE_ORDERED;
00860         i_dti.property.order.term_adj_type = JUNOS_DFW_TERM_ADJ_PREV;
00861     } else {
00862         i_dti.type = JUNOS_DFW_TERM_TYPE_PRIORITISED;
00863         i_dti.property.priority = 0;
00864     }
00865 
00866 
00867     bzero(&e_dti, sizeof(e_dti));
00868     strlcpy(e_dti.namestr_key, sub_name, sizeof(e_dti.namestr_key));
00869     if (use_classic_filters) {
00870         e_dti.type = JUNOS_DFW_TERM_TYPE_ORDERED;
00871         e_dti.property.order.term_adj_type = JUNOS_DFW_TERM_ADJ_PREV;
00872     } else {
00873         e_dti.type = JUNOS_DFW_TERM_TYPE_PRIORITISED;
00874         e_dti.property.priority = 0;
00875     }
00876     
00877     if(junos_dfw_term_start(i_trans_hdl, &i_dti, JUNOS_DFW_TERM_OP_DELETE)) {
00878         LOG(LOG_ERR, "%s: junos_dfw_term_start failed (i)", __func__);
00879         goto failed;
00880     }
00881     if(junos_dfw_term_start(e_trans_hdl, &e_dti, JUNOS_DFW_TERM_OP_DELETE)) {
00882         LOG(LOG_ERR, "%s: junos_dfw_term_start failed (e)", __func__);
00883         goto failed;
00884     }
00885     
00886     if(junos_dfw_term_end(i_trans_hdl) < 0) {
00887         LOG(LOG_ERR, "%s: junos_dfw_term_end failed (i)", __func__);
00888         goto failed;
00889     }
00890     if(junos_dfw_term_end(e_trans_hdl) < 0) {
00891         LOG(LOG_ERR, "%s: junos_dfw_term_end failed (e)", __func__);
00892         goto failed;
00893     }
00894     
00895     // Send transaction to finish the filter change
00896     
00897     if(junos_dfw_trans_send(dfw_handle, i_trans_hdl, dpm_cid, 0)) {
00898         LOG(LOG_ERR, "%s: junos_dfw_trans_send failed (i)", __func__);
00899         goto failed;
00900     }
00901     if(junos_dfw_trans_send(dfw_handle, e_trans_hdl, dpm_cid, 0)) {
00902         LOG(LOG_ERR, "%s: junos_dfw_trans_send failed (e)", __func__);
00903         goto failed;
00904     }
00905 
00906     rc = 0;
00907     
00908 failed:
00909     junos_dfw_trans_handle_free(i_trans_hdl);
00910     junos_dfw_trans_handle_free(e_trans_hdl);
00911     
00912     return rc;
00913 }
00914 

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