secgateway/Platform/user/configm/config-server/netconfig/bridge/brconfig.c

1006 lines
24 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include "list.h"
#include "configm.h"
#include "brconfig.h"
#include "rpc.h"
#include "parsefile.h"
#include "brnetlink.h"
#include "parsefile.h"
#include "libbridge.h"
#include "libbridge_private.h"
/* 事件通知函数 */
br_event_head_t br_event_tbl = {.head.first = NULL, .lock = 0, .init = FALSE};
int br_invoke_event(BR_EVENT_TYPE event_type, br_event_t event_arg)
{
br_event_node_t *hnode;
pthread_mutex_lock(&(br_event_tbl.lock));
hlist_for_each_entry(hnode, &(br_event_tbl.head), list)
{
if(hnode->br_event == event_type)
{
hnode->event_func(event_type, event_arg);
}
}
pthread_mutex_unlock(&(br_event_tbl.lock));
}
int br_event_register(BR_EVENT_TYPE event_type, BR_EVENT_FUNC event_func)
{
br_event_node_t *hnode = NULL;
if(br_event_tbl.init == FALSE)
{
INIT_HLIST_HEAD(&(br_event_tbl.head));
pthread_mutex_init(&(br_event_tbl.lock), NULL);
br_event_tbl.init = TRUE;
}
hnode = (br_event_node_t *)rpc_new0(br_event_node_t, 1);
if(!hnode)
{
rpc_log_error("br_event_register failed\n");
return -1;
}
INIT_HLIST_NODE(&hnode->list);
hnode->br_event = event_type;
hnode->event_func = event_func;
pthread_mutex_lock(&(br_event_tbl.lock));
hlist_add_head(&hnode->list, &(br_event_tbl.head));
pthread_mutex_unlock(&(br_event_tbl.lock));
return 0;
}
int br_event_unregister(BR_EVENT_TYPE event_type, BR_EVENT_FUNC event_func)
{
br_event_node_t *hnode = NULL;
struct hlist_node *n;
if(br_event_tbl.init == FALSE)
{
return 0;
}
pthread_mutex_lock(&(br_event_tbl.lock));
hlist_for_each_entry_safe(hnode, n, &(br_event_tbl.head), list)
{
if(event_type == hnode->br_event &&
event_func == hnode->event_func)
{
hlist_del(&hnode->list);
rpc_free(hnode);
break;
}
}
pthread_mutex_unlock(&(br_event_tbl.lock));
return 0;
}
/* 桥配置辅助函数 */
int br_copy_port_name(const char *b, const char *p, void *arg)
{
br_if_temp_t *br_if = (br_if_temp_t *)arg;
br_if->ports[br_if->index] = rpc_new0(char, INTERFACE_NAMSIZ);
ASSERT_PTR_RET(br_if->ports[br_if->index]);
strncpy(br_if->ports[br_if->index], p, INTERFACE_NAMSIZ - 1);
br_if->index++;
return 0;
}
ret_code br_name_chk(char *br_name)
{
if(strlen(br_name) == 0
|| strlen(br_name) > BR_NAMSIZ - 1
|| strstr(br_name, "br-vl") != NULL)
{
return RET_BR_INVALID;
}
return RET_OK;
}
int br_name_cmp(const char *br_name, void *args)
{
br_temp_t *cmp_args = (br_temp_t *)args;
if(strcmp(br_name, cmp_args->br_name) == 0)
{
cmp_args->result = TRUE;
return 1;
}
return 0;
}
boolean br_is_exist(char *br_name)
{
br_temp_t cmp_args = {br_name, FALSE};
br_foreach_bridge(br_name_cmp, &cmp_args);
return cmp_args.result;
}
ret_code br_if_bridge_get(char *port_name, char* br_name)
{
char bridge_name[BR_NAMSIZ] = {0};
if(get_br_from_port(port_name, bridge_name) == RET_OK)
{
if(br_name)
{
strncpy(br_name, bridge_name, BR_NAMSIZ - 1);
}
return RET_OK;
}
return RET_NOTFOUND;
}
ret_code br_if_bridge_check(char *port_list, int cnt, uint config_type)
{
char *ptr_name = NULL;
int i;
for(i = 0; i< cnt; i++)
{
ptr_name = port_list + INTERFACE_NAMSIZ * i;
if (if_nametoindex(ptr_name) == 0)
{
return RET_NOTFOUND;
}
if(br_if_bridge_get(ptr_name, NULL) == RET_OK)
{
if(config_type == CM_CONFIG_ADD)
{
return RET_EXIST;
}
}
else if(config_type == CM_CONFIG_DEL)
{
return RET_NOTFOUND;
}
}
return RET_OK;
}
ret_code br_save_file(BR_EVENT_TYPE event_type,
char *br_name, char *port_name)
{
char *key_str = "bridge_ports";
char config_str[IF_BUFF_LEN] = {0};
ret_code ret;
switch(event_type)
{
case BR_CREATE_EVENT:
if_conf_file_add(br_name);
break;
case BR_DELETE_EVENT:
if_conf_file_del(br_name);
break;
case BR_IF_JOIN_EVENT:
if(if_conf_file_get(br_name, key_str, config_str) == RET_OK)
{
if(strstr(config_str, port_name) != NULL)
{
return RET_OK;
}
strcat(config_str, " ");
strcat(config_str, port_name);
}
if_conf_file_set(br_name, key_str, config_str);
break;
case BR_IF_LEAVE_EVENT:
if(if_conf_file_get(br_name, key_str, config_str) == RET_OK)
{
if(strstr(config_str, port_name) != NULL)
{
del_sub_string(config_str, port_name);
rpc_log_info("BR_IF_LEAVE_EVENT: %s\n", config_str);
if_conf_file_set(br_name, key_str, config_str);
return RET_OK;
}
}
break;
default:
break;
}
return RET_OK;
}
ret_code br_if_bridge_add(char *br_name, char *port_list, int cnt, int *sys_err)
{
br_event_t event_arg = {0};
ret_code ret = RET_OK;
char *port_name;
int err = 0;
int i;
for(i = 0; i < cnt; i++)
{
br_invoke_event(BR_IF_JOIN_EVENT_PRE, event_arg);
port_name = port_list + INTERFACE_NAMSIZ * i;
err = br_add_interface(br_name, port_name);
if(err != 0)
{
*sys_err = err;
ret = RET_SYSERR;
continue;
}
event_arg.br_name = br_name;
event_arg.if_name = port_name;
br_invoke_event(BR_IF_JOIN_EVENT, event_arg);
br_save_file(BR_IF_JOIN_EVENT, br_name, port_name);
}
return ret;
}
ret_code br_if_bridge_del(char * br_name, char *port_list, int cnt, int *sys_err)
{
br_event_t event_arg = {0};
ret_code ret = RET_OK;
char *port_name;
int err = 0;
int i;
for(i = 0; i < cnt; i++)
{
br_invoke_event(BR_IF_LEAVE_EVENT_PRE, event_arg);
port_name = port_list + INTERFACE_NAMSIZ * i;
err = br_del_interface(br_name, port_name);
if(err != 0)
{
*sys_err = err;
ret = RET_SYSERR;
continue;
}
event_arg.br_name = br_name;
event_arg.if_name = port_name;
br_invoke_event(BR_IF_LEAVE_EVENT, event_arg);
br_save_file(BR_IF_LEAVE_EVENT, br_name, port_name);
}
return ret;
}
int br_if_bridge_num(char *br_name)
{
int cnt = 0;
int err = 0;
err = br_for_port_num(br_name, &cnt);
cnt = (err != 0) ? 0 : cnt;
return cnt;
}
ret_code br_bridge_add(char *br_name, int *sys_err)
{
br_event_t event_arg = {br_name, NULL};
int sys_ret = 0;
br_invoke_event(BR_CREATE_EVENT_PRE, event_arg);
sys_ret = br_add_bridge(br_name);
*sys_err = sys_ret;
if(sys_ret != 0)
{
return RET_SYSERR;
}
br_invoke_event(BR_CREATE_EVENT, event_arg);
br_save_file(BR_CREATE_EVENT, br_name, NULL);
return RET_OK;
}
ret_code br_bridge_del(char * br_name, int *sys_err)
{
br_event_t event_arg = {br_name, NULL};
int sys_ret = 0;
br_invoke_event(BR_DELETE_EVENT_PRE, event_arg);
sys_ret = br_del_bridge(br_name);
*sys_err = sys_ret;
if(sys_ret != 0)
{
return RET_SYSERR;
}
br_invoke_event(BR_DELETE_EVENT, event_arg);
br_save_file(BR_DELETE_EVENT, br_name, NULL);
return RET_OK;
}
/* 桥配置json格式转换函数 */
ret_code br_config_json_parse(pointer input, uint *conf_type, char *br_name)
{
cJSON *json_obj;
json_obj = cJSON_Parse(input);
ASSERT_PTR_RET(json_obj);
rpc_log_info("json input:\n %s\n", cJSON_Print(json_obj));
s2j_create_struct_obj(br_config, br_config_string_t);
if(br_config == NULL)
{
cJSON_Delete(json_obj);
return RET_NOMEM;
}
s2j_struct_get_basic_element(br_config, json_obj, int, config_type);
s2j_struct_get_string_element(br_config, json_obj, br_name, BR_NAMSIZ);
strncpy(br_name, br_config->br_name, BR_NAMSIZ - 1);
*conf_type = br_config->config_type;
s2j_delete_struct_obj(br_config);
cJSON_Delete(json_obj);
return RET_OK;
}
int br_json_to_string( cJSON *json_obj, pointer output)
{
char *json_str;
int output_len = 0;
if(json_obj == NULL)
{
return 0;
}
json_str = cJSON_PrintUnformatted(json_obj);
output_len = strlen(json_str) + 1;
if(output_len > CM_BUFF_SIZE)
{
rpc_log_warn("output len is too long %d, cut off!", output_len);
json_str[CM_BUFF_SIZE - 1] = '\0';
output_len = CM_BUFF_SIZE;
}
memcpy(output, json_str, output_len);
rpc_free(json_str);
s2j_delete_json_obj(json_obj);
return output_len;
}
cJSON *br_config_format_json(const char *br_name, br_if_temp_t *br_if)
{
s2j_create_json_obj(json_obj);
if(json_obj == NULL)
{
return NULL;
}
s2j_json_set_basic_element(json_obj, br_config, string, br_name);
s2j_json_set_array_element(json_obj, br_config, string, ports, br_if->index);
return json_obj;
}
ret_code br_bridge_info(const char *br_name, cJSON *json_obj, int *err)
{
ret_code ret = RET_OK;
br_if_temp_t br_if = {0};
int i = 0;
br_if.index = 0;
br_if.ports = NULL;
*err = br_foreach_port(br_name, br_copy_port_name, &br_if);
if (*err >= 0)
{
json_obj = br_config_format_json(&br_if);
}
else
{
ret = RET_SYSERR;
}
for(i = 0; i < br_if.index; i++)
{
if(br_if.ports[i])
{
rpc_free(br_if.ports[i]);
}
}
return ret;
}
int br_bridge_info_each(const char *br_name, void *args)
{
cJSON *json_array = (cJSON *)args;
cJSON *json_obj = NULL;
ret_code ret = RET_OK;
int err = 0;
ret = br_bridge_info(br_name, json_obj, &err);
if(json_obj)
{
cJSON_AddItemToArray(json_array, json_obj);
}
return 0;
}
ret_code br_if_config_json_parse(pointer input, uint *conf_type, br_config_t *br_if)
{
cJSON *json_obj;
int port_num = 0;
json_obj = cJSON_Parse(input);
ASSERT_PTR_RET(json_obj);
rpc_log_info("json input:\n %s\n", cJSON_Print(json_obj));
s2j_create_struct_obj(br_if_conf, br_if_config_string_t);
if(br_if_conf == NULL)
{
cJSON_Delete(json_obj);
return RET_NOMEM;
}
s2j_struct_get_basic_element(br_if_conf, json_obj, int, config_type);
*conf_type = br_if_conf->config_type;
if(br_if_conf->config_type != CM_CONFIG_GET_ALL)
{
s2j_struct_get_string_element(br_if_conf, json_obj, br_name, BR_NAMSIZ);
strncpy(br_if->br_name, br_if_conf->br_name, BR_NAMSIZ - 1);
}
if(br_if_conf->config_type == CM_CONFIG_ADD
|| br_if_conf->config_type == CM_CONFIG_DEL)
{
s2j_struct_get_array_string_n(br_if_conf, json_obj, ports, port_num, INTERFACE_NAMSIZ);
br_if->port_num = port_num;
br_if->ports = br_if_conf->ports; /*指针赋值,后续需要对该指针进行内存释放*/
br_if_conf->ports = NULL;
}
s2j_delete_struct_obj(br_if_conf);
cJSON_Delete(json_obj);
return RET_OK;
}
/* 桥配置钩子函数 */
ret_code br_config_chk(uint source,uint *config_type,
pointer input, int *input_len,
pointer output, int *output_len)
{
int config_len = 0;
uint conf_type = CM_CONFIG_GET;
char br_name[BR_NAMSIZ] = {0};
ret_code ret = RET_OK;
int code = 0;
br_config_json_parse(input, &conf_type, br_name);
config_len = strlen(br_name) + 1;
switch (conf_type)
{
case CM_CONFIG_ADD:
case CM_CONFIG_DEL:
case CM_CONFIG_GET:
ret = br_name_chk(br_name);
break;
case CM_CONFIG_GET_ALL:
break;
default:
ret = RET_NOTSUPPORT;
}
/* 将传入的json数据转换成结构体便于后续处理 */
if(config_len <= CM_BUFF_SIZE)
{
memset(input, 0, *input_len);
memcpy(input, br_name, config_len);
*config_type = conf_type;
*input_len = config_len;
}
else
{
ret = RET_NOMEM;
}
RET_ERR_FORMART(ret, code, output, *output_len);
return ret;
}
ret_code br_config_proc(uint source, uint config_type,
pointer input, int input_len,
pointer output, int *output_len)
{
ret_code ret = RET_OK;
int sys_ret = 0;
char *br_name;
br_name = (char *)input;
if(config_type == CM_CONFIG_ADD)
{
ret = br_bridge_add(br_name, &sys_ret);
}
else if(config_type == CM_CONFIG_DEL)
{
ret = br_bridge_del(br_name, &sys_ret);
}
RET_ERR_FORMART(ret, sys_ret, output, *output_len);
return ret;
}
/* 桥接口配置钩子函数 */
ret_code br_if_config_chk(uint source,uint *config_type,
pointer input, int *input_len,
pointer output, int *output_len)
{
ret_code ret = RET_OK;
br_config_t br_config = {0};
br_config_t *temp_conf = NULL;
int cfg_len = 0;
br_if_config_json_parse(input, config_type, &br_config);
cfg_len = BR_NAMSIZ + sizeof(br_config.port_num)
+ br_config.port_num * INTERFACE_NAMSIZ;
if(cfg_len > CM_BUFF_SIZE)
{
ret = RET_NOMEM;
goto exit;
}
ret = br_name_chk(br_config.br_name);
if(ret != RET_OK)
{
goto exit;
}
if(br_is_exist(br_config.br_name) == FALSE)
{
ret = RET_NOTFOUND;
goto exit;
}
if(*config_type != CM_CONFIG_ADD && *config_type != CM_CONFIG_DEL)
{
ret = RET_INPUTERR;
goto exit;
}
ret = br_if_bridge_check(br_config.ports, br_config.port_num, *config_type);
if(ret != RET_OK)
{
goto exit;
}
memset(input, 0, *input_len);
temp_conf = (br_config_t *)input;
strncpy(temp_conf->br_name, br_config.br_name, BR_NAMSIZ - 1);
temp_conf->port_num = br_config.port_num;
memcpy(temp_conf->ports, br_config.ports, br_config.port_num * INTERFACE_NAMSIZ);
*input_len = cfg_len;
exit:
RET_ERR_FORMART(ret, 0, output, *output_len);
rpc_free(br_config.ports);
return ret;
}
ret_code br_if_config_proc(uint source, uint config_type,
pointer input, int input_len,
pointer output, int *output_len)
{
br_config_t *br_conf = (br_config_t *)input;
ret_code ret = RET_OK;
int err = 0;
if(config_type == CM_CONFIG_ADD)
{
ret = br_if_bridge_add(br_conf->br_name, br_conf->ports,
br_conf->port_num, &err);
}
else if(config_type == CM_CONFIG_DEL)
{
ret = br_if_bridge_del(br_conf->br_name, br_conf->ports,
br_conf->port_num, &err);
}
RET_ERR_FORMART(ret, err, output, *output_len);
return ret;
}
ret_code br_if_config_get(uint source,
pointer input, int input_len,
pointer output, int *output_len)
{
ret_code ret = RET_OK;
cJSON *json_obj = NULL;
int err = 0;
ret = br_bridge_info((char *)input, json_obj, &err);
if(ret != RET_OK)
{
RET_ERR_FORMART(ret, err, output, *output_len);
}
else
{
*output_len = br_json_to_string(json_obj, output);
}
return ret;
}
ret_code br_if_config_get_all(uint source,
pointer output, int *output_len)
{
cJSON *json_obj = NULL;
ret_code ret = RET_OK;
int err = 0;
json_obj = cJSON_CreateArray();
if(json_obj == NULL)
{
ret = RET_NOMEM;
RET_ERR_FORMART(RET_NOMEM, err, output, *output_len);
return ret;
}
if(br_foreach_bridge(br_bridge_info_each, json_obj) > 0)
{
*output_len = br_json_to_string(json_obj, output);
}
return ret;
}
/* 桥FDB配置辅助函数 */
void br_format_time(const struct timeval *tv, char *str, int len)
{
snprintf(str, len, "%4i.%.2i", (int)tv->tv_sec, (int)tv->tv_usec/10000);
}
int br_compare_fdbs(const void *_f0, const void *_f1)
{
const struct fdb_entry *f0 = _f0;
const struct fdb_entry *f1 = _f1;
return memcmp(f0->mac_addr, f1->mac_addr, 6);
}
int br_get_if_from_portno(const char *brname, int port_no, char *ifname)
{
int ifindices[MAX_PORTS];
unsigned long args[4] = { BRCTL_GET_PORT_LIST,
(unsigned long)ifindices, MAX_PORTS, 0 };
struct ifreq ifr;
int br_fd = -1;
if (port_no >= MAX_PORTS)
return -1;
memset(ifindices, 0, sizeof(ifindices));
strncpy(ifr.ifr_name, brname, IFNAMSIZ);
ifr.ifr_data = (char *) &args;
if ((br_fd = socket(AF_LOCAL, SOCK_STREAM, 0)) < 0)
{
return -1;
}
if (ioctl(br_fd, SIOCDEVPRIVATE, &ifr) < 0) {
dprintf("get_portno: get ports of %s failed: %s\n",
brname, strerror(errno));
close(br_fd);
return -1;
}
if(if_indextoname(ifindices[port_no], ifname) == NULL)
{
close(br_fd);
return -1;
}
close(br_fd);
return 0;
}
int br_fdb_get(char *brname, struct fdb_entry **br_fdb)
{
struct fdb_entry *fdb;
int i = 0, n = 0;
int offset = 0;
fdb = NULL;
*br_fdb = NULL;
for(;;) {
fdb = realloc(fdb, (offset + FDB_CHUNK) * sizeof(struct fdb_entry));
if (!fdb) {
rpc_log_error("Out of memory\n");
return offset;
}
*br_fdb = fdb;
n = br_read_fdb(brname, fdb+offset, offset, FDB_CHUNK);
if (n == 0)
break;
if (n < 0) {
rpc_log_error( "read of forward table failed: %s\n", strerror(errno));
return offset;
}
offset += n;
}
qsort(fdb, offset, sizeof(struct fdb_entry), br_compare_fdbs);
#if 0
printf("port no\tmac addr\t\tis local?\tageing timer\n");
for (i = 0; i < offset; i++) {
const struct fdb_entry *f = fdb + i;
printf("%3i\t", f->port_no);
printf("%.2x:%.2x:%.2x:%.2x:%.2x:%.2x\t",
f->mac_addr[0], f->mac_addr[1], f->mac_addr[2],
f->mac_addr[3], f->mac_addr[4], f->mac_addr[5]);
printf("%s\t\t", f->is_local?"yes":"no");
br_show_timer(&f->ageing_timer_value);
printf("\n");
}
#endif
return offset;
}
int br_fdb_cpy(br_fdb_status_t *fdb_status, struct fdb_entry *fdb)
{
struct fdb_entry *temp_fdb;
char if_name[INTERFACE_NAMSIZ];
int i = 0;
for(i = 0; i < fdb_status->fdb_num && i < MAC_MAXIZS; i++)
{
temp_fdb = fdb + i;
memset(if_name, 0, INTERFACE_NAMSIZ);
if(br_get_if_from_portno(fdb_status->br_name,
temp_fdb->port_no,
if_name) != 0)
{
rpc_log_error("port no %d can not get ifname\n", temp_fdb->port_no);
continue;
}
snprintf(fdb_status->fdb_info[i].mac_addr, MAC_STRSIZ,
"%02x:%02x:%02x:%02x:%02x:%02x",
temp_fdb->mac_addr[0], temp_fdb->mac_addr[1], temp_fdb->mac_addr[2],
temp_fdb->mac_addr[3], temp_fdb->mac_addr[4], temp_fdb->mac_addr[5]);
strncpy(fdb_status->fdb_info[i].port, if_name, INTERFACE_NAMSIZ - 1);
if(temp_fdb->is_local)
{
strncpy(fdb_status->fdb_info[i].local, "true", LOCAL_STRSIZ - 1);
}
else
{
strncpy(fdb_status->fdb_info[i].local, "false", LOCAL_STRSIZ - 1);
}
br_format_time(&temp_fdb->ageing_timer_value,
fdb_status->fdb_info[i].time, TIME_STRSIZ);
}
return i;
}
/* 桥FDB配置json格式转换 */
ret_code br_fdb_config_json_parse(pointer input, uint *conf_type, br_fdb_config_t *br_fdb)
{
cJSON *json_obj;
int port_num = 0;
json_obj = cJSON_Parse(input);
if(!json_obj)
{
return RET_INPUTERR;
}
rpc_log_info("json input:\n %s\n", cJSON_Print(json_obj));
s2j_create_struct_obj(br_fdb_conf, br_fdb_string_t);
if(br_fdb_conf == NULL)
{
cJSON_Delete(json_obj);
return RET_NOMEM;
}
s2j_struct_get_string_element(br_fdb_conf, json_obj, br_name, BR_NAMSIZ);
*conf_type = br_fdb_conf->config_type;
strncpy(br_fdb->br_name, br_fdb_conf->br_name, BR_NAMSIZ - 1);
s2j_delete_struct_obj(br_fdb_conf);
cJSON_Delete(json_obj);
return RET_OK;
}
ret_code br_each_fdb_to_json_string(cJSON *json_array, fdb_info_t *fdb_info)
{
s2j_create_json_obj(fdb_obj);
if(fdb_obj == NULL)
{
return RET_NOMEM;
}
s2j_json_set_basic_element(fdb_obj, fdb_info, string, mac_addr);
s2j_json_set_basic_element(fdb_obj, fdb_info, string, port);
s2j_json_set_basic_element(fdb_obj, fdb_info, string, local);
s2j_json_set_basic_element(fdb_obj, fdb_info, string, time);
cJSON_AddItemToArray(json_array, fdb_obj);
return RET_OK;
}
int br_fdb_to_json_string(br_fdb_status_t *fdb_status, char *output)
{
cJSON *fdb_array;
char *json_str;
int i;
s2j_create_json_obj(br_obj);
fdb_array = cJSON_CreateArray();
if(br_obj == NULL || fdb_array)
{
return 0;
}
s2j_json_set_basic_element(br_obj, fdb_status, string, br_name);
s2j_json_set_basic_element(br_obj, fdb_status, int, fdb_num);
for(i = 0; i < fdb_status->fdb_num; i++)
{
br_each_fdb_to_json_string(fdb_array, &(fdb_status->fdb_info[i]));
}
cJSON_AddItemToObject(br_obj, "fdb", fdb_array);
br_json_to_string(br_obj, output);
return (strlen(output) + 1);
}
/* 桥FDB表配置钩子函数 */
ret_code br_fdb_config_chk(uint source,uint *config_type,
pointer input, int *input_len,
pointer output, int *output_len)
{
ret_code ret = RET_OK;
br_fdb_config_t br_fdb = {0};
br_fdb_config_t *temp_conf;
int cfg_len = 0;
ret = br_fdb_config_json_parse(input, config_type, &br_fdb);
if(ret != RET_OK)
{
RET_ERR_FORMART(ret, 0, output, *output_len);
return ret;
}
if(*config_type != CM_CONFIG_GET)
{
ret = RET_INPUTERR;
RET_ERR_FORMART(ret, 0, output, *output_len);
return ret;
}
/* 回填解析过的数据 */
memset(input, 0, *input_len);
temp_conf = (br_fdb_config_t *)input;
strncpy(temp_conf->br_name, br_fdb.br_name, BR_NAMSIZ - 1);
*input_len = cfg_len;
return ret;
}
ret_code br_fdb_config_get(uint source,
pointer input, int input_len,
pointer output, int *output_len)
{
br_fdb_status_t *fdb_status;
br_fdb_config_t *br_fdb;
struct fdb_entry *fdb;
ret_code ret = RET_OK;
int err = 0;
br_fdb = (br_fdb_config_t *)input;
fdb_status = (br_fdb_status_t *)rpc_new0(br_fdb_status_t, 1);
if(fdb_status == NULL)
{
ret = RET_NOMEM;
RET_ERR_FORMART(ret, 0, output, *output_len);
return ret;
}
strncpy(fdb_status->br_name, br_fdb->br_name, BR_NAMSIZ - 1);
fdb_status->fdb_num = br_fdb_get(br_fdb->br_name, &fdb);
fdb_status->fdb_num = br_fdb_cpy(fdb_status, fdb);
*output_len = br_fdb_to_json_string(fdb_status, output);
rpc_free(fdb);
rpc_free(fdb_status);
return ret;
}