|
|
|
@@ -10,16 +10,25 @@
|
|
|
|
#include <netinet/in.h>
|
|
|
|
#include <netinet/in.h>
|
|
|
|
#include <netinet/if_ether.h>
|
|
|
|
#include <netinet/if_ether.h>
|
|
|
|
#include <net/if_arp.h>
|
|
|
|
#include <net/if_arp.h>
|
|
|
|
|
|
|
|
#include <netinet/ip.h>
|
|
|
|
|
|
|
|
#include <netinet/ip_icmp.h>
|
|
|
|
|
|
|
|
#include <net/if.h>
|
|
|
|
#include <arpa/inet.h>
|
|
|
|
#include <arpa/inet.h>
|
|
|
|
#include <errno.h>
|
|
|
|
#include <errno.h>
|
|
|
|
|
|
|
|
#include <linux/netlink.h>
|
|
|
|
|
|
|
|
#include <linux/rtnetlink.h>
|
|
|
|
|
|
|
|
#include <netinet/ether.h>
|
|
|
|
|
|
|
|
|
|
|
|
#include "log.h"
|
|
|
|
#include "log.h"
|
|
|
|
#include "uthash.h"
|
|
|
|
#include "uthash.h"
|
|
|
|
#include "bfd.h"
|
|
|
|
#include "bfd.h"
|
|
|
|
#include "sf_status.h"
|
|
|
|
#include "sf_status.h"
|
|
|
|
|
|
|
|
#include "utils.h"
|
|
|
|
#include "health_check.h"
|
|
|
|
#include "health_check.h"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define BUF_SIZE 4096
|
|
|
|
|
|
|
|
#define SEND_MAX 1
|
|
|
|
|
|
|
|
#define PACKET_SIZE 64
|
|
|
|
#define HC_MAC_LEN 6
|
|
|
|
#define HC_MAC_LEN 6
|
|
|
|
#define HC_DEV_NAME_LEN 16
|
|
|
|
#define HC_DEV_NAME_LEN 16
|
|
|
|
#define HC_LOCAL_ADDRESS_LEN 64
|
|
|
|
#define HC_LOCAL_ADDRESS_LEN 64
|
|
|
|
@@ -38,8 +47,7 @@ struct session_iterm
|
|
|
|
struct health_check policy; // value1: deep copy
|
|
|
|
struct health_check policy; // value1: deep copy
|
|
|
|
int is_active; // value2
|
|
|
|
int is_active; // value2
|
|
|
|
int profile_id; // value3
|
|
|
|
int profile_id; // value3
|
|
|
|
uint8_t mac[HC_MAC_LEN]; // value4
|
|
|
|
int vsys_id; // value4
|
|
|
|
int vsys_id; // value5
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
UT_hash_handle hh1; /* handle for first hash table */
|
|
|
|
UT_hash_handle hh1; /* handle for first hash table */
|
|
|
|
};
|
|
|
|
};
|
|
|
|
@@ -48,13 +56,14 @@ struct session_table_addr
|
|
|
|
{
|
|
|
|
{
|
|
|
|
// handler;
|
|
|
|
// handler;
|
|
|
|
struct node_addr *htable;
|
|
|
|
struct node_addr *htable;
|
|
|
|
|
|
|
|
pthread_rwlock_t rwlock;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
struct node_addr
|
|
|
|
struct node_addr
|
|
|
|
{
|
|
|
|
{
|
|
|
|
char address[64]; // key
|
|
|
|
char address[64]; // key
|
|
|
|
|
|
|
|
|
|
|
|
uint64_t session_id; // session id
|
|
|
|
uint8_t mac[HC_MAC_LEN];
|
|
|
|
int ref_cnt; // reference
|
|
|
|
int ref_cnt; // reference
|
|
|
|
|
|
|
|
|
|
|
|
UT_hash_handle hh; /* handle for first hash table */
|
|
|
|
UT_hash_handle hh; /* handle for first hash table */
|
|
|
|
@@ -62,11 +71,13 @@ struct node_addr
|
|
|
|
|
|
|
|
|
|
|
|
static uint64_t g_session_id;
|
|
|
|
static uint64_t g_session_id;
|
|
|
|
static struct session_table g_handle;
|
|
|
|
static struct session_table g_handle;
|
|
|
|
static struct session_table_addr g_handle_addr;
|
|
|
|
static struct session_table_addr g_handle_bfd;
|
|
|
|
|
|
|
|
static struct session_table_addr g_handle_none;
|
|
|
|
static struct sf_status *g_sf_status = NULL;
|
|
|
|
static struct sf_status *g_sf_status = NULL;
|
|
|
|
|
|
|
|
|
|
|
|
int sleep_ms = 300;
|
|
|
|
int sleep_ms = 300;
|
|
|
|
int enable = 1;
|
|
|
|
int enable = 1;
|
|
|
|
|
|
|
|
int icmp_cycle_time_s = 10;
|
|
|
|
char path[BFD_PATHLEN];
|
|
|
|
char path[BFD_PATHLEN];
|
|
|
|
char hc_dev_name[HC_DEV_NAME_LEN];
|
|
|
|
char hc_dev_name[HC_DEV_NAME_LEN];
|
|
|
|
char local_address[HC_LOCAL_ADDRESS_LEN];
|
|
|
|
char local_address[HC_LOCAL_ADDRESS_LEN];
|
|
|
|
@@ -76,31 +87,242 @@ uint8_t default_gw_mac[HC_MAC_LEN];
|
|
|
|
static int get_mac_by_addr(char *addr, uint8_t *buf);
|
|
|
|
static int get_mac_by_addr(char *addr, uint8_t *buf);
|
|
|
|
static int health_check_session_foreach();
|
|
|
|
static int health_check_session_foreach();
|
|
|
|
|
|
|
|
|
|
|
|
static void health_check_ref_inc(struct node_addr *node)
|
|
|
|
static int health_check_method_table_set_mac(struct session_table_addr *table, char *addr, uint8_t *mac)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
node->ref_cnt++;
|
|
|
|
struct node_addr *tmp = NULL;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pthread_rwlock_wrlock(&(table->rwlock));
|
|
|
|
|
|
|
|
HASH_FIND_STR(table->htable, addr, tmp);
|
|
|
|
|
|
|
|
if (tmp == NULL) {
|
|
|
|
|
|
|
|
pthread_rwlock_unlock(&(table->rwlock));
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
memcpy(tmp->mac, mac, HC_MAC_LEN);
|
|
|
|
|
|
|
|
pthread_rwlock_unlock(&(table->rwlock));
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int health_check_ref_dec(struct node_addr *node)
|
|
|
|
static int health_check_method_table_get_mac(struct session_table_addr *table, char *addr, uint8_t *out_mac)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
node->ref_cnt--;
|
|
|
|
struct node_addr *tmp = NULL;
|
|
|
|
return node->ref_cnt;
|
|
|
|
|
|
|
|
|
|
|
|
pthread_rwlock_rdlock(&(table->rwlock));
|
|
|
|
|
|
|
|
HASH_FIND_STR(table->htable, addr, tmp);
|
|
|
|
|
|
|
|
if (tmp == NULL) {
|
|
|
|
|
|
|
|
pthread_rwlock_unlock(&(table->rwlock));
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
memcpy(out_mac, tmp->mac, HC_MAC_LEN);
|
|
|
|
|
|
|
|
pthread_rwlock_unlock(&(table->rwlock));
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static struct session_iterm *health_check_get_iterm_by_id(uint64_t session_id)
|
|
|
|
static int health_check_method_table_del(struct session_table_addr *table, char *addr)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
struct session_iterm *tmp = NULL;
|
|
|
|
struct node_addr *tmp = NULL;
|
|
|
|
pthread_rwlock_rdlock(&g_handle.rwlock);
|
|
|
|
|
|
|
|
HASH_FIND(hh1, g_handle.root_by_id, &session_id, sizeof(session_id), tmp);
|
|
|
|
pthread_rwlock_wrlock(&(table->rwlock));
|
|
|
|
pthread_rwlock_unlock(&g_handle.rwlock);
|
|
|
|
HASH_FIND_STR(table->htable, addr, tmp);
|
|
|
|
return tmp;
|
|
|
|
if (tmp == NULL) {
|
|
|
|
|
|
|
|
pthread_rwlock_unlock(&(table->rwlock));
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (--tmp->ref_cnt) {
|
|
|
|
|
|
|
|
pthread_rwlock_unlock(&(table->rwlock));
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
HASH_DEL(table->htable, tmp);
|
|
|
|
|
|
|
|
free(tmp);
|
|
|
|
|
|
|
|
tmp = NULL;
|
|
|
|
|
|
|
|
pthread_rwlock_unlock(&(table->rwlock));
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static int health_check_method_table_add(struct session_table_addr *table, char *addr)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
struct node_addr *tmp = NULL;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pthread_rwlock_wrlock(&(table->rwlock));
|
|
|
|
|
|
|
|
HASH_FIND_STR(table->htable, addr, tmp);
|
|
|
|
|
|
|
|
if (tmp) {
|
|
|
|
|
|
|
|
tmp->ref_cnt++;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else {
|
|
|
|
|
|
|
|
tmp = (struct node_addr *)calloc(1, sizeof(struct node_addr));
|
|
|
|
|
|
|
|
assert(tmp);
|
|
|
|
|
|
|
|
snprintf(tmp->address, sizeof(tmp->address), addr);
|
|
|
|
|
|
|
|
tmp->ref_cnt++;
|
|
|
|
|
|
|
|
HASH_ADD_STR(table->htable, address, tmp);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
pthread_rwlock_unlock(&(table->rwlock));
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static int send_icmp_pkt(char *addr)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
int sockfd;
|
|
|
|
|
|
|
|
char packet[PACKET_SIZE] = {0};
|
|
|
|
|
|
|
|
struct ifreq ifr;
|
|
|
|
|
|
|
|
struct icmp *icmp = (struct icmp *)packet;
|
|
|
|
|
|
|
|
struct sockaddr_in dest_addr;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
|
|
|
|
|
|
|
|
if (sockfd < 0)
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
dest_addr.sin_family = AF_INET;
|
|
|
|
|
|
|
|
dest_addr.sin_port = 0;
|
|
|
|
|
|
|
|
if (inet_pton(AF_INET, addr, &(dest_addr.sin_addr)) <= 0) {
|
|
|
|
|
|
|
|
close(sockfd);
|
|
|
|
|
|
|
|
LOG_ERROR("unable to send icmp packet, address[%s] invalid!", addr);
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
memset(&ifr, 0, sizeof(ifr));
|
|
|
|
|
|
|
|
snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s", hc_dev_name);
|
|
|
|
|
|
|
|
if (setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE, (void *)&ifr, sizeof(ifr)) < 0) {
|
|
|
|
|
|
|
|
close(sockfd);
|
|
|
|
|
|
|
|
LOG_ERROR("unable to send icmp packet, device[%s] bind failed!", hc_dev_name);
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
icmp->icmp_type = ICMP_ECHO;
|
|
|
|
|
|
|
|
icmp->icmp_code = 0;
|
|
|
|
|
|
|
|
icmp->icmp_id = htons(getpid());
|
|
|
|
|
|
|
|
icmp->icmp_seq = 0;
|
|
|
|
|
|
|
|
icmp->icmp_cksum = 0;
|
|
|
|
|
|
|
|
int sum = checksum((uint16_t *)icmp, PACKET_SIZE);
|
|
|
|
|
|
|
|
icmp->icmp_cksum = CHECKSUM_CARRY(sum);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for(int i=0; i<SEND_MAX; i++){
|
|
|
|
|
|
|
|
sendto(sockfd, packet, PACKET_SIZE, 0, (struct sockaddr *)&dest_addr, sizeof(dest_addr));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
close(sockfd);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void *_listen_arp_table(void *arg)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
struct sockaddr_nl sa;
|
|
|
|
|
|
|
|
int nl_sock;
|
|
|
|
|
|
|
|
char buf[BUF_SIZE];
|
|
|
|
|
|
|
|
struct in_addr ipaddr;
|
|
|
|
|
|
|
|
uint8_t *mac = NULL;
|
|
|
|
|
|
|
|
char str_addr[INET_ADDRSTRLEN] = {0};
|
|
|
|
|
|
|
|
uint8_t init_mac[HC_MAC_LEN] = {0};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
start:
|
|
|
|
|
|
|
|
nl_sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
|
|
|
|
|
|
|
|
if (nl_sock < 0) {
|
|
|
|
|
|
|
|
LOG_ERROR("listen_arp_table: unable to create socket!");
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
memset(&sa, 0, sizeof(sa));
|
|
|
|
|
|
|
|
sa.nl_family = AF_NETLINK;
|
|
|
|
|
|
|
|
sa.nl_groups = RTMGRP_NEIGH;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (bind(nl_sock, (struct sockaddr *)&sa, sizeof(sa)) != 0) {
|
|
|
|
|
|
|
|
close(nl_sock);
|
|
|
|
|
|
|
|
LOG_ERROR("listen_arp_table: unable to bind!");
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
while (1) {
|
|
|
|
|
|
|
|
int len = recv(nl_sock, buf, sizeof(buf), 0);
|
|
|
|
|
|
|
|
if (len < 0) {
|
|
|
|
|
|
|
|
close(nl_sock);
|
|
|
|
|
|
|
|
goto start;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct nlmsghdr *nh;
|
|
|
|
|
|
|
|
for (nh = (struct nlmsghdr *)buf; NLMSG_OK(nh, len); nh = NLMSG_NEXT(nh, len)) {
|
|
|
|
|
|
|
|
if (nh->nlmsg_type == NLMSG_DONE)
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (nh->nlmsg_type == NLMSG_ERROR) {
|
|
|
|
|
|
|
|
close(nl_sock);
|
|
|
|
|
|
|
|
goto start;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct ndmsg *nd = (struct ndmsg *)NLMSG_DATA(nh);
|
|
|
|
|
|
|
|
struct rtattr *rth = (struct rtattr *)RTM_RTA(nd);
|
|
|
|
|
|
|
|
int rtl = RTM_PAYLOAD(nh);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
memset(&ipaddr, 0, sizeof(ipaddr));
|
|
|
|
|
|
|
|
mac = NULL;
|
|
|
|
|
|
|
|
for (; RTA_OK(rth, rtl); rth = RTA_NEXT(rth, rtl)) {
|
|
|
|
|
|
|
|
if (rth->rta_type == NDA_DST) {
|
|
|
|
|
|
|
|
memcpy(&ipaddr, RTA_DATA(rth), sizeof(struct in_addr));
|
|
|
|
|
|
|
|
} else if (rth->rta_type == NDA_LLADDR) {
|
|
|
|
|
|
|
|
mac = (uint8_t *)RTA_DATA(rth);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (inet_ntop(AF_INET, &ipaddr, str_addr, INET_ADDRSTRLEN) != NULL) {
|
|
|
|
|
|
|
|
if (mac == NULL) {
|
|
|
|
|
|
|
|
health_check_method_table_set_mac(&g_handle_bfd, str_addr, init_mac);
|
|
|
|
|
|
|
|
health_check_method_table_set_mac(&g_handle_none, str_addr, init_mac);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else {
|
|
|
|
|
|
|
|
health_check_method_table_set_mac(&g_handle_bfd, str_addr, mac);
|
|
|
|
|
|
|
|
health_check_method_table_set_mac(&g_handle_none, str_addr, mac);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
close(nl_sock);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static int listen_arp_table()
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
pthread_t pid;
|
|
|
|
|
|
|
|
pthread_create(&pid, NULL, _listen_arp_table, NULL);
|
|
|
|
|
|
|
|
pthread_detach(pid);
|
|
|
|
|
|
|
|
return pid;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void *_send_icmp_cycle(void *arg)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
struct node_addr *node = NULL;
|
|
|
|
|
|
|
|
struct node_addr *tmp = NULL;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
while (1) {
|
|
|
|
|
|
|
|
pthread_rwlock_rdlock(&g_handle_none.rwlock);
|
|
|
|
|
|
|
|
HASH_ITER(hh, g_handle_none.htable, node, tmp) {
|
|
|
|
|
|
|
|
send_icmp_pkt(node->address);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
pthread_rwlock_unlock(&g_handle_none.rwlock);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
sleep(icmp_cycle_time_s);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static int send_icmp_cycle()
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
pthread_t pid;
|
|
|
|
|
|
|
|
pthread_create(&pid, NULL, _send_icmp_cycle, NULL);
|
|
|
|
|
|
|
|
pthread_detach(pid);
|
|
|
|
|
|
|
|
return pid;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void health_check_session_init(const char *profile)
|
|
|
|
void health_check_session_init(const char *profile)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
memset(&g_handle, 0, sizeof(g_handle));
|
|
|
|
memset(&g_handle, 0, sizeof(g_handle));
|
|
|
|
pthread_rwlock_init(&g_handle.rwlock, NULL);
|
|
|
|
pthread_rwlock_init(&g_handle.rwlock, NULL);
|
|
|
|
|
|
|
|
memset(&g_handle_bfd, 0, sizeof(g_handle_bfd));
|
|
|
|
|
|
|
|
pthread_rwlock_init(&g_handle_bfd.rwlock, NULL);
|
|
|
|
|
|
|
|
memset(&g_handle_none, 0, sizeof(g_handle_none));
|
|
|
|
|
|
|
|
pthread_rwlock_init(&g_handle_none.rwlock, NULL);
|
|
|
|
MESA_load_profile_int_def(profile, "bfdd", "enable", &enable, 1);
|
|
|
|
MESA_load_profile_int_def(profile, "bfdd", "enable", &enable, 1);
|
|
|
|
|
|
|
|
MESA_load_profile_int_def(profile, "bfdd", "icmp_cycle_time_s", &icmp_cycle_time_s, 10);
|
|
|
|
MESA_load_profile_string_def(profile, "bfdd", "path", path, sizeof(path), "/var/run/frr/bfdd.vty");
|
|
|
|
MESA_load_profile_string_def(profile, "bfdd", "path", path, sizeof(path), "/var/run/frr/bfdd.vty");
|
|
|
|
MESA_load_profile_string_def(profile, "bfdd", "device", hc_dev_name, sizeof(hc_dev_name), "eth0");
|
|
|
|
MESA_load_profile_string_def(profile, "bfdd", "device", hc_dev_name, sizeof(hc_dev_name), "eth0");
|
|
|
|
MESA_load_profile_string_def(profile, "bfdd", "local_address", local_address, sizeof(local_address), "127.0.0.1");
|
|
|
|
MESA_load_profile_string_def(profile, "bfdd", "local_address", local_address, sizeof(local_address), "127.0.0.1");
|
|
|
|
@@ -112,9 +334,10 @@ void health_check_session_init(const char *profile)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
g_sf_status = sf_status_create(profile);
|
|
|
|
g_sf_status = sf_status_create(profile);
|
|
|
|
// TODO: 循环获取?
|
|
|
|
health_check_method_table_add(&g_handle_none, gateway_address);
|
|
|
|
get_mac_by_addr(gateway_address, default_gw_mac);
|
|
|
|
|
|
|
|
health_check_session_foreach();
|
|
|
|
health_check_session_foreach();
|
|
|
|
|
|
|
|
listen_arp_table();
|
|
|
|
|
|
|
|
send_icmp_cycle();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int health_check_session_recover_cfg(struct bfd_vtysh_client *client)
|
|
|
|
static int health_check_session_recover_cfg(struct bfd_vtysh_client *client)
|
|
|
|
@@ -148,38 +371,40 @@ static void health_check_session_recover_bfd(struct bfd_vtysh_client *client)
|
|
|
|
client->recover_config = health_check_session_recover_cfg;
|
|
|
|
client->recover_config = health_check_session_recover_cfg;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static struct node_addr *health_check_get_node_by_addr(const char *addr)
|
|
|
|
static int bfd_rule_add(const struct health_check *policy)
|
|
|
|
{
|
|
|
|
|
|
|
|
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;
|
|
|
|
int ret = 0;
|
|
|
|
struct node_addr *node = NULL;
|
|
|
|
struct bfd_vtysh_client client;
|
|
|
|
|
|
|
|
|
|
|
|
node = health_check_get_node_by_addr(addr);
|
|
|
|
health_check_session_init_bfd_client(&client);
|
|
|
|
if (node == NULL)
|
|
|
|
bfd_vtysh_connect(&client);
|
|
|
|
return 0;
|
|
|
|
ret = bfd_vtysh_add_dev(&client, policy->address, policy->retires, policy->interval_ms);
|
|
|
|
|
|
|
|
|
|
|
|
ret = health_check_ref_dec(node);
|
|
|
|
|
|
|
|
if (ret != 0)
|
|
|
|
if (ret != 0)
|
|
|
|
return 1;
|
|
|
|
LOG_ERROR("bfd vtysh add dev address [%s] failed!", policy->address);
|
|
|
|
|
|
|
|
bfd_vtysh_close(&client);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
HASH_DEL(g_handle_addr.htable, node);
|
|
|
|
static int bfd_rule_del(const struct health_check *policy)
|
|
|
|
free(node);
|
|
|
|
{
|
|
|
|
node = NULL;
|
|
|
|
int ret = 0;
|
|
|
|
return 0;
|
|
|
|
struct bfd_vtysh_client client;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
health_check_session_init_bfd_client(&client);
|
|
|
|
|
|
|
|
bfd_vtysh_connect(&client);
|
|
|
|
|
|
|
|
ret = bfd_vtysh_del_dev(&client, policy->address);
|
|
|
|
|
|
|
|
if (ret != 0) {
|
|
|
|
|
|
|
|
LOG_ERROR("bfd vtysh delete dev address [%s] failed!", policy->address);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
bfd_vtysh_close(&client);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static struct session_iterm *health_check_session_get(uint64_t session_id)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
struct session_iterm *tmp = NULL;
|
|
|
|
|
|
|
|
HASH_FIND(hh1, g_handle.root_by_id, &session_id, sizeof(session_id), tmp);
|
|
|
|
|
|
|
|
return tmp;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static uint64_t health_check_get_session_id()
|
|
|
|
static uint64_t health_check_get_session_id()
|
|
|
|
@@ -193,7 +418,7 @@ static uint64_t health_check_get_session_id()
|
|
|
|
g_session_id++;
|
|
|
|
g_session_id++;
|
|
|
|
if (tmp_session_id == g_session_id)
|
|
|
|
if (tmp_session_id == g_session_id)
|
|
|
|
return 0;
|
|
|
|
return 0;
|
|
|
|
tmp = health_check_get_iterm_by_id(g_session_id);
|
|
|
|
tmp = health_check_session_get(g_session_id);
|
|
|
|
if (tmp)
|
|
|
|
if (tmp)
|
|
|
|
continue;
|
|
|
|
continue;
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
@@ -206,18 +431,19 @@ static uint64_t health_check_get_session_id()
|
|
|
|
// struct health_check *policy : need deep copy
|
|
|
|
// struct health_check *policy : need deep copy
|
|
|
|
uint64_t health_check_session_add(int profile_id, int vsys_id, const struct health_check *policy)
|
|
|
|
uint64_t health_check_session_add(int profile_id, int vsys_id, const struct health_check *policy)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
int ret = 0;
|
|
|
|
|
|
|
|
uint64_t session_id = 0;
|
|
|
|
uint64_t session_id = 0;
|
|
|
|
struct bfd_vtysh_client client;
|
|
|
|
uint8_t mac[HC_MAC_LEN] = {0};
|
|
|
|
struct node_addr *node = NULL;
|
|
|
|
|
|
|
|
struct session_iterm *tmp = NULL;
|
|
|
|
struct session_iterm *tmp = NULL;
|
|
|
|
|
|
|
|
|
|
|
|
if (enable == 0)
|
|
|
|
if (enable == 0)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
return 1;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pthread_rwlock_wrlock(&g_handle.rwlock);
|
|
|
|
session_id = health_check_get_session_id();
|
|
|
|
session_id = health_check_get_session_id();
|
|
|
|
if (session_id == 0) {
|
|
|
|
if (session_id == 0) {
|
|
|
|
|
|
|
|
pthread_rwlock_unlock(&g_handle.rwlock);
|
|
|
|
LOG_ERROR("health check get session id failed!");
|
|
|
|
LOG_ERROR("health check get session id failed!");
|
|
|
|
return 0;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@@ -230,26 +456,18 @@ uint64_t health_check_session_add(int profile_id, int vsys_id, const struct heal
|
|
|
|
tmp->profile_id = profile_id;
|
|
|
|
tmp->profile_id = profile_id;
|
|
|
|
memcpy(&tmp->policy, policy, sizeof(struct health_check));
|
|
|
|
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);
|
|
|
|
HASH_ADD(hh1, g_handle.root_by_id, session_id, sizeof(tmp->session_id), tmp);
|
|
|
|
pthread_rwlock_unlock(&g_handle.rwlock);
|
|
|
|
pthread_rwlock_unlock(&g_handle.rwlock);
|
|
|
|
|
|
|
|
|
|
|
|
if (policy->method == HEALTH_CHECK_METHOD_BFD) {
|
|
|
|
if (policy->method == HEALTH_CHECK_METHOD_BFD) {
|
|
|
|
node = health_check_get_node_by_addr(policy->address);
|
|
|
|
health_check_method_table_add(&g_handle_bfd, tmp->policy.address);
|
|
|
|
if (node) {
|
|
|
|
bfd_rule_add(policy);
|
|
|
|
health_check_ref_inc(node);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
else if (policy->method == HEALTH_CHECK_METHOD_NONE) {
|
|
|
|
node = (struct node_addr *)calloc(1, sizeof(struct node_addr));
|
|
|
|
health_check_method_table_add(&g_handle_none, tmp->policy.address);
|
|
|
|
assert(node);
|
|
|
|
send_icmp_pkt(tmp->policy.address);
|
|
|
|
health_check_add_node_by_addr(node, policy->address, session_id);
|
|
|
|
get_mac_by_addr(tmp->policy.address, mac);
|
|
|
|
}
|
|
|
|
health_check_method_table_set_mac(&g_handle_none, tmp->policy.address, mac);
|
|
|
|
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: profile id [%d] session id [%lu] address [%s] success", profile_id, session_id, policy->address);
|
|
|
|
LOG_DEBUG("health check session table insert: profile id [%d] session id [%lu] address [%s] success", profile_id, session_id, policy->address);
|
|
|
|
@@ -261,7 +479,6 @@ uint64_t health_check_session_add(int profile_id, int vsys_id, const struct heal
|
|
|
|
int health_check_session_del(uint64_t session_id, int profile_id)
|
|
|
|
int health_check_session_del(uint64_t session_id, int profile_id)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
int ret = 0;
|
|
|
|
int ret = 0;
|
|
|
|
struct bfd_vtysh_client client;
|
|
|
|
|
|
|
|
struct session_iterm *tmp = NULL;
|
|
|
|
struct session_iterm *tmp = NULL;
|
|
|
|
|
|
|
|
|
|
|
|
if (enable == 0)
|
|
|
|
if (enable == 0)
|
|
|
|
@@ -269,35 +486,32 @@ int health_check_session_del(uint64_t session_id, int profile_id)
|
|
|
|
return 0;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
tmp = health_check_get_iterm_by_id(session_id);
|
|
|
|
pthread_rwlock_wrlock(&g_handle.rwlock);
|
|
|
|
|
|
|
|
tmp = health_check_session_get(session_id);
|
|
|
|
if (!tmp) {
|
|
|
|
if (!tmp) {
|
|
|
|
|
|
|
|
pthread_rwlock_unlock(&g_handle.rwlock);
|
|
|
|
LOG_DEBUG("health check session table delete: session id [%lu] not exists", session_id);
|
|
|
|
LOG_DEBUG("health check session table delete: session id [%lu] not exists", session_id);
|
|
|
|
return -1;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (tmp->policy.method == HEALTH_CHECK_METHOD_BFD) {
|
|
|
|
if (tmp->policy.method == HEALTH_CHECK_METHOD_BFD) {
|
|
|
|
ret = health_check_del_node_by_addr(tmp->policy.address);
|
|
|
|
ret = health_check_method_table_del(&g_handle_bfd, tmp->policy.address);
|
|
|
|
if (ret == 1)
|
|
|
|
if (ret != 0)
|
|
|
|
goto end;
|
|
|
|
goto end;
|
|
|
|
|
|
|
|
bfd_rule_del(&tmp->policy);
|
|
|
|
health_check_session_init_bfd_client(&client);
|
|
|
|
|
|
|
|
bfd_vtysh_connect(&client);
|
|
|
|
|
|
|
|
ret = bfd_vtysh_del_dev(&client, tmp->policy.address);
|
|
|
|
|
|
|
|
if (ret != 0) {
|
|
|
|
|
|
|
|
LOG_ERROR("bfd vtysh delete dev address [%s] failed!", tmp->policy.address);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
bfd_vtysh_close(&client);
|
|
|
|
else if (tmp->policy.method == HEALTH_CHECK_METHOD_NONE) {
|
|
|
|
|
|
|
|
ret = health_check_method_table_del(&g_handle_none, tmp->policy.address);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
end:
|
|
|
|
end:
|
|
|
|
pthread_rwlock_wrlock(&g_handle.rwlock);
|
|
|
|
|
|
|
|
HASH_DELETE(hh1, g_handle.root_by_id, tmp);
|
|
|
|
HASH_DELETE(hh1, g_handle.root_by_id, tmp);
|
|
|
|
sf_status_delete(g_sf_status, profile_id);
|
|
|
|
sf_status_delete(g_sf_status, profile_id);
|
|
|
|
pthread_rwlock_unlock(&g_handle.rwlock);
|
|
|
|
pthread_rwlock_unlock(&g_handle.rwlock);
|
|
|
|
free(tmp);
|
|
|
|
free(tmp);
|
|
|
|
tmp = NULL;
|
|
|
|
tmp = NULL;
|
|
|
|
|
|
|
|
|
|
|
|
LOG_DEBUG("health check session table delete: session id [%lu] success", session_id);
|
|
|
|
LOG_DEBUG("health check session table delete: profile id [%d] session id [%lu] success", profile_id, session_id);
|
|
|
|
return 0;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@@ -370,9 +584,7 @@ static int get_mac_by_addr(char *addr, uint8_t *buf)
|
|
|
|
return -1;
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
|
|
|
|
ret = ioctl(sfd, SIOCGARP, &arp_req);
|
|
|
|
ret = ioctl(sfd, SIOCGARP, &arp_req);
|
|
|
|
if (ret < 0)
|
|
|
|
if (ret == 0)
|
|
|
|
memcpy(buf, default_gw_mac, HC_MAC_LEN);
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
memcpy(buf, arp_req.arp_ha.sa_data, HC_MAC_LEN);
|
|
|
|
memcpy(buf, arp_req.arp_ha.sa_data, HC_MAC_LEN);
|
|
|
|
|
|
|
|
|
|
|
|
LOG_DEBUG("IP:%s, MAC: %02x:%02x:%02x:%02x:%02x:%02x",
|
|
|
|
LOG_DEBUG("IP:%s, MAC: %02x:%02x:%02x:%02x:%02x:%02x",
|
|
|
|
@@ -388,6 +600,9 @@ static void *_health_check_session_foreach(void *arg)
|
|
|
|
struct bfd_vtysh_client client;
|
|
|
|
struct bfd_vtysh_client client;
|
|
|
|
struct session_iterm *tmp = NULL;
|
|
|
|
struct session_iterm *tmp = NULL;
|
|
|
|
struct session_iterm *node = NULL;
|
|
|
|
struct session_iterm *node = NULL;
|
|
|
|
|
|
|
|
uint8_t mac[HC_MAC_LEN] = {0};
|
|
|
|
|
|
|
|
uint8_t init_mac[HC_MAC_LEN] = {0};
|
|
|
|
|
|
|
|
struct sockaddr_in addr;
|
|
|
|
|
|
|
|
|
|
|
|
struct timespec current_time;
|
|
|
|
struct timespec current_time;
|
|
|
|
struct timespec g_status_last_send_time;
|
|
|
|
struct timespec g_status_last_send_time;
|
|
|
|
@@ -399,13 +614,12 @@ static void *_health_check_session_foreach(void *arg)
|
|
|
|
bfd_vtysh_connect(&client);
|
|
|
|
bfd_vtysh_connect(&client);
|
|
|
|
|
|
|
|
|
|
|
|
while(1) {
|
|
|
|
while(1) {
|
|
|
|
// TODO: 改为读锁,更新数据入队列,通过写锁更新
|
|
|
|
|
|
|
|
pthread_rwlock_wrlock(&g_handle.rwlock);
|
|
|
|
pthread_rwlock_wrlock(&g_handle.rwlock);
|
|
|
|
HASH_ITER(hh1, g_handle.root_by_id, node, tmp) {
|
|
|
|
HASH_ITER(hh1, g_handle.root_by_id, node, tmp) {
|
|
|
|
if (node->policy.method != HEALTH_CHECK_METHOD_BFD)
|
|
|
|
if (node->policy.method != HEALTH_CHECK_METHOD_BFD)
|
|
|
|
continue;
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
if (strlen(node->policy.address) != 0) {
|
|
|
|
if (inet_pton(AF_INET, node->policy.address, &(addr.sin_addr)) > 0) {
|
|
|
|
is_active = bfd_vtysh_get_dev_active(&client, node->policy.address);
|
|
|
|
is_active = bfd_vtysh_get_dev_active(&client, node->policy.address);
|
|
|
|
if (is_active == -1) {
|
|
|
|
if (is_active == -1) {
|
|
|
|
bfd_vtysh_close(&client);
|
|
|
|
bfd_vtysh_close(&client);
|
|
|
|
@@ -424,10 +638,12 @@ static void *_health_check_session_foreach(void *arg)
|
|
|
|
if (node->is_active != is_active) {
|
|
|
|
if (node->is_active != is_active) {
|
|
|
|
node->is_active = is_active;
|
|
|
|
node->is_active = is_active;
|
|
|
|
if (node->is_active == 1) {
|
|
|
|
if (node->is_active == 1) {
|
|
|
|
get_mac_by_addr(node->policy.address, node->mac);
|
|
|
|
memset(mac, 0, HC_MAC_LEN);
|
|
|
|
|
|
|
|
get_mac_by_addr(node->policy.address, mac);
|
|
|
|
|
|
|
|
health_check_method_table_set_mac(&g_handle_bfd, node->policy.address, mac);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
else {
|
|
|
|
memset(node->mac, 0, sizeof(node->mac));
|
|
|
|
health_check_method_table_set_mac(&g_handle_bfd, node->policy.address, init_mac);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (sleep_ms > node->policy.interval_ms)
|
|
|
|
if (sleep_ms > node->policy.interval_ms)
|
|
|
|
@@ -452,6 +668,8 @@ static void *_health_check_session_foreach(void *arg)
|
|
|
|
// sleep_ms : 1000 ms
|
|
|
|
// sleep_ms : 1000 ms
|
|
|
|
else
|
|
|
|
else
|
|
|
|
{
|
|
|
|
{
|
|
|
|
|
|
|
|
int tmp_time = sleep_ms;
|
|
|
|
|
|
|
|
while(tmp_time > interval_s * 1000) {
|
|
|
|
usleep(interval_s * 1000 * 1000);
|
|
|
|
usleep(interval_s * 1000 * 1000);
|
|
|
|
|
|
|
|
|
|
|
|
clock_gettime(CLOCK_MONOTONIC, ¤t_time);
|
|
|
|
clock_gettime(CLOCK_MONOTONIC, ¤t_time);
|
|
|
|
@@ -460,7 +678,9 @@ static void *_health_check_session_foreach(void *arg)
|
|
|
|
sf_status_send(g_sf_status);
|
|
|
|
sf_status_send(g_sf_status);
|
|
|
|
clock_gettime(CLOCK_MONOTONIC, &g_status_last_send_time);
|
|
|
|
clock_gettime(CLOCK_MONOTONIC, &g_status_last_send_time);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
usleep(sleep_ms * 1000 - interval_s * 1000 * 1000);
|
|
|
|
tmp_time -= interval_s * 1000;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
usleep(tmp_time * 1000);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
bfd_vtysh_close(&client);
|
|
|
|
bfd_vtysh_close(&client);
|
|
|
|
@@ -475,12 +695,30 @@ static int health_check_session_foreach()
|
|
|
|
return pid;
|
|
|
|
return pid;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static const char *health_check_method_str(enum health_check_method method)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
switch (method) {
|
|
|
|
|
|
|
|
case HEALTH_CHECK_METHOD_NONE:
|
|
|
|
|
|
|
|
return "HEALTH_CHECK_METHOD_NONE";
|
|
|
|
|
|
|
|
case HEALTH_CHECK_METHOD_IN_BAND_BFD:
|
|
|
|
|
|
|
|
return "HEALTH_CHECK_METHOD_IN_BAND_BFD";
|
|
|
|
|
|
|
|
case HEALTH_CHECK_METHOD_BFD:
|
|
|
|
|
|
|
|
return "HEALTH_CHECK_METHOD_BFD";
|
|
|
|
|
|
|
|
case HEALTH_CHECK_METHOD_HTTP:
|
|
|
|
|
|
|
|
return "HEALTH_CHECK_METHOD_HTTP";
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// return 0 : success
|
|
|
|
// return 0 : success
|
|
|
|
// return -1 : key not exist
|
|
|
|
// return -1 : key not exist
|
|
|
|
int health_check_session_get_mac(uint64_t session_id, char *mac_buff)
|
|
|
|
int health_check_session_get_mac(uint64_t session_id, char *mac_buff)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
uint8_t *p = NULL;
|
|
|
|
uint8_t *p = NULL;
|
|
|
|
|
|
|
|
const char *str_method = NULL;
|
|
|
|
struct session_iterm *tmp = NULL;
|
|
|
|
struct session_iterm *tmp = NULL;
|
|
|
|
|
|
|
|
uint8_t mac[HC_MAC_LEN] = {0};
|
|
|
|
uint8_t init_mac[HC_MAC_LEN] = {0};
|
|
|
|
uint8_t init_mac[HC_MAC_LEN] = {0};
|
|
|
|
|
|
|
|
|
|
|
|
if (enable == 0)
|
|
|
|
if (enable == 0)
|
|
|
|
@@ -495,14 +733,31 @@ int health_check_session_get_mac(uint64_t session_id, char *mac_buff)
|
|
|
|
return -1;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
p = (uint8_t *)tmp->mac;
|
|
|
|
str_method = health_check_method_str(tmp->policy.method);
|
|
|
|
if (memcmp(p, init_mac, HC_MAC_LEN) == 0) {
|
|
|
|
if (tmp->policy.method == HEALTH_CHECK_METHOD_BFD && tmp->is_active == 0) {
|
|
|
|
|
|
|
|
LOG_DEBUG("health check session id [%lu] profile id [%d] health check method [%s] active is down", session_id, tmp->profile_id, str_method);
|
|
|
|
pthread_rwlock_unlock(&g_handle.rwlock);
|
|
|
|
pthread_rwlock_unlock(&g_handle.rwlock);
|
|
|
|
return -1;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
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 id [%lu] get mac [%s]", session_id, mac_buff);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (tmp->policy.method == HEALTH_CHECK_METHOD_BFD) {
|
|
|
|
|
|
|
|
health_check_method_table_get_mac(&g_handle_bfd, tmp->policy.address, mac);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else if (tmp->policy.method == HEALTH_CHECK_METHOD_NONE) {
|
|
|
|
|
|
|
|
health_check_method_table_get_mac(&g_handle_none, tmp->policy.address, mac);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (memcmp(mac, init_mac, HC_MAC_LEN) == 0) {
|
|
|
|
|
|
|
|
health_check_method_table_get_mac(&g_handle_none, gateway_address, mac);
|
|
|
|
|
|
|
|
if (memcmp(mac, init_mac, HC_MAC_LEN) == 0) {
|
|
|
|
|
|
|
|
LOG_DEBUG("health check session id [%lu] profile id [%d] health check method [%s] get mac [null]", session_id, tmp->profile_id, str_method);
|
|
|
|
|
|
|
|
pthread_rwlock_unlock(&g_handle.rwlock);
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
p = mac;
|
|
|
|
|
|
|
|
snprintf(mac_buff, 18, "%02x:%02x:%02x:%02x:%02x:%02x", p[0], p[1], p[2], p[3], p[4], p[5]);
|
|
|
|
|
|
|
|
LOG_DEBUG("health check session id [%lu] profile id [%d] health check method [%s] get mac [%s]", session_id, tmp->profile_id, str_method, mac_buff);
|
|
|
|
|
|
|
|
pthread_rwlock_unlock(&g_handle.rwlock);
|
|
|
|
return 0;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|