ped_conn.c

Go to the documentation of this file.
00001 /*
00002  * $Id: ped_conn.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 
00021 #include <sync/common.h>
00022 #include <sync/policy_ipc.h>
00023 #include <jnx/pconn.h>
00024 #include "ped_config.h"
00025 #include "ped_conn.h"
00026 #include "ped_logging.h"
00027 
00028 #include PE_OUT_H
00029 
00030 /*** Constants ***/
00031 
00032 #define PED_SERVER_MAX_CONN 2  
00033 
00034 #define IF_NAME_SIZE  64 
00035 
00036 /*** Data Structures ***/
00037 
00038 static pconn_server_t   * mgmt_server; 
00039 static pconn_session_t  * cpd_session; 
00040 static pconn_session_t  * pfd_session; 
00041 static char cpd_pic_name[IF_NAME_SIZE]; 
00042 static char pfd_pic_name[IF_NAME_SIZE]; 
00043 
00044 
00045 /*** STATIC/INTERNAL Functions ***/
00046 
00047 
00062 static status_t
00063 send_peer_info(pconn_session_t * to_session,
00064                pconn_session_t * for_session)
00065 {
00066     pconn_peer_info_t info;
00067     int rc;
00068     
00069     rc = pconn_session_get_peer_info(for_session, &info);
00070     
00071     if(rc != PCONN_OK) {
00072         ERRMSG(PED, TRACE_LOG_ERR,
00073             "%s: Cannot retrieve peer info for given session. "
00074             "Error: %d", __func__, rc);
00075          return EFAIL;
00076     }
00077     
00078     info.ppi_peer_type = htonl(info.ppi_peer_type);
00079     info.ppi_fpc_slot = htonl(info.ppi_fpc_slot);
00080     info.ppi_pic_slot = htonl(info.ppi_pic_slot);
00081     
00082     // got the peer info for the for_session, so send it
00083     rc = pconn_server_send(to_session, MSG_PEER,
00084                            &info, sizeof(pconn_peer_info_t));
00085     
00086     if(rc != PCONN_OK) {
00087         ERRMSG(PED, TRACE_LOG_ERR,
00088             "%s: Failed to send peer info to peer component. "
00089             "Error: %d", __func__, rc);
00090          return EFAIL;
00091     }
00092     
00093     junos_trace(PED_TRACEFLAG_CONNECTION,
00094         "%s: Sent the PIC peer info to a PIC peer", __func__);
00095 
00096     return SUCCESS;
00097 }
00098 
00099 
00110 static status_t
00111 send_addresses(pconn_session_t * to_session)
00112 {
00113     int rc;
00114     struct {
00115         in_addr_t cpd_address;
00116         in_addr_t pfd_address;
00117     } addresses;
00118     
00119     addresses.pfd_address = get_pfd_address();
00120     addresses.cpd_address = get_cpd_address();
00121         
00122     if(!addresses.cpd_address || !addresses.pfd_address) {
00123         junos_trace(PED_TRACEFLAG_CONNECTION,
00124             "%s: Skipping because addresses are not set yet", __func__);
00125         return SUCCESS; // don't send when not set
00126     }
00127 
00128     // got the peer info for the pfd_session, so send it
00129     rc = pconn_server_send(to_session, MSG_ADDRESSES,
00130                            &addresses, sizeof(addresses));
00131     
00132     if(rc != PCONN_OK) {
00133         ERRMSG(PED, TRACE_LOG_ERR,
00134             "%s: Failed to send addresses to peer component. "
00135             "Error: %d", __func__, rc);
00136          return EFAIL;
00137     }
00138     
00139     junos_trace(PED_TRACEFLAG_CONNECTION,
00140         "%s: Sent the addresses info to a PIC peer", __func__);
00141 
00142     return SUCCESS;
00143 }
00144 
00145 
00152 static status_t
00153 configure_pics(void)
00154 {
00155     int rc;
00156     
00157     junos_trace(PED_TRACEFLAG_CONNECTION, "%s: Sending CPD peer info to PFD",
00158         __func__);
00159     
00160     rc = send_peer_info(pfd_session, cpd_session);
00161     if(rc != SUCCESS) {
00162         return rc;
00163     }
00164 
00165     junos_trace(PED_TRACEFLAG_CONNECTION, "%s: Sending addresses to the CPD",
00166         __func__);
00167     
00168     rc = send_addresses(cpd_session);
00169     if(rc != SUCCESS) {
00170         return rc;
00171     }
00172     
00173     junos_trace(PED_TRACEFLAG_CONNECTION, "%s: Sending addresses to the PFD",
00174         __func__);
00175     
00176     return send_addresses(pfd_session);
00177 }
00178 
00179 
00192 static void
00193 receive_connection(pconn_session_t * session,
00194                    pconn_event_t event,
00195                    void * cookie __unused)
00196 {
00197     pconn_peer_info_t info;
00198     int rc;
00199     
00200     rc = pconn_session_get_peer_info(session, &info);
00201     
00202     if(rc != PCONN_OK) {
00203         ERRMSG(PED, TRACE_LOG_ERR,
00204             "%s: Cannot retrieve peer info for session. Error: %d",
00205              __func__, rc);
00206     } else {
00207         INSIST_ERR(info.ppi_peer_type == PCONN_PEER_TYPE_PIC);
00208         
00209         junos_trace(PED_TRACEFLAG_CONNECTION,
00210             "%s: Received a %s event from ms-%d/%d/0", __func__, 
00211             ((event == PCONN_EVENT_ESTABLISHED) ? "CONENCT" : "DISCONNECT"),
00212             info.ppi_fpc_slot, info.ppi_pic_slot);
00213     }
00214 
00215     switch (event) {
00216 
00217         case PCONN_EVENT_ESTABLISHED:
00218             // nothing to do
00219             break;
00220 
00221         case PCONN_EVENT_SHUTDOWN:
00222             
00223             if(session == cpd_session) {
00224                 cpd_session = NULL;
00225                 cpd_pic_name[0] = '\0';
00226             } else if(session == pfd_session) {
00227                 pfd_session = NULL;
00228                 pfd_pic_name[0] = '\0';
00229             } else {
00230                 ERRMSG(PED, TRACE_LOG_ERR,
00231                     "%s: Cannot find an existing peer session to shutdown",
00232                      __func__);
00233             }
00234                       
00235             break;
00236 
00237         default:
00238             ERRMSG(PED, TRACE_LOG_ERR,
00239                 "%s: Received an unknown or PCONN_EVENT_FAILED event",
00240                  __func__);
00241             break;
00242     }
00243 }
00244 
00245 
00262 static status_t
00263 receive_message(pconn_session_t * session,
00264                 ipc_msg_t * msg,
00265                 void * cookie __unused)
00266 {
00267     uint32_t id;
00268     pconn_peer_info_t info;
00269     int rc;
00270     
00271     if(session == cpd_session) {
00272 
00273         switch(msg->subtype) {
00274             
00275             case MSG_ID:
00276             
00277                 break; // do nothing we already have it (shouldn't happen)
00278                        // otherwise we wouldn't know session == cpd_session
00279             
00280             default:
00281             
00282                 ERRMSG(PED, TRACE_LOG_ERR,
00283                     "%s: Received an unknown message type (%d) from the "
00284                     "control component", __func__, msg->subtype);
00285                 break;
00286         }
00287     } else if(session == pfd_session) {
00288 
00289         switch(msg->subtype) {
00290             
00291             case MSG_ID:
00292             
00293                 break; // do nothing we already have it (shouldn't happen)
00294                        // otherwise we wouldn't know session == pfd_session
00295             
00296             default:
00297             
00298                 ERRMSG(PED, TRACE_LOG_ERR,
00299                     "%s: Received an unknown message type (%d) from the "
00300                     "data component", __func__, msg->subtype);
00301                 break;
00302         }
00303     } else {
00304         
00305         // It must be an identifier message to tell us who it is
00306         
00307         if(msg->subtype == MSG_ID) {
00308             
00309             INSIST_ERR(msg->length == sizeof(uint32_t));
00310             id = ntohl(*(uint32_t *)msg->data);
00311             
00312             switch(id) {
00313                 
00314                 case ID_CPD:
00315                     if(cpd_session == NULL) {
00316 
00317                         cpd_session = session;
00318                         
00319                         rc = pconn_session_get_peer_info(session, &info);
00320                         
00321                         if(rc != PCONN_OK) {
00322                             ERRMSG(PED, TRACE_LOG_ERR,
00323                                 "%s: Cannot retrieve peer info for session. "
00324                                 "Error: %d", __func__, rc);
00325                         } else {
00326                             // save PIC IFD name
00327                             snprintf(cpd_pic_name, IF_NAME_SIZE, "ms-%d/%d/0",
00328                                 info.ppi_fpc_slot, info.ppi_pic_slot);                        
00329                         }
00330                         
00331                         // only when we have both cnxs do we configure them
00332                         if(pfd_session) {
00333                             configure_pics();
00334                         }
00335                     } else { // cpd_session != session
00336                         ERRMSG(PED, TRACE_LOG_ERR,
00337                             "%s: Received ID for another CPD when a session to "
00338                             "a CPD is already established", __func__);
00339                     }
00340                     break;
00341                     
00342                 case ID_PFD:
00343                     if(pfd_session == NULL) {
00344 
00345                         pfd_session = session;
00346                         
00347                         rc = pconn_session_get_peer_info(session, &info);
00348                         
00349                         if(rc != PCONN_OK) {
00350                             ERRMSG(PED, TRACE_LOG_ERR,
00351                                 "%s: Cannot retrieve peer info for session. "
00352                                 "Error: %d", __func__, rc);
00353                         } else {
00354                             // save PIC IFD name
00355                             snprintf(pfd_pic_name, IF_NAME_SIZE, "ms-%d/%d/0",
00356                                 info.ppi_fpc_slot, info.ppi_pic_slot);                        
00357                         }
00358                         
00359                         // only when we have both cnxs do we configure them
00360                         if(cpd_session) {
00361                             configure_pics();
00362                         }
00363                     } else { // pfd_session != session
00364                         ERRMSG(PED, TRACE_LOG_ERR,
00365                             "%s: Received ID for another PFD when a session to "
00366                             "a PFD is already established", __func__);
00367                     }
00368                     break;
00369                     
00370                 default:
00371                     ERRMSG(PED, TRACE_LOG_ERR,
00372                         "%s: Received an ID (%d) that is not the CPD or PFD",
00373                          __func__, id);
00374                     break;
00375             }
00376         } else {
00377             ERRMSG(PED, TRACE_LOG_ERR,
00378                 "%s: Received a message (%d) for an unknown component. "
00379                 "ID is expected", __func__, msg->subtype);
00380         }
00381     }
00382     
00383     return SUCCESS;
00384 }
00385 
00386 
00387 /*** GLOBAL/EXTERNAL Functions ***/
00388 
00389 
00399 status_t
00400 init_server(evContext ctx)
00401 {
00402     pconn_server_params_t params;
00403     
00404     // init the sessions
00405     cpd_session = NULL;
00406     pfd_session = NULL;
00407     
00408     bzero(&params, sizeof(pconn_server_params_t));
00409     
00410     // setup the server args
00411     params.pconn_port            = PED_PORT_NUM;
00412     params.pconn_max_connections = PED_SERVER_MAX_CONN;
00413     params.pconn_event_handler   = receive_connection;
00414     
00415     // bind
00416     mgmt_server = pconn_server_create(&params, ctx, receive_message, &ctx);
00417     
00418     if(mgmt_server == NULL) {
00419         ERRMSG(PED, TRACE_LOG_ERR,
00420             "%s: Failed to initialize the pconn server on port %d.",
00421             __func__, PED_PORT_NUM);
00422         return EFAIL;
00423     }
00424     
00425     junos_trace(PED_TRACEFLAG_CONNECTION,
00426         "%s: Successfully initialized the pconn server on port %d.",
00427         __func__, PED_PORT_NUM);
00428     
00429     return SUCCESS;
00430 }
00431 
00432 
00436 void
00437 close_connections(void)
00438 {
00439     if(pfd_session) {
00440         junos_trace(PED_TRACEFLAG_CONNECTION,
00441             "%s: Closing the session to the data component.", __func__);
00442         pconn_session_close(pfd_session);
00443         pfd_session = NULL;
00444         pfd_pic_name[0] = '\0';
00445     }
00446     
00447     if(cpd_session) {
00448         junos_trace(PED_TRACEFLAG_CONNECTION,
00449             "%s: Closing the session to the control component.", __func__);
00450         pconn_session_close(cpd_session);
00451         cpd_session = NULL;
00452         cpd_pic_name[0] = '\0';
00453     }
00454     
00455     if(mgmt_server) {
00456         junos_trace(PED_TRACEFLAG_CONNECTION, "%s: Shuting down the "
00457             "server on port %d.", __func__, PED_PORT_NUM);
00458         pconn_server_shutdown(mgmt_server);
00459         mgmt_server = NULL;
00460     }
00461 }
00462 
00463 
00468 void
00469 reconfigure_peers(void)
00470 {
00471     if(!cpd_session || !pfd_session) {
00472         return;
00473     }
00474 
00475     junos_trace(PED_TRACEFLAG_CONNECTION, "%s: Sending addresses to the CPD",
00476         __func__);
00477     
00478     send_addresses(cpd_session);
00479     
00480     junos_trace(PED_TRACEFLAG_CONNECTION, "%s: Sending addresses to the PFD",
00481         __func__);
00482     
00483     send_addresses(pfd_session);
00484 }
00485 
00486 
00493 void
00494 mspic_offline(char * intername_name)
00495 {
00496     if(strcmp(intername_name, cpd_pic_name) == 0 && cpd_session) {
00497 
00498         junos_trace(PED_TRACEFLAG_CONNECTION,
00499             "%s: Closing the session to the control component.", __func__);
00500         pconn_session_close(cpd_session);
00501         cpd_session = NULL;
00502         cpd_pic_name[0] = '\0';
00503         
00504     }
00505     
00506     if(strcmp(intername_name, pfd_pic_name) == 0 && pfd_session) {
00507 
00508         junos_trace(PED_TRACEFLAG_CONNECTION,
00509             "%s: Closing the session to the data component.", __func__);
00510         pconn_session_close(pfd_session);
00511         pfd_session = NULL;
00512         pfd_pic_name[0] = '\0';
00513     }
00514 }

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