00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
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
00031
00032 #define PED_SERVER_MAX_CONN 2
00033
00034 #define IF_NAME_SIZE 64
00035
00036
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
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
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;
00126 }
00127
00128
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
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;
00278
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;
00294
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
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
00327 snprintf(cpd_pic_name, IF_NAME_SIZE, "ms-%d/%d/0",
00328 info.ppi_fpc_slot, info.ppi_pic_slot);
00329 }
00330
00331
00332 if(pfd_session) {
00333 configure_pics();
00334 }
00335 } else {
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
00355 snprintf(pfd_pic_name, IF_NAME_SIZE, "ms-%d/%d/0",
00356 info.ppi_fpc_slot, info.ppi_pic_slot);
00357 }
00358
00359
00360 if(cpd_session) {
00361 configure_pics();
00362 }
00363 } else {
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
00388
00389
00399 status_t
00400 init_server(evContext ctx)
00401 {
00402 pconn_server_params_t params;
00403
00404
00405 cpd_session = NULL;
00406 pfd_session = NULL;
00407
00408 bzero(¶ms, sizeof(pconn_server_params_t));
00409
00410
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
00416 mgmt_server = pconn_server_create(¶ms, 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 }