00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00021 #include <sync/equilibrium2.h>
00022 #include "equilibrium2-mgmt.h"
00023
00024 #include <stdlib.h>
00025 #include <string.h>
00026 #include <arpa/inet.h>
00027 #include <jnx/trace.h>
00028 #include <jnx/junos_trace.h>
00029 #include <ddl/ddl.h>
00030 #include <ddl/dax.h>
00031
00032 #include EQUILIBRIUM2_OUT_H
00033
00034
00035
00036 #define DDLNAME_SVC_SET_NAME "service-set-name"
00037
00038 #define DDLNAME_EXT_SVC "extension-service"
00039
00040 #define DDLNAME_EXT_SVC_NAME "service-name"
00041
00042 #define DDLNAME_IF_SVC "interface-service"
00043
00044 #define DDLNAME_IF_SVC_IF_NAME "service-interface"
00045
00047
00048
00049 static svc_gate_head_t svc_gate_head;
00050 static svc_type_head_t svc_type_head;
00051 static svr_group_head_t svr_group_head;
00052 static int svr_group_count;
00053 static svc_set_head_t ss_head;
00054 static ssrb_head_t ssrb_head;
00055 static blob_ss_head_t blob_ss_head;
00056 static svc_rule_head_t balance_rule_head;
00058 static svc_rule_head_t classify_rule_head;
00060 static blob_svr_group_set_t *blob_svr_group_set;
00063
00064
00069 static void
00070 clear_svc_if (void)
00071 {
00072 svc_if_t *svc_if;
00073
00074 while ((svc_if = LIST_FIRST(&svc_if_head))) {
00075 LIST_REMOVE(svc_if, entry);
00076 free(svc_if);
00077 }
00078 svc_if_count = 0;
00079 }
00080
00088 static void
00089 add_svc_if (char *name)
00090 {
00091 svc_if_t *svc_if;
00092
00093
00094 LIST_FOREACH(svc_if, &svc_if_head, entry) {
00095 if (strcmp(svc_if->if_name, name) == 0) {
00096 return;
00097 }
00098 }
00099 svc_if = malloc(sizeof(svc_if_t));
00100 INSIST_ERR(svc_if != NULL);
00101 svc_if->if_name = name;
00102 LIST_INSERT_HEAD(&svc_if_head, svc_if, entry);
00103 svc_if_count++;
00104 }
00105
00119 static svc_rule_t *
00120 get_eq2_svc_rule (svc_rule_head_t *head, char *name)
00121 {
00122 svc_rule_t *rule;
00123
00124 if ((head == NULL) || (name == NULL)) {
00125 return NULL;
00126 }
00127 LIST_FOREACH(rule, head, entry) {
00128 if (strcmp(rule->rule_name, name) == 0) {
00129 break;
00130 }
00131 }
00132 return rule;
00133 }
00134
00148 static blob_svc_set_node_t *
00149 get_svc_set_blob_node (char *name, int eq2_svc)
00150 {
00151 blob_svc_set_node_t *blob_ss_node;
00152
00153 LIST_FOREACH(blob_ss_node, &blob_ss_head, entry) {
00154 if ((strcmp(blob_ss_node->ss->ss_name, name) == 0) &&
00155 (blob_ss_node->ss->ss_eq2_svc_id == eq2_svc)) {
00156 break;
00157 }
00158 }
00159 return blob_ss_node;
00160 }
00161
00169 static void
00170 free_eq2_svc_rule (svc_rule_t *rule)
00171 {
00172 svc_term_t *term;
00173
00174 if (rule == NULL) {
00175 return;
00176 }
00177
00178 EQ2_TRACE(EQ2_TRACEFLAG_CONF, "%s %s", __func__, rule->rule_name);
00179
00180
00181 while ((term = LIST_FIRST(&rule->rule_term_head))) {
00182 LIST_REMOVE(term, entry);
00183 free(term);
00184 }
00185 free(rule);
00186 }
00187
00198 static void
00199 del_eq2_svc_rule (svc_rule_t *rule)
00200 {
00201 if (rule == NULL) {
00202 return;
00203 }
00204
00205 EQ2_TRACE(EQ2_TRACEFLAG_CONF, "%s %s", __func__, rule->rule_name);
00206
00207
00208 LIST_REMOVE(rule, entry);
00209
00210
00211 free_eq2_svc_rule(rule);
00212 }
00213
00221 static void
00222 clear_eq2_svc_rule (svc_rule_head_t *head)
00223 {
00224 svc_rule_t *rule;
00225
00226 if (head == NULL) {
00227 return;
00228 }
00229 EQ2_TRACE(EQ2_TRACEFLAG_CONF, "%s", __func__);
00230
00231
00232 while ((rule = LIST_FIRST(head))) {
00233 LIST_REMOVE(rule, entry);
00234 free_eq2_svc_rule(rule);
00235 }
00236 }
00237
00245 static void
00246 del_svc_set (svc_set_t *ss)
00247 {
00248 svc_set_rule_t *rule;
00249
00250 if (ss == NULL) {
00251 return;
00252 }
00253
00254 EQ2_TRACE(EQ2_TRACEFLAG_CONF, "%s %s", __func__, ss->ss_name);
00255
00256 LIST_REMOVE(ss, entry);
00257
00258
00259 while ((rule = LIST_FIRST(&ss->ss_rule_head))) {
00260 LIST_REMOVE(rule, entry);
00261 free(rule);
00262 }
00263 free(ss);
00264 }
00265
00270 static void
00271 clear_svc_set (void)
00272 {
00273 svc_set_t *ss;
00274
00275 EQ2_TRACE(EQ2_TRACEFLAG_CONF, "%s", __func__);
00276
00277 while ((ss = LIST_FIRST(&ss_head))) {
00278 del_svc_set(ss);
00279 }
00280 }
00281
00292 static ssrb_node_t *
00293 config_get_ssrb (char *name)
00294 {
00295 ssrb_node_t *ssrb;
00296
00297 if (name == NULL) {
00298 return NULL;
00299 }
00300 LIST_FOREACH(ssrb, &ssrb_head, entry) {
00301 if (strcmp(ssrb->ssrb.svc_set_name, name) == 0) {
00302 break;
00303 }
00304 }
00305 return ssrb;
00306 }
00307
00321 static int
00322 read_svc_set_rule (ddl_handle_t *dop, svc_set_rule_head_t *head)
00323 {
00324 const char *rule_config[] = { "rule", NULL };
00325 ddl_handle_t *dop_rule_head = NULL;
00326 ddl_handle_t *dop_rule = NULL;
00327 char rule_name[MAX_NAME_LEN];
00328 svc_set_rule_t *rule;
00329 int count = 0;
00330
00331 if (!dax_get_object_by_path(dop, rule_config, &dop_rule_head, FALSE)) {
00332 dax_error(dop, "No rules configured!");
00333 dax_release_object(&dop_rule_head);
00334 return -1;
00335 }
00336 while (dax_visit_container(dop_rule_head, &dop_rule)) {
00337 if (!dax_get_stringr_by_name(dop_rule, "name", rule_name,
00338 sizeof(rule_name))) {
00339 continue;
00340 }
00341 EQ2_TRACE(EQ2_TRACEFLAG_CONF, "%s: Read rule %s.", __func__, rule_name);
00342 rule = malloc(sizeof(svc_set_rule_t));
00343 INSIST_ERR(rule != NULL);
00344 strlcpy(rule->rule_name, rule_name, sizeof(rule->rule_name));
00345 LIST_INSERT_HEAD(head, rule, entry);
00346 count++;
00347 }
00348 dax_release_object(&dop_rule_head);
00349 return count;
00350 }
00351
00362 static int
00363 read_svc_set (ddl_handle_t *dop_ss)
00364 {
00365 const char *svc_if_config[] = { DDLNAME_IF_SVC, NULL };
00366 const char *ext_svc_config[] = { DDLNAME_EXT_SVC, NULL };
00367 ddl_handle_t *dop_svc_if = NULL;
00368 ddl_handle_t *dop_ext_svc_head = NULL;
00369 ddl_handle_t *dop_ext_svc = NULL;
00370 char svc_if_name[MAX_NAME_LEN];
00371 char ext_svc_name[MAX_NAME_LEN];
00372 char ss_name[MAX_NAME_LEN];
00373 svc_set_t *ss;
00374 svc_set_rule_head_t balance_rl_head;
00375 svc_set_rule_head_t classify_rl_head;
00376 int balance_rule_count = 0;
00377 int classify_rule_count = 0;
00378 ssrb_node_t *ssrb_node;
00379
00380
00381 if (!dax_get_stringr_by_name(dop_ss, DDLNAME_SVC_SET_NAME, ss_name,
00382 sizeof(ss_name))) {
00383 dax_error(dop_ss, "Parse a service set name ERROR!");
00384 return -1;
00385 }
00386
00387 EQ2_TRACE(EQ2_TRACEFLAG_CONF, "%s: Reading %s.", __func__, ss_name);
00388
00389
00390 if (!dax_get_object_by_path(dop_ss, ext_svc_config, &dop_ext_svc_head,
00391 FALSE)) {
00392
00393 EQ2_TRACE(EQ2_TRACEFLAG_CONF, "%s: No external service.", __func__);
00394 return -1;
00395 }
00396
00397
00398 if (!dax_get_object_by_path(dop_ss, svc_if_config, &dop_svc_if, FALSE)) {
00399 dax_error(dop_ss, "Service interface is not configured!");
00400 return -1;
00401 }
00402
00403
00404 if (!dax_get_stringr_by_name(dop_svc_if, DDLNAME_IF_SVC_IF_NAME,
00405 svc_if_name, sizeof(svc_if_name))) {
00406 dax_error(dop_svc_if, "Read service-interface name ERROR!");
00407 dax_release_object(&dop_svc_if);
00408 return -1;
00409 }
00410 dax_release_object(&dop_svc_if);
00411
00412 LIST_INIT(&balance_rl_head);
00413 balance_rule_count = 0;
00414 LIST_INIT(&classify_rl_head);
00415 classify_rule_count = 0;
00416 while (dax_visit_container(dop_ext_svc_head, &dop_ext_svc)) {
00417 if (!dax_get_stringr_by_name(dop_ext_svc, DDLNAME_EXT_SVC_NAME,
00418 ext_svc_name, sizeof(ext_svc_name))) {
00419 dax_error(dop_ext_svc, "Read external service name ERROR!");
00420 dax_release_object(&dop_ext_svc);
00421 dax_release_object(&dop_ext_svc_head);
00422 return -1;
00423 }
00424
00425 if (strcmp(ext_svc_name, EQ2_BALANCE_SVC_NAME) == 0) {
00426 EQ2_TRACE(EQ2_TRACEFLAG_CONF,
00427 "%s: Equilibrium2 balance service.", __func__);
00428 balance_rule_count = read_svc_set_rule(dop_ext_svc,
00429 &balance_rl_head);
00430 if (balance_rule_count <= 0) {
00431
00432
00433 dax_error(dop_ext_svc, "Read balance rules ERROR!");
00434 dax_release_object(&dop_ext_svc);
00435 dax_release_object(&dop_ext_svc_head);
00436 return -1;
00437 }
00438 }
00439 if (strcmp(ext_svc_name, EQ2_CLASSIFY_SVC_NAME) == 0) {
00440 EQ2_TRACE(EQ2_TRACEFLAG_CONF,
00441 "%s: Equilibrium2 classify service.", __func__);
00442 classify_rule_count = read_svc_set_rule(dop_ext_svc,
00443 &classify_rl_head);
00444 if (classify_rule_count <= 0) {
00445
00446
00447 dax_error(dop_ext_svc, "Read classify rules ERROR!");
00448 dax_release_object(&dop_ext_svc);
00449 dax_release_object(&dop_ext_svc_head);
00450 return -1;
00451 }
00452 }
00453 }
00454 dax_release_object(&dop_ext_svc_head);
00455
00456 if (balance_rule_count > 0) {
00457 ss = calloc(1, sizeof(svc_set_t));
00458 INSIST_ERR(ss != NULL);
00459 strlcpy(ss->ss_name, ss_name, sizeof(ss->ss_name));
00460 strlcpy(ss->ss_if_name, svc_if_name, sizeof(ss->ss_if_name));
00461 ss->ss_eq2_svc_id = EQ2_BALANCE_SVC;
00462
00463 LIST_INSERT_HEAD(&ss->ss_rule_head, LIST_FIRST(&balance_rl_head),
00464 entry);
00465 ss->ss_rule_count = balance_rule_count;
00466 LIST_INSERT_HEAD(&ss_head, ss, entry);
00467 EQ2_TRACE(EQ2_TRACEFLAG_CONF, "%s: Read %d balance rules.",
00468 __func__, balance_rule_count);
00469 }
00470 if (classify_rule_count > 0) {
00471 ss = calloc(1, sizeof(svc_set_t));
00472 INSIST_ERR(ss != NULL);
00473 strlcpy(ss->ss_name, ss_name, sizeof(ss->ss_name));
00474 strlcpy(ss->ss_if_name, svc_if_name, sizeof(ss->ss_if_name));
00475 ss->ss_eq2_svc_id = EQ2_CLASSIFY_SVC;
00476
00477 LIST_INSERT_HEAD(&ss->ss_rule_head, LIST_FIRST(&classify_rl_head),
00478 entry);
00479 ss->ss_rule_count = classify_rule_count;
00480 LIST_INSERT_HEAD(&ss_head, ss, entry);
00481 EQ2_TRACE(EQ2_TRACEFLAG_CONF, "%s: Read %d classify rules.",
00482 __func__, classify_rule_count);
00483 }
00484
00485
00486
00487
00488
00489
00490
00491
00492 if (dax_is_changed(dop_ss) && (balance_rule_count > 0 ||
00493 classify_rule_count >0)) {
00494 ssrb_node = config_get_ssrb(ss_name);
00495 if (ssrb_node && (ssrb_node->ssrb_state != SSRB_UPDATED)) {
00496 ssrb_node->ssrb_state = SSRB_PENDING;
00497 }
00498 }
00499
00500 return 0;
00501 }
00502
00513 static void
00514 add_eq2_svc_gate (char *name, char *addr)
00515 {
00516 svc_gate_t *gate;
00517
00518 if ((name == NULL) || (addr == NULL)) {
00519 return;
00520 }
00521 EQ2_TRACE(EQ2_TRACEFLAG_CONF, "%s %s: %s", __func__, name, addr);
00522
00523 gate = malloc(sizeof(svc_gate_t));
00524 INSIST_ERR(gate != NULL);
00525
00526 strlcpy(gate->gate_name, name, sizeof(gate->gate_name));
00527 gate->gate_addr = inet_addr(addr);
00528
00529 LIST_INSERT_HEAD(&svc_gate_head, gate, entry);
00530 }
00531
00542 static in_addr_t
00543 get_eq2_svc_gate (char *name)
00544 {
00545 svc_gate_t *gate;
00546
00547 if (name == NULL) {
00548 return 0;
00549 }
00550 LIST_FOREACH(gate, &svc_gate_head, entry) {
00551 if (strcmp(gate->gate_name, name) == 0) {
00552 break;
00553 }
00554 }
00555 return (gate ? gate->gate_addr : INADDR_ANY);
00556 }
00557
00568 static void
00569 add_eq2_svc_type (char *name, uint16_t port)
00570 {
00571 svc_type_t *type;
00572
00573 if ((name == NULL) || (port == 0)) {
00574 return;
00575 }
00576 EQ2_TRACE(EQ2_TRACEFLAG_CONF, "%s %s: %d", __func__, name, port);
00577
00578 type = malloc(sizeof(svc_type_t));
00579 INSIST_ERR(type != NULL);
00580
00581 strlcpy(type->type_name, name, sizeof(type->type_name));
00582 type->type_port = port;
00583
00584 LIST_INSERT_HEAD(&svc_type_head, type, entry);
00585 }
00586
00597 static uint16_t
00598 get_eq2_svc_type (char *name)
00599 {
00600 svc_type_t *type;
00601
00602 if (name == NULL) {
00603 return 0;
00604 }
00605 LIST_FOREACH(type, &svc_type_head, entry) {
00606 if (strcmp(type->type_name, name) == 0) {
00607 break;
00608 }
00609 }
00610 return (type ? type->type_port : 0);
00611 }
00612
00626 static void
00627 add_eq2_svr_group (char *name, svr_addr_head_t *head, int addr_count)
00628 {
00629 svr_group_t *group;
00630 svr_addr_t *addr;
00631
00632 if ((name == NULL) || (head == NULL)) {
00633 return;
00634 }
00635 EQ2_TRACE(EQ2_TRACEFLAG_CONF, "%s: %s", __func__, name);
00636
00637 group = calloc(1, sizeof(svr_group_t));
00638 INSIST_ERR(group != NULL);
00639
00640 LIST_INIT(&group->group_addr_head);
00641 strlcpy(group->group_name, name, sizeof(group->group_name));
00642
00643
00644 while ((addr = LIST_FIRST(head))) {
00645 LIST_REMOVE(addr, entry);
00646 LIST_INSERT_HEAD(&group->group_addr_head, addr, entry);
00647 }
00648 group->group_addr_count = addr_count;
00649
00650
00651 LIST_INSERT_HEAD(&svr_group_head, group, entry);
00652 svr_group_count++;
00653 }
00654
00659 static void
00660 clear_eq2_svc_gate (void)
00661 {
00662 svc_gate_t *gate;
00663
00664 EQ2_TRACE(EQ2_TRACEFLAG_CONF, "%s", __func__);
00665
00666 while ((gate = LIST_FIRST(&svc_gate_head))) {
00667 LIST_REMOVE(gate, entry);
00668 free(gate);
00669 }
00670 }
00671
00676 static void
00677 clear_eq2_svc_type (void)
00678 {
00679 svc_type_t *type;
00680
00681 EQ2_TRACE(EQ2_TRACEFLAG_CONF, "%s", __func__);
00682 while ((type = LIST_FIRST(&svc_type_head)) != NULL) {
00683 LIST_REMOVE(type, entry);
00684 free(type);
00685 }
00686 }
00687
00692 static void
00693 clear_eq2_svr_group (void)
00694 {
00695 svr_group_t *group;
00696 svr_addr_t *addr;
00697
00698 EQ2_TRACE(EQ2_TRACEFLAG_CONF, "%s", __func__);
00699 while ((group = LIST_FIRST(&svr_group_head))) {
00700 LIST_REMOVE(group, entry);
00701 while ((addr = LIST_FIRST(&group->group_addr_head))) {
00702 LIST_REMOVE(addr, entry);
00703 free(addr);
00704 }
00705 free(group);
00706 }
00707 svr_group_count = 0;
00708 }
00709
00714 static void
00715 read_eq2_svc_gate (void)
00716 {
00717 ddl_handle_t *cop = NULL;
00718 ddl_handle_t *dop = NULL;
00719 const char *svc_gate_config[] = { "sync", "equilibrium2", "service-gate",
00720 NULL };
00721 char name_str[MAX_NAME_LEN];
00722 char addr_str[MAX_NAME_LEN];
00723
00724 if (!dax_get_object_by_path(NULL, svc_gate_config, &cop, FALSE)) {
00725 EQ2_TRACE(EQ2_TRACEFLAG_CONF, "%s: No service-gate.", __func__);
00726 clear_eq2_svc_gate();
00727 return;
00728 }
00729 if (!dax_is_changed(cop)) {
00730 EQ2_TRACE(EQ2_TRACEFLAG_CONF, "%s: No change.", __func__);
00731 goto exit_success;
00732 }
00733
00734
00735 clear_eq2_svc_gate();
00736 while (dax_visit_container(cop, &dop)) {
00737 if (!dax_get_stringr_by_name(dop, "name", name_str, sizeof(name_str))) {
00738 dax_error(dop, "Read name ERROR!");
00739 dax_release_object(&dop);
00740 break;
00741 }
00742 if (!dax_get_stringr_by_name(dop, "address", addr_str,
00743 sizeof(addr_str))) {
00744 dax_error(cop, "Read address ERROR!");
00745 dax_release_object(&dop);
00746 break;
00747 }
00748 add_eq2_svc_gate(name_str, addr_str);
00749 }
00750
00751 exit_success:
00752 dax_release_object(&cop);
00753 }
00754
00759 static void
00760 read_eq2_svc_type (void)
00761 {
00762 ddl_handle_t *cop = NULL;
00763 ddl_handle_t *dop = NULL;
00764 const char *svc_type_config[] = { "sync", "equilibrium2", "service-type",
00765 NULL };
00766 char name_str[MAX_NAME_LEN];
00767 in_port_t port;
00768
00769 if (!dax_get_object_by_path(NULL, svc_type_config, &cop, FALSE)) {
00770 EQ2_TRACE(EQ2_TRACEFLAG_CONF, "%s: No service-type.", __func__);
00771 clear_eq2_svc_type();
00772 return;
00773 }
00774 if (!dax_is_changed(cop)) {
00775 EQ2_TRACE(EQ2_TRACEFLAG_CONF, "%s: No change.", __func__);
00776 goto exit_success;
00777 }
00778
00779
00780 clear_eq2_svc_type();
00781 while (dax_visit_container(cop, &dop)) {
00782 if (!dax_get_stringr_by_name(dop, "name", name_str, sizeof(name_str))) {
00783 dax_error(dop, "Read name ERROR!");
00784 dax_release_object(&dop);
00785 break;
00786 }
00787 if (!dax_get_ushort_by_name(dop, "port", &port)) {
00788 dax_error(dop, "Read port ERROR!");
00789 dax_release_object(&dop);
00790 break;
00791 }
00792 add_eq2_svc_type(name_str, port);
00793 }
00794
00795 exit_success:
00796 dax_release_object(&cop);
00797 }
00798
00803 static void
00804 read_eq2_svr_group (void)
00805 {
00806 ddl_handle_t *cop_group = NULL;
00807 ddl_handle_t *dop_group = NULL;
00808 ddl_handle_t *cop_addr = NULL;
00809 ddl_handle_t *dop_addr = NULL;
00810 const char *svr_group_config[] = { "sync", "equilibrium2", "server-group",
00811 NULL };
00812 const char *svr_config[] = { "servers", NULL };
00813 char name_str[MAX_NAME_LEN];
00814 char addr_str[MAX_NAME_LEN];
00815 svr_addr_head_t addr_head;
00816 svr_addr_t *addr;
00817 int addr_count = 0;
00818
00819 if (!dax_get_object_by_path(NULL, svr_group_config, &cop_group, FALSE)) {
00820 EQ2_TRACE(EQ2_TRACEFLAG_CONF, "%s: No server-group.", __func__);
00821 clear_eq2_svr_group();
00822 return;
00823 }
00824 if (!dax_is_changed(cop_group)) {
00825 EQ2_TRACE(EQ2_TRACEFLAG_CONF, "%s: No change.", __func__);
00826 goto exit_success;
00827 }
00828
00829
00830 clear_eq2_svr_group();
00831 LIST_INIT(&addr_head);
00832 while (dax_visit_container(cop_group, &dop_group)) {
00833 if (!dax_get_stringr_by_name(dop_group, "name", name_str,
00834 sizeof(name_str))) {
00835 dax_error(dop_group, "Read name ERROR!");
00836 dax_release_object(&dop_group);
00837 goto exit_success;
00838 }
00839 if (!dax_get_object_by_path(dop_group, svr_config, &cop_addr, FALSE)) {
00840 dax_error(cop_addr, "Read address list ERROR!");
00841 dax_release_object(&dop_group);
00842 goto exit_success;
00843 }
00844 addr_count = 0;
00845 while (dax_visit_container(cop_addr, &dop_addr)) {
00846 if (!dax_get_stringr_by_name(dop_addr, "address", addr_str,
00847 sizeof(addr_str))) {
00848 dax_error(dop_addr, "Read address list ERROR!");
00849 dax_release_object(&dop_addr);
00850 dax_release_object(&cop_addr);
00851 goto exit_success;
00852 }
00853 addr = calloc(1, sizeof(svr_addr_t));
00854 INSIST_ERR(addr != NULL);
00855 addr->addr = inet_addr(addr_str);
00856 LIST_INSERT_HEAD(&addr_head, addr, entry);
00857 addr_count++;
00858 EQ2_TRACE(EQ2_TRACEFLAG_CONF, "%s %s: %s", __func__,
00859 name_str, addr_str);
00860 }
00861 add_eq2_svr_group(name_str, &addr_head, addr_count);
00862 }
00863
00864 exit_success:
00865 dax_release_object(&cop_group);
00866 }
00867
00881 static int
00882 read_eq2_term (ddl_handle_t *top, svc_rule_t *rule)
00883 {
00884 const char *term_config[] = { "term", NULL };
00885 const char *from_config[] = { "from", NULL };
00886 const char *then_config[] = { "then", NULL };
00887 ddl_handle_t *cop_term = NULL;
00888 ddl_handle_t *dop_term = NULL;
00889 ddl_handle_t *dop_from = NULL;
00890 ddl_handle_t *dop_then = NULL;
00891 char term_name[MAX_NAME_LEN];
00892 char buf[MAX_NAME_LEN];
00893 char tog;
00894 svc_term_t *term;
00895
00896 EQ2_TRACE(EQ2_TRACEFLAG_CONF, "%s", __func__);
00897
00898 if (!dax_get_object_by_path(top, term_config, &cop_term, FALSE)) {
00899 dax_error(top, "Read term ERROR.");
00900 return -1;
00901 }
00902
00903 while (dax_visit_container(cop_term, &dop_term)) {
00904 if (!dax_get_stringr_by_name(dop_term, "name", term_name,
00905 sizeof(term_name))) {
00906 dax_error(dop_term, "Read term name ERROR!");
00907 dax_release_object(&dop_term);
00908 dax_release_object(&cop_term);
00909 return -1;
00910 }
00911
00912 term = calloc(1, sizeof(svc_term_t));
00913 INSIST_ERR(term != NULL);
00914 strlcpy(term->term_name, term_name, sizeof(term->term_name));
00915 LIST_INSERT_HEAD(&rule->rule_term_head, term, entry);
00916 rule->rule_term_count++;
00917
00918
00919 if (dax_get_object_by_path(dop_term, from_config, &dop_from, FALSE)) {
00920 if (dax_get_stringr_by_name(dop_from, "service-type", buf,
00921 sizeof(buf))) {
00922 term->term_match = TERM_FROM_SVC_TYPE;
00923 strlcpy(term->term_match_val, buf,
00924 sizeof(term->term_match_val));
00925 }
00926 if (dax_get_stringr_by_name(dop_from, "service-gate", buf,
00927 sizeof(buf))) {
00928 term->term_match = TERM_FROM_SVC_GATE;
00929 strlcpy(term->term_match_val, buf,
00930 sizeof(term->term_match_val));
00931 }
00932 if (dax_get_toggle_by_name(dop_from, "except", &tog)) {
00933 term->term_match |= TERM_FROM_EXCEPT;
00934 }
00935 dax_release_object(&dop_from);
00936 }
00937
00938
00939 if (dax_get_object_by_path(dop_term, then_config, &dop_then, FALSE)) {
00940 if (dax_get_toggle_by_name(dop_then, "accept", &tog)) {
00941 term->term_act = TERM_THEN_ACCEPT;
00942 } else if (dax_get_toggle_by_name(dop_then, "discard", &tog)) {
00943 term->term_act = TERM_THEN_DISCARD;
00944 } else if (dax_get_stringr_by_name(dop_then, "server-group", buf,
00945 sizeof(buf))) {
00946 term->term_act = TERM_THEN_SVR_GROUP;
00947 strlcpy(term->term_act_val, buf, sizeof(term->term_act_val));
00948 } else if (dax_get_stringr_by_name(dop_then, "service-gate", buf,
00949 sizeof(buf))) {
00950 term->term_act = TERM_THEN_SVC_GATE;
00951 strlcpy(term->term_act_val, buf, sizeof(term->term_act_val));
00952 }
00953 dax_release_object(&dop_then);
00954 }
00955 }
00956 dax_release_object(&cop_term);
00957 return 0;
00958 }
00959
00979 static int
00980 read_eq2_rule (dax_walk_data_t *dwd, ddl_handle_t *dop, int action, void *data)
00981 {
00982 char rule_name[MAX_NAME_LEN];
00983 svc_rule_head_t *rule_head = data;
00984 svc_rule_t *rule;
00985
00986 switch (action) {
00987 case DAX_ITEM_DELETE_ALL:
00988 EQ2_TRACE(EQ2_TRACEFLAG_CONF, "%s: Delete all rules.", __func__);
00989 clear_eq2_svc_rule(rule_head);
00990 return DAX_WALK_OK;
00991 break;
00992
00993 case DAX_ITEM_DELETE:
00994 if (!dax_get_stringr_by_dwd_ident(dwd, NULL, 0, rule_name,
00995 sizeof(rule_name))) {
00996 dax_error(dop, "Read rule name ERROR!");
00997 return DAX_WALK_ABORT;
00998 }
00999 EQ2_TRACE(EQ2_TRACEFLAG_CONF, "%s: Delete rule %s.", __func__,
01000 rule_name);
01001 del_eq2_svc_rule(get_eq2_svc_rule(rule_head, rule_name));
01002 break;
01003
01004 case DAX_ITEM_CHANGED:
01005 INSIST_ERR(dop != NULL);
01006 if (!dax_get_stringr_by_name(dop, "name", rule_name,
01007 sizeof(rule_name))) {
01008 dax_error(dop, "Read rule name ERROR!");
01009 return DAX_WALK_ABORT;
01010 }
01011 EQ2_TRACE(EQ2_TRACEFLAG_CONF, "%s: Change rule %s.", __func__,
01012 rule_name);
01013
01014
01015 del_eq2_svc_rule(get_eq2_svc_rule(rule_head, rule_name));
01016
01017
01018 rule = calloc(1, sizeof(svc_rule_t));
01019 INSIST_ERR(rule != NULL);
01020 strlcpy(rule->rule_name, rule_name, sizeof(rule->rule_name));
01021 LIST_INSERT_HEAD(rule_head, rule, entry);
01022
01023 if (read_eq2_term(dop, rule) < 0) {
01024 dax_error(NULL, "Read term ERROR!");
01025 return DAX_WALK_ABORT;
01026 }
01027 break;
01028
01029 case DAX_ITEM_UNCHANGED:
01030 EQ2_TRACE(EQ2_TRACEFLAG_CONF, "%s: No change.", __func__);
01031 break;
01032
01033 default:
01034 break;
01035 }
01036
01037 return DAX_WALK_OK;
01038 }
01039
01053 static uint16_t
01054 blob_cksum (void *buf, int len)
01055 {
01056 uint8_t *p = buf;
01057 uint32_t sum = 0;
01058
01059 while (len > 1) {
01060 sum += (*p << 8) + *(p + 1);
01061 len -= 2;
01062 p += 2;
01063 }
01064 if (len == 1) {
01065 sum += (*p << 8);
01066 }
01067
01068 while (sum >> 16)
01069 sum = (sum & 0xFFFF) + (sum >> 16);
01070
01071 sum = ~sum;
01072
01073 return (uint16_t)sum;
01074 }
01075
01080 static void
01081 pack_svr_group_blob (void)
01082 {
01083 svr_group_t *group;
01084 blob_svr_group_t *blob_svr_group;
01085 in_addr_t *blob_addr;
01086 svr_addr_t *addr;
01087 int addr_count = 0;
01088 int blob_size = 0;
01089
01090
01091 LIST_FOREACH(group, &svr_group_head, entry) {
01092 addr_count += group->group_addr_count;
01093 }
01094 blob_size = sizeof(blob_svr_group_set_t) +
01095 svr_group_count * sizeof(blob_svr_group_t) +
01096 addr_count * sizeof(in_addr_t);
01097 blob_svr_group_set = calloc(1, blob_size);
01098 INSIST_ERR(blob_svr_group_set != NULL);
01099
01100
01101 blob_svr_group_set->gs_cksum = 0;
01102 blob_svr_group_set->gs_size = htons(blob_size);
01103 blob_svr_group_set->gs_count = htons(svr_group_count);
01104
01105
01106 blob_svr_group = blob_svr_group_set->gs_group;
01107 LIST_FOREACH(group, &svr_group_head, entry) {
01108 strlcpy(blob_svr_group->group_name, group->group_name,
01109 sizeof(blob_svr_group->group_name));
01110 blob_svr_group->group_addr_count = htons(group->group_addr_count);
01111 EQ2_TRACE(EQ2_TRACEFLAG_CONF, "%s: Group %s with %d addresses.",
01112 __func__, group->group_name, group->group_addr_count);
01113
01114
01115 blob_addr = blob_svr_group->group_addr;
01116 LIST_FOREACH(addr, &group->group_addr_head, entry) {
01117 *blob_addr = addr->addr;
01118 EQ2_TRACE(EQ2_TRACEFLAG_CONF, "%s: 0x%08x", __func__,
01119 addr->addr);
01120 blob_addr++;
01121 }
01122 blob_svr_group = (blob_svr_group_t *)blob_addr;
01123 }
01124
01125 blob_svr_group_set->gs_cksum = blob_cksum(blob_svr_group_set, blob_size);
01126
01127 EQ2_TRACE(EQ2_TRACEFLAG_CONF, "%s: size %d, count %d.", __func__,
01128 blob_size, svr_group_count);
01129 }
01130
01141 static blob_svc_set_t *
01142 pack_svc_set_blob (svc_set_t *ss)
01143 {
01144 svc_rule_head_t *svc_rule_head;
01145 svc_set_rule_t *ss_rule;
01146 svc_rule_t *rule;
01147 svc_term_t *term;
01148 int rule_count;
01149 int term_count;
01150 blob_svc_set_t *blob_ss = NULL;
01151 blob_rule_t *blob_rule;
01152 blob_term_t *blob_term;
01153 int blob_size = 0;
01154
01155 switch (ss->ss_eq2_svc_id) {
01156 case EQ2_BALANCE_SVC:
01157 EQ2_TRACE(EQ2_TRACEFLAG_CONF, "%s: %s for balance service.", __func__,
01158 ss->ss_name);
01159 svc_rule_head = &balance_rule_head;
01160 break;
01161 case EQ2_CLASSIFY_SVC:
01162 EQ2_TRACE(EQ2_TRACEFLAG_CONF, "%s: %s for classify service.", __func__,
01163 ss->ss_name);
01164 svc_rule_head = &classify_rule_head;
01165 break;
01166 default:
01167 EQ2_LOG(TRACE_LOG_ERR, "%s: Unknown service %d!",
01168 __func__, ss->ss_eq2_svc_id);
01169 return NULL;
01170 }
01171
01172
01173 term_count = 0;
01174 LIST_FOREACH(ss_rule, &ss->ss_rule_head, entry) {
01175 rule = get_eq2_svc_rule(svc_rule_head, ss_rule->rule_name);
01176 INSIST_ERR(rule != NULL);
01177 term_count += rule->rule_term_count;
01178 }
01179 rule_count = ss->ss_rule_count;
01180 blob_size = sizeof(blob_svc_set_t) + rule_count * sizeof(blob_rule_t) +
01181 term_count * sizeof(blob_term_t);
01182 blob_ss = calloc(1, blob_size);
01183 INSIST_ERR(blob_ss != NULL);
01184
01185
01186 strlcpy(blob_ss->ss_name, ss->ss_name, sizeof(blob_ss->ss_name));
01187 strlcpy(blob_ss->ss_if_name, ss->ss_if_name, sizeof(blob_ss->ss_if_name));
01188 blob_ss->ss_size = htons(blob_size);
01189 blob_ss->ss_id = htons(ss->ss_id);
01190 blob_ss->ss_eq2_svc_id = ss->ss_eq2_svc_id;
01191 blob_ss->ss_rule_count = htons(rule_count);
01192
01193
01194 blob_rule = blob_ss->ss_rule;
01195 LIST_FOREACH(ss_rule, &ss->ss_rule_head, entry) {
01196 rule = get_eq2_svc_rule(svc_rule_head, ss_rule->rule_name);
01197 INSIST_ERR(rule != NULL);
01198 strlcpy(blob_rule->rule_name, ss_rule->rule_name,
01199 sizeof(blob_rule->rule_name));
01200 blob_rule->rule_term_count = htons(rule->rule_term_count);
01201
01202 EQ2_TRACE(EQ2_TRACEFLAG_CONF, "%s: Rule %s with %d terms.",
01203 __func__, ss_rule->rule_name, rule->rule_term_count);
01204
01205
01206 blob_term = blob_rule->rule_term;
01207 LIST_FOREACH(term, &rule->rule_term_head, entry) {
01208
01209
01210 strlcpy(blob_term->term_name, term->term_name,
01211 sizeof(blob_term->term_name));
01212
01213
01214 blob_term->term_match_id = term->term_match;
01215 switch (blob_term->term_match_id) {
01216 case TERM_FROM_SVC_TYPE:
01217 blob_term->term_match_port = htons(get_eq2_svc_type(
01218 term->term_match_val));
01219 EQ2_TRACE(EQ2_TRACEFLAG_CONF, "%s: Term %s, value %s, port %d.",
01220 __func__, term->term_name, term->term_match_val,
01221 get_eq2_svc_type(term->term_match_val));
01222 break;
01223 case TERM_FROM_SVC_GATE:
01224 blob_term->term_match_addr = get_eq2_svc_gate(
01225 term->term_match_val);
01226 EQ2_TRACE(EQ2_TRACEFLAG_CONF, "%s: Term %s, match value %s, "
01227 "addr %x.",
01228 __func__, term->term_name, term->term_match_val,
01229 get_eq2_svc_gate(term->term_match_val));
01230 break;
01231 default:
01232 EQ2_LOG(TRACE_LOG_ERR, "%s: Unknown match ID!", __func__);
01233 }
01234
01235
01236 blob_term->term_act_id = term->term_act;
01237 switch (blob_term->term_act_id) {
01238 case TERM_THEN_SVC_GATE:
01239 blob_term->term_act_addr = get_eq2_svc_gate(
01240 term->term_act_val);
01241 EQ2_TRACE(EQ2_TRACEFLAG_CONF, "%s: Term %s, act value %s, "
01242 "addr %x.",
01243 __func__, term->term_name, term->term_act_val,
01244 get_eq2_svc_gate(term->term_act_val));
01245 break;
01246 case TERM_THEN_SVR_GROUP:
01247 strlcpy(blob_term->term_act_group_name, term->term_act_val,
01248 sizeof(blob_term->term_act_group_name));
01249 EQ2_TRACE(EQ2_TRACEFLAG_CONF, "%s: Term %s, act value %s",
01250 __func__, term->term_name, term->term_act_val);
01251 break;
01252 default:
01253 EQ2_LOG(TRACE_LOG_ERR, "%s: Unknown action ID!", __func__);
01254 }
01255 blob_term++;
01256 }
01257 blob_rule = (blob_rule_t *)blob_term;
01258 }
01259
01260
01261 blob_ss->ss_cksum = blob_cksum(blob_ss, blob_size);
01262 EQ2_TRACE(EQ2_TRACEFLAG_CONF, "%s: blob size %d, rule %d.", __func__,
01263 blob_size, rule_count);
01264 return blob_ss;
01265 }
01266
01277 static void
01278 add_svc_set_blob (blob_svc_set_node_t *blob_ss_node,
01279 junos_kcom_pub_ssrb_t *ssrb)
01280 {
01281 config_blob_key_t key;
01282
01283 blob_ss_node->ss->ss_id = ntohs(ssrb->svc_set_id);
01284 blob_ss_node->ss->ss_gen_num = ntohl(ssrb->gen_num);
01285 blob_ss_node->ss->ss_svc_id = ntohl(ssrb->svc_id);
01286
01287 bzero(&key, sizeof(key));
01288 strlcpy(key.key_name, blob_ss_node->ss->ss_name, sizeof(key.key_name));
01289 key.key_tag = CONFIG_BLOB_SVC_SET;
01290 key.key_plugin_id = blob_ss_node->ss->ss_eq2_svc_id;
01291 kcom_add_config_blob(&key, blob_ss_node->ss);
01292
01293
01294 LIST_REMOVE(blob_ss_node, entry);
01295 free(blob_ss_node->ss);
01296 free(blob_ss_node);
01297 }
01298
01305 static void
01306 config_post_proc (void)
01307 {
01308 svc_set_t *ss;
01309 blob_svc_set_t *blob_ss;
01310 blob_svc_set_node_t *blob_ss_node, *blob_ss_node_tmp;
01311 ssrb_node_t *ssrb_node;
01312 config_blob_key_t key;
01313
01314
01315
01316
01317
01318 EQ2_TRACE(EQ2_TRACEFLAG_CONF, "%s: Build the list of service interface.",
01319 __func__);
01320 clear_svc_if();
01321 LIST_FOREACH(ss, &ss_head, entry) {
01322 add_svc_if(ss->ss_if_name);
01323 }
01324
01325
01326 pack_svr_group_blob();
01327
01328
01329
01330
01331 LIST_FOREACH(ss, &ss_head, entry) {
01332 blob_ss = pack_svc_set_blob(ss);
01333 if (blob_ss) {
01334 blob_ss_node = calloc(1, sizeof(blob_svc_set_node_t));
01335 INSIST_ERR(blob_ss_node != NULL);
01336 blob_ss_node->ss = blob_ss;
01337 LIST_INSERT_HEAD(&blob_ss_head, blob_ss_node, entry);
01338 }
01339 }
01340
01341
01342
01343
01344
01345 kcom_get_config_blob();
01346
01347
01348
01349
01350
01351
01352 if (blob_svr_group_set) {
01353 bzero(&key, sizeof(key));
01354 strlcpy(key.key_name, "server-group", sizeof(key.key_name));
01355 key.key_tag = CONFIG_BLOB_SVR_GROUP;
01356 key.key_plugin_id = EQ2_BALANCE_SVC;
01357 kcom_add_config_blob(&key, blob_svr_group_set);
01358 free(blob_svr_group_set);
01359 blob_svr_group_set = NULL;
01360 }
01361
01362
01363 LIST_FOREACH_SAFE(blob_ss_node, &blob_ss_head, entry, blob_ss_node_tmp) {
01364
01365
01366 ssrb_node = config_get_ssrb(blob_ss_node->ss->ss_name);
01367
01368 if (ssrb_node == NULL || ssrb_node->ssrb_state == SSRB_PENDING) {
01369
01370
01371
01372
01373
01374
01375
01376 continue;
01377 }
01378
01379
01380
01381
01382 add_svc_set_blob(blob_ss_node, &ssrb_node->ssrb);
01383 }
01384
01385
01386 LIST_FOREACH(ssrb_node, &ssrb_head, entry) {
01387 if (ssrb_node->ssrb_state == SSRB_UPDATED) {
01388 ssrb_node->ssrb_state = SSRB_IDLE;
01389 }
01390 }
01391 }
01392
01404 static bool
01405 check_ssrb (junos_kcom_pub_ssrb_t *ssrb)
01406 {
01407 ssrb_svc_info_t *info;
01408 int i;
01409
01410
01411 if (!ssrb->svc_order.fwd_flow_svc_order ||
01412 !ssrb->svc_order.rev_flow_svc_order) {
01413 return false;
01414 }
01415 info = ssrb->svc_order.fwd_flow_svc_order->elems;
01416 for (i = 0; i < ssrb->svc_order.fwd_flow_svc_order->num_elems; i++) {
01417 if ((strcmp(info->name, EQ2_BALANCE_SVC_NAME) == 0) ||
01418 (strcmp(info->name, EQ2_CLASSIFY_SVC_NAME) == 0)) {
01419 return true;
01420 }
01421 info++;
01422 }
01423 info = ssrb->svc_order.rev_flow_svc_order->elems;
01424 for (i = 0; i < ssrb->svc_order.rev_flow_svc_order->num_elems; i++) {
01425 if ((strcmp(info->name, EQ2_BALANCE_SVC_NAME) == 0) ||
01426 (strcmp(info->name, EQ2_CLASSIFY_SVC_NAME) == 0)) {
01427 return true;
01428 }
01429 info++;
01430 }
01431 return false;
01432 }
01433
01434
01435
01441 void
01442 config_init (void)
01443 {
01444 EQ2_TRACE(EQ2_TRACEFLAG_NORMAL, "%s: Initialize configuration.", __func__);
01445
01446 LIST_INIT(&svc_gate_head);
01447 LIST_INIT(&svr_group_head);
01448 svr_group_count = 0;
01449 LIST_INIT(&svc_type_head);
01450 LIST_INIT(&balance_rule_head);
01451 LIST_INIT(&classify_rule_head);
01452 LIST_INIT(&ss_head);
01453 LIST_INIT(&ssrb_head);
01454 LIST_INIT(&blob_ss_head);
01455 LIST_INIT(&svc_if_head);
01456 svc_if_count = 0;
01457 blob_svr_group_set = NULL;
01458 }
01459
01464 void
01465 config_clear (void)
01466 {
01467 clear_eq2_svc_gate();
01468 clear_eq2_svc_type();
01469 clear_eq2_svr_group();
01470 clear_eq2_svc_rule(&balance_rule_head);
01471 clear_eq2_svc_rule(&classify_rule_head);
01472 clear_svc_set();
01473 clear_ssrb_config();
01474 }
01475
01480 void
01481 clear_ssrb_config (void)
01482 {
01483 ssrb_node_t *ssrb;
01484
01485 while((ssrb = LIST_FIRST(&ssrb_head))) {
01486 LIST_REMOVE(ssrb, entry);
01487 free(ssrb);
01488 }
01489 }
01490
01504 int
01505 config_ssrb_op (junos_kcom_pub_ssrb_t *ssrb, config_ssrb_op_t op)
01506 {
01507 ssrb_node_t *ssrb_node;
01508 blob_svc_set_node_t *blob_ss_node;
01509
01510 if (!check_ssrb(ssrb)) {
01511 EQ2_TRACE(EQ2_TRACEFLAG_KCOM,
01512 "%s: SSRB doesn't contain Equilibrium II service.", __func__);
01513 return -1;
01514 }
01515
01516 switch (op) {
01517 case CONFIG_SSRB_ADD:
01518 EQ2_TRACE(EQ2_TRACEFLAG_KCOM, "%s: Add SSRB %s, ID %d", __func__,
01519 ssrb->svc_set_name, ssrb->svc_set_id);
01520
01521
01522 ssrb_node = config_get_ssrb(ssrb->svc_set_name);
01523 if (ssrb_node) {
01524 EQ2_TRACE(EQ2_TRACEFLAG_KCOM, "%s: SSRB exists.", __func__);
01525 return -1;
01526 }
01527
01528
01529 ssrb_node = calloc(1, sizeof(ssrb_node_t));
01530 INSIST_ERR(ssrb_node != NULL);
01531
01532 LIST_INSERT_HEAD(&ssrb_head, ssrb_node, entry);
01533 bcopy(ssrb, &ssrb_node->ssrb, sizeof(ssrb_node->ssrb));
01534
01535
01536 case CONFIG_SSRB_CHANGE:
01537 EQ2_TRACE(EQ2_TRACEFLAG_KCOM, "%s: Change SSRB %s, ID %d", __func__,
01538 ssrb->svc_set_name, ssrb->svc_set_id);
01539
01540
01541 ssrb_node = config_get_ssrb(ssrb->svc_set_name);
01542 if (!ssrb_node) {
01543 EQ2_TRACE(EQ2_TRACEFLAG_KCOM, "%s: SSRB doesn't exist.", __func__);
01544 return -1;
01545 }
01546
01547
01548 bcopy(ssrb, &ssrb_node->ssrb, sizeof(ssrb_node->ssrb));
01549 ssrb_node->ssrb_state = SSRB_UPDATED;
01550
01551
01552
01553
01554
01555
01556
01557
01558 blob_ss_node = get_svc_set_blob_node(ssrb->svc_set_name,
01559 EQ2_BALANCE_SVC);
01560 if (blob_ss_node) {
01561 add_svc_set_blob(blob_ss_node, ssrb);
01562 ssrb_node->ssrb_state = SSRB_IDLE;
01563 }
01564
01565
01566 blob_ss_node = get_svc_set_blob_node(ssrb->svc_set_name,
01567 EQ2_CLASSIFY_SVC);
01568 if (blob_ss_node) {
01569 add_svc_set_blob(blob_ss_node, ssrb);
01570 ssrb_node->ssrb_state = SSRB_IDLE;
01571 }
01572
01573 break;
01574 case CONFIG_SSRB_DEL:
01575 EQ2_TRACE(EQ2_TRACEFLAG_KCOM, "%s: Delete SSRB %s, ID %d", __func__,
01576 ssrb->svc_set_name, ssrb->svc_set_id);
01577
01578
01579 ssrb_node = config_get_ssrb(ssrb->svc_set_name);
01580 if (!ssrb_node) {
01581 EQ2_TRACE(EQ2_TRACEFLAG_KCOM, "%s: SSRB doesn't exist.", __func__);
01582 return -1;
01583 }
01584
01585
01586 LIST_REMOVE(ssrb_node, entry);
01587 free(ssrb_node);
01588 break;
01589 }
01590
01591 return 0;
01592 }
01593
01604 void
01605 config_svr_group_blob_proc (config_blob_key_t *key, void *blob)
01606 {
01607 blob_svr_group_set_t *blob_sg_set = blob;
01608
01609 if (!blob_svr_group_set) {
01610 return;
01611 }
01612
01613 if (blob_svr_group_set->gs_cksum == blob_sg_set->gs_cksum) {
01614 EQ2_TRACE(EQ2_TRACEFLAG_KCOM, "%s: Blob %s is not changed.",
01615 __func__, key->key_name);
01616
01617
01618 free(blob_svr_group_set);
01619 blob_svr_group_set = NULL;
01620 } else {
01621 EQ2_TRACE(EQ2_TRACEFLAG_KCOM, "%s: Blob %s is changed %d -> %d.",
01622 __func__, key->key_name, blob_sg_set->gs_cksum,
01623 blob_svr_group_set->gs_cksum);
01624
01625
01626 kcom_del_config_blob(key);
01627 }
01628 }
01629
01640 void
01641 config_svc_set_blob_proc (config_blob_key_t *key, void *blob)
01642 {
01643 blob_svc_set_t *blob_ss = blob;
01644 blob_svc_set_node_t *blob_ss_node;
01645
01646
01647 blob_ss_node = get_svc_set_blob_node(key->key_name, key->key_plugin_id);
01648
01649 if (blob_ss_node && (blob_ss_node->ss->ss_cksum == blob_ss->ss_cksum)) {
01650 EQ2_TRACE(EQ2_TRACEFLAG_KCOM, "%s: Blob %s %d is not changed.",
01651 __func__, key->key_name, key->key_plugin_id);
01652
01653
01654 LIST_REMOVE(blob_ss_node, entry);
01655 free(blob_ss_node->ss);
01656 free(blob_ss_node);
01657
01658 } else {
01659 if (blob_ss_node == NULL) {
01660 EQ2_TRACE(EQ2_TRACEFLAG_KCOM, "%s: %s %d is deleted.",
01661 __func__, key->key_name, key->key_plugin_id);
01662 } else {
01663 EQ2_TRACE(EQ2_TRACEFLAG_KCOM, "%s: %s %d is changed %d -> %d.",
01664 __func__, key->key_name, key->key_plugin_id,
01665 blob_ss->ss_cksum, blob_ss_node->ss->ss_cksum);
01666 }
01667
01668
01669
01670
01671
01672
01673
01674
01675 kcom_del_config_blob(key);
01676 }
01677 }
01678
01691 int
01692 eq2_config_read (int check)
01693 {
01694 ddl_handle_t *top = NULL;
01695 ddl_handle_t *dop = NULL;
01696 const char *svc_set_config[] = { "services", "service-set", NULL };
01697 const char *eq2_config[] = { "sync", "equilibrium2", NULL };
01698 const char *eq2_balance_rules_config[] = { "sync", "equilibrium2",
01699 "balance-rules", "rule", NULL };
01700 const char *eq2_classify_rules_config[] = { "sync", "equilibrium2",
01701 "classify-rules", "rule", NULL };
01702
01703
01704 if (junos_trace_read_config(check, eq2_config)) {
01705 dax_error(NULL, "Parsing equilibrium2 traceoptions ERROR!");
01706 return -1;
01707 }
01708
01709 EQ2_TRACE(EQ2_TRACEFLAG_CONF, "%s: Start reading config.", __func__);
01710
01711
01712 read_eq2_svc_gate();
01713
01714
01715 read_eq2_svr_group();
01716
01717
01718 read_eq2_svc_type();
01719
01720
01721 if (dax_get_object_by_path(NULL, eq2_balance_rules_config, &top, FALSE)) {
01722 EQ2_TRACE(EQ2_TRACEFLAG_CONF, "%s: Read balance rules.", __func__);
01723 if (dax_walk_list(top, DAX_WALK_DELTA, read_eq2_rule,
01724 &balance_rule_head) != DAX_WALK_OK) {
01725 dax_release_object(&top);
01726 dax_error(NULL, "Walk through equilibrium2 balance rules ERROR!");
01727 return -1;
01728 }
01729 dax_release_object(&top);
01730 }
01731
01732
01733 if (dax_get_object_by_path(NULL, eq2_classify_rules_config, &top, FALSE)) {
01734 EQ2_TRACE(EQ2_TRACEFLAG_CONF, "%s: Read classify rules.", __func__);
01735 if (dax_walk_list(top, DAX_WALK_DELTA, read_eq2_rule,
01736 &classify_rule_head) != DAX_WALK_OK) {
01737 dax_release_object(&top);
01738 dax_error(NULL, "Walk through equilibrium2 classify rules ERROR!");
01739 return -1;
01740 }
01741 dax_release_object(&top);
01742 }
01743
01744
01745
01746 clear_svc_set();
01747
01748
01749 if (dax_get_object_by_path(NULL, svc_set_config, &top, FALSE)) {
01750 while (dax_visit_container(top, &dop)) {
01751
01752
01753
01754
01755
01756 read_svc_set(dop);
01757 }
01758 dax_release_object(&top);
01759 }
01760
01761 if (!check) {
01762 config_post_proc();
01763 }
01764
01765 EQ2_TRACE(EQ2_TRACEFLAG_CONF, "%s: Configuration was loaded.", __func__);
01766
01767 return 0;
01768 }
01769