支持bfd
This commit is contained in:
@@ -6,7 +6,22 @@ extern "C"
|
|||||||
{
|
{
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// TODO
|
#define BFD_PATHLEN 108
|
||||||
|
|
||||||
|
struct bfd_vtysh_client {
|
||||||
|
int fd;
|
||||||
|
char path[BFD_PATHLEN];
|
||||||
|
|
||||||
|
// exec after connect server
|
||||||
|
int (*pre_config)(struct bfd_vtysh_client *);
|
||||||
|
};
|
||||||
|
|
||||||
|
int bfd_vtysh_connect(struct bfd_vtysh_client *client);
|
||||||
|
void bfd_vtysh_close(struct bfd_vtysh_client *client);
|
||||||
|
int bfd_vtysh_add_dev(struct bfd_vtysh_client *client, const char *local_addr, const char *peer_addr, int retires, int interval_ms);
|
||||||
|
int bfd_vtysh_del_dev(struct bfd_vtysh_client *client, const char *local_addr, char *peer_addr);
|
||||||
|
int bfd_vtysh_get_dev_active(struct bfd_vtysh_client *client, char *addr);
|
||||||
|
int bfd_vtysh_pre_config(struct bfd_vtysh_client *client);
|
||||||
|
|
||||||
#ifdef __cpluscplus
|
#ifdef __cpluscplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,301 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/un.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/uio.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include "log.h"
|
||||||
#include "bfd.h"
|
#include "bfd.h"
|
||||||
|
|
||||||
// TODO
|
// return 0 : success
|
||||||
|
// return -1 : fail
|
||||||
|
int bfd_vtysh_connect(struct bfd_vtysh_client *client)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
int sock, len;
|
||||||
|
struct stat s_stat;
|
||||||
|
struct sockaddr_un addr;
|
||||||
|
|
||||||
|
/* Stat socket to see if we have permission to access it. */
|
||||||
|
ret = stat(client->path, &s_stat);
|
||||||
|
if (ret < 0 && errno != ENOENT) {
|
||||||
|
LOG_DEBUG("bfd vtysh_connect(%s): stat = %s", client->path, strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret >= 0) {
|
||||||
|
if (!S_ISSOCK(s_stat.st_mode)) {
|
||||||
|
LOG_DEBUG("bfd vtysh_connect(%s): Not a socket", client->path);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sock = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||||
|
if (sock < 0) {
|
||||||
|
LOG_DEBUG("bfd vtysh_connect(%s): socket = %s", client->path, strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&addr, 0, sizeof(addr));
|
||||||
|
addr.sun_family = AF_UNIX;
|
||||||
|
strncpy(addr.sun_path, client->path, sizeof(addr.sun_path));
|
||||||
|
len = sizeof(addr.sun_family) + strlen(addr.sun_path);
|
||||||
|
|
||||||
|
ret = connect(sock, (struct sockaddr *)&addr, len);
|
||||||
|
if (ret < 0) {
|
||||||
|
LOG_DEBUG("bfd vtysh_connect(%s): connect = %s", client->path, strerror(errno));
|
||||||
|
close(sock);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
client->fd = sock;
|
||||||
|
|
||||||
|
if (client->pre_config) {
|
||||||
|
ret = client->pre_config(client);
|
||||||
|
if (ret < 0)
|
||||||
|
bfd_vtysh_close(client);
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_DEBUG("bfd vtysh_connect(%d): succ", client->fd);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// return 0 : success
|
||||||
|
// return -1 : fail
|
||||||
|
void bfd_vtysh_close(struct bfd_vtysh_client *client)
|
||||||
|
{
|
||||||
|
if (client->fd >= 0) {
|
||||||
|
close(client->fd);
|
||||||
|
client->fd = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int bfd_vtysh_client_send(struct bfd_vtysh_client *client, const char *line)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
ret = write(client->fd, line, strlen(line) + 1);
|
||||||
|
if (ret <= 0) {
|
||||||
|
/* close connection and try to reconnect */
|
||||||
|
bfd_vtysh_close(client);
|
||||||
|
ret = bfd_vtysh_connect(client);
|
||||||
|
if (ret < 0)
|
||||||
|
return -1;
|
||||||
|
/* retry line */
|
||||||
|
ret = write(client->fd, line, strlen(line) + 1);
|
||||||
|
if (ret <= 0)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t bfd_vtysh_client_receive(struct bfd_vtysh_client *client, char *buf, size_t bufsz)
|
||||||
|
{
|
||||||
|
struct iovec iov[1] = {
|
||||||
|
{
|
||||||
|
.iov_base = buf,
|
||||||
|
.iov_len = bufsz,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
union {
|
||||||
|
uint8_t buf[CMSG_SPACE(sizeof(int))];
|
||||||
|
struct cmsghdr align;
|
||||||
|
} u;
|
||||||
|
struct msghdr mh = {
|
||||||
|
.msg_iov = iov,
|
||||||
|
.msg_iovlen = 1,
|
||||||
|
.msg_control = u.buf,
|
||||||
|
.msg_controllen = sizeof(u.buf),
|
||||||
|
};
|
||||||
|
struct cmsghdr *cmh = CMSG_FIRSTHDR(&mh);
|
||||||
|
ssize_t ret;
|
||||||
|
|
||||||
|
cmh->cmsg_level = SOL_SOCKET;
|
||||||
|
cmh->cmsg_type = SCM_RIGHTS;
|
||||||
|
cmh->cmsg_len = CMSG_LEN(sizeof(int));
|
||||||
|
memset(CMSG_DATA(cmh), -1, sizeof(int));
|
||||||
|
|
||||||
|
do {
|
||||||
|
ret = recvmsg(client->fd, &mh, 0);
|
||||||
|
if (ret >= 0 || (errno != EINTR && errno != EAGAIN))
|
||||||
|
break;
|
||||||
|
} while (1);
|
||||||
|
|
||||||
|
if (cmh->cmsg_len == CMSG_LEN(sizeof(int))) {
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
memcpy(&fd, CMSG_DATA(cmh), sizeof(int));
|
||||||
|
if (fd != -1)
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int bfd_vtysh_cmd_exec(struct bfd_vtysh_client *client, const char *cmd, char *data, size_t datasz)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
char *bufvalid;
|
||||||
|
char *buf = data;
|
||||||
|
|
||||||
|
ret = bfd_vtysh_client_send(client, cmd);
|
||||||
|
if (ret < 0)
|
||||||
|
goto out_err;
|
||||||
|
|
||||||
|
// if (data == NULL)
|
||||||
|
// return 0;
|
||||||
|
|
||||||
|
bufvalid = buf;
|
||||||
|
do {
|
||||||
|
ssize_t nread;
|
||||||
|
nread = bfd_vtysh_client_receive(client, bufvalid, datasz-1);
|
||||||
|
if (nread < 0 && (errno == EINTR || errno == EAGAIN))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (nread <= 0) {
|
||||||
|
LOG_DEBUG("bfd vtysh_receive: error reading from [%s] (%d)", strerror(errno), errno);
|
||||||
|
goto out_err;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
// LOG_DEBUG("bfd cmd [%s] nread[%d]", cmd, nread);
|
||||||
|
// bufvalid += nread;
|
||||||
|
// bufvalid[0] = '\0';
|
||||||
|
// if (bufvalid - buf >= 4)
|
||||||
|
// end = (char*)memmem(bufvalid - 4, 4, "\0", 1);
|
||||||
|
// size_t textlen = (end ? end : bufvalid) - buf;
|
||||||
|
|
||||||
|
// LOG_DEBUG("bfd cmd [%s] buf[%s]", cmd, buf);
|
||||||
|
// memmove(buf, buf + textlen, bufvalid - buf - textlen);
|
||||||
|
// bufvalid -= textlen;
|
||||||
|
// if (end)
|
||||||
|
// end -= textlen;
|
||||||
|
|
||||||
|
// assert(((buf == bufvalid)
|
||||||
|
// || (bufvalid - buf <= 4 && buf[0] == 0x00)));
|
||||||
|
|
||||||
|
// if (end && bufvalid - buf == 4) {
|
||||||
|
// if (memcmp(buf, terminator, 3))
|
||||||
|
// goto out_err;
|
||||||
|
// ret = buf[3];
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
} while (1);
|
||||||
|
return 0;
|
||||||
|
out_err:
|
||||||
|
bfd_vtysh_close(client);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// return 0 : success
|
||||||
|
// return -1 : fail
|
||||||
|
int bfd_vtysh_pre_config(struct bfd_vtysh_client *client)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
char stackbuf[4096];
|
||||||
|
|
||||||
|
ret = bfd_vtysh_cmd_exec(client, "enable", stackbuf, sizeof(stackbuf)-1);
|
||||||
|
if (ret < 0) {
|
||||||
|
LOG_DEBUG("bfd vtysh cmd [enable] error");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
ret = bfd_vtysh_cmd_exec(client, "conf t", stackbuf, sizeof(stackbuf)-1);
|
||||||
|
if (ret < 0) {
|
||||||
|
LOG_DEBUG("bfd vtysh cmd [conf t] error");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
ret = bfd_vtysh_cmd_exec(client, "bfd", stackbuf, sizeof(stackbuf)-1);
|
||||||
|
if (ret < 0) {
|
||||||
|
LOG_DEBUG("bfd vtysh cmd [bfd] error");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// return 0 : success
|
||||||
|
// return -1 : fail
|
||||||
|
int bfd_vtysh_add_dev(struct bfd_vtysh_client *client, const char *local_addr, const char *peer_addr, int retires, int interval_ms)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
char cmd[256] = {0};
|
||||||
|
char stackbuf[4096];
|
||||||
|
|
||||||
|
snprintf(cmd, sizeof(cmd), "peer %s local-address %s", peer_addr, local_addr);
|
||||||
|
ret = bfd_vtysh_cmd_exec(client, cmd, stackbuf, sizeof(stackbuf)-1);
|
||||||
|
if (ret < 0) {
|
||||||
|
LOG_DEBUG("bfd vtysh cmd [%s] error", cmd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(cmd, sizeof(cmd), "detect-multiplier %d", retires);
|
||||||
|
ret = bfd_vtysh_cmd_exec(client, cmd, stackbuf, sizeof(stackbuf)-1);
|
||||||
|
if (ret < 0) {
|
||||||
|
LOG_DEBUG("bfd vtysh cmd [%s] error", cmd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(cmd, sizeof(cmd), "receive-interval %d", interval_ms);
|
||||||
|
ret = bfd_vtysh_cmd_exec(client, cmd, stackbuf, sizeof(stackbuf)-1);
|
||||||
|
if (ret < 0) {
|
||||||
|
LOG_DEBUG("bfd vtysh cmd [%s] error", cmd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(cmd, sizeof(cmd), "transmit-interval %d", interval_ms);
|
||||||
|
ret = bfd_vtysh_cmd_exec(client, cmd, stackbuf, sizeof(stackbuf)-1);
|
||||||
|
if (ret < 0) {
|
||||||
|
LOG_DEBUG("bfd vtysh cmd [%s] error", cmd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// return 0 : success
|
||||||
|
// return -1 : fail
|
||||||
|
int bfd_vtysh_del_dev(struct bfd_vtysh_client *client, const char *local_addr, char *peer_addr)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
char cmd[256] = {0};
|
||||||
|
char stackbuf[4096];
|
||||||
|
|
||||||
|
snprintf(cmd, sizeof(cmd), "no peer %s local-address %s", peer_addr, local_addr);
|
||||||
|
ret = bfd_vtysh_cmd_exec(client, cmd, stackbuf, sizeof(stackbuf)-1);
|
||||||
|
if (ret < 0) {
|
||||||
|
LOG_DEBUG("bfd vtysh cmd [%s] error", cmd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// return 1 : up
|
||||||
|
// return 0 : down
|
||||||
|
// return -1 : fail
|
||||||
|
int bfd_vtysh_get_dev_active(struct bfd_vtysh_client *client, char *addr)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
char *p = NULL;
|
||||||
|
char cmd[256] = {0};
|
||||||
|
char stackbuf[4096];
|
||||||
|
|
||||||
|
snprintf(cmd, sizeof(cmd), "do show bfd peer %s", addr);
|
||||||
|
ret = bfd_vtysh_cmd_exec(client, cmd, stackbuf, sizeof(stackbuf)-1);
|
||||||
|
if (ret < 0) {
|
||||||
|
LOG_DEBUG("bfd vtysh cmd [%s] error", cmd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ex: Status: up/Status: down
|
||||||
|
if ((p = strstr(stackbuf, "Status: ")) == NULL)
|
||||||
|
return -1;
|
||||||
|
if (strncmp(p+8, "up", 2) == 0)
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -38,6 +38,14 @@ add_executable(gtest_utils gtest_utils.cpp)
|
|||||||
target_include_directories(gtest_utils PUBLIC ${CMAKE_SOURCE_DIR}/common/include)
|
target_include_directories(gtest_utils PUBLIC ${CMAKE_SOURCE_DIR}/common/include)
|
||||||
target_link_libraries(gtest_utils common gtest)
|
target_link_libraries(gtest_utils common gtest)
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# gtest_health_check_table
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
add_executable(gtest_health_check_table gtest_health_check_table.cpp)
|
||||||
|
target_include_directories(gtest_health_check_table PUBLIC ${CMAKE_SOURCE_DIR}/common/include ${CMAKE_SOURCE_DIR}/platform/include)
|
||||||
|
target_link_libraries(gtest_health_check_table common gtest platform)
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
# gtest_discover_tests
|
# gtest_discover_tests
|
||||||
###############################################################################
|
###############################################################################
|
||||||
@@ -47,4 +55,5 @@ gtest_discover_tests(gtest_addr_tuple4)
|
|||||||
gtest_discover_tests(gtest_session_table)
|
gtest_discover_tests(gtest_session_table)
|
||||||
gtest_discover_tests(gtest_raw_packet)
|
gtest_discover_tests(gtest_raw_packet)
|
||||||
gtest_discover_tests(gtest_ctrl_packet)
|
gtest_discover_tests(gtest_ctrl_packet)
|
||||||
gtest_discover_tests(gtest_utils)
|
gtest_discover_tests(gtest_utils)
|
||||||
|
gtest_discover_tests(gtest_health_check_table)
|
||||||
|
|||||||
219
common/test/gtest_health_check_table.cpp
Normal file
219
common/test/gtest_health_check_table.cpp
Normal file
@@ -0,0 +1,219 @@
|
|||||||
|
#include <gtest/gtest.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
|
#include "bfd.h"
|
||||||
|
#include "policy.h"
|
||||||
|
#include "health_check.h"
|
||||||
|
|
||||||
|
|
||||||
|
TEST(HEALTH_CHECK_TABLE, INSERT)
|
||||||
|
{
|
||||||
|
// TEST Create
|
||||||
|
health_check_session_init("./sce.conf");
|
||||||
|
|
||||||
|
// TEST Insert
|
||||||
|
struct health_check policy1;
|
||||||
|
memset(&policy1, 0, sizeof(policy1));
|
||||||
|
policy1.method = HEALTH_CHECK_METHOD_BFD;
|
||||||
|
snprintf(policy1.address, sizeof(policy1.address), "1.1.1.1");
|
||||||
|
policy1.port = 65535;
|
||||||
|
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);
|
||||||
|
|
||||||
|
struct health_check policy2;
|
||||||
|
memset(&policy2, 0, sizeof(policy2));
|
||||||
|
policy2.method = HEALTH_CHECK_METHOD_BFD;
|
||||||
|
snprintf(policy2.address, sizeof(policy2.address), "2.2.2.2");
|
||||||
|
policy2.port = 65535;
|
||||||
|
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);
|
||||||
|
|
||||||
|
struct health_check policy3;
|
||||||
|
memset(&policy3, 0, sizeof(policy3));
|
||||||
|
policy3.method = HEALTH_CHECK_METHOD_BFD;
|
||||||
|
snprintf(policy3.address, sizeof(policy3.address), "2001:0db8:0000:0000:0000:8a2e:0370:7334");
|
||||||
|
policy3.port = 65535;
|
||||||
|
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);
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(HEALTH_CHECK_TABLE, GET_STATUS)
|
||||||
|
{
|
||||||
|
// TEST Insert
|
||||||
|
struct health_check policy1;
|
||||||
|
memset(&policy1, 0, sizeof(policy1));
|
||||||
|
policy1.method = HEALTH_CHECK_METHOD_BFD;
|
||||||
|
snprintf(policy1.address, sizeof(policy1.address), "4.4.4.4");
|
||||||
|
policy1.port = 65535;
|
||||||
|
policy1.retires = 5;
|
||||||
|
policy1.interval_ms = 300;
|
||||||
|
EXPECT_TRUE(health_check_session_add(4, &policy1) == 0);
|
||||||
|
|
||||||
|
struct health_check policy2;
|
||||||
|
memset(&policy2, 0, sizeof(policy2));
|
||||||
|
policy2.method = HEALTH_CHECK_METHOD_BFD;
|
||||||
|
snprintf(policy2.address, sizeof(policy2.address), "5.5.5.5");
|
||||||
|
policy2.port = 65535;
|
||||||
|
policy2.retires = 5;
|
||||||
|
policy2.interval_ms = 300;
|
||||||
|
EXPECT_TRUE(health_check_session_add(5, &policy2) == 0);
|
||||||
|
|
||||||
|
struct health_check policy3;
|
||||||
|
memset(&policy3, 0, sizeof(policy3));
|
||||||
|
policy3.method = HEALTH_CHECK_METHOD_BFD;
|
||||||
|
snprintf(policy3.address, sizeof(policy3.address), "6.6.6.6");
|
||||||
|
policy3.port = 65535;
|
||||||
|
policy3.retires = 5;
|
||||||
|
policy3.interval_ms = 300;
|
||||||
|
EXPECT_TRUE(health_check_session_add(6, &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(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);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(HEALTH_CHECK_TABLE, SET_STATUS)
|
||||||
|
{
|
||||||
|
// TEST Insert
|
||||||
|
struct health_check policy1;
|
||||||
|
memset(&policy1, 0, sizeof(policy1));
|
||||||
|
policy1.method = HEALTH_CHECK_METHOD_BFD;
|
||||||
|
snprintf(policy1.address, sizeof(policy1.address), "7.7.7.7");
|
||||||
|
policy1.port = 65535;
|
||||||
|
policy1.retires = 5;
|
||||||
|
policy1.interval_ms = 300;
|
||||||
|
EXPECT_TRUE(health_check_session_add(7, &policy1) == 0);
|
||||||
|
|
||||||
|
struct health_check policy2;
|
||||||
|
memset(&policy2, 0, sizeof(policy2));
|
||||||
|
policy2.method = HEALTH_CHECK_METHOD_BFD;
|
||||||
|
snprintf(policy2.address, sizeof(policy2.address), "8.8.8.8");
|
||||||
|
policy2.port = 65535;
|
||||||
|
policy2.retires = 5;
|
||||||
|
policy2.interval_ms = 300;
|
||||||
|
EXPECT_TRUE(health_check_session_add(8, &policy2) == 0);
|
||||||
|
|
||||||
|
struct health_check policy3;
|
||||||
|
memset(&policy3, 0, sizeof(policy3));
|
||||||
|
policy3.method = HEALTH_CHECK_METHOD_BFD;
|
||||||
|
snprintf(policy3.address, sizeof(policy3.address), "9.9.9.9");
|
||||||
|
policy3.port = 65535;
|
||||||
|
policy3.retires = 5;
|
||||||
|
policy3.interval_ms = 300;
|
||||||
|
EXPECT_TRUE(health_check_session_add(9, &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);
|
||||||
|
|
||||||
|
// 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(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);
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(HEALTH_CHECK_TABLE, DELETE)
|
||||||
|
{
|
||||||
|
// TEST Insert
|
||||||
|
struct health_check policy1;
|
||||||
|
memset(&policy1, 0, sizeof(policy1));
|
||||||
|
policy1.method = HEALTH_CHECK_METHOD_BFD;
|
||||||
|
snprintf(policy1.address, sizeof(policy1.address), "10.10.10.10");
|
||||||
|
policy1.port = 65535;
|
||||||
|
policy1.retires = 5;
|
||||||
|
policy1.interval_ms = 300;
|
||||||
|
EXPECT_TRUE(health_check_session_add(10, &policy1) == 0);
|
||||||
|
|
||||||
|
struct health_check policy2;
|
||||||
|
memset(&policy2, 0, sizeof(policy2));
|
||||||
|
policy2.method = HEALTH_CHECK_METHOD_BFD;
|
||||||
|
snprintf(policy2.address, sizeof(policy2.address), "11.11.11.11");
|
||||||
|
policy2.port = 65535;
|
||||||
|
policy2.retires = 5;
|
||||||
|
policy2.interval_ms = 300;
|
||||||
|
EXPECT_TRUE(health_check_session_add(11, &policy2) == 0);
|
||||||
|
|
||||||
|
struct health_check policy3;
|
||||||
|
memset(&policy3, 0, sizeof(policy3));
|
||||||
|
policy3.method = HEALTH_CHECK_METHOD_BFD;
|
||||||
|
snprintf(policy3.address, sizeof(policy3.address), "12.12.12.12");
|
||||||
|
policy3.port = 65535;
|
||||||
|
policy3.retires = 5;
|
||||||
|
policy3.interval_ms = 300;
|
||||||
|
EXPECT_TRUE(health_check_session_add(12, &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);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *bfd_get_status(void *arg)
|
||||||
|
{
|
||||||
|
while(1) {
|
||||||
|
health_check_session_get_status(10);
|
||||||
|
sleep(1);
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(HEALTH_CHECK_TABLE, CHECK_BFD_ENVIRONMENT)
|
||||||
|
{
|
||||||
|
// TEST Insert
|
||||||
|
struct health_check policy1;
|
||||||
|
memset(&policy1, 0, sizeof(policy1));
|
||||||
|
policy1.method = HEALTH_CHECK_METHOD_BFD;
|
||||||
|
snprintf(policy1.address, sizeof(policy1.address), "192.168.32.82");
|
||||||
|
policy1.port = 65535;
|
||||||
|
policy1.retires = 5;
|
||||||
|
policy1.interval_ms = 300;
|
||||||
|
EXPECT_TRUE(health_check_session_add(10, &policy1) == 0);
|
||||||
|
|
||||||
|
pthread_t pid1;
|
||||||
|
pthread_create(&pid1, NULL, bfd_get_status, NULL);
|
||||||
|
|
||||||
|
char mac[18] = {0};
|
||||||
|
while(1) {
|
||||||
|
health_check_session_get_mac(10, mac);
|
||||||
|
sleep(5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
::testing::InitGoogleTest(&argc, argv);
|
||||||
|
return RUN_ALL_TESTS();
|
||||||
|
}
|
||||||
@@ -44,4 +44,10 @@ statsd_port=8100
|
|||||||
statsd_format=1
|
statsd_format=1
|
||||||
statsd_cycle=2
|
statsd_cycle=2
|
||||||
prometheus_listen_port=9001
|
prometheus_listen_port=9001
|
||||||
prometheus_listen_url=/sce_prometheus
|
prometheus_listen_url=/sce_prometheus
|
||||||
|
|
||||||
|
[bfdd]
|
||||||
|
path=/var/run/frr/bfdd.vty
|
||||||
|
device=eth0
|
||||||
|
local_address=127.0.0.1
|
||||||
|
gateway=127.0.0.1
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ target_link_libraries(platform PUBLIC MESA_field_stat)
|
|||||||
target_link_libraries(platform PUBLIC maatframe)
|
target_link_libraries(platform PUBLIC maatframe)
|
||||||
target_link_libraries(platform PUBLIC mrzcpd)
|
target_link_libraries(platform PUBLIC mrzcpd)
|
||||||
target_link_libraries(platform PUBLIC cjson)
|
target_link_libraries(platform PUBLIC cjson)
|
||||||
|
target_link_libraries(platform PUBLIC pthread)
|
||||||
target_include_directories(platform PUBLIC ${CMAKE_CURRENT_LIST_DIR}/include/)
|
target_include_directories(platform PUBLIC ${CMAKE_CURRENT_LIST_DIR}/include/)
|
||||||
|
|
||||||
add_executable(sce src/main.cpp)
|
add_executable(sce src/main.cpp)
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ extern "C"
|
|||||||
|
|
||||||
#include "policy.h"
|
#include "policy.h"
|
||||||
|
|
||||||
void health_check_session_init();
|
void health_check_session_init(const char *profile);
|
||||||
|
|
||||||
// return 0 : success
|
// return 0 : success
|
||||||
// return -1 : key exist
|
// return -1 : key exist
|
||||||
|
|||||||
@@ -1,11 +1,34 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <MESA/MESA_prof_load.h>
|
||||||
|
#include <net/if.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <netinet/if_ether.h>
|
||||||
|
#include <net/if_arp.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include "log.h"
|
||||||
|
#include "uthash.h"
|
||||||
|
#include "bfd.h"
|
||||||
#include "health_check.h"
|
#include "health_check.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define HC_MAC_LEN 6
|
||||||
|
#define HC_DEV_NAME_LEN 16
|
||||||
|
#define HC_LOCAL_ADDRESS_LEN 64
|
||||||
|
|
||||||
struct session_table
|
struct session_table
|
||||||
{
|
{
|
||||||
// rwlock ???;
|
// rwlock ???;
|
||||||
// handler;
|
// handler;
|
||||||
|
struct session_iterm *root_by_id;
|
||||||
|
pthread_rwlock_t rwlock;
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct session_table g_handle;
|
static struct session_table g_handle;
|
||||||
@@ -15,16 +38,49 @@ struct session_iterm
|
|||||||
int session_id; // key
|
int session_id; // key
|
||||||
|
|
||||||
struct health_check policy; // value1: deep copy
|
struct health_check policy; // value1: deep copy
|
||||||
int is_active; // value2
|
int is_active; // value2
|
||||||
char dst_ip[16]; // value3
|
uint8_t mac[HC_MAC_LEN]; // value3
|
||||||
char dst_mac[32]; // value4
|
|
||||||
|
UT_hash_handle hh1; /* handle for first hash table */
|
||||||
};
|
};
|
||||||
|
|
||||||
void health_check_session_init()
|
int sleep_ms = 300;
|
||||||
|
char path[BFD_PATHLEN];
|
||||||
|
char hc_dev_name[HC_DEV_NAME_LEN];
|
||||||
|
char local_address[HC_LOCAL_ADDRESS_LEN];
|
||||||
|
char gateway_address[HC_LOCAL_ADDRESS_LEN];
|
||||||
|
uint8_t default_gw_mac[HC_MAC_LEN];
|
||||||
|
|
||||||
|
static int get_mac_by_addr(char *addr, uint8_t *buf);
|
||||||
|
|
||||||
|
static struct session_iterm *health_check_get_iterm_by_id(int session_id)
|
||||||
|
{
|
||||||
|
struct session_iterm *tmp = NULL;
|
||||||
|
pthread_rwlock_rdlock(&g_handle.rwlock);
|
||||||
|
HASH_FIND(hh1, g_handle.root_by_id, &session_id, sizeof(session_id), tmp);
|
||||||
|
pthread_rwlock_unlock(&g_handle.rwlock);
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
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", "local_address", local_address, sizeof(local_address), "127.0.0.1");
|
||||||
|
MESA_load_profile_string_def(profile, "bfdd", "gateway", gateway_address, sizeof(gateway_address), "127.0.0.1");
|
||||||
|
|
||||||
// TODO
|
// TODO: 循环获取?
|
||||||
|
get_mac_by_addr(gateway_address, default_gw_mac);
|
||||||
|
health_check_session_foreach();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void health_check_session_init_bfd_client(struct bfd_vtysh_client *client)
|
||||||
|
{
|
||||||
|
memset(client, 0, sizeof(*client));
|
||||||
|
snprintf(client->path, sizeof(client->path), path);
|
||||||
|
client->pre_config = bfd_vtysh_pre_config;
|
||||||
}
|
}
|
||||||
|
|
||||||
// return 0 : success
|
// return 0 : success
|
||||||
@@ -32,7 +88,38 @@ void health_check_session_init()
|
|||||||
// struct health_check *policy : need deep copy
|
// struct health_check *policy : need deep copy
|
||||||
int health_check_session_add(int session_id, const struct health_check *policy)
|
int health_check_session_add(int session_id, const struct health_check *policy)
|
||||||
{
|
{
|
||||||
// TODO
|
int ret = 0;
|
||||||
|
struct bfd_vtysh_client client;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp = (struct session_iterm *)calloc(1, sizeof(struct session_iterm));
|
||||||
|
assert(tmp);
|
||||||
|
|
||||||
|
health_check_session_init_bfd_client(&client);
|
||||||
|
bfd_vtysh_connect(&client);
|
||||||
|
ret = bfd_vtysh_add_dev(&client, local_address, policy->address, policy->retires, policy->interval_ms);
|
||||||
|
if (ret != 0) {
|
||||||
|
LOG_DEBUG("bfd vtysh add dev address [%s] failed!", tmp->policy.address);
|
||||||
|
bfd_vtysh_close(&client);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
bfd_vtysh_close(&client);
|
||||||
|
|
||||||
|
memset(tmp, 0, sizeof(*tmp));
|
||||||
|
tmp->session_id = session_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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -40,7 +127,33 @@ int health_check_session_add(int session_id, const struct health_check *policy)
|
|||||||
// return -1 : key not exist
|
// return -1 : key not exist
|
||||||
int health_check_session_del(int session_id)
|
int health_check_session_del(int session_id)
|
||||||
{
|
{
|
||||||
// TODO
|
int ret = 0;
|
||||||
|
struct bfd_vtysh_client client;
|
||||||
|
struct session_iterm *tmp = NULL;
|
||||||
|
|
||||||
|
tmp = health_check_get_iterm_by_id(session_id);
|
||||||
|
if (!tmp) {
|
||||||
|
LOG_DEBUG("health check session table delete: key %d not exists", session_id);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
health_check_session_init_bfd_client(&client);
|
||||||
|
bfd_vtysh_connect(&client);
|
||||||
|
ret = bfd_vtysh_del_dev(&client, local_address, tmp->policy.address);
|
||||||
|
if (ret != 0) {
|
||||||
|
LOG_DEBUG("bfd vtysh delete dev address [%s] failed!", tmp->policy.address);
|
||||||
|
bfd_vtysh_close(&client);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
bfd_vtysh_close(&client);
|
||||||
|
|
||||||
|
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);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,28 +162,133 @@ int health_check_session_del(int session_id)
|
|||||||
// return -1 : key not exist
|
// return -1 : key not exist
|
||||||
int health_check_session_get_status(int session_id)
|
int health_check_session_get_status(int session_id)
|
||||||
{
|
{
|
||||||
// TODO
|
int status = 0;
|
||||||
return 1;
|
struct session_iterm *tmp = NULL;
|
||||||
|
|
||||||
|
tmp = health_check_get_iterm_by_id(session_id);
|
||||||
|
if (!tmp) {
|
||||||
|
LOG_DEBUG("health check session table get status: key %d not exists", session_id);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = tmp->is_active;
|
||||||
|
LOG_DEBUG("health check session get status: %d", status);
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
// return 0 : success
|
// return 0 : success
|
||||||
// return -1 : key not exist
|
// return -1 : key not exist
|
||||||
int health_check_session_set_status(int session_id, int is_active)
|
int health_check_session_set_status(int session_id, int is_active)
|
||||||
{
|
{
|
||||||
// TODO
|
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);
|
||||||
|
pthread_rwlock_unlock(&g_handle.rwlock);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp->is_active = is_active;
|
||||||
|
pthread_rwlock_unlock(&g_handle.rwlock);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int get_mac_by_addr(char *addr, uint8_t *buf)
|
||||||
|
{
|
||||||
|
int sfd, saved_errno, ret;
|
||||||
|
struct arpreq arp_req;
|
||||||
|
struct sockaddr_in *sin;
|
||||||
|
|
||||||
|
sin = (struct sockaddr_in *)&(arp_req.arp_pa);
|
||||||
|
|
||||||
|
memset(&arp_req, 0, sizeof(arp_req));
|
||||||
|
sin->sin_family = AF_INET;
|
||||||
|
inet_pton(AF_INET, addr, &(sin->sin_addr));
|
||||||
|
snprintf(arp_req.arp_dev, IFNAMSIZ, hc_dev_name);
|
||||||
|
|
||||||
|
sfd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||||
|
|
||||||
|
saved_errno = errno;
|
||||||
|
ret = ioctl(sfd, SIOCGARP, &arp_req);
|
||||||
|
if (ret < 0) {
|
||||||
|
LOG_DEBUG("Get ARP entry failed : %s\n", strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
errno = saved_errno;
|
||||||
|
|
||||||
|
if (arp_req.arp_flags & ATF_COM)
|
||||||
|
memcpy(buf, arp_req.arp_ha.sa_data, HC_MAC_LEN);
|
||||||
|
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]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *_health_check_session_foreach(void *arg)
|
||||||
|
{
|
||||||
|
int is_active = 0;
|
||||||
|
struct bfd_vtysh_client client;
|
||||||
|
struct session_iterm *tmp = NULL;
|
||||||
|
struct session_iterm *node = NULL;
|
||||||
|
|
||||||
|
health_check_session_init_bfd_client(&client);
|
||||||
|
bfd_vtysh_connect(&client);
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
// TODO: 改为读锁,更新数据入队列,通过写锁更新
|
||||||
|
pthread_rwlock_wrlock(&g_handle.rwlock);
|
||||||
|
HASH_ITER(hh1, g_handle.root_by_id, node, tmp) {
|
||||||
|
if (node->policy.method != HEALTH_CHECK_METHOD_BFD)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
is_active = bfd_vtysh_get_dev_active(&client, node->policy.address);
|
||||||
|
if (is_active == -1)
|
||||||
|
continue;
|
||||||
|
if (node->is_active != is_active) {
|
||||||
|
node->is_active = is_active;
|
||||||
|
if (node->is_active == 1) {
|
||||||
|
get_mac_by_addr(node->policy.address, node->mac);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
memset(node->mac, 0, sizeof(node->mac));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (sleep_ms > node->policy.interval_ms)
|
||||||
|
sleep_ms = node->policy.interval_ms;
|
||||||
|
}
|
||||||
|
pthread_rwlock_unlock(&g_handle.rwlock);
|
||||||
|
usleep(sleep_ms*1000);
|
||||||
|
}
|
||||||
|
bfd_vtysh_close(&client);
|
||||||
|
}
|
||||||
|
|
||||||
|
int health_check_session_foreach()
|
||||||
|
{
|
||||||
|
pthread_t pid;
|
||||||
|
pthread_create(&pid, NULL, _health_check_session_foreach, NULL);
|
||||||
|
pthread_detach(pid);
|
||||||
|
return pid;
|
||||||
|
}
|
||||||
|
|
||||||
// return 0 : success
|
// return 0 : success
|
||||||
// return -1 : key not exist
|
// return -1 : key not exist
|
||||||
int health_check_session_get_mac(int session_id, char *mac_buff)
|
int health_check_session_get_mac(int session_id, char *mac_buff)
|
||||||
{
|
{
|
||||||
strcpy(mac_buff, "66:AA:AA:AA:AA:AA");
|
uint8_t *p = NULL;
|
||||||
// TODO
|
struct session_iterm *tmp = NULL;
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void health_check_session_foreach()
|
tmp = health_check_get_iterm_by_id(session_id);
|
||||||
{
|
if (!tmp) {
|
||||||
// TODO
|
LOG_DEBUG("health check session table get status: key %d not exists", session_id);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
p = (uint8_t *)tmp->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 get mac: %s", mac_buff);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -18,4 +18,10 @@ json_cfg_file=test_resource/sce.json
|
|||||||
foreign_cont_dir=test_resource/foreign_files
|
foreign_cont_dir=test_resource/foreign_files
|
||||||
redis_db_idx=0
|
redis_db_idx=0
|
||||||
redis_server=127.0.0.1
|
redis_server=127.0.0.1
|
||||||
redis_port_range=6379
|
redis_port_range=6379
|
||||||
|
|
||||||
|
[bfdd]
|
||||||
|
path=/var/run/frr/bfdd.vty
|
||||||
|
device=eth0
|
||||||
|
local_address=127.0.0.1
|
||||||
|
gateway=127.0.0.1
|
||||||
Reference in New Issue
Block a user