00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00021 #include <sync/common.h>
00022 #include <ddl/dax.h>
00023 #include "equilibrium-mgmt_config.h"
00024 #include "equilibrium-mgmt_conn.h"
00025 #include "equilibrium-mgmt_logging.h"
00026
00027 #include EQUILIBRIUM_OUT_H
00028
00029
00030
00031 #define MAX_SVC_SETID 0xFFFF
00032
00033 #define DDLNAME_SERVICE_SET_IDENT "service-set-name"
00034 #define DDLNAME_EXTENTION_SERVICE_IDENT "service-name"
00035 #define DDLNAME_INTERFACE_SERVICE "interface-service"
00036 #define DDLNAME_INTERFACE_SERVICE_SVC_INT "service-interface"
00037
00038
00039
00040
00041
00045 const char * equilibrium_service_prefix = "equilibrium-";
00046
00052 typedef struct eq_app_key_s {
00053 in_addr_t addr;
00054 uint16_t port;
00055 TAILQ_ENTRY(eq_app_key_s) entries;
00056 } eq_app_key_t;
00057
00061 typedef TAILQ_HEAD(, eq_app_key_s) eq_app_key_set_t;
00062
00067 typedef struct eq_ssrb_s {
00068 patnode node;
00069 junos_kcom_pub_ssrb_t ssrb;
00070 } eq_ssrb_t;
00071
00072 static patroot services_conf;
00073 static patroot ssrb_conf;
00074
00075 static eq_serviceset_t * current_svc_set = NULL;
00076 static eq_app_t * current_app = NULL;
00077
00078
00079
00080
00081
00086 PATNODE_TO_STRUCT(ssrb_entry, eq_ssrb_t, node)
00087
00088
00089
00093 PATNODE_TO_STRUCT(service_entry, eq_serviceset_t, node)
00094
00095
00100 PATNODE_TO_STRUCT(app_entry, eq_app_t, node)
00101
00102
00119 static eq_serviceset_t *
00120 update_service_set(const char * ss_name,
00121 const char * svc_name,
00122 const char * svc_int_name)
00123 {
00124 eq_serviceset_t * service_set = NULL;
00125
00126 junos_trace(EQUILIBRIUM_TRACEFLAG_CONF, "%s", __func__);
00127
00128
00129 service_set = service_entry(patricia_get(&services_conf,
00130 strlen(ss_name) + 1, ss_name));
00131
00132 if(service_set == NULL) {
00133 service_set = calloc(1, sizeof(eq_serviceset_t));
00134 INSIST(service_set != NULL);
00135 service_set->svc_set_id = -1;
00136 strncpy(service_set->svc_set_name, ss_name, MAX_SVC_SET_NAME);
00137
00138
00139 patricia_node_init_length(&service_set->node, strlen(ss_name) + 1);
00140
00141 if(!patricia_add(&services_conf, &service_set->node)) {
00142 junos_trace(EQUILIBRIUM_TRACEFLAG_CONF, "%s: Failed to add "
00143 "service set to configuration", __func__);
00144 }
00145 }
00146
00147 strncpy(service_set->svc_int_name, svc_int_name, MAX_SVC_INT_NAME);
00148 strncpy(service_set->ext_svc_name, svc_name, MAX_SVC_NAME);
00149
00150 return service_set;
00151 }
00152
00153
00175 static eq_app_t *
00176 update_application(const char * name,
00177 in_addr_t address,
00178 uint16_t port,
00179 eq_smon_t * server_monitor,
00180 uint16_t session_timeout)
00181 {
00182 eq_app_t * app;
00183
00184 INSIST_ERR(current_svc_set != NULL);
00185
00186 junos_trace(EQUILIBRIUM_TRACEFLAG_CONF, "%s", __func__);
00187
00188
00189 if(current_svc_set->applications == NULL) {
00190
00191 current_svc_set->applications =
00192 patricia_root_init(NULL, FALSE, MAX_APP_NAME, 0);
00193 }
00194
00195 app = app_entry(patricia_get(current_svc_set->applications,
00196 strlen(name) + 1, name));
00197
00198 if(app == NULL) {
00199 app = calloc(1, sizeof(eq_app_t));
00200 INSIST(app != NULL);
00201 strncpy(app->application_name, name, MAX_APP_NAME);
00202
00203
00204 patricia_node_init_length(&app->node, strlen(name) + 1);
00205
00206 if(!patricia_add(current_svc_set->applications, &app->node)) {
00207 junos_trace(EQUILIBRIUM_TRACEFLAG_CONF, "%s: Failed to add "
00208 "application to configuration", __func__);
00209 return NULL;
00210 }
00211 }
00212
00213 app->application_addr = address;
00214 app->application_port = port;
00215 app->session_timeout = session_timeout;
00216
00217 if(app->server_mon_params == NULL) {
00218 app->server_mon_params = server_monitor;
00219
00220 if(server_monitor == NULL) {
00221 notify_application_update(current_svc_set->svc_set_name,
00222 name, address, port, session_timeout, 0, 0, 0, 0);
00223 } else {
00224 notify_application_update(current_svc_set->svc_set_name,
00225 name, address, port, session_timeout,
00226 server_monitor->connection_interval,
00227 server_monitor->connection_timeout,
00228 server_monitor->timeouts_allowed,
00229 server_monitor->down_retry_interval);
00230 }
00231 } else {
00232 if(server_monitor == NULL) {
00233 free(app->server_mon_params);
00234 app->server_mon_params = NULL;
00235
00236 notify_application_update(current_svc_set->svc_set_name,
00237 name, address, port, session_timeout, 0, 0, 0, 0);
00238 } else {
00239 app->server_mon_params->connection_interval =
00240 server_monitor->connection_interval;
00241 app->server_mon_params->connection_timeout =
00242 server_monitor->connection_timeout;
00243 app->server_mon_params->timeouts_allowed =
00244 server_monitor->timeouts_allowed;
00245 app->server_mon_params->down_retry_interval =
00246 server_monitor->down_retry_interval;
00247
00248 notify_application_update(current_svc_set->svc_set_name,
00249 name, address, port, session_timeout,
00250 server_monitor->connection_interval,
00251 server_monitor->connection_timeout,
00252 server_monitor->timeouts_allowed,
00253 server_monitor->down_retry_interval);
00254 }
00255 }
00256
00257 return app;
00258 }
00259
00260
00267 static void
00268 update_server(in_addr_t server_address)
00269 {
00270 eq_server_t * server = NULL;
00271
00272 INSIST_ERR(current_app != NULL);
00273 INSIST_ERR(current_svc_set != NULL);
00274
00275 junos_trace(EQUILIBRIUM_TRACEFLAG_CONF, "%s", __func__);
00276
00277 if(current_app->servers == NULL) {
00278 current_app->servers = malloc(sizeof(server_list_t));
00279 INSIST(current_app->servers != NULL);
00280 TAILQ_INIT(current_app->servers);
00281 }
00282
00283 server = calloc(1, sizeof(eq_server_t));
00284 INSIST(server != NULL);
00285
00286 server->server_addr = server_address;
00287 TAILQ_INSERT_TAIL(current_app->servers, server, entries);
00288
00289 notify_server_update(current_svc_set->svc_set_name,
00290 current_app->application_name, server->server_addr);
00291 }
00292
00293
00300 static void
00301 delete_server(in_addr_t server_address)
00302 {
00303 eq_server_t * server = NULL;
00304
00305 INSIST_ERR(current_app != NULL);
00306 INSIST_ERR(current_svc_set != NULL);
00307
00308 junos_trace(EQUILIBRIUM_TRACEFLAG_CONF, "%s", __func__);
00309
00310 if(current_app->servers != NULL) {
00311 server = TAILQ_FIRST(current_app->servers);
00312 while(server != NULL) {
00313 if(server->server_addr == server_address) {
00314 TAILQ_REMOVE(current_app->servers, server, entries);
00315
00316 notify_server_delete(current_svc_set->svc_set_name,
00317 current_app->application_name, server->server_addr);
00318
00319 free(server);
00320 break;
00321 }
00322 server = TAILQ_NEXT(server, entries);
00323 }
00324 }
00325 }
00326
00327
00341 static void
00342 delete_application(patroot * apps, eq_app_t ** application, boolean notify)
00343 {
00344 eq_app_t * app = *application;
00345 eq_server_t * server = NULL;
00346
00347 if(notify) {
00348 INSIST_ERR(current_svc_set != NULL);
00349 }
00350
00351 junos_trace(EQUILIBRIUM_TRACEFLAG_CONF, "%s", __func__);
00352
00353
00354 if (!patricia_delete(apps, &app->node)) {
00355 junos_trace(EQUILIBRIUM_TRACEFLAG_CONF,
00356 "%s: Deleting application failed", __func__);
00357 return;
00358 }
00359
00360 if(app->server_mon_params != NULL) {
00361 free(app->server_mon_params);
00362 }
00363
00364 if(app->servers != NULL) {
00365 while((server = TAILQ_FIRST(app->servers)) != NULL) {
00366 TAILQ_REMOVE(app->servers, server, entries);
00367 free(server);
00368 }
00369 }
00370
00371 if(notify) {
00372 notify_application_delete(current_svc_set->svc_set_name,
00373 app->application_name);
00374 }
00375
00376 free(*application);
00377 *application = NULL;
00378 }
00379
00380
00391 static void
00392 delete_service_set(eq_serviceset_t ** service_set, boolean notify)
00393 {
00394 eq_serviceset_t * ss = *service_set;
00395 eq_app_t * app;
00396 junos_kcom_pub_ssrb_t * ssrb;
00397
00398 junos_trace(EQUILIBRIUM_TRACEFLAG_CONF, "%s", __func__);
00399
00400
00401 if (!patricia_delete(&services_conf, &ss->node)) {
00402 junos_trace(EQUILIBRIUM_TRACEFLAG_CONF,
00403 "%s: Deleting service set failed", __func__);
00404 return;
00405 }
00406
00407 if(ss->applications != NULL) {
00408 while(NULL != (app =
00409 app_entry(patricia_find_next(ss->applications, NULL)))) {
00410
00411 delete_application(ss->applications, &app, FALSE);
00412 }
00413 patricia_root_delete(ss->applications);
00414 }
00415
00416 if(notify) {
00417 if(ss->svc_set_id != -1) {
00418
00419 notify_serviceset_delete(ss->svc_set_name,(uint16_t)ss->svc_set_id);
00420 } else if((ssrb = get_ssrb_by_name(ss->svc_set_name)) != NULL){
00421
00422 notify_serviceset_delete(ss->svc_set_name, ssrb->svc_set_id);
00423 } else {
00424
00425 junos_trace(EQUILIBRIUM_TRACEFLAG_CONF,
00426 "%s: Cannot find the service-set id to delete "
00427 "the %s service set", __func__, ss->svc_set_name);
00428 }
00429 }
00430
00431 free(*service_set);
00432 *service_set = NULL;
00433 }
00434
00435
00439 static void
00440 delete_all_servers(void)
00441 {
00442
00443
00444 eq_server_t * server = NULL;
00445
00446 junos_trace(EQUILIBRIUM_TRACEFLAG_CONF, "%s", __func__);
00447
00448 if(current_app->servers != NULL) {
00449 while((server = TAILQ_FIRST(current_app->servers)) != NULL) {
00450 TAILQ_REMOVE(current_app->servers, server, entries);
00451 free(server);
00452 }
00453 notify_delete_all_servers(current_svc_set->svc_set_name,
00454 current_app->application_name);
00455 }
00456 }
00457
00458
00462 static void
00463 delete_all_applications(void)
00464 {
00465
00466 eq_app_t * app;
00467 junos_kcom_pub_ssrb_t * ssrb;
00468
00469 INSIST_ERR(current_svc_set != NULL);
00470
00471 junos_trace(EQUILIBRIUM_TRACEFLAG_CONF, "%s", __func__);
00472
00473 if(current_svc_set->applications != NULL) {
00474 while((app = app_entry(patricia_find_next(
00475 current_svc_set->applications, NULL))) != NULL) {
00476 delete_application(current_svc_set->applications, &app, FALSE);
00477 }
00478 patricia_root_delete(current_svc_set->applications);
00479 current_svc_set->applications = NULL;
00480
00481 if(current_svc_set->svc_set_id != -1) {
00482
00483 notify_delete_all_applications(current_svc_set->svc_set_name,
00484 current_svc_set->svc_set_id);
00485 } else if((ssrb = get_ssrb_by_name(current_svc_set->svc_set_name))
00486 != NULL) {
00487
00488 notify_delete_all_applications(current_svc_set->svc_set_name,
00489 ssrb->svc_set_id);
00490 } else {
00491
00492 junos_trace(EQUILIBRIUM_TRACEFLAG_CONF,
00493 "%s: Cannot find the service-set id to delete "
00494 "the %s service set's applications", __func__,
00495 current_svc_set->svc_set_name);
00496 }
00497 }
00498 }
00499
00500
00504 static void
00505 delete_all_service_sets(void)
00506 {
00507 eq_serviceset_t * ss;
00508
00509 junos_trace(EQUILIBRIUM_TRACEFLAG_CONF, "%s", __func__);
00510
00511 while((ss = service_entry(patricia_find_next(&services_conf, NULL)))
00512 != NULL) {
00513 delete_service_set(&ss, FALSE);
00514 }
00515
00516 notify_delete_all();
00517 }
00518
00519
00538 static int
00539 parse_server(dax_walk_data_t * dwd,
00540 ddl_handle_t * dop,
00541 int action,
00542 void * data)
00543 {
00544
00545 char ip_str[INET_ADDRSTRLEN];
00546 struct in_addr tmp;
00547 in_addr_t server_addr;
00548 int addr_fam;
00549 int check = *((int *)data);
00550
00551 junos_trace(EQUILIBRIUM_TRACEFLAG_CONF, "%s", __func__);
00552
00553 if(action == DAX_ITEM_DELETE_ALL) {
00554
00555 delete_all_servers();
00556 return DAX_WALK_OK;
00557 }
00558
00559 INSIST(dop != NULL);
00560
00561 switch(action) {
00562
00563 case DAX_ITEM_DELETE:
00564
00565
00566
00567
00568 if (!dax_get_stringr_by_dwd_ident(dwd, NULL, 0,
00569 ip_str, sizeof(ip_str))) {
00570 dax_error(dop, "Failed to parse server IP");
00571 return DAX_WALK_ABORT;
00572 }
00573
00574 if(inet_aton(ip_str, &tmp) != 1) {
00575 dax_error(dop, "Failed to parse server IP: %s", ip_str);
00576 return DAX_WALK_ABORT;
00577 }
00578 server_addr = tmp.s_addr;
00579
00580 if(!check) {
00581 delete_server(server_addr);
00582
00583
00584 if(TAILQ_FIRST(current_app->servers) == NULL) {
00585 free(current_app);
00586 current_app->servers = NULL;
00587 }
00588 }
00589
00590 break;
00591
00592 case DAX_ITEM_CHANGED:
00593
00594
00595 if(!dax_get_ipaddr_by_name(dop, DDLNAME_APP_SERVERS_SERVER,
00596 &addr_fam, &server_addr, sizeof(server_addr)) ||
00597 addr_fam != AF_INET) {
00598 dax_error(dop, "Failed to parse server IP");
00599 return DAX_WALK_ABORT;
00600 }
00601
00602 if(!check) {
00603 update_server(server_addr);
00604 }
00605
00606 break;
00607
00608 case DAX_ITEM_UNCHANGED:
00609 junos_trace(EQUILIBRIUM_TRACEFLAG_CONF,
00610 "%s: DAX_ITEM_UNCHANGED observed", __func__);
00611 break;
00612
00613 default:
00614 break;
00615 }
00616
00617 return DAX_WALK_OK;
00618 }
00619
00620
00642 static int
00643 check_applications(dax_walk_data_t * dwd __unused,
00644 ddl_handle_t * dop,
00645 int action __unused,
00646 void * data)
00647 {
00648
00649
00650 eq_app_key_set_t * app_key_set = (eq_app_key_set_t *)data;
00651 eq_app_key_t * key, * tmp;
00652 int addr_fam;
00653
00654 INSIST_ERR(dop != NULL);
00655 INSIST_ERR(app_key_set != NULL);
00656
00657 key = calloc(1, sizeof(eq_app_key_t));
00658 INSIST_ERR(key != NULL);
00659
00660
00661 if (!dax_get_ipaddr_by_name(dop,
00662 DDLNAME_SVCS_SVC_SET_EXT_SERVICE_APP_APPLICATION_ADDRESS,
00663 &addr_fam, &key->addr, sizeof(key->addr)) ||
00664 addr_fam != AF_INET) {
00665 dax_error(dop, "Failed to parse application address");
00666 return DAX_WALK_ABORT;
00667 }
00668
00669 if (!dax_get_ushort_by_name(dop,
00670 DDLNAME_SVCS_SVC_SET_EXT_SERVICE_APP_APPLICATION_PORT,
00671 &key->port)) {
00672 dax_error(dop, "Failed to parse application port");
00673 return DAX_WALK_ABORT;
00674 }
00675
00676
00677
00678 tmp = TAILQ_FIRST(app_key_set);
00679 while(tmp != NULL) {
00680 if(tmp->addr == key->addr && tmp->port == key->port) {
00681 dax_error(dop, "Found another application with the same "
00682 "facade address and port within the same service set. "
00683 "This is not allowed.");
00684 return DAX_WALK_ABORT;
00685 }
00686 tmp = TAILQ_NEXT(tmp, entries);
00687 }
00688
00689 TAILQ_INSERT_TAIL(app_key_set, key, entries);
00690
00691 return DAX_WALK_OK;
00692 }
00693
00694
00713 static int
00714 parse_application(dax_walk_data_t * dwd,
00715 ddl_handle_t * dop,
00716 int action,
00717 void * data)
00718 {
00719
00720
00721 char app_name[MAX_APP_NAME];
00722 in_addr_t app_addr;
00723 int addr_fam;
00724 uint16_t app_port;
00725 uint16_t app_session_timeout;
00726 eq_smon_t * app_s_monitor;
00727 eq_app_t * app;
00728 ddl_handle_t * smon_dop;
00729 ddl_handle_t * servers_dop;
00730 int check = *((int *)data);
00731
00732 junos_trace(EQUILIBRIUM_TRACEFLAG_CONF, "%s", __func__);
00733
00734 switch (action) {
00735
00736 case DAX_ITEM_DELETE_ALL:
00737
00738
00739 delete_all_applications();
00740 return DAX_WALK_OK;
00741
00742 break;
00743
00744 case DAX_ITEM_DELETE:
00745
00746
00747 if (!dax_get_stringr_by_dwd_ident(dwd, NULL, 0,
00748 app_name, sizeof(app_name))) {
00749 dax_error(dop, "Failed to parse a service set name");
00750 return DAX_WALK_ABORT;
00751 }
00752
00753 if(check) {
00754 break;
00755 }
00756
00757 app = app_entry(patricia_get(current_svc_set->applications,
00758 strlen(app_name) + 1, app_name));
00759 if(app != NULL) {
00760 delete_application(current_svc_set->applications, &app, TRUE);
00761 }
00762
00763
00764 if((patricia_find_next(current_svc_set->applications, NULL)) == NULL) {
00765 patricia_root_delete(current_svc_set->applications);
00766 current_svc_set->applications = NULL;
00767 }
00768
00769 break;
00770
00771 case DAX_ITEM_CHANGED:
00772
00773 INSIST_ERR(dop != NULL);
00774
00775
00776
00777 if (!dax_get_stringr_by_name(dop,
00778 DDLNAME_SVCS_SVC_SET_EXT_SERVICE_APP_APPLICATION_NAME,
00779 app_name, sizeof(app_name))) {
00780 dax_error(dop, "Failed to parse application name");
00781 return DAX_WALK_ABORT;
00782 }
00783
00784
00785
00786 if (!dax_get_ipaddr_by_name(dop,
00787 DDLNAME_SVCS_SVC_SET_EXT_SERVICE_APP_APPLICATION_ADDRESS,
00788 &addr_fam, &app_addr, sizeof(app_addr)) ||
00789 addr_fam != AF_INET) {
00790 dax_error(dop, "Failed to parse application address");
00791 return DAX_WALK_ABORT;
00792 }
00793
00794 if (!dax_get_ushort_by_name(dop,
00795 DDLNAME_SVCS_SVC_SET_EXT_SERVICE_APP_APPLICATION_PORT,
00796 &app_port)) {
00797 dax_error(dop, "Failed to parse application port");
00798 return DAX_WALK_ABORT;
00799 }
00800
00801 if (!dax_get_ushort_by_name(dop,
00802 DDLNAME_SVCS_SVC_SET_EXT_SERVICE_APP_SESSION_TIMEOUT,
00803 &app_session_timeout)) {
00804 dax_error(dop, "Failed to parse session timeout");
00805 return DAX_WALK_ABORT;
00806 }
00807
00808 if(!dax_get_object_by_name(dop, DDLNAME_APP_SMON, &smon_dop, FALSE)) {
00809 app_s_monitor = NULL;
00810 } else {
00811 app_s_monitor = malloc(sizeof(eq_smon_t));
00812 INSIST(app_s_monitor != NULL);
00813
00814 if (!dax_get_ushort_by_name(smon_dop,
00815 DDLNAME_APP_SMON_SERVER_CONNECTION_INTERVAL,
00816 &app_s_monitor->connection_interval)) {
00817 dax_error(smon_dop, "Failed to parse connection interval");
00818 dax_release_object(&smon_dop);
00819 return DAX_WALK_ABORT;
00820 }
00821
00822 if (!dax_get_ushort_by_name(smon_dop,
00823 DDLNAME_APP_SMON_SERVER_CONNECTION_TIMEOUT,
00824 &app_s_monitor->connection_timeout)) {
00825 dax_error(smon_dop, "Failed to parse connection timeout");
00826 dax_release_object(&smon_dop);
00827 return DAX_WALK_ABORT;
00828 }
00829
00830 if (!dax_get_ubyte_by_name(smon_dop,
00831 DDLNAME_APP_SMON_SERVER_TIMEOUTS_ALLOWED,
00832 &app_s_monitor->timeouts_allowed)) {
00833 dax_error(smon_dop, "Failed to parse timeouts allowed");
00834 dax_release_object(&smon_dop);
00835 return DAX_WALK_ABORT;
00836 }
00837
00838 if (!dax_get_ushort_by_name(smon_dop,
00839 DDLNAME_APP_SMON_SERVER_DOWN_RETRY_INTERVAL,
00840 &app_s_monitor->down_retry_interval)) {
00841 dax_error(smon_dop, "Failed to parse down retry interval");
00842 dax_release_object(&smon_dop);
00843 return DAX_WALK_ABORT;
00844 }
00845 dax_release_object(&smon_dop);
00846
00847 if(check) {
00848 free(app_s_monitor);
00849 }
00850 }
00851
00852
00853 if(!check) {
00854 current_app = update_application(app_name, app_addr, app_port,
00855 app_s_monitor, app_session_timeout);
00856 }
00857
00858
00859 if(!dax_get_object_by_name(dop, DDLNAME_APP_SERVERS, &servers_dop,
00860 FALSE)) {
00861 dax_error(dop, "Failed to parse servers");
00862 return DAX_WALK_ABORT;
00863
00864 } else if(dax_walk_list(servers_dop, DAX_WALK_DELTA, parse_server, data)
00865 != DAX_WALK_OK) {
00866
00867 dax_release_object(&servers_dop);
00868 current_app = NULL;
00869 return DAX_WALK_ABORT;
00870 }
00871 current_app = NULL;
00872 dax_release_object(&servers_dop);
00873
00874 break;
00875
00876 case DAX_ITEM_UNCHANGED:
00877 junos_trace(EQUILIBRIUM_TRACEFLAG_CONF,
00878 "%s: DAX_ITEM_UNCHANGED observed", __func__);
00879 break;
00880
00881 default:
00882 break;
00883 }
00884
00885 return DAX_WALK_OK;
00886 }
00887
00888
00907 static int
00908 parse_service_set(dax_walk_data_t * dwd,
00909 ddl_handle_t * dop,
00910 int action,
00911 void * data)
00912 {
00913 const char * service_config[] =
00914 {DDLNAME_SVCS_SVC_SET_EXT_SERVICE, NULL};
00915 const char * applications_config[] =
00916 {DDLNAME_SVCS_SVC_SET_EXT_SERVICE_APP, NULL};
00917 const char * service_int_config[] =
00918 {DDLNAME_INTERFACE_SERVICE, NULL};
00919
00920 char svc_set_name[MAX_SVC_SET_NAME];
00921 char service_name[MAX_SVC_NAME];
00922 char service_int_name[MAX_SVC_INT_NAME];
00923 eq_serviceset_t * service_set = NULL;
00924 eq_app_key_set_t app_key_set;
00925 eq_app_key_t * key;
00926 ddl_handle_t * service_container_dop = NULL;
00927 ddl_handle_t * service_dop = NULL;
00928 ddl_handle_t * applications_dop = NULL;
00929 ddl_handle_t * svc_int_dop = NULL;
00930 int check = *((int *)data);
00931 int found = 0;
00932
00933 junos_trace(EQUILIBRIUM_TRACEFLAG_CONF, "%s", __func__);
00934
00935 switch (action) {
00936
00937 case DAX_ITEM_DELETE_ALL:
00938
00939
00940 delete_all_service_sets();
00941 return DAX_WALK_OK;
00942
00943 break;
00944
00945 case DAX_ITEM_DELETE:
00946
00947
00948
00949
00950 if (!dax_get_stringr_by_dwd_ident(dwd, NULL, 0,
00951 svc_set_name, sizeof(svc_set_name))) {
00952 dax_error(dop, "Failed to parse a service set name");
00953 return DAX_WALK_ABORT;
00954 }
00955
00956 if(!check) {
00957
00958 service_set = service_entry(patricia_get(&services_conf,
00959 strlen(svc_set_name) + 1, svc_set_name));
00960
00961 if(service_set != NULL) {
00962
00963
00964 delete_service_set(&service_set, TRUE);
00965 }
00966 }
00967
00968 break;
00969
00970 case DAX_ITEM_CHANGED:
00971
00972
00973
00974
00975 INSIST_ERR(dop != NULL);
00976
00977
00978 if (!dax_get_stringr_by_name(dop, DDLNAME_SERVICE_SET_IDENT,
00979 svc_set_name, sizeof(svc_set_name))) {
00980 dax_error(dop, "Failed to parse a service set name");
00981 return DAX_WALK_ABORT;
00982 }
00983
00984
00985
00986
00987 if (dax_get_object_by_path(dop, service_config,
00988 &service_container_dop, FALSE)) {
00989
00990
00991
00992
00993 while (dax_visit_container(service_container_dop, &service_dop)) {
00994
00995 if (!dax_get_stringr_by_name(service_dop,
00996 DDLNAME_EXTENTION_SERVICE_IDENT, service_name,
00997 sizeof(service_name))) {
00998 dax_error(service_dop,
00999 "Failed to parse an extension-service name");
01000 return DAX_WALK_ABORT;
01001 }
01002
01003
01004 if(strstr(service_name, equilibrium_service_prefix) == NULL) {
01005 continue;
01006 }
01007
01008
01009
01010 if(found) {
01011 dax_error(service_dop, "More than one equilibrium "
01012 "service per service set is not allowed");
01013 dax_release_object(&service_dop);
01014 dax_release_object(&service_container_dop);
01015 return DAX_WALK_ABORT;
01016 }
01017 found = 1;
01018
01019
01020
01021
01022 if(!dax_get_object_by_path(dop, service_int_config,
01023 &svc_int_dop, FALSE)) {
01024
01025 dax_error(service_dop, "Equilibrium service has no "
01026 "service interface configured in service set");
01027 dax_release_object(&service_dop);
01028 dax_release_object(&service_container_dop);
01029 return DAX_WALK_ABORT;
01030 }
01031
01032
01033 if (!dax_get_stringr_by_name(svc_int_dop,
01034 DDLNAME_INTERFACE_SERVICE_SVC_INT,
01035 service_int_name, sizeof(service_int_name))) {
01036
01037 dax_error(svc_int_dop,
01038 "Failed to parse the service-interface name");
01039 dax_release_object(&service_dop);
01040 dax_release_object(&svc_int_dop);
01041 dax_release_object(&service_container_dop);
01042 return DAX_WALK_ABORT;
01043 }
01044
01045 dax_release_object(&svc_int_dop);
01046
01047
01048 if(!check) {
01049 current_svc_set = update_service_set(
01050 svc_set_name, service_name, service_int_name);
01051 }
01052
01053
01054 if(!dax_get_object_by_path(service_dop, applications_config,
01055 &applications_dop, FALSE)) {
01056
01057 dax_error(service_dop, "Equilibrium "
01058 "service has no applications configured");
01059 dax_release_object(&service_dop);
01060 dax_release_object(&service_container_dop);
01061 return DAX_WALK_ABORT;
01062 }
01063
01064 if(dax_walk_list(applications_dop, DAX_WALK_DELTA,
01065 parse_application, data) != DAX_WALK_OK) {
01066
01067 dax_release_object(&service_dop);
01068 dax_release_object(&service_container_dop);
01069 current_svc_set = NULL;
01070 return DAX_WALK_ABORT;
01071 }
01072 if(check) {
01073
01074
01075
01076 TAILQ_INIT(&app_key_set);
01077
01078 if(dax_walk_list(applications_dop, DAX_WALK_CONFIGURED,
01079 check_applications, &app_key_set) != DAX_WALK_OK) {
01080
01081 dax_release_object(&service_dop);
01082 dax_release_object(&service_container_dop);
01083 current_svc_set = NULL;
01084
01085 while((key = TAILQ_FIRST(&app_key_set)) != NULL) {
01086 TAILQ_REMOVE(&app_key_set, key, entries);
01087 free(key);
01088 }
01089 return DAX_WALK_ABORT;
01090 }
01091
01092
01093 while((key = TAILQ_FIRST(&app_key_set)) != NULL) {
01094 TAILQ_REMOVE(&app_key_set, key, entries);
01095 free(key);
01096 }
01097 }
01098 current_svc_set = NULL;
01099
01100 }
01101 dax_release_object(&service_container_dop);
01102
01103 if(found) {
01104 return DAX_WALK_OK;
01105 }
01106
01107 }
01108
01109 if(!check) {
01110
01111 service_set = service_entry(patricia_get(&services_conf,
01112 strlen(svc_set_name) + 1, svc_set_name));
01113
01114 if(service_set != NULL) {
01115 delete_service_set(&service_set, TRUE);
01116 }
01117 }
01118
01119 break;
01120
01121 case DAX_ITEM_UNCHANGED:
01122 junos_trace(EQUILIBRIUM_TRACEFLAG_CONF,
01123 "%s: DAX_ITEM_UNCHANGED observed", __func__);
01124 break;
01125
01126 default:
01127 break;
01128 }
01129
01130 return DAX_WALK_OK;
01131 }
01132
01133
01134
01135
01136
01141 void
01142 init_config(void)
01143 {
01144
01145 patricia_root_init(&services_conf, FALSE, MAX_SVC_SET_NAME, 0);
01146 patricia_root_init(&ssrb_conf, FALSE, MAX_SVC_SET_NAME, 0);
01147 }
01148
01149
01153 void
01154 clear_config(void)
01155 {
01156 delete_all_service_sets();
01157
01158 clear_ssrb_config();
01159 }
01160
01161
01165 void
01166 clear_ssrb_config(void)
01167 {
01168 eq_ssrb_t * s;
01169 while((s = ssrb_entry(patricia_find_next(&ssrb_conf, NULL))) != NULL) {
01170 if(!patricia_delete(&ssrb_conf, &s->node)) {
01171 LOG(TRACE_LOG_ERR, "%s: patricia delete FAILED!",
01172 __func__);
01173 }
01174 free(s);
01175 }
01176 }
01177
01178
01188 int
01189 add_ssrb(junos_kcom_pub_ssrb_t * ssrb)
01190 {
01191 eq_ssrb_t * s;
01192
01193
01194 if(get_ssrb_by_name(ssrb->svc_set_name) != NULL)
01195 return EFAIL;
01196
01197
01198 s = malloc(sizeof(eq_ssrb_t));
01199 INSIST(s != NULL);
01200
01201
01202 strncpy(s->ssrb.svc_set_name, ssrb->svc_set_name, MAX_SVC_SET_NAME);
01203 s->ssrb.svc_set_id = ssrb->svc_set_id;
01204 s->ssrb.in_nh_idx = ssrb->in_nh_idx;
01205 s->ssrb.out_nh_idx = ssrb->out_nh_idx;
01206
01207 patricia_node_init_length(&s->node, strlen(ssrb->svc_set_name) +1);
01208 if(!patricia_add(&ssrb_conf, &s->node)) {
01209 LOG(TRACE_LOG_ERR, "%s: failed to add SSRB to configuration",
01210 __func__);
01211 return EFAIL;
01212 }
01213 return SUCCESS;
01214
01215 }
01216
01217
01227 junos_kcom_pub_ssrb_t *
01228 get_ssrb_by_name(char * name)
01229 {
01230 eq_ssrb_t * s;
01231
01232 s = ssrb_entry(patricia_get(&ssrb_conf, strlen(name) + 1, name));
01233 if(s != NULL)
01234 return &s->ssrb;
01235 return NULL;
01236 }
01237
01238
01248 junos_kcom_pub_ssrb_t *
01249 get_ssrb_by_id(uint16_t svc_set_id)
01250 {
01251 eq_ssrb_t * s;
01252
01253 s = ssrb_entry(patricia_find_next(&ssrb_conf, NULL));
01254 while(s != NULL) {
01255 if(s->ssrb.svc_set_id == svc_set_id) {
01256 return &s->ssrb;
01257 }
01258 s = ssrb_entry(patricia_find_next(&ssrb_conf, &s->node));
01259 }
01260 return NULL;
01261 }
01262
01263
01270 void
01271 delete_ssrb_by_name(char * name)
01272 {
01273 eq_ssrb_t * s;
01274 eq_serviceset_t * service_set;
01275
01276 if(name == NULL)
01277 return;
01278
01279 s = ssrb_entry(patricia_get(&ssrb_conf, strlen(name) + 1, name));
01280
01281 if(s == NULL)
01282 return;
01283
01284
01285
01286
01287
01288
01289
01290
01291
01292
01293
01294
01295 service_set = service_entry(patricia_get(&services_conf,
01296 strlen(name) + 1, name));
01297 if(service_set != NULL) {
01298 service_set->svc_set_id = s->ssrb.svc_set_id;
01299 }
01300
01301
01302 if (!patricia_delete(&ssrb_conf, &s->node)) {
01303 LOG(TRACE_LOG_ERR, "%s: patricia delete FAILED!",
01304 __func__);
01305 }
01306 free(s);
01307 }
01308
01309
01316 void
01317 delete_ssrb_by_id(uint16_t svc_set_id)
01318 {
01319 delete_ssrb_by_name((get_ssrb_by_id(svc_set_id))->svc_set_name);
01320 }
01321
01322
01338 void
01339 set_server_status(uint16_t svc_set_id,
01340 char * app_name,
01341 in_addr_t server_addr,
01342 uint8_t status)
01343 {
01344 junos_kcom_pub_ssrb_t * ssrb;
01345 eq_serviceset_t * service_set = NULL;
01346 eq_app_t * app = NULL;
01347 eq_server_t * server = NULL;
01348
01349 INSIST_ERR(app_name != NULL);
01350
01351
01352 if((ssrb = get_ssrb_by_id(svc_set_id)) == NULL) {
01353 return;
01354 }
01355
01356
01357 service_set = service_entry(patricia_get(&services_conf,
01358 strlen(ssrb->svc_set_name) + 1, ssrb->svc_set_name));
01359
01360 if(service_set == NULL || service_set->applications == NULL) {
01361 return;
01362 }
01363
01364
01365 app = app_entry(patricia_get(service_set->applications,
01366 strlen(app_name) + 1, app_name));
01367
01368 if(app == NULL || app->servers == NULL) {
01369 return;
01370 }
01371
01372
01373 server = TAILQ_FIRST(app->servers);
01374 while(server != NULL) {
01375 if(server->server_addr == server_addr) {
01376 server->status = status;
01377 return;
01378 }
01379 server = TAILQ_NEXT(server, entries);
01380 }
01381
01382 }
01383
01384
01397 void
01398 set_app_sessions(uint16_t svc_set_id,
01399 char * app_name,
01400 uint32_t session_count)
01401 {
01402 junos_kcom_pub_ssrb_t * ssrb;
01403 eq_serviceset_t * service_set = NULL;
01404 eq_app_t * app = NULL;
01405
01406 INSIST_ERR(app_name != NULL);
01407
01408
01409 if((ssrb = get_ssrb_by_id(svc_set_id)) == NULL) {
01410 return;
01411 }
01412
01413
01414 service_set = service_entry(patricia_get(&services_conf,
01415 strlen(ssrb->svc_set_name) + 1, ssrb->svc_set_name));
01416
01417 if(service_set == NULL || service_set->applications == NULL) {
01418 return;
01419 }
01420
01421
01422 app = app_entry(patricia_get(service_set->applications,
01423 strlen(app_name) + 1, app_name));
01424
01425 if(app == NULL) {
01426 return;
01427 }
01428
01429 app->session_count = session_count;
01430 }
01431
01432
01442 eq_serviceset_t *
01443 next_service_set(eq_serviceset_t * data)
01444 {
01445 return service_entry(
01446 patricia_find_next(&services_conf, (data ? &(data->node) : NULL)));
01447 }
01448
01449
01462 eq_app_t *
01463 next_application(eq_serviceset_t * ss, eq_app_t * data)
01464 {
01465 return app_entry(patricia_find_next(ss->applications,
01466 (data ? &(data->node) : NULL)));
01467 }
01468
01469
01478 eq_serviceset_t *
01479 find_service_set(const char * name)
01480 {
01481 return service_entry(patricia_get(&services_conf, strlen(name) + 1, name));
01482 }
01483
01484
01496 eq_app_t *
01497 find_application(const eq_serviceset_t * ss, const char * name)
01498 {
01499 return app_entry(patricia_get(ss->applications, strlen(name) + 1, name));
01500 }
01501
01502
01514 int
01515 equilibrium_config_read(int check)
01516 {
01517 const char * services_config[] = {DDLNAME_SVCS, DDLNAME_SVCS_SVC_SET, NULL};
01518
01519 ddl_handle_t * top = NULL;
01520
01521 junos_trace(EQUILIBRIUM_TRACEFLAG_CONF, "%s: Starting equilibrium "
01522 "configuration load", __func__);
01523
01524
01525
01526 if (!dax_get_object_by_path(NULL, services_config, &top, FALSE)) {
01527
01528
01529 junos_trace(EQUILIBRIUM_TRACEFLAG_CONF,
01530 "%s: Cleared equilibrium services configuration", __func__);
01531
01532 delete_all_service_sets();
01533 return SUCCESS;
01534 }
01535 if (!dax_is_changed(top)) {
01536 junos_trace(EQUILIBRIUM_TRACEFLAG_CONF, "%s: No change in equilibrium"
01537 " services configuration", __func__);
01538 return SUCCESS;
01539 }
01540
01541
01542
01543 if(dax_walk_list(top, DAX_WALK_DELTA, parse_service_set, &check)
01544 != DAX_WALK_OK) {
01545 dax_release_object(&top);
01546 junos_trace(EQUILIBRIUM_TRACEFLAG_CONF, "%s: walk service list failed"
01547 " services configuration", __func__);
01548 return EFAIL;
01549 }
01550
01551 if(!check) {
01552 process_notifications();
01553 }
01554
01555 junos_trace(EQUILIBRIUM_TRACEFLAG_CONF,
01556 "%s: Loaded equilibrium configuration", __func__);
01557
01558 return SUCCESS;
01559 }