diff --git a/common/test/gtest_health_check_table.cpp b/common/test/gtest_health_check_table.cpp index 770b2dd..eb7224d 100644 --- a/common/test/gtest_health_check_table.cpp +++ b/common/test/gtest_health_check_table.cpp @@ -5,9 +5,13 @@ #include "policy.h" #include "health_check.h" - TEST(HEALTH_CHECK_TABLE, INSERT) { + uint64_t session_id1 = 0; + uint64_t session_id2 = 0; + uint64_t session_id3 = 0; + uint64_t session_id4 = 0; + uint64_t session_id5 = 0; // TEST Create health_check_session_init("./sce.conf"); @@ -18,8 +22,7 @@ TEST(HEALTH_CHECK_TABLE, INSERT) snprintf(policy1.address, sizeof(policy1.address), "1.1.1.1"); policy1.retires = 11; policy1.interval_ms = 111; - EXPECT_TRUE(health_check_session_add(1, &policy1) == 0); - EXPECT_TRUE(health_check_session_add(1, &policy1) == -1); + EXPECT_TRUE((session_id1 = health_check_session_add(1, &policy1)) > 0); struct health_check policy2; memset(&policy2, 0, sizeof(policy2)); @@ -27,8 +30,8 @@ TEST(HEALTH_CHECK_TABLE, INSERT) snprintf(policy2.address, sizeof(policy2.address), "2.2.2.2"); policy2.retires = 22; policy2.interval_ms = 222; - EXPECT_TRUE(health_check_session_add(2, &policy2) == 0); - EXPECT_TRUE(health_check_session_add(2, &policy2) == -1); + EXPECT_TRUE((session_id2 = health_check_session_add(2, &policy2)) > 0); + EXPECT_TRUE((session_id3 = health_check_session_add(3, &policy2)) > 0); struct health_check policy3; memset(&policy3, 0, sizeof(policy3)); @@ -36,17 +39,23 @@ TEST(HEALTH_CHECK_TABLE, INSERT) snprintf(policy3.address, sizeof(policy3.address), "2001:0db8:0000:0000:0000:8a2e:0370:7334"); policy3.retires = 33; policy3.interval_ms = 333; - EXPECT_TRUE(health_check_session_add(3, &policy3) == 0); - EXPECT_TRUE(health_check_session_add(3, &policy3) == -1); + EXPECT_TRUE((session_id4 = health_check_session_add(4, &policy3)) > 0); + EXPECT_TRUE((session_id5 = health_check_session_add(5, &policy3)) > 0); // TEST Delete By Session ID - EXPECT_TRUE(health_check_session_del(1) == 0); - EXPECT_TRUE(health_check_session_del(2) == 0); - EXPECT_TRUE(health_check_session_del(3) == 0); + EXPECT_TRUE(health_check_session_del(session_id1, 1) == 0); + EXPECT_TRUE(health_check_session_del(session_id2, 2) == 0); + EXPECT_TRUE(health_check_session_del(session_id3, 3) == 0); + EXPECT_TRUE(health_check_session_del(session_id4, 4) == 0); + EXPECT_TRUE(health_check_session_del(session_id5, 5) == 0); } TEST(HEALTH_CHECK_TABLE, GET_STATUS) { + uint64_t session_id1 = 0; + uint64_t session_id2 = 0; + uint64_t session_id3 = 0; + // TEST Insert struct health_check policy1; memset(&policy1, 0, sizeof(policy1)); @@ -54,7 +63,7 @@ TEST(HEALTH_CHECK_TABLE, GET_STATUS) snprintf(policy1.address, sizeof(policy1.address), "4.4.4.4"); policy1.retires = 5; policy1.interval_ms = 300; - EXPECT_TRUE(health_check_session_add(4, &policy1) == 0); + EXPECT_TRUE((session_id1 = health_check_session_add(1, &policy1)) > 0); struct health_check policy2; memset(&policy2, 0, sizeof(policy2)); @@ -62,7 +71,7 @@ TEST(HEALTH_CHECK_TABLE, GET_STATUS) snprintf(policy2.address, sizeof(policy2.address), "5.5.5.5"); policy2.retires = 5; policy2.interval_ms = 300; - EXPECT_TRUE(health_check_session_add(5, &policy2) == 0); + EXPECT_TRUE((session_id2 = health_check_session_add(2, &policy2)) > 0); struct health_check policy3; memset(&policy3, 0, sizeof(policy3)); @@ -70,22 +79,26 @@ TEST(HEALTH_CHECK_TABLE, GET_STATUS) snprintf(policy3.address, sizeof(policy3.address), "6.6.6.6"); policy3.retires = 5; policy3.interval_ms = 300; - EXPECT_TRUE(health_check_session_add(6, &policy3) == 0); + EXPECT_TRUE((session_id3 = health_check_session_add(3, &policy3)) > 0); // TEST get status - EXPECT_TRUE(health_check_session_get_status(4) == 0); - EXPECT_TRUE(health_check_session_get_status(5) == 0); - EXPECT_TRUE(health_check_session_get_status(6) == 0); + EXPECT_TRUE(health_check_session_get_status(session_id1) == 0); + EXPECT_TRUE(health_check_session_get_status(session_id2) == 0); + EXPECT_TRUE(health_check_session_get_status(session_id3) == 0); EXPECT_TRUE(health_check_session_get_status(7) == -1); // TEST Delete By Session ID - EXPECT_TRUE(health_check_session_del(4) == 0); - EXPECT_TRUE(health_check_session_del(5) == 0); - EXPECT_TRUE(health_check_session_del(6) == 0); + EXPECT_TRUE(health_check_session_del(session_id1, 1) == 0); + EXPECT_TRUE(health_check_session_del(session_id2, 2) == 0); + EXPECT_TRUE(health_check_session_del(session_id3, 3) == 0); } TEST(HEALTH_CHECK_TABLE, SET_STATUS) { + uint64_t session_id1 = 0; + uint64_t session_id2 = 0; + uint64_t session_id3 = 0; + // TEST Insert struct health_check policy1; memset(&policy1, 0, sizeof(policy1)); @@ -93,7 +106,7 @@ TEST(HEALTH_CHECK_TABLE, SET_STATUS) snprintf(policy1.address, sizeof(policy1.address), "7.7.7.7"); policy1.retires = 5; policy1.interval_ms = 300; - EXPECT_TRUE(health_check_session_add(7, &policy1) == 0); + EXPECT_TRUE((session_id1 = health_check_session_add(1, &policy1)) > 0); struct health_check policy2; memset(&policy2, 0, sizeof(policy2)); @@ -101,7 +114,7 @@ TEST(HEALTH_CHECK_TABLE, SET_STATUS) snprintf(policy2.address, sizeof(policy2.address), "8.8.8.8"); policy2.retires = 5; policy2.interval_ms = 300; - EXPECT_TRUE(health_check_session_add(8, &policy2) == 0); + EXPECT_TRUE((session_id2 = health_check_session_add(2, &policy2)) > 0); struct health_check policy3; memset(&policy3, 0, sizeof(policy3)); @@ -109,32 +122,39 @@ TEST(HEALTH_CHECK_TABLE, SET_STATUS) snprintf(policy3.address, sizeof(policy3.address), "9.9.9.9"); policy3.retires = 5; policy3.interval_ms = 300; - EXPECT_TRUE(health_check_session_add(9, &policy3) == 0); + EXPECT_TRUE((session_id3 = health_check_session_add(3, &policy3)) > 0); // TEST get status - EXPECT_TRUE(health_check_session_get_status(7) == 0); - EXPECT_TRUE(health_check_session_get_status(8) == 0); - EXPECT_TRUE(health_check_session_get_status(9) == 0); + EXPECT_TRUE(health_check_session_get_status(session_id1) == 0); + EXPECT_TRUE(health_check_session_get_status(session_id2) == 0); + EXPECT_TRUE(health_check_session_get_status(session_id3) == 0); // TEST set status - EXPECT_TRUE(health_check_session_set_status(7, 1) == 0); - EXPECT_TRUE(health_check_session_set_status(8, 1) == 0); - EXPECT_TRUE(health_check_session_set_status(9, 1) == 0); + EXPECT_TRUE(health_check_session_set_status(session_id1, 1) == 0); + EXPECT_TRUE(health_check_session_set_status(session_id2, 1) == 0); + EXPECT_TRUE(health_check_session_set_status(session_id3, 1) == 0); EXPECT_TRUE(health_check_session_set_status(10, 1) == -1); // TEST get status - EXPECT_TRUE(health_check_session_get_status(7) == 1); - EXPECT_TRUE(health_check_session_get_status(8) == 1); - EXPECT_TRUE(health_check_session_get_status(9) == 1); + EXPECT_TRUE(health_check_session_get_status(session_id1) == 1); + EXPECT_TRUE(health_check_session_get_status(session_id2) == 1); + EXPECT_TRUE(health_check_session_get_status(session_id3) == 1); // TEST Delete By Session ID - EXPECT_TRUE(health_check_session_del(7) == 0); - EXPECT_TRUE(health_check_session_del(8) == 0); - EXPECT_TRUE(health_check_session_del(9) == 0); + EXPECT_TRUE(health_check_session_del(session_id1, 1) == 0); + EXPECT_TRUE(health_check_session_del(session_id2, 2) == 0); + EXPECT_TRUE(health_check_session_del(session_id3, 3) == 0); } TEST(HEALTH_CHECK_TABLE, DELETE) { + uint64_t session_id1 = 0; + uint64_t session_id2 = 0; + uint64_t session_id3 = 0; + uint64_t session_id4 = 0; + uint64_t session_id5 = 0; + uint64_t session_id6 = 0; + // TEST Insert struct health_check policy1; memset(&policy1, 0, sizeof(policy1)); @@ -142,7 +162,7 @@ TEST(HEALTH_CHECK_TABLE, DELETE) snprintf(policy1.address, sizeof(policy1.address), "10.10.10.10"); policy1.retires = 5; policy1.interval_ms = 300; - EXPECT_TRUE(health_check_session_add(10, &policy1) == 0); + EXPECT_TRUE((session_id1 = health_check_session_add(1, &policy1)) > 0); struct health_check policy2; memset(&policy2, 0, sizeof(policy2)); @@ -150,7 +170,8 @@ TEST(HEALTH_CHECK_TABLE, DELETE) snprintf(policy2.address, sizeof(policy2.address), "11.11.11.11"); policy2.retires = 5; policy2.interval_ms = 300; - EXPECT_TRUE(health_check_session_add(11, &policy2) == 0); + EXPECT_TRUE((session_id2 = health_check_session_add(2, &policy2)) > 0); + EXPECT_TRUE((session_id3 = health_check_session_add(3, &policy2)) > 0); struct health_check policy3; memset(&policy3, 0, sizeof(policy3)); @@ -158,15 +179,20 @@ TEST(HEALTH_CHECK_TABLE, DELETE) snprintf(policy3.address, sizeof(policy3.address), "12.12.12.12"); policy3.retires = 5; policy3.interval_ms = 300; - EXPECT_TRUE(health_check_session_add(12, &policy3) == 0); + EXPECT_TRUE((session_id4 = health_check_session_add(4, &policy3)) > 0); + EXPECT_TRUE((session_id5 = health_check_session_add(5, &policy3)) > 0); + EXPECT_TRUE((session_id6 = health_check_session_add(6, &policy3)) > 0); // TEST Delete By Session ID - EXPECT_TRUE(health_check_session_del(10) == 0); - EXPECT_TRUE(health_check_session_del(10) == -1); - EXPECT_TRUE(health_check_session_del(11) == 0); - EXPECT_TRUE(health_check_session_del(11) == -1); - EXPECT_TRUE(health_check_session_del(12) == 0); - EXPECT_TRUE(health_check_session_del(12) == -1); + EXPECT_TRUE(health_check_session_del(session_id1, 1) == 0); + EXPECT_TRUE(health_check_session_del(session_id1, 1) == -1); + EXPECT_TRUE(health_check_session_del(session_id2, 2) == 0); + EXPECT_TRUE(health_check_session_del(session_id3, 3) == 0); + EXPECT_TRUE(health_check_session_del(session_id3, 3) == -1); + EXPECT_TRUE(health_check_session_del(session_id5, 4) == 0); + EXPECT_TRUE(health_check_session_del(session_id5, 5) == 0); + EXPECT_TRUE(health_check_session_del(session_id6, 6) == 0); + EXPECT_TRUE(health_check_session_del(session_id6, 6) == -1); } int main(int argc, char **argv) diff --git a/platform/include/health_check.h b/platform/include/health_check.h index 7081d87..e9003f3 100644 --- a/platform/include/health_check.h +++ b/platform/include/health_check.h @@ -13,24 +13,24 @@ void health_check_session_init(const char *profile); // return 0 : success // return -1 : key exist // struct health_check *policy : need deep copy -int health_check_session_add(int session_id, const struct health_check *policy); +uint64_t health_check_session_add(int profile_id, const struct health_check *policy); // return 0 : success // return -1 : key not exist -int health_check_session_del(int session_id); +int health_check_session_del(uint64_t session_id, int profile_id); // return 1 : active // return 0 : inactive // return -1 : key not exist -int health_check_session_get_status(int session_id); +int health_check_session_get_status(uint64_t session_id); // return 0 : success // return -1 : key not exist -int health_check_session_set_status(int session_id, int is_active); +int health_check_session_set_status(uint64_t session_id, int is_active); // return 0 : success // return -1 : key not exist -int health_check_session_get_mac(int session_id, char *mac_buff); +int health_check_session_get_mac(uint64_t session_id, char *mac_buff); #ifdef __cpluscplus } diff --git a/platform/include/policy.h b/platform/include/policy.h index faa3a77..dd7bccf 100644 --- a/platform/include/policy.h +++ b/platform/include/policy.h @@ -34,7 +34,6 @@ enum session_action_reason { ACTION_BYPASS_DUE_DEFAULT = 0x00, - ACTION_BYPASS_DUE_NO_AVAILABLE_SF = 0x11, ACTION_BYPASS_DUE_HEALTH_SF_LIMIT = 0x12, ACTION_BYPASS_DUE_UNAVAILABLE_ACTION = 0x13, ACTION_BYPASS_DUE_FAILURE_ACTION = 0x14, diff --git a/platform/src/health_check.cpp b/platform/src/health_check.cpp index 0346f3a..1912ec6 100644 --- a/platform/src/health_check.cpp +++ b/platform/src/health_check.cpp @@ -26,26 +26,44 @@ struct session_table { - // rwlock ???; // handler; struct session_iterm *root_by_id; pthread_rwlock_t rwlock; }; -static struct session_table g_handle; -static struct sf_status *g_sf_status = NULL; - struct session_iterm { - int session_id; // key + uint64_t session_id; // key - struct health_check policy; // value1: deep copy - int is_active; // value2 - uint8_t mac[HC_MAC_LEN]; // value3 + struct health_check policy; // value1: deep copy + int is_active; // value2 + int profile_id; // value3 + uint8_t mac[HC_MAC_LEN]; // value4 UT_hash_handle hh1; /* handle for first hash table */ }; +struct session_table_addr +{ + // handler; + struct node_addr *htable; +}; + +struct node_addr +{ + char address[64]; // key + + uint64_t session_id; // session id + int ref_cnt; // reference + + UT_hash_handle hh; /* handle for first hash table */ +}; + +static uint64_t g_session_id; +static struct session_table g_handle; +static struct session_table_addr g_handle_addr; +static struct sf_status *g_sf_status = NULL; + int sleep_ms = 300; char path[BFD_PATHLEN]; char hc_dev_name[HC_DEV_NAME_LEN]; @@ -56,7 +74,18 @@ uint8_t default_gw_mac[HC_MAC_LEN]; static int get_mac_by_addr(char *addr, uint8_t *buf); static int health_check_session_foreach(); -static struct session_iterm *health_check_get_iterm_by_id(int session_id) +static void health_check_ref_inc(struct node_addr *node) +{ + node->ref_cnt++; +} + +static int health_check_ref_dec(struct node_addr *node) +{ + node->ref_cnt--; + return node->ref_cnt; +} + +static struct session_iterm *health_check_get_iterm_by_id(uint64_t session_id) { struct session_iterm *tmp = NULL; pthread_rwlock_rdlock(&g_handle.rwlock); @@ -111,62 +140,130 @@ static void health_check_session_recover_bfd(struct bfd_vtysh_client *client) client->recover_config = health_check_session_recover_cfg; } -// return 0 : success -// return -1 : key exist -// struct health_check *policy : need deep copy -int health_check_session_add(int session_id, const struct health_check *policy) +static struct node_addr *health_check_get_node_by_addr(const char *addr) +{ + struct node_addr *tmp = NULL; + HASH_FIND_STR(g_handle_addr.htable, addr, tmp); + return tmp; +} + +static void health_check_add_node_by_addr(struct node_addr *node, const char *addr, uint64_t session_id) +{ + snprintf(node->address, sizeof(node->address), addr); + node->session_id = session_id; + health_check_ref_inc(node); + HASH_ADD_STR(g_handle_addr.htable, address, node); +} + +static int health_check_del_node_by_addr(const char *addr) { int ret = 0; + struct node_addr *node = NULL; + + node = health_check_get_node_by_addr(addr); + if (node == NULL) + return 0; + + ret = health_check_ref_dec(node); + if (ret != 0) + return 1; + + HASH_DEL(g_handle_addr.htable, node); + free(node); + node = NULL; + return 0; +} + +static uint64_t health_check_get_session_id() +{ + struct session_iterm *tmp = NULL; + uint64_t tmp_session_id = g_session_id; + + while(1) { + g_session_id++; + if (g_session_id == 0) + g_session_id++; + if (tmp_session_id == g_session_id) + return 0; + tmp = health_check_get_iterm_by_id(g_session_id); + if (tmp) + continue; + break; + } + return g_session_id; +} + +// return >0 : session id +// return 0 : fail +// struct health_check *policy : need deep copy +uint64_t health_check_session_add(int profile_id, const struct health_check *policy) +{ + int ret = 0; + uint64_t session_id = 0; struct bfd_vtysh_client client; + struct node_addr *node = NULL; struct session_iterm *tmp = NULL; - tmp = health_check_get_iterm_by_id(session_id); - if (tmp) { - LOG_DEBUG("health check session table insert: key %d exists", session_id); - return -1; + session_id = health_check_get_session_id(); + if (session_id == 0) { + LOG_ERROR("health check get session id failed!"); + return 0; } tmp = (struct session_iterm *)calloc(1, sizeof(struct session_iterm)); assert(tmp); - if (policy->method == HEALTH_CHECK_METHOD_BFD) { - health_check_session_init_bfd_client(&client); - bfd_vtysh_connect(&client); - ret = bfd_vtysh_add_dev(&client, policy->address, policy->retires, policy->interval_ms); - if (ret != 0) { - LOG_ERROR("bfd vtysh add dev address [%s] failed!", policy->address); - } - bfd_vtysh_close(&client); - } - - memset(tmp, 0, sizeof(*tmp)); tmp->session_id = session_id; + tmp->profile_id = profile_id; memcpy(&tmp->policy, policy, sizeof(struct health_check)); pthread_rwlock_wrlock(&g_handle.rwlock); HASH_ADD(hh1, g_handle.root_by_id, session_id, sizeof(tmp->session_id), tmp); pthread_rwlock_unlock(&g_handle.rwlock); - LOG_DEBUG("health check session table insert: key %d success", session_id); - return 0; + if (policy->method == HEALTH_CHECK_METHOD_BFD) { + node = health_check_get_node_by_addr(policy->address); + if (node) { + health_check_ref_inc(node); + } + else { + node = (struct node_addr *)calloc(1, sizeof(struct node_addr)); + assert(node); + + health_check_add_node_by_addr(node, policy->address, session_id); + health_check_session_init_bfd_client(&client); + bfd_vtysh_connect(&client); + ret = bfd_vtysh_add_dev(&client, policy->address, policy->retires, policy->interval_ms); + if (ret != 0) + LOG_ERROR("bfd vtysh add dev address [%s] failed!", policy->address); + bfd_vtysh_close(&client); + } + } + + LOG_DEBUG("health check session table insert: session id [%lu] success", session_id); + return session_id; } // return 0 : success // return -1 : key not exist -int health_check_session_del(int session_id) +int health_check_session_del(uint64_t session_id, int profile_id) { int ret = 0; struct bfd_vtysh_client client; struct session_iterm *tmp = NULL; - sf_status_delete(g_sf_status, session_id); + sf_status_delete(g_sf_status, profile_id); tmp = health_check_get_iterm_by_id(session_id); if (!tmp) { - LOG_DEBUG("health check session table delete: key %d not exists", session_id); + LOG_DEBUG("health check session table delete: session id [%lu] not exists", session_id); return -1; } if (tmp->policy.method == HEALTH_CHECK_METHOD_BFD) { + ret = health_check_del_node_by_addr(tmp->policy.address); + if (ret == 1) + goto end; + health_check_session_init_bfd_client(&client); bfd_vtysh_connect(&client); ret = bfd_vtysh_del_dev(&client, tmp->policy.address); @@ -176,20 +273,21 @@ int health_check_session_del(int session_id) bfd_vtysh_close(&client); } +end: pthread_rwlock_wrlock(&g_handle.rwlock); HASH_DELETE(hh1, g_handle.root_by_id, tmp); pthread_rwlock_unlock(&g_handle.rwlock); free(tmp); tmp = NULL; - LOG_DEBUG("health check session table delete: key %d success", session_id); + LOG_DEBUG("health check session table delete: session id [%lu] success", session_id); return 0; } // return 1 : active // return 0 : inactive // return -1 : key not exist -int health_check_session_get_status(int session_id) +int health_check_session_get_status(uint64_t session_id) { int status = 0; struct session_iterm *tmp = NULL; @@ -197,27 +295,27 @@ int health_check_session_get_status(int session_id) pthread_rwlock_rdlock(&g_handle.rwlock); HASH_FIND(hh1, g_handle.root_by_id, &session_id, sizeof(session_id), tmp); if (!tmp) { - LOG_DEBUG("health check session table get status: key %d not exists", session_id); + LOG_DEBUG("health check session table get status: session id [%lu] not exists", session_id); pthread_rwlock_unlock(&g_handle.rwlock); return -1; } status = tmp->is_active; pthread_rwlock_unlock(&g_handle.rwlock); - LOG_DEBUG("health check session get status: %d", status); + LOG_DEBUG("health check session id[%lu] get status [%d]", session_id, status); return status; } // return 0 : success // return -1 : key not exist -int health_check_session_set_status(int session_id, int is_active) +int health_check_session_set_status(uint64_t session_id, int is_active) { struct session_iterm *tmp = NULL; pthread_rwlock_wrlock(&g_handle.rwlock); HASH_FIND(hh1, g_handle.root_by_id, &session_id, sizeof(session_id), tmp); if (!tmp) { - LOG_DEBUG("health check session table get status: key %d not exists", session_id); + LOG_DEBUG("health check session table set status: session id [%lu] not exists", session_id); pthread_rwlock_unlock(&g_handle.rwlock); return -1; } @@ -245,7 +343,7 @@ static int get_mac_by_addr(char *addr, uint8_t *buf) saved_errno = errno; ret = ioctl(sfd, SIOCGARP, &arp_req); if (ret < 0) { - LOG_ERROR("Get ARP entry failed : %s\n", strerror(errno)); + LOG_ERROR("Get IP [%s] MAC failed : %s", addr, strerror(errno)); return -1; } errno = saved_errno; @@ -255,8 +353,8 @@ static int get_mac_by_addr(char *addr, uint8_t *buf) else memcpy(buf, default_gw_mac, HC_MAC_LEN); - LOG_DEBUG("MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", - buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]); + LOG_DEBUG("IP:%s, MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", + addr, buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]); return 0; } @@ -298,11 +396,11 @@ static void *_health_check_session_foreach(void *arg) node->is_active = is_active; if (node->is_active == 1) { get_mac_by_addr(node->policy.address, node->mac); - sf_status_update(g_sf_status, node->session_id, 1, 0); + sf_status_update(g_sf_status, node->profile_id, 1, 0); } else { memset(node->mac, 0, sizeof(node->mac)); - sf_status_update(g_sf_status, node->session_id, 0, 0); + sf_status_update(g_sf_status, node->profile_id, 0, 0); } } if (sleep_ms > node->policy.interval_ms) @@ -352,7 +450,7 @@ static int health_check_session_foreach() // return 0 : success // return -1 : key not exist -int health_check_session_get_mac(int session_id, char *mac_buff) +int health_check_session_get_mac(uint64_t session_id, char *mac_buff) { uint8_t *p = NULL; struct session_iterm *tmp = NULL; @@ -361,7 +459,7 @@ int health_check_session_get_mac(int session_id, char *mac_buff) pthread_rwlock_rdlock(&g_handle.rwlock); HASH_FIND(hh1, g_handle.root_by_id, &session_id, sizeof(session_id), tmp); if (!tmp) { - LOG_DEBUG("health check session table get status: key %d not exists", session_id); + LOG_DEBUG("health check session get mac: session id [%lu] not exists", session_id); pthread_rwlock_unlock(&g_handle.rwlock); return -1; } @@ -373,7 +471,7 @@ int health_check_session_get_mac(int session_id, char *mac_buff) } snprintf(mac_buff, 18, "%02x:%02x:%02x:%02x:%02x:%02x", p[0], p[1], p[2], p[3], p[4], p[5]); pthread_rwlock_unlock(&g_handle.rwlock); - LOG_DEBUG("health check session get mac: %s", mac_buff); + LOG_DEBUG("health check session id [%lu] get mac [%s]", session_id, mac_buff); return 0; } \ No newline at end of file diff --git a/platform/src/policy.cpp b/platform/src/policy.cpp index 6705b37..8db3015 100644 --- a/platform/src/policy.cpp +++ b/platform/src/policy.cpp @@ -142,6 +142,8 @@ struct sf_param enum admin_status sf_admin_status; struct connectivity sf_connectivity; struct health_check sf_health_check; + + uint64_t health_check_session_id; }; /****************************************************************************** @@ -199,8 +201,6 @@ const char *session_action_reason_to_string(enum session_action_reason session_a { case ACTION_BYPASS_DUE_DEFAULT: return "bypass_due_default"; - case ACTION_BYPASS_DUE_NO_AVAILABLE_SF: - return "bypass_due_no_available_sf"; case ACTION_BYPASS_DUE_HEALTH_SF_LIMIT: return "bypass_due_health_sf_limit"; case ACTION_BYPASS_DUE_UNAVAILABLE_ACTION: @@ -911,7 +911,7 @@ static void sf_param_new_cb(int table_id, const char *key, const char *table_lin param->sf_health_check.retires = item->valueint; LOG_DEBUG("%s: parse sf profile: %d, health_check->retires: %d", LOG_TAG_POLICY, param->sf_profile_id, item->valueint); } - health_check_session_add(param->sf_profile_id, ¶m->sf_health_check); + param->health_check_session_id = health_check_session_add(param->sf_profile_id, ¶m->sf_health_check); *ad = param; LOG_INFO("%s: Add sf profile: %d", LOG_TAG_POLICY, param->sf_profile_id); @@ -950,7 +950,7 @@ static void sf_param_free_cb(int table_id, MAAT_PLUGIN_EX_DATA *ad, long argl, v if ((__sync_sub_and_fetch(¶m->sf_ref_cnt, 1) == 0)) { - health_check_session_del(param->sf_profile_id); + health_check_session_del(param->health_check_session_id, param->sf_profile_id); LOG_INFO("%s: Del sf profile: %d", LOG_TAG_POLICY, param->sf_profile_id); free(param); param = NULL; @@ -1019,15 +1019,18 @@ static void select_sf_by_nearby_and_active(struct policy_enforcer *enforcer, str // return : SESSION_ACTION_BYPASS, not care selected_sf_profile_id // return : SESSION_ACTION_BLOCK, not care selected_sf_profile_id // return : SESSION_ACTION_FORWARD, care selected_sf_profile_id -static enum session_action select_sf_by_ldbc(uint64_t hash, struct sff_param *sff_param, struct fixed_num_array *array, int *selected_sf_profile_id, enum session_action_reason *sf_action_reason, char *sf_dst_mac, struct session_ctx *s_ctx) +static enum session_action select_sf_by_ldbc(uint64_t hash, struct policy_enforcer *enforcer, struct sff_param *sff_param, struct fixed_num_array *array, int *selected_sf_profile_id, enum session_action_reason *sf_action_reason, char *sf_dst_mac, struct session_ctx *s_ctx) { struct thread_ctx *thread = (struct thread_ctx *)s_ctx->ref_thread_ctx; struct global_metrics *g_metrics = thread->ref_metrics; + struct sf_param *sf = NULL; + char buffer[16]; *selected_sf_profile_id = -1; int sf_profile_id = 0; int sf_profile_index = 0; int sf_profile_num = 0; + uint64_t health_check_session_id = 0; sf_profile_num = fixed_num_array_count_elem(array); @@ -1036,8 +1039,20 @@ static enum session_action select_sf_by_ldbc(uint64_t hash, struct sff_param *sf sf_profile_index = (int)(hash % sf_profile_num); sf_profile_id = fixed_num_array_index_elem(array, sf_profile_index); + memset(&buffer, 0, sizeof(buffer)); + snprintf(buffer, sizeof(buffer), "%u", sf_profile_id); + sf = (struct sf_param *)Maat_plugin_get_EX_data(enforcer->maat, enforcer->sf_table_id, buffer); + if (sf == NULL) + { + LOG_ERROR("%s: failed to get sf parameter of profile %d", LOG_TAG_POLICY, sf_profile_id); + fixed_num_array_del_elem(array, sf_profile_id); + continue; + } + health_check_session_id = sf->health_check_session_id; + sf_param_free(sf); + memset(sf_dst_mac, 0, 32); - if (health_check_session_get_mac(sf_profile_id, sf_dst_mac) == 0) + if (health_check_session_get_mac(health_check_session_id, sf_dst_mac) == 0) { __atomic_fetch_add(&g_metrics->sf_active_times, 1, __ATOMIC_RELAXED); @@ -1095,7 +1110,7 @@ static enum session_action select_sf_by_ldbc(uint64_t hash, struct sff_param *sf } }; - *sf_action_reason = ACTION_BYPASS_DUE_NO_AVAILABLE_SF; + *sf_action_reason = ACTION_BYPASS_DUE_INVALID_POLICY; return SESSION_ACTION_BYPASS; } @@ -1477,7 +1492,7 @@ void policy_enforce_select_chaining(struct selected_chaining *chaining, struct p } hash_value = raw_packet_parser_get_hash_value(parser, sff_param->sff_ldbc.method, dir_is_internal); - item->sf_action = select_sf_by_ldbc(hash_value, sff_param, &array, &(item->sf_profile_id), &(item->sf_action_reason), item->sf_dst_mac, s_ctx); + item->sf_action = select_sf_by_ldbc(hash_value, enforcer, sff_param, &array, &(item->sf_profile_id), &(item->sf_action_reason), item->sf_dst_mac, s_ctx); LOG_DEBUG("%s: chaining policy %d -> sff_profile %d sf_profile_ids_num %d (after filter ldbc)", LOG_TAG_POLICY, policy_id, item->sff_profile_id, fixed_num_array_count_elem(&array)); if (item->sf_action != SESSION_ACTION_FORWARD) {