route-manager_ssd.c

Go to the documentation of this file.
00001 /*
00002  * $Id$
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) 2010, Juniper Networks, Inc.
00011  * All rights reserved.
00012  */
00013 
00022 #include <stdbool.h>
00023 #include <string.h>
00024 #include <strings.h>
00025 #include <sys/types.h>
00026 #include <sys/queue.h>
00027 #include <sys/socket.h>
00028 #include <isc/eventlib.h>
00029 #include <jnx/aux_types.h>
00030 #include <jnx/junos_trace.h>
00031 #include <jnx/ssd_ipc.h>
00032 #include <jnx/ssd_ipc_msg.h>
00033 #include "route-manager.h"
00034 
00035 #include OUT_H
00036 
00037 extern nh_t nh_pool[];
00038 
00040 bool svc_ready;
00041 
00043 static int ssd_fd;
00044 
00045 /* SSD client ID. */
00046 static int client_id;
00047 
00058 static int
00059 ssd_client_conn_open (int fd)
00060 {
00061     ssd_fd = fd;
00062     RM_TRACE(TF_SSD, "%s: SSD connection is open.", __func__);
00063 
00064     /* Request SSD client ID. */
00065     ssd_get_client_id(fd, client_id);
00066     return 0;
00067 }
00068 
00076 static void
00077 ssd_client_conn_close (int fd UNUSED, int cause)
00078 {
00079     ssd_fd = -1;
00080     RM_TRACE(TF_SSD, "%s: SSD connection is closed by %d.", __func__, cause);
00081 }
00082 
00092 static void
00093 ssd_client_msg_hdlr (int fd UNUSED, struct ssd_ipc_msg *msg)
00094 {
00095     route_t *rt;
00096 
00097     switch (msg->ssd_ipc_cmd) {
00098     case  SSD_SESSION_ID_REPLY:
00099         if (SSD_SESSION_ID_REPLY_CHECK_STATUS(msg)) {
00100             if (client_id == 0) {
00101                 /* New session. */
00102                 client_id = SSD_SESSION_ID_REPLY_GET_CLIENT_ID(msg);
00103                 kcom_client_id_save(client_id);
00104                 RM_TRACE(TF_SSD, "%s: Got client ID %d and saved it.",
00105                         __func__, client_id);
00106 
00107                 /* Request for route service */
00108                 ssd_setup_route_service(fd);
00109             } else {
00110                 /* Restore session. */
00111                 RM_TRACE(TF_SSD, "%s: Session is restored %d.", __func__,
00112                         client_id);
00113                 svc_ready = true;
00114             }
00115         } else {
00116             RM_TRACE(TF_SSD, "%s: Request client ID %d ERROR!", __func__,
00117                     client_id);
00118         }
00119         break;
00120 
00121     case  SSD_ROUTE_SERVICE_REPLY:
00122         if (SSD_ROUTE_SERVICE_REPLY_CHECK_STATUS(msg)) {
00123             RM_TRACE(TF_SSD, "%s: Route service is ready.", __func__);
00124             svc_ready = true;
00125             config_rt_proc(NULL);
00126         } else {
00127             RM_TRACE(TF_SSD, "%s: Setup route service ERROR!", __func__);
00128         }
00129         break;
00130 
00131     case  SSD_ROUTE_TABLE_LOOKUP_REPLY:
00132         rt = (route_t *)SSD_ROUTE_TABLE_LOOKUP_REPLY_GET_CLIENT_CTX(msg);
00133         if (SSD_ROUTE_TABLE_LOOKUP_REPLY_CHECK_STATUS(msg)) {
00134             RM_TRACE(TF_SSD, "%s: Routing table ID %d.", __func__,
00135                     SSD_ROUTE_TABLE_LOOKUP_REPLY_GET_RTTID(msg));
00136 
00137             /* Update the routing table ID. */
00138             if (rt->ctx_id) {
00139                 nh_pool[rt->ctx_id].idx =
00140                         SSD_ROUTE_TABLE_LOOKUP_REPLY_GET_RTTID(msg);
00141                 nh_pool[rt->ctx_id].op_state = NH_STATE_ADD_OK;
00142             } else {
00143                 /* Should not get here. */
00144                 RM_LOG(LOG_ERR, "%s: No route is waiting for this!", __func__);
00145             }
00146         } else {
00147             RM_TRACE(TF_SSD, "%s: Routing table ID lookup ERROR %d.", __func__,
00148                     SSD_ROUTE_TABLE_LOOKUP_REPLY_GET_ERROR_CODE(msg));
00149 
00150             /* Update the route who requested this routing table ID. */
00151             rt->op_state = RT_STATE_ADD_ERR;
00152         }
00153         /* Contiue adding route. */
00154         config_rt_proc(rt);
00155         break;
00156     case  SSD_ROUTE_ADD_REPLY:
00157         rt = (route_t *)SSD_ROUTE_ADD_REPLY_GET_CLIENT_CTX(msg);
00158         if (SSD_ROUTE_ADD_REPLY_CHECK_STATUS(msg)) {
00159             RM_TRACE(TF_SSD, "%s: Add route %08x OK.", __func__,
00160                     rt->dst_addr.in.gin_addr);
00161             rt->op_state = RT_STATE_ADD_OK;
00162         } else {
00163             RM_TRACE(TF_SSD, "%s: Add route %08x ERROR %d.", __func__,
00164                     rt->dst_addr.in.gin_addr,
00165                     SSD_ROUTE_ADD_REPLY_GET_ERROR_CODE(msg));
00166             rt->op_state = RT_STATE_ADD_ERR;
00167         }
00168         /* Contiue adding route. */
00169         config_rt_proc(rt);
00170         break;
00171     case  SSD_NH_ADD_REPLY:
00172         rt = (route_t *)SSD_NEXTHOP_ADD_REPLY_GET_CLIENT_CTX(msg);
00173         if (SSD_NEXTHOP_ADD_REPLY_CHECK_STATUS(msg)) {
00174             RM_TRACE(TF_SSD, "%s: Add next-hop %s OK %d.", __func__,
00175                     nh_pool[rt->ctx_id].name,
00176                     SSD_NEXTHOP_ADD_REPLY_GET_NH_ID(msg));
00177             nh_pool[rt->ctx_id].idx = SSD_NEXTHOP_ADD_REPLY_GET_NH_ID(msg);
00178             nh_pool[rt->ctx_id].op_state = NH_STATE_ADD_OK;
00179         } else {
00180             RM_TRACE(TF_SSD, "%s: Add next-hop %s ERROR %d.", __func__,
00181                     nh_pool[rt->ctx_id].name,
00182                     SSD_NEXTHOP_ADD_REPLY_GET_ERROR_CODE(msg));
00183             nh_pool[rt->ctx_id].op_state = NH_STATE_ADD_ERR;
00184             /* Adding next-hop failed, so adding route failed. */
00185             rt->op_state = RT_STATE_ADD_ERR;
00186         }
00187         /* Contiue adding route. */
00188         config_rt_proc(rt);
00189         break;
00190 
00191     case  SSD_ROUTE_DELETE_REPLY:
00192         rt = (route_t *)SSD_ROUTE_DELETE_REPLY_GET_CLIENT_CTX(msg);
00193         if (SSD_ROUTE_DELETE_REPLY_CHECK_STATUS(msg)) {
00194             RM_TRACE(TF_SSD, "%s: Delete route %08x OK.", __func__,
00195                     rt->dst_addr.in.gin_addr);
00196             rt->op_state = RT_STATE_DEL_OK;
00197 
00198         } else {
00199             RM_TRACE(TF_SSD, "%s: Delete route %08x ERROR %d.", __func__,
00200                     rt->dst_addr.in.gin_addr,
00201                     SSD_ROUTE_DELETE_REPLY_GET_ERROR_CODE(msg));
00202             rt->op_state = RT_STATE_DEL_ERR;
00203             /* Some junk may be left in the routing table.
00204              * can't continue to delete dependencies if there is any.
00205              */
00206         }
00207         /* Continue deleting route. */
00208         config_rt_proc(rt);
00209         break;
00210 
00211     case  SSD_NH_DELETE_REPLY:
00212         rt = (route_t *)SSD_NEXTHOP_DELETE_REPLY_GET_CLIENT_CTX(msg);
00213         if (SSD_NEXTHOP_DELETE_REPLY_CHECK_STATUS(msg)) {
00214             RM_TRACE(TF_SSD, "%s: Delete next-hop %s OK.", __func__,
00215                     nh_pool[rt->ctx_id].name);
00216         } else {
00217             RM_TRACE(TF_SSD, "%s: Delete next-hop %s ERROR %d.", __func__,
00218                     nh_pool[rt->ctx_id].name,
00219                     SSD_NEXTHOP_DELETE_REPLY_GET_ERROR_CODE(msg));
00220         }
00221         /* Free next-hop from local pool no matter it's deleted from kernel
00222          * successfully or not.
00223          */
00224         nh_pool[rt->ctx_id].op_state = NH_STATE_FREE;
00225         /* Continue deleting route. */
00226         config_rt_proc(rt);
00227         break;
00228 
00229     case SSD_ROUTE_SERVICE_CLEAN_UP_REPLY:
00230         if (SSD_ROUTE_SERVICE_CLEAN_UP_REPLY_CHECK_STATUS(msg)) {
00231             RM_TRACE(TF_SSD, "%s: Clean up routing service OK.", __func__);
00232         } else {
00233             RM_TRACE(TF_SSD, "%s: Clean up routing service ERROR.", __func__);
00234         }
00235         break;
00236     default:
00237         RM_TRACE(TF_SSD, "%s: Undefined message command %d.", __func__,
00238                 msg->ssd_ipc_cmd);
00239     }
00240 }
00241 
00243 static struct ssd_ipc_ft ssd_client_cbs = {
00244     ssd_client_conn_open,
00245     ssd_client_conn_close,
00246     ssd_client_msg_hdlr
00247 };
00248 
00259 int
00260 ssd_rt_add (route_t *rt)
00261 {
00262     struct ssd_route_parms params;
00263     int i;
00264 
00265     bzero(&params, sizeof(params));
00266     params.rta_dest = &rt->dst_addr;
00267     params.rta_prefixlen = rt->prefix_len;
00268     params.rta_rtt = nh_pool[rt->rtt_id].idx;
00269     params.rta_nhtype = rt->nh_type;
00270     params.rta_state = rt->op_state;
00271     params.rta_flags = rt->flag;
00272     params.rta_preferences.rtm_val[0] = rt->preference;
00273     params.rta_preferences.rtm_type[0] = SSD_RTM_VALUE_PRESENT;
00274     params.rta_n_gw = rt->gw_num;
00275     for (i = 0; i < rt->gw_num; i++) {
00276         if (rt->gw_addr[i].in.gin_family == SSD_GF_INET) {
00277             params.rta_gateway[i].rtg_gwaddr = &rt->gw_addr[i];
00278         }
00279         if (rt->gw_ifl_addr[i].in.gin_family == SSD_GF_INET) {
00280             params.rta_gateway[i].rtg_lcladdr = &rt->gw_ifl_addr[i];
00281         }
00282         if (rt->gw_ifl_name[i][0] != '\0') {
00283             params.rta_gateway[i].rtg_iflname = rt->gw_ifl_name[i];
00284         }
00285         ifl_idx_t_setval(params.rta_gateway[i].rtg_ifl, rt->gw_ifl_idx);
00286         nh_idx_t_setval(params.rta_gateway[i].rtg_nhindex,
00287                 nh_pool[rt->nh_id[i]].idx);
00288         RM_TRACE(TF_SSD, "%s: %d, %d, %d, %d, %d", __func__,
00289                 rt->gw_addr[i].in.gin_family,
00290                 rt->gw_ifl_addr[i].in.gin_family,
00291                 rt->gw_ifl_name[i][0],
00292                 rt->gw_ifl_idx,
00293                 nh_pool[rt->nh_id[i]].idx);
00294 
00295     }
00296     if (ssd_request_route_add(ssd_fd, &params, (unsigned int)rt) < 0) {
00297         return -1;
00298     } else {
00299         return 0;
00300     }
00301 }
00302 
00313 int
00314 ssd_rt_del (route_t *rt)
00315 {
00316     struct ssd_rt_delete_parms params;
00317 
00318     bzero(&params, sizeof(params));
00319     params.rtd_dest = &rt->dst_addr;
00320     params.rtd_prefixlen = rt->prefix_len;
00321     params.rtd_rtt = nh_pool[rt->rtt_id].idx;
00322 
00323     if (ssd_request_route_delete(ssd_fd, &params, (unsigned int)rt) < 0) {
00324         return -1;
00325     } else {
00326         return 0;
00327     }
00328 }
00329 
00342 int
00343 ssd_nh_add (route_t *rt, int nh_id)
00344 {
00345     struct ssd_nh_add_parms params;
00346     int ifl_idx;
00347     char *name;
00348     int rc;
00349 
00350     if (rt->rtt_id == nh_id) {
00351         /* Routing table ID. */
00352         name = strdup(nh_pool[nh_id].name);
00353         if (ssd_request_route_table_lookup(ssd_fd, name,
00354                 (unsigned int)rt) < 0) {
00355             RM_LOG(LOG_ERR, "%s: Request routing table ID ERROR!");
00356             return -1;
00357         } else {
00358             RM_TRACE(TF_SSD, "%s: Request routing table %s ID OK.", __func__,
00359                     nh_pool[nh_id].name);
00360             return 0;
00361         }
00362     }
00363 
00364     switch (rt->nh_type) {
00365     case SSD_RNH_SERVICE:
00366         bzero(&params, sizeof(params));
00367         ifl_idx = kcom_ifl_get_idx_by_name(nh_pool[nh_id].name);
00368         if (ifl_idx < 0) {
00369             return -1;
00370         }
00371         ifl_idx_t_setval(params.ifl, ifl_idx);
00372         rc = ssd_request_nexthop_add(ssd_fd, nh_id, &params, (unsigned int)rt);
00373         break;
00374     case SSD_RNH_TABLE:
00375         name = strdup(nh_pool[nh_id].name);
00376         rc = ssd_request_route_table_lookup(ssd_fd, name, (unsigned int)rt);
00377         break;
00378     default:
00379         rc = -1;
00380     }
00381     return rc;
00382 }
00383 
00396 int
00397 ssd_nh_del (route_t *rt, int nh_id)
00398 {
00399     nh_idx_t idx;
00400 
00401     nh_idx_t_setval(idx, nh_pool[nh_id].idx);
00402     if (ssd_request_nexthop_delete(ssd_fd, nh_id, idx, (unsigned int)rt) < 0) {
00403         return -1;
00404     } else {
00405         return 0;
00406     }
00407 }
00408 
00414 void
00415 ssd_close (void)
00416 {
00417     ssd_clean_up_route_service(ssd_fd, 1);
00418     ssd_ipc_close(ssd_fd);
00419     ssd_fd = -1;
00420     svc_ready = false;
00421 }
00422 
00433 int
00434 ssd_open (evContext ev_ctx)
00435 {
00436     svc_ready = false;
00437     client_id = kcom_client_id_restore();
00438     if (client_id < 0) {
00439         client_id = 0;
00440     }
00441     ssd_fd = ssd_ipc_connect_rt_tbl(NULL, &ssd_client_cbs, 0, ev_ctx);
00442     if (ssd_fd < 0) {
00443         return -1;
00444     } else {
00445         return 0;
00446     }
00447 }
00448 

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:07 2010 for SDK Your Net Corporation Route Manager: route-manager 1.0 by Doxygen 1.5.1