2380 lines
67 KiB
C
2380 lines
67 KiB
C
#include "vlan_config.h"
|
||
|
||
extern boolean br_is_exist(char *br_name);
|
||
|
||
/* 定义全局接口vlan信息变量 */
|
||
interface_vlan_info g_if_vlan_info[MAX_INTERFACES] = {0};
|
||
|
||
/* 存放全局error data信息 */
|
||
char g_err_data[ERR_DATA_LEN] = {0};
|
||
/************************************************************
|
||
* 函数功能:设置vlan bitmap某位
|
||
* 输入:
|
||
* 输出:
|
||
* 返回值:
|
||
************************************************************/
|
||
void vlan_bitmap_set(int *v, int i)
|
||
{
|
||
if(!v || i < 0){
|
||
printf("[vlan]vlan_bitmap_set: input error.\n");
|
||
return;
|
||
}
|
||
v[i >> SHIFT] |= (1 << (i & MASK));
|
||
}
|
||
|
||
/************************************************************
|
||
* 函数功能:清除vlan bitmap某位
|
||
* 输入:
|
||
* 输出:
|
||
* 返回值:
|
||
************************************************************/
|
||
void vlan_bitmap_clear(int *v, int i)
|
||
{
|
||
if(!v || i < 0){
|
||
printf("[vlan]vlan_bitmap_clear: input error.\n");
|
||
return;
|
||
}
|
||
v[i >> SHIFT] &= ~(1 << (i & MASK));
|
||
}
|
||
|
||
/************************************************************
|
||
* 函数功能:查询vlan bitmap某位是否被设置
|
||
* 输入:
|
||
* 输出:
|
||
* 返回值:
|
||
************************************************************/
|
||
int vlan_bitmap_check(int *v, int i)
|
||
{
|
||
if(!v || i < 0){
|
||
printf("[vlan]vlan_bitmap_check: input error.\n");
|
||
return -1;
|
||
}
|
||
return v[i >> SHIFT] & (1 << (i & MASK));
|
||
}
|
||
|
||
|
||
/************************************************************
|
||
* 函数功能:根据if_name查找attr在g_if_vlan_info[]中遍历
|
||
* if_name,求得其attr
|
||
* 输入:
|
||
* 输出:
|
||
* 返回值:
|
||
************************************************************/
|
||
interface_link_attr get_attr_from_ifname(char *if_name)
|
||
{
|
||
if(!if_name){
|
||
return LINK_TYPE_UNKNOWN;
|
||
}
|
||
int ifnode;
|
||
ifnode = get_ifnode_from_global(if_name);
|
||
if(ifnode == -1){
|
||
printf("[vlan]get_attr_from_ifname: ifnode is -1.\n");
|
||
return LINK_TYPE_UNKNOWN;
|
||
}
|
||
return g_if_vlan_info[ifnode].attr;
|
||
}
|
||
|
||
/************************************************************
|
||
* 函数功能:根据物理接口名称和vid生成子接口名称
|
||
* 输入:if_name、vid
|
||
* 输出:subif
|
||
* 返回值:
|
||
************************************************************/
|
||
int if_vlan2subif(char *if_name, int vid, char *subif)
|
||
{
|
||
if(!if_name || !subif){
|
||
printf("[vlan]if_vlan2subif: input error.\n");
|
||
return -1;
|
||
}
|
||
sprintf(subif, "%s.%d", if_name, vid);
|
||
return 0;
|
||
}
|
||
|
||
int br_if_num_stub(char *br_name, operation_type op_type)
|
||
{
|
||
int ret = 0;
|
||
if(op_type == OP_ADD){
|
||
ret = 0;
|
||
}
|
||
else if(op_type == OP_MOD){
|
||
ret = 1;
|
||
}
|
||
else if(op_type == OP_DEL){
|
||
ret = 0;
|
||
}
|
||
return ret;
|
||
}
|
||
/************************************************************
|
||
* 函数功能:返回br上的接口数目
|
||
* 输入:
|
||
* 输出:
|
||
* 返回值:
|
||
************************************************************/
|
||
int br_if_num(char *br_name)
|
||
{
|
||
return br_if_num_stub(br_name, OP_ADD);
|
||
}
|
||
|
||
int create_br_stub(char *br_vlname)
|
||
{
|
||
char buf[SYSCALL_BUF_LEN] = {0};
|
||
sprintf(buf, "brctl addbr %s", br_vlname);
|
||
system(buf);
|
||
return 0;
|
||
}
|
||
/************************************************************
|
||
* 函数功能:创建br
|
||
* 输入:
|
||
* 输出:
|
||
* 返回值:
|
||
************************************************************/
|
||
int create_br(char *br_vlname)
|
||
{
|
||
return create_br_stub(br_vlname);
|
||
}
|
||
|
||
int br_addif_stub(char *br_name, char *if_name)
|
||
{
|
||
char buf[SYSCALL_BUF_LEN] = {0};
|
||
sprintf(buf, "brctl addif %s %s", br_name, if_name);
|
||
system(buf);
|
||
return 0;
|
||
}
|
||
/************************************************************
|
||
* 函数功能:将接口加入br
|
||
* 输入:
|
||
* 输出:
|
||
* 返回值:
|
||
************************************************************/
|
||
int br_addif(char *br_name, char *if_name)
|
||
{
|
||
return br_addif_stub(br_name, if_name);
|
||
}
|
||
|
||
int interface_br_stub(char *if_name, char *br_name)
|
||
{
|
||
return 0;
|
||
}
|
||
/************************************************************
|
||
* 函数功能:判断某个接口是否在br上,在哪个br上
|
||
* 输入:
|
||
* 输出:br_name
|
||
* 返回值:
|
||
************************************************************/
|
||
int interface_br(char *if_name, char *br_name)
|
||
{
|
||
/* 先打桩处理 */
|
||
return interface_br_stub(if_name, br_name);
|
||
}
|
||
|
||
int del_br_stub(char *br_name)
|
||
{
|
||
char buf[SYSCALL_BUF_LEN] = {0};
|
||
sprintf(buf, "brctl delbr %s", br_name);
|
||
system(buf);
|
||
return 0;
|
||
}
|
||
/************************************************************
|
||
* 函数功能:删除br
|
||
* 输入:
|
||
* 输出:
|
||
* 返回值:
|
||
************************************************************/
|
||
int del_br(char *br_name)
|
||
{
|
||
return del_br_stub(br_name);
|
||
}
|
||
|
||
/************************************************************
|
||
* 函数功能:判断接口属于何种模型:路由桥接 or 桥接
|
||
* 目前只支持路由桥接
|
||
* 输入:
|
||
* 输出:
|
||
* 返回值:
|
||
************************************************************/
|
||
interface_model which_interface_model(char *if_name)
|
||
{
|
||
return INTERFACE_MODEL_ROUTE_FORWARD;
|
||
}
|
||
|
||
|
||
/************************************************************
|
||
* 函数功能:初始化init,这个应该放在配置管理的init,
|
||
* 而不是配置触发阶段的这里,后面再调整
|
||
* 输入:
|
||
* 输出:
|
||
* 返回值:
|
||
************************************************************/
|
||
ret_code vlan_config_init(void)
|
||
{
|
||
ret_code ret = RET_OK;
|
||
//int sys_ret = 0;
|
||
|
||
(void)system("modprobe 8021q");
|
||
|
||
ret = br_event_register(BR_IF_LEAVE_EVENT_PRE, del_interface_vlan_cb);
|
||
if(ret != RET_OK){
|
||
printf("[vlan]vlan_config_init: event register failed(%d).\n", ret);
|
||
return ret;
|
||
}
|
||
#if 0
|
||
/* 创建br0 */
|
||
ret = br_bridge_add("br0", &sys_ret);
|
||
if(ret != RET_OK){
|
||
printf("[vlan]vlan_config_init: br0_bridge_add failed(%d)\n", sys_ret);
|
||
return;
|
||
}
|
||
/* 将子接口添加进br0 */
|
||
br_if_bridge_add("br0", "ens38", 1, &sys_ret);
|
||
if(sys_ret != 0){
|
||
printf("[vlan]vlan_config_init: br0_if_bridge_add failed(%d)(%s)\n", sys_ret, strerror(sys_ret));
|
||
return;
|
||
}
|
||
|
||
/* 创建br1 */
|
||
ret = br_bridge_add("br1", &sys_ret);
|
||
if(ret != RET_OK){
|
||
printf("[vlan]vlan_config_init: br1_bridge_add failed(%d)\n", sys_ret);
|
||
return;
|
||
}
|
||
/* 将子接口添加进br1 */
|
||
br_if_bridge_add("br1", "ens39", 1, &sys_ret);
|
||
if(sys_ret != 0){
|
||
printf("[vlan]vlan_config_init: br1_if_bridge_add failed(%d)(%s)\n", sys_ret, strerror(sys_ret));
|
||
return;
|
||
}
|
||
#endif
|
||
return ret;
|
||
}
|
||
|
||
/************************************************************
|
||
* 函数功能:添加桥接模式的access vlan
|
||
* 目前只支持路由桥接,涉及桥接的暂不实现
|
||
* 输入:
|
||
* 输出:
|
||
* 返回值:
|
||
************************************************************/
|
||
int add_bridge_vlan_access(char *if_name, int vid)
|
||
{
|
||
//系统调用("bridge vlan add vid %d dev %s pvid untagged", vid, if_name);
|
||
//调用张亮的iproute2接口,创建bridge vlan
|
||
return 0;
|
||
}
|
||
|
||
|
||
/************************************************************
|
||
* 函数功能:校验:之前是否添加过该接口
|
||
* 输入:
|
||
* 输出:
|
||
* 返回值: 0:未配置过
|
||
* 1:配置过
|
||
************************************************************/
|
||
int check_config(char *if_name)
|
||
{
|
||
int i;
|
||
|
||
for(i = 0; i < MAX_INTERFACES; i++){
|
||
if(!strcmp(g_if_vlan_info[i].if_name, if_name)){
|
||
printf("[vlan]check_config:already exists, return 1\n");
|
||
return 1;
|
||
}
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
/************************************************************
|
||
* 函数功能:添加access vlan
|
||
* 目前只支持路由桥接,涉及桥接的暂不实现
|
||
* 输入:
|
||
* 输出:
|
||
* 返回值:
|
||
************************************************************/
|
||
int add_interface_vlan_access(char *if_name, int *vlan_bitmap, interface_model if_model)
|
||
{
|
||
int i;
|
||
|
||
/* 检查接口属于何种模型 */
|
||
if(INTERFACE_MODEL_FORWARD != if_model){
|
||
printf("access必须属于桥接模型,否则报错\n");
|
||
return -1;
|
||
}
|
||
|
||
for(i = VID_MIN; i <= VID_MAX; i++){
|
||
if(vlan_bitmap_check(vlan_bitmap, i)){
|
||
return add_bridge_vlan_access(if_name, i);
|
||
}
|
||
}
|
||
return -1;
|
||
}
|
||
|
||
/************************************************************
|
||
* 函数功能:添加trunk vlan
|
||
* 目前只支持路由桥接,涉及桥接的暂不实现
|
||
* vids[i]如果为1,表示配置了vlan的vid为i
|
||
* 输入:
|
||
* 输出:
|
||
* 返回值:
|
||
************************************************************/
|
||
|
||
int add_bridge_vlan_trunk(char *if_name, int *vlan_bitmap)
|
||
{
|
||
int i;
|
||
char buf[SYSCALL_BUF_LEN] = {0};
|
||
if(!if_name || !vlan_bitmap){
|
||
return -1;
|
||
}
|
||
for(i = VID_MIN; i <= VID_MAX; i++){
|
||
if(vlan_bitmap_check(vlan_bitmap, i)){
|
||
sprintf(buf,"bridge vlan add vid %d dev %s", i, if_name);//after change to snprintf
|
||
system(buf);//after change to execv
|
||
return 0;
|
||
}
|
||
}
|
||
return -1;
|
||
}
|
||
|
||
|
||
/************************************************************
|
||
* 函数功能:创建vlan子接口
|
||
* vids[i]如果为1,表示配置了vlan的vid为i
|
||
* 遍历vid从2开始
|
||
* 输入:
|
||
* 输出:
|
||
* 返回值:
|
||
************************************************************/
|
||
ret_code add_vlan_sub_interface(char *if_name, int *vlan_bitmap)
|
||
{
|
||
if(!if_name || !vlan_bitmap){
|
||
printf("[vlan]add_vlan_sub_interface: input is null.\n");
|
||
return RET_NULLP;
|
||
}
|
||
printf("[vlan]add_vlan_sub_interface: begin.\n");
|
||
int vid;
|
||
char subif[IF_NAME_LEN] = {0};
|
||
char buf[SYSCALL_BUF_LEN] = {0};
|
||
char br_vlname[BR_VLAN_NAME_LEN] = {0};
|
||
char tmp_brname[BR_VLAN_NAME_LEN] = {0};
|
||
int sys_ret = 0, status = 0;
|
||
ret_code ret = RET_OK;
|
||
for(vid = VID_MIN; vid <= VID_MAX; vid++){
|
||
if(vlan_bitmap_check(vlan_bitmap, vid)){
|
||
|
||
/* vconfig创建子接口 */
|
||
sprintf(buf, "vconfig add %s %d", if_name, vid);
|
||
printf("[vlan]add_vlan_sub_interface: vconfig buf=%s\n", buf);
|
||
status = system(buf);
|
||
if(status != 0){
|
||
printf("[vlan]add_vlan_sub_if: subif status error. (%s)\n", strerror(errno));
|
||
return RET_SYS_VCONFIG_ERR;
|
||
}
|
||
memset(buf, 0, SYSCALL_BUF_LEN);
|
||
|
||
/* 生成子接口 */
|
||
(void)if_vlan2subif(if_name, vid, subif);
|
||
sprintf(buf, "ifconfig %s up", subif);
|
||
printf("[vlan]add_vlan_sub_interface: ifconfig sub buf=%s\n", buf);
|
||
status = system(buf);
|
||
if(status != 0){
|
||
printf("[vlan]add_vlan_sub_if: ifconfig subif status error. (%s)\n", strerror(errno));
|
||
return RET_SYS_IFCONFIG_ERR;
|
||
}
|
||
memset(buf, 0, SYSCALL_BUF_LEN);
|
||
|
||
/* WAN口不需要建桥 */
|
||
/* 如果返回不是RET_OK,则说明是WAN口,不需要做后面的建vlan桥,继续下一个循环 */
|
||
if(RET_OK != br_if_bridge_get(if_name, tmp_brname)){
|
||
printf("[vlan]add_vlan_sub_interface: port is WAN, don't creat br-vl and addif, continue\n");
|
||
memset(subif, 0, IF_NAME_LEN);
|
||
memset(tmp_brname, 0, BR_VLAN_NAME_LEN);
|
||
continue;
|
||
}
|
||
/* 生成br-vl桥 */
|
||
sprintf(br_vlname, "br-vl%d", vid);
|
||
printf("[vlan]add_vlan_sub_interface: br_vlname=%s\n", br_vlname);
|
||
|
||
/* 查询生成的br-vl是否存在,不存在则创建br-vl */
|
||
if(br_is_exist(br_vlname) == FALSE){
|
||
ret = br_bridge_add(br_vlname);
|
||
if(ret != RET_OK){
|
||
printf("[vlan]add_vlan_sub_interface: br_bridge_add failed(%s)\n", strerror(errno));
|
||
return ret;
|
||
}
|
||
}
|
||
|
||
/* 将子接口添加进br */
|
||
br_if_bridge_add(br_vlname, subif, 1);
|
||
if(ret != RET_OK){
|
||
printf("[vlan]add_vlan_sub_interface: br_if_bridge_add failed(%s)\n", strerror(errno));
|
||
return ret;
|
||
}
|
||
memset(subif, 0, IF_NAME_LEN);
|
||
memset(br_vlname, 0, BR_VLAN_NAME_LEN);
|
||
}
|
||
}
|
||
return RET_OK;
|
||
}
|
||
|
||
|
||
/************************************************************
|
||
* 函数功能:创建vlan trunk
|
||
* 输入:
|
||
* 输出:
|
||
* 返回值:
|
||
************************************************************/
|
||
ret_code add_interface_vlan_trunk(char *if_name, int *vlan_bitmap, interface_model if_model)
|
||
{
|
||
ret_code ret = RET_OK;
|
||
/* 桥接 */
|
||
if(INTERFACE_MODEL_FORWARD == if_model){
|
||
ret = add_bridge_vlan_trunk(if_name, vlan_bitmap);
|
||
}
|
||
|
||
/* 路由桥接,需创建子接口和br-vlan */
|
||
else if(INTERFACE_MODEL_ROUTE_FORWARD == if_model){
|
||
ret = add_vlan_sub_interface(if_name, vlan_bitmap);
|
||
}
|
||
|
||
return ret;
|
||
}
|
||
|
||
|
||
/************************************************************
|
||
* 函数功能:添加接口vlan
|
||
* 输入:
|
||
* 输出:
|
||
* 返回值:
|
||
************************************************************/
|
||
ret_code add_interface_vlan(interface_vlan_info *if_vlan_info)
|
||
{
|
||
interface_link_attr new_attr = if_vlan_info->attr;
|
||
ret_code ret = RET_OK;
|
||
/* 配置校验 */
|
||
//ret = check_config(if_vlan_info->if_name);
|
||
//if(0 != ret){
|
||
//return -1;
|
||
//}
|
||
|
||
/* 接口模型赋值 */
|
||
if_vlan_info->if_model = which_interface_model(if_vlan_info->if_name);
|
||
|
||
/* 判断链路类型 */
|
||
if(new_attr == LINK_TYPE_TRUNK){
|
||
ret = add_interface_vlan_trunk(if_vlan_info->if_name, if_vlan_info->vlan_bitmap, if_vlan_info->if_model);
|
||
if(ret != RET_OK){
|
||
printf("[vlan]add_interface_vlan: add trunk failed.\n");
|
||
return ret;
|
||
}
|
||
}
|
||
else if(new_attr == LINK_TYPE_ACCESS){
|
||
ret = add_interface_vlan_access(if_vlan_info->if_name, if_vlan_info->vlan_bitmap, if_vlan_info->if_model);
|
||
if(ret != RET_OK){
|
||
printf("[vlan]add_interface_vlan: add access failed.\n");
|
||
return ret;
|
||
}
|
||
}
|
||
else{
|
||
printf("[vlan]add_interface_vlan: LINK-TYPE attr(%d) input error.\n", new_attr);
|
||
return RET_ATTR_INVALID;
|
||
}
|
||
|
||
/* 更新全局接口vlan数据结构 */
|
||
ret = refresh_if_vlan_info(if_vlan_info);
|
||
return ret;
|
||
}
|
||
|
||
/************************************************************
|
||
* 函数功能:删除bridge vlan
|
||
* 目前用不到,目前不支持桥接
|
||
* 输入:
|
||
* 输出:
|
||
* 返回值:
|
||
************************************************************/
|
||
int del_bridge_vlan_access(char *if_name)
|
||
{
|
||
int vid;
|
||
char buf[SYSCALL_BUF_LEN] = {0};
|
||
int ifnode;
|
||
ifnode = get_ifnode_from_global(if_name);
|
||
|
||
/* 在这个节点i上再遍历VLAN,找到该节点所有的vlan j,j有多个
|
||
找到一个j,拼接成一个子接口,删除这个子接口*/
|
||
for(vid = VID_MIN; vid <= VID_MAX; vid++){
|
||
if(vlan_bitmap_check(g_if_vlan_info[ifnode].vlan_bitmap, vid)){
|
||
sprintf(buf, "bridge vlan del vid %d dev %s pvid untagged", vid, if_name);
|
||
system(buf);
|
||
memset(buf, 0, SYSCALL_BUF_LEN);
|
||
sprintf(buf, "bridge vlan add vid %d dev %s pvid untagged", 1, if_name);
|
||
system(buf);
|
||
memset(buf, 0, SYSCALL_BUF_LEN);
|
||
}
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
/************************************************************
|
||
* 函数功能:删除access vlan
|
||
* 目前用不到,目前不支持桥接
|
||
* 输入:
|
||
* 输出:
|
||
* 返回值:
|
||
************************************************************/
|
||
int del_interface_vlan_access(char *if_name, interface_model if_model)
|
||
{
|
||
int ret;
|
||
/* 检查接口属于何种模型 */
|
||
if(INTERFACE_MODEL_FORWARD != if_model){
|
||
printf("access必须属于桥接模型,否则报错\n");
|
||
return -1;
|
||
}
|
||
ret = del_bridge_vlan_access(if_name);
|
||
return ret;
|
||
}
|
||
|
||
/************************************************************
|
||
* 函数功能:删除trunk vlan
|
||
* 输入:
|
||
* 输出:
|
||
* 返回值:
|
||
************************************************************/
|
||
int del_bridge_vlan_trunk(char *if_name)
|
||
{
|
||
int ifnode, vid;
|
||
char buf[SYSCALL_BUF_LEN] = {0};
|
||
|
||
/* 根据ifname遍历全局结构中在哪个节点i上,i只有一个 */
|
||
for(ifnode = 0; ifnode < MAX_INTERFACES; ifnode++){
|
||
if(!strcmp(g_if_vlan_info[ifnode].if_name, if_name)){
|
||
break;
|
||
}
|
||
}
|
||
/* 没找到 */
|
||
if(ifnode >= MAX_INTERFACES){
|
||
return -1;
|
||
}
|
||
|
||
/* 在这个节点i上再遍历VLAN,找到该节点所有的vlan j,j有多个 */
|
||
for(vid = 1; vid < MAX_VLAN; vid++){
|
||
//if(g_if_vlan_info[i].vid[j]){
|
||
if(vlan_bitmap_check(g_if_vlan_info[ifnode].vlan_bitmap, vid)){
|
||
sprintf(buf, "bridge vlan del vid %d dev %s", vid, if_name);
|
||
system(buf);
|
||
memset(buf, 0, SYSCALL_BUF_LEN);
|
||
}
|
||
}
|
||
|
||
/* 恢复vlan 1 pvid untagged */
|
||
sprintf(buf, "bridge vlan add vid %d dev %s pvid untagged", 1, if_name);
|
||
system(buf);
|
||
return 0;
|
||
}
|
||
|
||
interface_network_type lan_or_wan_stub(char *if_name)
|
||
{
|
||
return IF_TYPE_LAN;
|
||
}
|
||
|
||
/************************************************************
|
||
* 函数功能:读配置文件区分LAN还是WAN
|
||
* 输入:
|
||
* 输出:
|
||
* 返回值:
|
||
************************************************************/
|
||
|
||
interface_network_type lan_or_wan(char *if_name)
|
||
{
|
||
return lan_or_wan_stub(if_name);
|
||
}
|
||
|
||
/************************************************************
|
||
* 函数功能:删除vlan子接口
|
||
* 这里不用做校验了,前面chk校验过了
|
||
* 输入:
|
||
* 输出:
|
||
* 返回值:
|
||
************************************************************/
|
||
ret_code del_vlan_sub_interface(char *if_name, int *vlan_bitmap)
|
||
{
|
||
int ifnode, vid;
|
||
char br_vlname[BR_VLAN_NAME_LEN] = {0};
|
||
char tmp_brname[BR_VLAN_NAME_LEN] = {0};
|
||
char subif[IF_NAME_LEN]= {0};
|
||
char buf[SYSCALL_BUF_LEN] = {0};
|
||
int sys_ret = 0, status = 0, num = 0;
|
||
ret_code ret = RET_OK;
|
||
if(!if_name || !vlan_bitmap){
|
||
return -1;
|
||
}
|
||
printf("[vlan]del_vlan_sub_interface: begin.\n");
|
||
|
||
/* 在这个节点i上再遍历VLAN,找到该节点所有的vlan j,j有多个
|
||
找到一个j,拼接成一个子接口,删除这个子接口*/
|
||
for(vid = VID_MIN; vid <= VID_MAX; vid++){
|
||
if(vlan_bitmap_check(vlan_bitmap, vid)){//这里就不做校验了,下发哪个vid,就删除哪个
|
||
/* 生成子接口 */
|
||
(void)if_vlan2subif(if_name, vid, subif);
|
||
|
||
/* 查询物理口是否挂桥上 */
|
||
ret = br_if_bridge_get(if_name, tmp_brname);
|
||
|
||
/* 没找到桥,是WAN,只删除VLAN子接口 */
|
||
if(RET_NOTFOUND == ret){
|
||
printf("[vlan]del_vlan_sub_interface: %s is WAN,only del vlansubif\n", if_name);
|
||
/* 删除vlan子接口 */
|
||
sprintf(buf, "vconfig rem %s", subif);
|
||
printf("[vlan]del_vlan_sub_interface: buf=%s\n", buf);
|
||
status = system(buf);
|
||
if(status != 0){
|
||
printf("[vlan]del_vlan_sub_if:status error. (%s)\n", strerror(errno));
|
||
return RET_SYS_VCONFIG_ERR;
|
||
}
|
||
memset(buf, 0, SYSCALL_BUF_LEN);
|
||
memset(tmp_brname, 0, BR_VLAN_NAME_LEN);
|
||
memset(subif, 0, IF_NAME_LEN);
|
||
}
|
||
/* 找到桥了,是LAN */
|
||
else if(RET_OK == ret){
|
||
sprintf(br_vlname, "br-vl%d", vid);
|
||
printf("[vlan]del_vlan_sub_interface: br_vlname=%s\n", br_vlname);
|
||
|
||
/* 如果br-vlxx不存在,报错返回 */
|
||
if(br_is_exist(br_vlname) == FALSE){
|
||
printf("[vlan]del_vlan_sub_interface: %s is not exist, error,return.\n", br_vlname);
|
||
return RET_UNKNOWN;
|
||
}
|
||
|
||
/* brctl delif删除br-vl上的vlan子接口 */
|
||
printf("[vlan]del_vlan_sub_interface: br-vl%d delif %s\n", vid, subif);
|
||
ret = br_if_bridge_del(br_vlname, subif, 1);
|
||
if(ret != RET_OK){
|
||
printf("[vlan]del_vlan_sub_interface: br_if_bridge_del error(%s).\n", strerror(errno));
|
||
return ret;
|
||
}
|
||
|
||
/* 删除vlan子接口 */
|
||
sprintf(buf, "vconfig rem %s", subif);
|
||
printf("[vlan]del_vlan_sub_interface: buf=%s\n", buf);
|
||
status = system(buf);
|
||
if(status != 0){
|
||
printf("[vlan]del_vlan_sub_if:status error. (%s)\n",strerror(errno));
|
||
return RET_SYS_VCONFIG_ERR;
|
||
}
|
||
memset(buf, 0, SYSCALL_BUF_LEN);
|
||
|
||
|
||
/* br-vlan上的接口数为0,则删除br-vlan */
|
||
num = br_if_bridge_num(br_vlname);
|
||
printf("[vlan]del_vlan_sub_interface: num=%d\n", num);
|
||
if(num == 0){
|
||
printf("[vlan]del_vlan_sub_interface: br's port is zero.\n");
|
||
ret = br_bridge_del(br_vlname);
|
||
if(ret != RET_OK){
|
||
printf("[vlan]del_vlan_sub_interface: del br failed(%s).\n", strerror(errno));
|
||
return ret;
|
||
}
|
||
}
|
||
memset(br_vlname, 0, BR_VLAN_NAME_LEN);
|
||
memset(subif, 0, IF_NAME_LEN);
|
||
memset(buf, 0, SYSCALL_BUF_LEN);
|
||
}
|
||
}
|
||
}
|
||
return RET_OK;
|
||
}
|
||
|
||
/************************************************************
|
||
* 函数功能:删除vlan trunk
|
||
* 输入:
|
||
* 输出:
|
||
* 返回值:
|
||
************************************************************/
|
||
ret_code del_interface_vlan_trunk(char *if_name, int *vlan_bitmap, interface_model if_model)
|
||
{
|
||
ret_code ret = RET_OK;
|
||
/* 桥接 */
|
||
if(INTERFACE_MODEL_FORWARD == if_model){
|
||
ret = del_bridge_vlan_trunk(if_name);
|
||
}
|
||
|
||
/* 路由桥接,需创建子接口和br-vlan */
|
||
else if(INTERFACE_MODEL_ROUTE_FORWARD == if_model){
|
||
ret = del_vlan_sub_interface(if_name, vlan_bitmap);
|
||
}
|
||
|
||
return ret;
|
||
}
|
||
|
||
|
||
/************************************************************
|
||
* 函数功能:在全局if_vlan结构中查找之前配置过的节点或者
|
||
* 空节点,以便插入
|
||
* 存在两种情况,一种是当前配置的接口,在之前已经配置过,匹配
|
||
* 出来在次节点更新就行,如果之前没配置过,那找到新节点插入
|
||
* 输入:
|
||
* 输出:
|
||
* 返回值: -1:没有空位置了
|
||
ifnode:第ifnode个位置
|
||
************************************************************/
|
||
int find_insert_ifnode_from_global(char *if_name)
|
||
{
|
||
int ifnode;
|
||
if(!if_name){
|
||
return -1;
|
||
}
|
||
|
||
/* 找到之前已经配置过的节点位置 */
|
||
for(ifnode = 0; ifnode < MAX_INTERFACES; ifnode++){
|
||
if(!strcmp(g_if_vlan_info[ifnode].if_name, if_name)){
|
||
printf("[vlan]find_empty_ifnode_from_global: find exist gnode[%d].%s\n", ifnode, if_name);
|
||
return ifnode;
|
||
}
|
||
}
|
||
|
||
/* 找到一个空的,插入 */
|
||
for(ifnode = 0; ifnode < MAX_INTERFACES; ifnode++){
|
||
if(!strcmp(g_if_vlan_info[ifnode].if_name, "")){
|
||
printf("[vlan]find_empty_ifnode_from_global: find empty gnode[%d]\n", ifnode);
|
||
return ifnode;
|
||
}
|
||
}
|
||
|
||
/* 说明满了,没有空的可插入信息的节点了 */
|
||
return -1;
|
||
}
|
||
|
||
/************************************************************
|
||
* 函数功能:ADD操作更新全局结构
|
||
* 输入:
|
||
* 输出:
|
||
* 返回值:
|
||
************************************************************/
|
||
ret_code refresh_if_vlan_info_op_add(interface_vlan_info *if_vlan_info)
|
||
{
|
||
int ifnode;
|
||
int vid;
|
||
if(!if_vlan_info){
|
||
return -1;
|
||
}
|
||
ifnode = find_insert_ifnode_from_global(if_vlan_info->if_name);
|
||
|
||
/* 没找到空白可插入信息的节点,add出错 */
|
||
if(-1 == ifnode){
|
||
printf("[vlan]refresh_if_vlan_info_op_add: donot find empty node.\n");
|
||
return -1;
|
||
}
|
||
printf("[vlan]refresh_if_vlan_info_op_add: find node[%d].ifname=%s\n", ifnode, if_vlan_info->if_name);
|
||
|
||
/* 更新ifname, attr, op_type, if_model */
|
||
memcpy(g_if_vlan_info[ifnode].if_name, if_vlan_info->if_name, strlen(if_vlan_info->if_name));
|
||
g_if_vlan_info[ifnode].attr = if_vlan_info->attr;
|
||
g_if_vlan_info[ifnode].op_type = if_vlan_info->op_type;
|
||
g_if_vlan_info[ifnode].if_model = if_vlan_info->if_model;
|
||
printf("[vlan]refresh_op_add: node[%d]'s info::\nif_name=%s, attr=%d, op_type=%d, if_model=%d\n",
|
||
ifnode, if_vlan_info->if_name, if_vlan_info->attr,
|
||
if_vlan_info->op_type, if_vlan_info->if_model);
|
||
/* 更新vlanbitmap */
|
||
printf("[vlan]refresh_op_add: vlan_info:\n<");
|
||
for(vid = VID_MIN; vid <= VID_MAX; vid++){
|
||
/* 如果找到了vid存在,则在全局结构的vlan_bitmap中设置vid bitmap */
|
||
if(vlan_bitmap_check(if_vlan_info->vlan_bitmap, vid)){
|
||
vlan_bitmap_set(g_if_vlan_info[ifnode].vlan_bitmap, vid);
|
||
g_if_vlan_info[ifnode].vidcnt++;
|
||
printf("%d, ", vid);
|
||
}
|
||
}
|
||
printf(">\n");
|
||
return 0;
|
||
}
|
||
|
||
|
||
/************************************************************
|
||
* 函数功能:DEL操作更新全局结构
|
||
* 输入:
|
||
* 输出:
|
||
* 返回值:
|
||
************************************************************/
|
||
ret_code refresh_if_vlan_info_op_del(interface_vlan_info *if_vlan_info)
|
||
{
|
||
int ifnode;
|
||
int vid = 0;
|
||
if(!if_vlan_info){
|
||
return -1;
|
||
}
|
||
ifnode = get_ifnode_from_global(if_vlan_info->if_name);
|
||
/* 如果==-1说明没找到,就不是del了 */
|
||
if(-1 == ifnode){
|
||
return -1;
|
||
}
|
||
|
||
/* 没找到对应的节点 */
|
||
if(ifnode >= MAX_INTERFACES){
|
||
return -1;
|
||
}
|
||
#if 0
|
||
/* 清除第ifnode节点的信息 */
|
||
memset(&g_if_vlan_info[ifnode], 0, sizeof(g_if_vlan_info[ifnode]));
|
||
printf("\n\n\n\n\n[vlan]refresh_op_del: g.ifname=%s, g.attr=%d, g.op_type=%d, g.ifmodel=%d\n",
|
||
g_if_vlan_info[ifnode].if_name, g_if_vlan_info[ifnode].attr,
|
||
g_if_vlan_info[ifnode].op_type, g_if_vlan_info[ifnode].if_model);
|
||
printf("[vlan]refresh_op_del: if_vlan_info vid:\n");
|
||
for(vid = 2; vid < MAX_VLAN; vid++){
|
||
if(vlan_bitmap_check(if_vlan_info->vlan_bitmap, vid)){
|
||
printf("%d\n", vid);
|
||
}
|
||
}
|
||
|
||
printf("[vlan]refresh_op_del: g_if_vlan_info vid:\n");
|
||
for(vid = 2; vid < MAX_VLAN; vid++){
|
||
if(vlan_bitmap_check(g_if_vlan_info[ifnode].vlan_bitmap, vid)){
|
||
printf("%d\n", vid);
|
||
}
|
||
}
|
||
#endif
|
||
/* 打印之前全局g结构信息 */
|
||
printf("[vlan]refresh_if_vlan_info_op_del: Before Gloabl node information:::::\n");
|
||
printf("[vlan]refresh_if_vlan_info_op_del: nodeid=%d, if_name=%s, op_type=%d, attr=%d, vid=["
|
||
, ifnode, g_if_vlan_info[ifnode].if_name, g_if_vlan_info[ifnode].op_type
|
||
, g_if_vlan_info[ifnode].attr);
|
||
|
||
for(vid = VID_MIN; vid <= VID_MAX; vid++){
|
||
if(vlan_bitmap_check(g_if_vlan_info[ifnode].vlan_bitmap, vid)){
|
||
printf("%d, ", vid);
|
||
}
|
||
}
|
||
printf("]\n");
|
||
|
||
/* 打印新下发结构信息 */
|
||
printf("[vlan]refresh_if_vlan_info_op_del: config if_vlan_info node information:::::\n");
|
||
printf("[vlan]refresh_if_vlan_info_op_del: if_name=%s, op_type=%d, attr=%d, vid=["
|
||
, if_vlan_info->if_name, if_vlan_info->op_type
|
||
, if_vlan_info->attr);
|
||
|
||
for(vid = VID_MIN; vid <= VID_MAX; vid++){
|
||
if(vlan_bitmap_check(if_vlan_info->vlan_bitmap, vid)){
|
||
printf("%d, ", vid);
|
||
}
|
||
}
|
||
printf("]\n");
|
||
|
||
printf("[vlan]refresh_if_vlan_info_op_del: if_vlan_info delete vid:[");
|
||
for(vid = VID_MIN; vid <= VID_MAX; vid++){
|
||
/* 去新下发结构if_vlan_info取配置的vid,
|
||
在旧的结构全局g_if_vlan_info中清除这些vid */
|
||
if(vlan_bitmap_check(if_vlan_info->vlan_bitmap, vid)){
|
||
printf("%d, ", vid);
|
||
vlan_bitmap_clear(g_if_vlan_info[ifnode].vlan_bitmap, vid);
|
||
g_if_vlan_info[ifnode].vidcnt--;
|
||
}
|
||
}
|
||
printf("]\n");
|
||
printf("[vlan]refresh_if_vlan_info_op_del: g_[%d].vidcnt=%d\n", ifnode, g_if_vlan_info[ifnode].vidcnt);
|
||
|
||
/* 如果本接口上还有vid,则不处理,如果没有,则清除接口信息 */
|
||
/* 如果vcnt == 0 说明idnode下已经没有vid了,清除ifnode信息 */
|
||
if(g_if_vlan_info[ifnode].vidcnt == 0){
|
||
printf("[vlan]refresh_if_vlan_info_op_del: clean g_if_vlan_info[%d] info.\n", ifnode);
|
||
memset(&g_if_vlan_info[ifnode], 0, sizeof(interface_vlan_info));
|
||
}
|
||
#if 0
|
||
printf("[vlan]refresh_if_vlan_info_op_del: g_vlan_info[%d],vid left:[", ifnode);
|
||
for(vid = VID_MIN; vid <= VID_MAX; vid++){
|
||
if(vlan_bitmap_check(g_if_vlan_info[ifnode].vlan_bitmap, vid)){
|
||
printf("%d, ", vid);
|
||
vcnt++;
|
||
}
|
||
}
|
||
printf("]\n");
|
||
/* 如果vcnt == 0 说明idnode下已经没有vid了,清除ifnode信息 */
|
||
if(vcnt == 0){
|
||
printf("[vlan]refresh_if_vlan_info_op_del: clean g_if_vlan_info[%d] info.\n", ifnode);
|
||
memset(&g_if_vlan_info[ifnode], 0, sizeof(interface_vlan_info));
|
||
}
|
||
#endif
|
||
return 0;
|
||
}
|
||
|
||
/************************************************************
|
||
* 函数功能:根据ifname获取全局结构中所在节点编号
|
||
* 输入:
|
||
* 输出:
|
||
* 返回值: -1:没找到
|
||
ifnode: 第ifnode个节点
|
||
************************************************************/
|
||
int get_ifnode_from_global(char *if_name)
|
||
{
|
||
int ifnode;
|
||
if(!if_name){
|
||
return -1;
|
||
}
|
||
if(!strcmp(if_name, "")){
|
||
printf("[vlan]get_ifnode_from_global: if_name is empty.\n");
|
||
return -1;
|
||
}
|
||
for(ifnode = 0; ifnode < MAX_INTERFACES; ifnode++){
|
||
if(!strcmp(g_if_vlan_info[ifnode].if_name, if_name)){
|
||
printf("[vlan]get_ifnode_from_global: find gnode[%d], ifname=%s\n", ifnode, if_name);
|
||
return ifnode;
|
||
}
|
||
}
|
||
return -1;
|
||
}
|
||
|
||
/************************************************************
|
||
* 函数功能:ADD操作存配置文件
|
||
* 输入:
|
||
* 输出:
|
||
* 返回值:
|
||
************************************************************/
|
||
ret_code vlan_save_conf_file_add(interface_vlan_info *if_vlan_info)
|
||
{
|
||
int vid;
|
||
char subif[IF_NAME_LEN] = {0};
|
||
char *addr_name = "address";
|
||
char addr_buff[IF_BUFF_LEN] = {0};
|
||
if(!if_vlan_info){
|
||
return RET_NULLP;
|
||
}
|
||
printf("[vlan]save_conf_file_add: begin.\n");
|
||
sprintf(addr_buff, "address %d\n", 0);
|
||
for(vid = VID_MIN; vid <= VID_MAX; vid++){
|
||
if(vlan_bitmap_check(if_vlan_info->vlan_bitmap, vid)){
|
||
(void)if_vlan2subif(if_vlan_info->if_name, vid, subif);
|
||
printf("[vlan]save_conf_file_add: vid is %d, subif is %s\n", vid, subif);
|
||
ip_conf_file_set(subif, addr_name, addr_buff);
|
||
}
|
||
}
|
||
printf("[vlan]save_conf_file_add: save file add end.\n");
|
||
return RET_OK;
|
||
}
|
||
|
||
ret_code vlan_conf_file_del(char *if_name, char *address)
|
||
{
|
||
if(!if_name || !address){
|
||
return RET_NULLP;
|
||
}
|
||
char buf[100] = {0};
|
||
int status = 0;
|
||
//sprintf(buf, "sed -r -i ':a;N;$!ba;s/auto[ \\t]+%s\\n[ \\t]*iface[ \\t]+%s[ \\t]+inet[ \\t]+static\\n[ \\t]*address[ \\t]+%s\\n//g' %s", if_name, if_name, address, ETC_NETWORK_IFS);
|
||
|
||
sprintf(buf, "sed -r -i '/^auto[ \\t]+%s*$/d' %s", if_name, ETC_NETWORK_IFS);
|
||
status = system(buf);
|
||
if(status != 0){
|
||
printf("[vlan]vlan_conf_file_del1: status error. (%s)\n", strerror(errno));
|
||
return RET_SYS_FILEOP_ERR;
|
||
}
|
||
memset(buf, 0, 100);
|
||
|
||
sprintf(buf, "sed -r -i '/^iface[ \\t]+%s[ \\t]+inet[ \\t]+static*$/,+1d' %s", if_name, ETC_NETWORK_IFS);
|
||
status = system(buf);
|
||
if(status != 0){
|
||
printf("[vlan]vlan_conf_file_del2: status error. (%s)\n", strerror(errno));
|
||
return RET_SYS_FILEOP_ERR;
|
||
}
|
||
|
||
memset(buf, 0, 100);
|
||
|
||
//sprintf(buf, "sed -r -i '/^address[ \\t]+%s*$/d' %s", address, ETC_NETWORK_IFS);
|
||
//system(buf);
|
||
|
||
return RET_OK;
|
||
}
|
||
/************************************************************
|
||
* 函数功能:DEL操作存配置文件
|
||
* 输入:
|
||
* 输出:
|
||
* 返回值:
|
||
************************************************************/
|
||
ret_code vlan_save_conf_file_del(interface_vlan_info *if_vlan_info)
|
||
{
|
||
//int ifnode;
|
||
int vid;
|
||
char subif[IF_NAME_LEN] = {0};
|
||
char *del_address = "0";
|
||
ret_code ret = RET_OK;
|
||
if(!if_vlan_info){
|
||
return RET_NULLP;
|
||
}
|
||
//ifnode = get_ifnode_from_global(if_vlan_info->if_name);
|
||
printf("[vlan]vlan_save_conf_file_del: begin.\n");
|
||
for(vid = VID_MIN; vid <= VID_MAX; vid++){
|
||
if(vlan_bitmap_check(if_vlan_info->vlan_bitmap, vid)){
|
||
(void)if_vlan2subif(if_vlan_info->if_name, vid, subif);
|
||
printf("[vlan]vlan_save_conf_file_del: vid=%d, subif=%s\n", vid, subif);
|
||
ret = vlan_conf_file_del(subif, del_address);
|
||
if(ret != RET_OK){
|
||
printf("[vlan]vlan_save_conf_file_del: vlan-conffile del failed(%d).\n", ret);
|
||
return ret;
|
||
}
|
||
}
|
||
}
|
||
printf("[vlan]vlan_save_conf_file_del: save file del end.\n");
|
||
return RET_OK;
|
||
}
|
||
|
||
/************************************************************
|
||
* 函数功能:存配置文件
|
||
* 输入:
|
||
* 输出:
|
||
* 返回值:
|
||
************************************************************/
|
||
ret_code vlan_save_conf_file(interface_vlan_info *if_vlan_info)
|
||
{
|
||
ret_code ret = RET_OK;
|
||
if(!if_vlan_info){
|
||
return RET_NULLP;
|
||
}
|
||
if(if_vlan_info->op_type == OP_ADD){
|
||
ret = vlan_save_conf_file_add(if_vlan_info);
|
||
}
|
||
else if(if_vlan_info->op_type == OP_DEL){
|
||
ret = vlan_save_conf_file_del(if_vlan_info);
|
||
}
|
||
else{
|
||
printf("[vlan]vlan_save_conf_file: OP_TYPE ERROR.return\n");
|
||
ret = RET_OPTYPE_ERR;
|
||
}
|
||
return ret;
|
||
}
|
||
|
||
/************************************************************
|
||
* 函数功能:更新全局结构
|
||
* 输入:
|
||
* 输出:
|
||
* 返回值:
|
||
************************************************************/
|
||
ret_code refresh_if_vlan_info(interface_vlan_info *if_vlan_info)
|
||
{
|
||
ret_code ret = RET_OK;
|
||
if(!if_vlan_info){
|
||
return RET_NULLP;
|
||
}
|
||
|
||
/* 路由桥接模型才会用到子接口,才需要保存配置文件 */
|
||
if(INTERFACE_MODEL_ROUTE_FORWARD == if_vlan_info->if_model){
|
||
ret = vlan_save_conf_file(if_vlan_info);
|
||
if(ret != RET_OK){
|
||
printf("[vlan]refresh_if_vlan_info: save conf file failed.return.(%d)\n", ret);
|
||
return ret;
|
||
}
|
||
}
|
||
if(OP_ADD == if_vlan_info->op_type){
|
||
ret = refresh_if_vlan_info_op_add(if_vlan_info);
|
||
}
|
||
else if(OP_DEL == if_vlan_info->op_type){
|
||
ret = refresh_if_vlan_info_op_del(if_vlan_info);
|
||
}
|
||
else {
|
||
printf("[vlan]refresh_if_vlan_info: OP_TYPE ERROR.return\n");
|
||
ret = RET_OPTYPE_ERR;
|
||
}
|
||
|
||
return ret;
|
||
}
|
||
|
||
/************************************************************
|
||
* 函数功能:删除接口vlan
|
||
* 此函数肯定是指定端口删除,默认删除端口下所有vlan信息
|
||
* 或者删除原接口下某个vlan,但是这种删除原接口下某个vlan可以
|
||
* 通过mod来做,没必要通过del来做
|
||
* 输入:
|
||
* 输出:
|
||
* 返回值:
|
||
************************************************************/
|
||
ret_code del_interface_vlan(interface_vlan_info *if_vlan_info)
|
||
{
|
||
ret_code ret = RET_OK;
|
||
if(!if_vlan_info){
|
||
return RET_NULLP;
|
||
}
|
||
/* 配置校验 */
|
||
//ret = check_config(if_vlan_info->if_name);
|
||
//if(0 == ret){//为0表示之前没有配置,返回错误。这种情况相当于ADD
|
||
//return -1;
|
||
//}
|
||
|
||
/* 接口模型赋值 */
|
||
if_vlan_info->if_model = which_interface_model(if_vlan_info->if_name);
|
||
|
||
/* 查询当前全局结构中此port的attr */
|
||
interface_link_attr old_attr = get_attr_from_ifname(if_vlan_info->if_name);
|
||
|
||
/* trunk */
|
||
if(old_attr == LINK_TYPE_TRUNK){
|
||
ret = del_interface_vlan_trunk(if_vlan_info->if_name, if_vlan_info->vlan_bitmap, if_vlan_info->if_model);
|
||
if(ret != RET_OK){
|
||
printf("[vlan]del_interface_vlan: del trunk failed(%d).\n", ret);
|
||
return ret;
|
||
}
|
||
}
|
||
else if(old_attr == LINK_TYPE_ACCESS){
|
||
ret = del_interface_vlan_access(if_vlan_info->if_name, if_vlan_info->if_model);
|
||
if(ret != RET_OK){
|
||
printf("[vlan]del_interface_vlan: del access failed(%d).\n", ret);
|
||
return ret;
|
||
}
|
||
}
|
||
else {
|
||
printf("[vlan]del_interface_vlan: LINK-TYPE attr(%d) input error.\n", old_attr);
|
||
return RET_ATTR_INVALID;
|
||
}
|
||
/* 更新全局接口vlan数据结构 */
|
||
ret = refresh_if_vlan_info(if_vlan_info);
|
||
return ret;
|
||
}
|
||
|
||
|
||
/************************************************************
|
||
* 函数功能:从全局gloabl结构中获取old的接口model
|
||
* 输入:
|
||
* 输出:
|
||
* 返回值:
|
||
************************************************************/
|
||
interface_model get_old_interface_model(char *if_name, interface_model *if_model)
|
||
{
|
||
int ifnode;
|
||
if(!if_name || !if_model){
|
||
printf("[vlan]get_old_interface_model: input or output para error.\n");
|
||
return -1;
|
||
}
|
||
ifnode = get_ifnode_from_global(if_name);
|
||
if(-1 == ifnode){
|
||
return -1;
|
||
}
|
||
*if_model = g_if_vlan_info[ifnode].if_model;
|
||
return 0;
|
||
}
|
||
|
||
|
||
/************************************************************
|
||
* 函数功能:判断新旧接口模型是否一致
|
||
* 输入:
|
||
* 输出:
|
||
* 返回值: 0: 一致,没变更
|
||
-1: 不一致,变更了
|
||
************************************************************/
|
||
int if_model_is_change(interface_model old, interface_model new)
|
||
{
|
||
if(old == new){
|
||
return 0;
|
||
}
|
||
else{
|
||
return -1;
|
||
}
|
||
}
|
||
|
||
int get_old_interface_attr(char *if_name, interface_link_attr *attr)
|
||
{
|
||
int ifnode;
|
||
if(!if_name || !attr){
|
||
printf("[vlan]get_old_interface_attr: input or output para error.\n");
|
||
return -1;
|
||
}
|
||
ifnode = get_ifnode_from_global(if_name);
|
||
if(-1 == ifnode){
|
||
return -1;
|
||
}
|
||
*attr = g_if_vlan_info[ifnode].attr;
|
||
return 0;
|
||
}
|
||
|
||
/************************************************************
|
||
* 函数功能:接口vlan设置
|
||
* 根据操作类型来分别处理add、mod、del
|
||
* 如果是add,则直接加
|
||
* 如果是del,则直接删
|
||
* 输入:
|
||
* 输出:
|
||
* 返回值:
|
||
************************************************************/
|
||
ret_code interface_vlan_set(interface_vlan_info *if_vlan_info)
|
||
{
|
||
operation_type op_type;
|
||
ret_code ret = RET_OK;
|
||
if(!if_vlan_info){
|
||
return RET_NULLP;
|
||
}
|
||
op_type = if_vlan_info->op_type;
|
||
/* ADD只管现在 */
|
||
if(op_type == OP_ADD){
|
||
ret = add_interface_vlan(if_vlan_info);
|
||
}
|
||
|
||
/* 只管以前 */
|
||
else if(op_type == OP_DEL){
|
||
ret = del_interface_vlan(if_vlan_info);
|
||
}
|
||
else{
|
||
printf("[vlan]interface_vlan_set: op_type error.\n");
|
||
ret = RET_OPTYPE_ERR;
|
||
}
|
||
return ret;
|
||
}
|
||
|
||
|
||
/************************************************************
|
||
* 函数功能: 循环解析json串,将分段的值填加进port_vlan_info[]
|
||
* 结构体数组中
|
||
* 只有ADD、DEL需要做chk校验,get和getall不需要,直接返回
|
||
* 每一个proc是一个operate操作
|
||
* {
|
||
* "operate" : "add",
|
||
* "conf_ifvlan": [
|
||
* {
|
||
* "if_name" : "eth0",
|
||
* "vid" : [
|
||
* 100,
|
||
* 200,
|
||
* ],
|
||
* "if_attr" : "trunk"
|
||
* },
|
||
* {
|
||
* "if_name" : "eth1",
|
||
* "vid" : [
|
||
* 300,
|
||
* 400,
|
||
* ],
|
||
* "if_attr" : "trunk"
|
||
* },
|
||
* ]
|
||
* }
|
||
* 输入:
|
||
* 输出: if_vlnum、if_vlan_info
|
||
* 返回值:
|
||
************************************************************/
|
||
ret_code vlan_config_json_parse(pointer input, interface_vlan_info *if_vlan_info, int *if_vlnum)
|
||
{
|
||
ret_code ret = RET_OK;
|
||
int i, if_num = 0, vl_num = 0, j;
|
||
cJSON *root = NULL, *operate = NULL, *conf_ifvlan = NULL;
|
||
if(!if_vlan_info || !input){
|
||
ret = RET_NULLP;
|
||
goto out;
|
||
}
|
||
if(!(root = cJSON_Parse(input))){
|
||
printf("[vlan-test]vlan_config_json_parse: json parse error, return error.\n");
|
||
ret = RET_INPUTERR;
|
||
goto out;
|
||
}
|
||
if(!(operate = cJSON_GetObjectItem(root, "operate"))){
|
||
printf("[vlan]vlan_config_json_parse: Json No operate node.\n");
|
||
ret = RET_INPUTERR;
|
||
goto out;
|
||
}
|
||
if(!(conf_ifvlan = cJSON_GetObjectItem(root, "conf_ifvlan"))){
|
||
printf("[vlan]vlan_config_json_parse: Json No conf_ifvlan node.\n");
|
||
ret = RET_INPUTERR;
|
||
goto out;
|
||
}
|
||
|
||
/* 解析最外层interface数组 */
|
||
if_num = cJSON_GetArraySize(conf_ifvlan);
|
||
if(if_num == 0){
|
||
printf("[vlan]vlan_config_json_parse: Json array has no interface.\n");
|
||
ret = RET_INPUTERR;
|
||
goto out;
|
||
}
|
||
cJSON *node = NULL;
|
||
for(i = 0; i < if_num; i++){
|
||
|
||
/* 给每个接口的op_type赋值 */
|
||
if(NULL == operate->valuestring){
|
||
printf("[vlan]vlan_config_json_parse: operate->valuestring is null.\n");
|
||
ret = RET_INPUTERR;
|
||
goto out;
|
||
}
|
||
if(!strcmp(operate->valuestring, "add")){
|
||
if_vlan_info[i].op_type = OP_ADD;
|
||
}
|
||
else if(!strcmp(operate->valuestring, "del")){
|
||
if_vlan_info[i].op_type = OP_DEL;
|
||
}
|
||
else if(!strcmp(operate->valuestring, "mod")){
|
||
if_vlan_info[i].op_type = OP_MOD;
|
||
}
|
||
|
||
node = cJSON_GetArrayItem(conf_ifvlan, i);
|
||
if(!node){
|
||
continue;
|
||
}
|
||
cJSON *ifName = cJSON_GetObjectItem(node, "if_name");
|
||
if(!ifName){
|
||
//continue;
|
||
printf("[vlan]vlan_config_json_parse: json has no ifName node.\n");
|
||
ret = RET_INPUTERR;
|
||
goto out;
|
||
}
|
||
if(NULL == ifName->valuestring){
|
||
printf("[vlan]vlan_config_json_parse: ifName->valuestring is null.\n");
|
||
ret = RET_INPUTERR;
|
||
goto out;
|
||
}
|
||
memcpy(if_vlan_info[i].if_name, ifName->valuestring, strlen(ifName->valuestring));
|
||
printf("[vlan]if_vlan_info[%d].if_name=%s\n", i, if_vlan_info[i].if_name);
|
||
cJSON *ifAttr = cJSON_GetObjectItem(node, "if_attr");
|
||
if(!ifAttr){
|
||
//continue;
|
||
printf("[vlan]vlan_config_json_parse: Json has no ifAttr node.\n");
|
||
ret = RET_INPUTERR;
|
||
goto out;
|
||
}
|
||
if(NULL == ifAttr->valuestring){
|
||
printf("[vlan]vlan_config_json_parse: ifAttr->valuestring is null.\n");
|
||
ret = RET_INPUTERR;
|
||
goto out;
|
||
}
|
||
if(!strcmp(ifAttr->valuestring, "trunk")){
|
||
if_vlan_info[i].attr = LINK_TYPE_TRUNK;
|
||
}
|
||
else if(!strcmp(ifAttr->valuestring, "access")){
|
||
if_vlan_info[i].attr = LINK_TYPE_ACCESS;
|
||
}
|
||
else {
|
||
printf("[vlan]vlan_config_json_parse: errror: is not trunk or access.\n");
|
||
ret = RET_ATTR_INVALID;
|
||
goto out;
|
||
}
|
||
cJSON *vId = cJSON_GetObjectItem(node, "vid");
|
||
if(!vId){
|
||
//continue;
|
||
printf("[vlan]vlan_config_json_parse: Json has no vId node.\n");
|
||
ret = RET_INPUTERR;
|
||
goto out;
|
||
}
|
||
|
||
/* 解析内层vid数组 */
|
||
vl_num = cJSON_GetArraySize(vId);
|
||
if(vl_num == 0){
|
||
printf("[vlan]vlan_config_json_parse: Json array has no vid element.\n");
|
||
ret = RET_INPUTERR;
|
||
goto out;
|
||
}
|
||
/* 校验vid个数,如果超过边界,报错 */
|
||
ret = vid_num_chk(if_vlan_info[i].if_name, if_vlan_info[i].op_type, vl_num);
|
||
if(ret != RET_OK){
|
||
printf("[vlan]vlan_config_json_parse: vid-num-chk error.\n");
|
||
goto out;
|
||
}
|
||
cJSON *item = NULL;
|
||
for(j = 0; j < vl_num; j++){
|
||
item = cJSON_GetArrayItem(vId, j);
|
||
printf("i=%d, vid=%d\n", i, item->valueint);
|
||
|
||
/* vid数值及范围校验 */
|
||
ret = vid_value_chk(item->valueint);
|
||
if(ret != RET_OK){
|
||
printf("[vlan]vlan_config_json_parse: vid check failed.\n");
|
||
goto out;
|
||
}
|
||
vlan_bitmap_set(if_vlan_info[i].vlan_bitmap, item->valueint);
|
||
}
|
||
}
|
||
if(if_vlnum){
|
||
*if_vlnum = if_num;
|
||
}
|
||
|
||
|
||
out:
|
||
if(root){
|
||
cJSON_Delete(root);
|
||
}
|
||
return ret;
|
||
}
|
||
|
||
|
||
/************************************************************
|
||
* 函数功能:vlan模块配置管理入口
|
||
* 输入:
|
||
* 输出:
|
||
* 返回值:
|
||
************************************************************/
|
||
ret_code vlan_config_proc(uint source, uint config_type,
|
||
pointer input, int input_len,
|
||
pointer output, int *output_len)
|
||
{
|
||
operation_type op_type;
|
||
int if_vl_num = 0, i;
|
||
ret_code ret = RET_OK;
|
||
interface_vlan_info if_vlan_info[MAX_INTERFACES] = {0};
|
||
printf("[vlan]===config-proc begin.===\n");
|
||
/* 配置下发 */
|
||
ret = vlan_config_json_parse(input, if_vlan_info, &if_vl_num);
|
||
if(ret != RET_OK){
|
||
printf("[vlan]vlan_config_proc: source:%d, json parse failed(%d).\n", source, ret);
|
||
return ret;
|
||
}
|
||
for(i = 0; i < if_vl_num; i++){
|
||
ret = interface_vlan_set(&if_vlan_info[i]);
|
||
if(ret != RET_OK){
|
||
printf("[vlan]vlan_config_proc: source:%d, vlan set failed(%d).\n", source, ret);
|
||
return ret;
|
||
}
|
||
}
|
||
|
||
return RET_OK;
|
||
}
|
||
|
||
/************************************************************
|
||
* 函数功能:从下发的get的json解析
|
||
* 根据ifname去全局结构中查询,如果节点存在,则将所在节点下标
|
||
* 放入interface结构,以便后续使用
|
||
* get格式
|
||
* {
|
||
* "get_ifvlan": [
|
||
* {
|
||
* "if_name" : "eth0",
|
||
* },
|
||
* {
|
||
* "if_name" : "eth1",
|
||
* },
|
||
* }
|
||
*
|
||
* 返回数据格式
|
||
* {
|
||
* "if_vlan": [
|
||
* {
|
||
* "if_name" : "eth0",
|
||
* "vid" : [
|
||
* 100,
|
||
* 200,
|
||
* ],
|
||
* "if_attr" : "trunk"
|
||
* },
|
||
* {
|
||
* "if_name" : "eth1",
|
||
* "vid" : [
|
||
* 300,
|
||
* 400,
|
||
* ],
|
||
* "if_attr" : "trunk"
|
||
* },
|
||
* }
|
||
* 输入:
|
||
* 输出:
|
||
* 返回值:
|
||
************************************************************/
|
||
ret_code vlan_get_json_parse(int *interface, pointer input)
|
||
{
|
||
ret_code ret = RET_OK;
|
||
int i, if_num, vl_num, j, ifnode;
|
||
cJSON *root = NULL, *operate = NULL, *get_ifvlan = NULL;
|
||
if(!interface){
|
||
printf("[vlan]vlan_get_json_parse: interface is null.\n");
|
||
ret = RET_NULLP;
|
||
goto out;
|
||
}
|
||
if(!(root = cJSON_Parse(input))){
|
||
printf("[vlan]vlan_get_json_parse: root failed.\n");
|
||
ret = RET_INPUTERR;
|
||
goto out;
|
||
}
|
||
if(!(operate = cJSON_GetObjectItem(root, "operate"))){
|
||
printf("[vlan]vlan_get_json_parse: No operate node.\n");
|
||
ret = RET_INPUTERR;
|
||
goto out;
|
||
}
|
||
//if(operate->valuestring == NULL || strcmp(operate->valuestring, "get") != 0){
|
||
//printf("[vlan]vlan_get_json_parse: error: operate-val is %s.\n", operate->valuestring);
|
||
//ret = RET_INPUTERR;
|
||
//goto out;
|
||
//}
|
||
|
||
if(!(get_ifvlan = cJSON_GetObjectItem(root, "get_ifvlan"))){
|
||
printf("[vlan]vlan_get_json_parse: No get_ifvlan node.\n");
|
||
ret = RET_INPUTERR;
|
||
goto out;
|
||
}
|
||
|
||
/* 解析最外层interface数组 */
|
||
if_num = cJSON_GetArraySize(get_ifvlan);
|
||
if(if_num == 0){
|
||
printf("[vlan]vlan_get_json_parse: json array has no interface.\n");
|
||
ret = RET_INPUTERR;
|
||
goto out;
|
||
}
|
||
cJSON *node = NULL;
|
||
for(i = 0; i < if_num; i++){
|
||
node = cJSON_GetArrayItem(get_ifvlan, i);
|
||
if(!node){//???
|
||
continue;
|
||
}
|
||
cJSON *ifName = cJSON_GetObjectItem(node, "if_name");
|
||
if(!ifName){
|
||
//continue;
|
||
printf("[vlan]vlan_get_json_parse: json has no ifName node.\n");
|
||
ret = RET_INPUTERR;
|
||
goto out;
|
||
}
|
||
if(NULL == ifName->valuestring){
|
||
printf("[vlan]vlan_get_json_parse: ifName->valuestring is null.\n");
|
||
ret = RET_INPUTERR;
|
||
goto out;
|
||
}
|
||
|
||
ret = if_name_chk(ifName->valuestring);
|
||
if(ret != RET_OK){
|
||
printf("[vlan-chk]vlan_get_json_parse: if-name-chk failed.\n");
|
||
goto out;
|
||
}
|
||
|
||
//if_vlan_info[i].if_name= ifName->valuestring;//memcpy
|
||
/* 如果找到了对应的ifnode,则对应下标置1 */
|
||
ifnode = get_ifnode_from_global(ifName->valuestring);
|
||
if(ifnode != -1){
|
||
interface[ifnode] = 1;
|
||
}
|
||
}
|
||
|
||
out:
|
||
if(root){
|
||
cJSON_Delete(root);
|
||
}
|
||
return ret;
|
||
}
|
||
|
||
/************************************************************
|
||
* 函数功能:将所传interface中数据为1则将此下标作为全局结构
|
||
* 下标,取出对应节点封装成json传出
|
||
* 输入:
|
||
* 输出:
|
||
* 返回值:
|
||
************************************************************/
|
||
ret_code vlan_config_format_json(int *interface, pointer output, int *output_len)
|
||
{
|
||
cJSON *root = NULL, *arr = NULL, *js_list = NULL, *js_vid = NULL;
|
||
char *out = NULL;
|
||
int i, j, vid, ret = RET_OK;
|
||
root = cJSON_CreateObject();
|
||
if(!root){
|
||
printf("[vlan]vlan_config_format_json: cJSON create root failed.\n");
|
||
return RET_ERR;
|
||
}
|
||
cJSON_AddItemToObject(root, "if_vlan", arr = cJSON_CreateArray());
|
||
for(i = 0; i < MAX_INTERFACES; i++){
|
||
//ifnode = get_ifnode_from_global(if_vlan_info[i].if_name)
|
||
if(!(interface[i])){
|
||
continue;
|
||
}
|
||
js_list = cJSON_CreateObject();
|
||
if(!js_list){
|
||
printf("[vlan]vlan_config_format_json: cJSON create js_list failed.\n");
|
||
cJSON_Delete(root);
|
||
return RET_ERR;
|
||
}
|
||
|
||
cJSON_AddStringToObject(js_list , "if_name", g_if_vlan_info[i].if_name);
|
||
if(g_if_vlan_info[i].attr == LINK_TYPE_TRUNK){
|
||
cJSON_AddStringToObject(js_list , "if_attr", "trunk");
|
||
}
|
||
//else if(g_if_vlan_info[i].attr == LINK_TYPE_ACCESS){
|
||
//cJSON_AddStringToObject(js_list , "if_attr", "access");
|
||
//}
|
||
else {
|
||
printf("[vlan]vlan_config_format_json: if_atrtr error.\n");
|
||
cJSON_Delete(root);
|
||
return RET_ERR;
|
||
|
||
}
|
||
cJSON_AddItemToObject(js_list, "vid", js_vid = cJSON_CreateArray());
|
||
for(vid = VID_MIN; vid <= VID_MAX;vid++){
|
||
if(vlan_bitmap_check(g_if_vlan_info[i].vlan_bitmap, vid)){
|
||
cJSON_AddItemToArray(js_vid, cJSON_CreateNumber(vid));
|
||
}
|
||
}
|
||
cJSON_AddItemToArray(arr, js_list);
|
||
}
|
||
out = cJSON_PrintUnformatted(root);
|
||
if(!out){
|
||
printf("[vlan]vlan_config_format_json: cJSON_PrintUnformatted failed.\n");
|
||
cJSON_Delete(root);
|
||
return RET_ERR;
|
||
}
|
||
*output_len = strlen(out) + 1;
|
||
memcpy(output, out, *output_len);
|
||
xfree(out);
|
||
if(root){
|
||
cJSON_Delete(root);
|
||
}
|
||
return ret;
|
||
}
|
||
|
||
|
||
/************************************************************
|
||
* 函数功能:vlan配置get总入口
|
||
* 输入:
|
||
* 输出:
|
||
* 返回值:
|
||
************************************************************/
|
||
ret_code vlan_config_get(uint source,
|
||
pointer input, int input_len,
|
||
pointer output, int *output_len)
|
||
{
|
||
//interface_vlan_info if_vlan_info[MAX_INTERFACES] = {0};
|
||
ret_code ret = RET_OK;
|
||
int interface[MAX_INTERFACES] = {0};
|
||
if(!input){
|
||
printf("[vlan]vlan_config_get: input is null.\n");
|
||
return RET_INPUTERR;
|
||
}
|
||
printf("[vlan]===config-get begin.===\n");
|
||
/* 将存匹配的节点下标传入interface中对应下标 */
|
||
ret = vlan_get_json_parse(interface, input);
|
||
if(ret != RET_OK){
|
||
printf("[vlan]vlan_config_get: get json parse failed.\n");
|
||
return ret;
|
||
}
|
||
/* 根据对应interface下标,去获取全局g_if_vlan_info信息 */
|
||
ret = vlan_config_format_json(interface, output, output_len);
|
||
if(ret != RET_OK){
|
||
printf("[vlan]vlan_config_get: format json failed.\n");
|
||
return ret;
|
||
}
|
||
return RET_OK;
|
||
}
|
||
|
||
/************************************************************
|
||
* 函数功能:从配置文件中读取子接口信息
|
||
* "/etc/network/interfaces"
|
||
* 解析物理口名字和vlan id
|
||
* auto ens38.100
|
||
* | | |
|
||
* pauto pifname ppoint
|
||
*
|
||
* 输入:
|
||
* 输出:
|
||
* 返回值:
|
||
************************************************************/
|
||
ret_code vlan_get_from_conf_file(int *interface)
|
||
{
|
||
FILE *fp = NULL;
|
||
char line[FILE_BUF_LINE] = {0};
|
||
int vid;
|
||
int node_num = 0;
|
||
char *pauto = NULL;//"auto"指针位置
|
||
char *point = NULL;//'.'指针位置
|
||
char *ifname = NULL;//"ens38"指针位置
|
||
char tmp_name[IF_NAME_LEN] = {0};//
|
||
int i;
|
||
if(!interface){
|
||
printf("[vlan]vlan_get_from_conf_file: para is null.\n");
|
||
return RET_NULLP;
|
||
}
|
||
if(!(fp = fopen(ETC_NETWORK_IFS, "r"))){
|
||
printf("[vlan]vlan_get_from_conf_file: file open failed.\n");
|
||
return RET_SYS_FILEOP_ERR;
|
||
}
|
||
//fseek(fp,0,SEEK_END);
|
||
//rewind(fp);
|
||
|
||
while(fgets(line, FILE_BUF_LINE, fp)){
|
||
|
||
/* 找到"auto" */
|
||
pauto = strstr(line, "auto");
|
||
if(!pauto){
|
||
continue;
|
||
}
|
||
/* 找到'.' */
|
||
point = strchr(pauto, '.');
|
||
if(!point){
|
||
continue;
|
||
}
|
||
/* auto后第一个字符 */
|
||
ifname = pauto + strlen("auto");
|
||
/* 过滤空格或TAB */
|
||
while(ifname && (*ifname == ' ' || *ifname == '\t')){
|
||
ifname++;
|
||
}
|
||
/* 找到ens38 */
|
||
if(ifname){
|
||
char *p;
|
||
printf("[vlan]vlan_get_from_conf_file: ifname=");
|
||
for(p = ifname; p < point && p; p++){
|
||
printf("%c", *p);
|
||
}
|
||
|
||
memcpy(tmp_name, ifname, point - ifname);
|
||
/* 在已经添加进g的node里的结构中的if-name做比较
|
||
如果发现重名的,说明该节点当时赋值过了,只需再设置
|
||
当前行解析出的vid即可*/
|
||
for(i = 0; i < node_num; i++){
|
||
if(!strcmp(g_if_vlan_info[i].if_name, tmp_name)){
|
||
vid = atoi(point+1);
|
||
printf("\n[vlan]vlan_get_from_conf_file: find same node, vid = %d\n", vid);
|
||
vlan_bitmap_set(g_if_vlan_info[i].vlan_bitmap, vid);
|
||
break;
|
||
}
|
||
}
|
||
/* i==node_num说明前面没找到,这是个全新的 */
|
||
if(i == node_num){
|
||
memcpy(g_if_vlan_info[node_num].if_name, ifname, point - ifname);
|
||
g_if_vlan_info[node_num].attr = LINK_TYPE_TRUNK;
|
||
g_if_vlan_info[node_num].op_type = OP_ADD;
|
||
g_if_vlan_info[node_num].if_model = INTERFACE_MODEL_ROUTE_FORWARD;
|
||
vid = atoi(point+1);
|
||
printf("\n[vlan]vlan_get_from_conf_file: vid = %d\n", vid);
|
||
vlan_bitmap_set(g_if_vlan_info[node_num].vlan_bitmap, vid);
|
||
interface[node_num] = 1;
|
||
node_num++;
|
||
}
|
||
}
|
||
}
|
||
|
||
fclose(fp);
|
||
return RET_OK;
|
||
}
|
||
|
||
/************************************************************
|
||
* 函数功能:vlan配置get all总入口
|
||
* 输入:
|
||
* 输出:
|
||
* 返回值:
|
||
************************************************************/
|
||
ret_code vlan_config_get_all(uint source, pointer output, int *output_len)
|
||
{
|
||
int interface[MAX_INTERFACES] = {0};
|
||
int i;
|
||
ret_code ret= RET_OK;
|
||
printf("[vlan]===config-get-all begin.===\n");
|
||
/* WEB下发,g_if_vlan_info对应的node是有数据的
|
||
只需将有数据的节点node返回到interface里即可*/
|
||
printf("[vlan]vlan_config_get_all: source=%d.\n", source);
|
||
if(source == CONFIG_FROM_WEB){
|
||
for(i = 0; i < MAX_INTERFACES; i++){
|
||
//if(get_ifnode_from_global(g_if_vlan_info[i].if_name) != -1)
|
||
/* 不为空串才给interface置1 */
|
||
if(strcmp(g_if_vlan_info[i].if_name, "")){
|
||
interface[i] = 1;
|
||
printf("[vlan]vlan_config_get_all: interface[%d].\n", i);
|
||
}
|
||
}
|
||
}
|
||
|
||
/* 配置恢复g_if_vlan_info里是空的,需要先从
|
||
配置文件将数据恢复到内存g_if_vlan_info[]中
|
||
然后再将有数据的节点node放入interface*/
|
||
else if(source == CONFIG_FROM_RECOVER1){
|
||
ret = vlan_get_from_conf_file(interface);
|
||
if(ret != RET_OK){
|
||
printf("[vlan]vlan_config_get_all: source %d, get from cfg file failed(%d).\n", source, ret);
|
||
return ret;
|
||
}
|
||
}
|
||
ret = vlan_config_format_json(interface, output, output_len);
|
||
if(ret != RET_OK){
|
||
printf("[vlan]vlan_config_get_all: source %d, get from cfg file failed(%d).\n", source, ret);
|
||
return ret;
|
||
}
|
||
return RET_OK;
|
||
}
|
||
|
||
/************************************************************
|
||
* 函数功能:对外提供的接口
|
||
* 组装删除vlan的信息
|
||
* 输入:
|
||
* 输出:
|
||
* 返回值:
|
||
************************************************************/
|
||
ret_code del_compose_if_vlan_info(char *if_name, interface_vlan_info *if_vlan_info)
|
||
{
|
||
int ifnode = -1, vid;
|
||
if(!if_name || !if_vlan_info){
|
||
printf("[vlan]del_compose_if_vlan_info: input pointer is null.\n");
|
||
return RET_NULLP;
|
||
}
|
||
|
||
/* 根据ifname查找到当前if节点,并将vlan赋值给if_vlan_info */
|
||
ifnode = get_ifnode_from_global(if_name);
|
||
if(ifnode == -1){
|
||
printf("[vlan]del_compose_if_vlan_info: find empty ifnode.\n");
|
||
return RET_NOTFOUND;
|
||
}
|
||
if_vlan_info->attr = g_if_vlan_info[ifnode].attr;
|
||
if_vlan_info->if_model = g_if_vlan_info[ifnode].if_model;
|
||
if_vlan_info->op_type = OP_DEL;
|
||
if_vlan_info->vidcnt = g_if_vlan_info[ifnode].vidcnt;
|
||
memcpy(if_vlan_info->if_name, g_if_vlan_info[ifnode].if_name, strlen(g_if_vlan_info[ifnode].if_name));
|
||
printf("[vlan]del_compose_if_vlan_info: attr=%d, op_type=%d, ifname=%s\n",
|
||
if_vlan_info->attr, if_vlan_info->op_type, if_vlan_info->if_name);
|
||
|
||
/* 提取vlanbitmap */
|
||
printf("[vlan]del_compose_if_vlan_info: vlan_info:\n(");
|
||
for(vid = VID_MIN; vid <= VID_MAX; vid++){
|
||
/* 如果找到了vid存在,则在新结构的vlan_bitmap中设置vid bitmap */
|
||
if(vlan_bitmap_check(g_if_vlan_info[ifnode].vlan_bitmap, vid)){
|
||
vlan_bitmap_set(if_vlan_info->vlan_bitmap, vid);
|
||
printf("%d, ", vid);
|
||
}
|
||
}
|
||
printf(")\n");
|
||
return RET_OK;
|
||
}
|
||
/************************************************************
|
||
* 函数功能:对外提供的接口
|
||
* 删除指定物理口上的vlan的回调函数
|
||
* 输入:
|
||
* 输出:
|
||
* 返回值:
|
||
************************************************************/
|
||
int del_interface_vlan_cb(BR_EVENT_TYPE event_type, br_event_t event_arg)
|
||
{
|
||
interface_vlan_info if_vlan_info = {0};
|
||
ret_code ret = RET_OK;
|
||
ret = del_compose_if_vlan_info(event_arg.if_name, &if_vlan_info);
|
||
if(ret != RET_OK){
|
||
printf("[vlan]del_interface_vlan_cb: compose-if-vlan-info failed(%d).\n", ret);
|
||
return ret;
|
||
}
|
||
ret = del_interface_vlan(&if_vlan_info);
|
||
if(ret != RET_OK){
|
||
printf("[vlan]del_interface_vlan_cb: del-if-vlan failed(%d).\n", ret);
|
||
return ret;
|
||
}
|
||
return RET_OK;
|
||
}
|
||
|
||
|
||
/************************************************************
|
||
* 函数功能:vlan vid值校验
|
||
* 输入:
|
||
* 输出:
|
||
* 返回值:
|
||
************************************************************/
|
||
ret_code vid_value_chk(int vid)
|
||
{
|
||
if(!(vid >= VID_MIN && vid <= VID_MAX)){
|
||
printf("[vlan]vid_value_chk: vid value error,return error\n");
|
||
return RET_VID_INVALID;
|
||
}
|
||
return RET_OK;
|
||
}
|
||
|
||
/************************************************************
|
||
* 函数功能:vlan数目校验
|
||
* 输入:
|
||
* 输出:
|
||
* 返回值:
|
||
************************************************************/
|
||
ret_code vid_num_chk(char *if_name, operation_type op_type, int num)
|
||
{
|
||
int ifnode = -1;
|
||
int total = 0;
|
||
if(!if_name){
|
||
printf("[vlan]vid_num_chk: if_name is null.\n");
|
||
return RET_NULLP;
|
||
}
|
||
printf("[vlan]vid_num_chk: if_name=%s, op_type=%d, num=%d\n", if_name, op_type, num);
|
||
ifnode = get_ifnode_from_global(if_name);
|
||
if(ifnode == -1){
|
||
total = num;
|
||
printf("[vlan]vid_num_chk: get ifnode empty, total = %d\n", total);
|
||
}
|
||
else{
|
||
total = g_if_vlan_info[ifnode].vidcnt + num;
|
||
printf("[vlan]vid_num_chk: total = %d + %d = %d\n", g_if_vlan_info[ifnode].vidcnt, num, total);
|
||
}
|
||
if(op_type == OP_ADD && total > EACH_PORT_MAX_VLAN_NUM){
|
||
printf("[vlan]vid_num_chk: ADD operation's total vid num > EACH_PORT_MAX_VLAN_NUM\n");
|
||
return RET_VIDNUM_INVALID;
|
||
}
|
||
|
||
return RET_OK;
|
||
}
|
||
|
||
/************************************************************
|
||
* 函数功能:vlan属性校验
|
||
* 目前只支持trunk,非trunk报错
|
||
* 输入:
|
||
* 输出:
|
||
* 返回值:
|
||
************************************************************/
|
||
ret_code if_attr_chk(interface_link_attr attr)
|
||
{
|
||
if(attr != LINK_TYPE_TRUNK){
|
||
printf("[vlan]if_attr_chk: now we only support link-type trunk.\n");
|
||
return RET_ATTR_INVALID;
|
||
}
|
||
return RET_OK;
|
||
}
|
||
|
||
/************************************************************
|
||
* 函数功能:vlan配置操作类型ADD校验
|
||
* 新下发的vlan id如果全局中有,则报错
|
||
* 输入:
|
||
* 输出:
|
||
* 返回值:
|
||
************************************************************/
|
||
ret_code op_type_add_chk(interface_vlan_info *if_vlan_info)
|
||
{
|
||
int ifnode, vid;
|
||
ifnode = get_ifnode_from_global(if_vlan_info->if_name);
|
||
if(ifnode == -1){
|
||
printf("[vlan]op_type_add_chk: This if_name has no node, return OK.\n");
|
||
return RET_OK;
|
||
}
|
||
|
||
/* 新下发的vid如果全局g中有,则报错返回 */
|
||
for(vid = VID_MIN; vid <= VID_MAX; vid++){
|
||
if(vlan_bitmap_check(if_vlan_info->vlan_bitmap, vid)
|
||
&& vlan_bitmap_check(g_if_vlan_info[ifnode].vlan_bitmap, vid)){
|
||
printf("[vlan]op_type_add_chk: Already have vid[%d], now return\n", vid);
|
||
return RET_VID_EXIST;
|
||
}
|
||
}
|
||
return RET_OK;
|
||
}
|
||
|
||
/************************************************************
|
||
* 函数功能:vlan配置操作类型DEL校验
|
||
* 新下发的vid如果全局中没有,则报错
|
||
* 输入:
|
||
* 输出:
|
||
* 返回值:
|
||
************************************************************/
|
||
ret_code op_type_del_chk(interface_vlan_info *if_vlan_info)
|
||
{
|
||
int ifnode, vid;
|
||
ret_code ret = RET_OK;
|
||
ifnode = get_ifnode_from_global(if_vlan_info->if_name);
|
||
if(ifnode == -1){
|
||
printf("[vlan]op_type_del_chk: get_ifnode failed.\n");
|
||
ret = RET_INTERFACE_NOT_EXIST;
|
||
goto out;
|
||
}
|
||
|
||
/* 新下发的vid如果全局g中没有,则报错返回 */
|
||
for(vid = VID_MIN; vid <= VID_MAX; vid++){
|
||
if(vlan_bitmap_check(if_vlan_info->vlan_bitmap, vid)
|
||
&& !vlan_bitmap_check(g_if_vlan_info[ifnode].vlan_bitmap, vid)){
|
||
printf("[vlan]op_type_del_chk: node[%d] do not have vid[%d], now return\n", ifnode, vid);
|
||
ret = RET_VID_NOT_EXIST;
|
||
goto out;
|
||
}
|
||
}
|
||
out:
|
||
return ret;
|
||
}
|
||
|
||
/************************************************************
|
||
* 函数功能:vlan配置操作类型校验
|
||
* 只支持ADD、DEL,其他类型报错
|
||
* 输入:
|
||
* 输出:
|
||
* 返回值:
|
||
************************************************************/
|
||
ret_code op_type_chk(interface_vlan_info *if_vlan_info)
|
||
{
|
||
ret_code ret = RET_OK;
|
||
if(!if_vlan_info){
|
||
printf("[vlan]op_type_chk: input is null.\n");
|
||
return RET_NULLP;
|
||
}
|
||
/* ADD操作校验 */
|
||
if(if_vlan_info->op_type == OP_ADD){
|
||
ret = op_type_add_chk(if_vlan_info);
|
||
}
|
||
/* DEL操作校验 */
|
||
else if(if_vlan_info->op_type == OP_DEL){
|
||
ret = op_type_del_chk(if_vlan_info);
|
||
}
|
||
else {
|
||
printf("[vlan]op_type_chk: op_type error.\n");
|
||
ret = RET_OPTYPE_ERR;
|
||
}
|
||
return ret;
|
||
}
|
||
/************************************************************
|
||
* 函数功能:接口名校验
|
||
* 如果下发的接口名为空,报错
|
||
* 输入:
|
||
* 输出:
|
||
* 返回值:
|
||
************************************************************/
|
||
ret_code if_name_chk(char *if_name)
|
||
{
|
||
if(!if_name){
|
||
printf("[vlan]if_name_chk: if_name null.\n");
|
||
return RET_NULLP;
|
||
}
|
||
if(!(strcmp(if_name, ""))){
|
||
printf("[vlan]if_name_chk: if-name is empty string, return error.\n");
|
||
return RET_INPUTERR;
|
||
}
|
||
return RET_OK;
|
||
}
|
||
|
||
/************************************************************
|
||
* 函数功能:vlan配置校验
|
||
* 接口名、属性、操作类型校验;vid放在json解析时校验
|
||
* 输入:
|
||
* 输出:
|
||
* 返回值:
|
||
************************************************************/
|
||
ret_code interface_vlan_check(interface_vlan_info *if_vlan_info)
|
||
{
|
||
ret_code ret = RET_OK;
|
||
if(!if_vlan_info){
|
||
return RET_NULLP;
|
||
}
|
||
printf("[vlan]interface_vlan_check: ifname=%s, op_type=%d, attr=%d\n",
|
||
if_vlan_info->if_name, if_vlan_info->op_type, if_vlan_info->attr);
|
||
/* if_name校验 */
|
||
ret = if_name_chk(if_vlan_info->if_name);
|
||
if(ret != RET_OK){
|
||
printf("[vlan-chk]interface_vlan_check: if-name-chk failed.\n");
|
||
goto out;
|
||
}
|
||
|
||
/* if_attr校验 */
|
||
ret = if_attr_chk(if_vlan_info->attr);
|
||
if(ret != RET_OK){
|
||
printf("[vlan-chk]interface_vlan_check: if-attr-chk failed.\n");
|
||
goto out;
|
||
}
|
||
|
||
/* 操作校验 */
|
||
ret = op_type_chk(if_vlan_info);
|
||
if(ret != RET_OK){
|
||
printf("[vlan-chk]interface_vlan_check: op-type-chk failed.\n");
|
||
goto out;
|
||
}
|
||
out:
|
||
return ret;
|
||
}
|
||
|
||
/************************************************************
|
||
* 函数功能:vlan配置操作类型校验
|
||
* 先json解析出来放入临时结构if_vlan_info[],然后调用校验函数
|
||
* 输入:
|
||
* 输出:
|
||
* 返回值:
|
||
************************************************************/
|
||
ret_code vlan_config_set_chk(uint source, pointer input)
|
||
{
|
||
int if_vl_num = 0, i;
|
||
ret_code ret = RET_OK;
|
||
interface_vlan_info if_vlan_info[MAX_INTERFACES] = {0};
|
||
|
||
ret = vlan_config_json_parse(input, if_vlan_info, &if_vl_num);
|
||
if(ret != RET_OK){
|
||
printf("[vlan]vlan_config_set_chk: json-parse failed(%d).\n", ret);
|
||
goto out;
|
||
}
|
||
for(i = 0; i < if_vl_num; i++){
|
||
ret = interface_vlan_check(&if_vlan_info[i]);
|
||
if(ret != RET_OK){
|
||
printf("[vlan]vlan_config_set_chk: if-node[%d] vlan chk failed(%d).\n", i, ret);
|
||
goto out;
|
||
}
|
||
}
|
||
out:
|
||
return ret;
|
||
|
||
}
|
||
|
||
/************************************************************
|
||
* 函数功能:解析操作类型
|
||
* 输入:
|
||
* 输出:
|
||
* 返回值:
|
||
************************************************************/
|
||
ret_code vlan_operate_parse(pointer input, int *oper_type)
|
||
{
|
||
ret_code ret = RET_OK;
|
||
int i, if_num, vl_num, j;
|
||
cJSON *root = NULL, *operate = NULL, *conf_ifvlan = NULL;
|
||
if(!input || !oper_type){
|
||
printf("[vlan]vlan_operate_chk: input or oper_type para is null.\n");
|
||
ret = RET_INPUTERR;
|
||
goto out;
|
||
}
|
||
if(!(root = cJSON_Parse(input))){
|
||
printf("[vlan]vlan_operate_chk: json parse error, return error.\n");
|
||
ret = RET_INPUTERR;
|
||
goto out;
|
||
}
|
||
if(!(operate = cJSON_GetObjectItem(root, "operate"))){
|
||
printf("[vlan]vlan_operate_chk: No operate node.\n");
|
||
ret = RET_INPUTERR;
|
||
goto out;
|
||
}
|
||
|
||
if(operate->valuestring != NULL && !strcmp(operate->valuestring, "add")
|
||
|| operate->valuestring != NULL && !strcmp(operate->valuestring, "del")){
|
||
printf("[vlan]vlan_operate_chk: operate-val is SET.\n");
|
||
*oper_type = CM_CONFIG_SET;
|
||
ret = RET_OK;
|
||
goto out;
|
||
}
|
||
else if(operate->valuestring != NULL && !strcmp(operate->valuestring, "get")){
|
||
printf("[vlan]vlan_operate_chk: operate-val is GET.\n");
|
||
*oper_type = CM_CONFIG_GET;
|
||
ret = RET_OK;
|
||
goto out;
|
||
}
|
||
else if(operate->valuestring != NULL && !strcmp(operate->valuestring, "getall")){
|
||
printf("[vlan]vlan_operate_chk: operate-val is GETALL.\n");
|
||
*oper_type = CM_CONFIG_GET_ALL;
|
||
ret = RET_OK;
|
||
goto out;
|
||
}
|
||
else {
|
||
printf("[vlan]vlan_operate_chk: operate-val is UNKNOWN, error.\n");
|
||
ret = RET_INPUTERR;
|
||
goto out;
|
||
}
|
||
out:
|
||
if(root){
|
||
cJSON_Delete(root);
|
||
}
|
||
return ret;
|
||
}
|
||
|
||
/************************************************************
|
||
* 函数功能:vlan get操作类型校验
|
||
* 根据operate类型分别进set、get、getall校验
|
||
* 目前只有set校验
|
||
* 输入:
|
||
* 输出:
|
||
* 返回值:
|
||
************************************************************/
|
||
|
||
ret_code vlan_config_get_chk(uint source, pointer input)
|
||
{
|
||
int ret = RET_OK;
|
||
int interface[MAX_INTERFACES] = {0};
|
||
if(!input){
|
||
printf("[vlan]vlan_config_get_chk: input null.\n");
|
||
return RET_NULLP;
|
||
}
|
||
ret = vlan_get_json_parse(interface, input);
|
||
if(ret != RET_OK){
|
||
printf("[vlan]vlan_config_get_chk: get json parse failed(%d).\n", ret);
|
||
return ret;
|
||
}
|
||
#if 0
|
||
for(i = 0; i < MAX_INTERFACES; i++){
|
||
if(interface[i] == 1){
|
||
printf("[vlan]find a node[%d]\n", i);
|
||
return RET_OK;
|
||
}
|
||
}
|
||
return RET_INPUTERR;
|
||
#endif
|
||
return RET_OK;
|
||
}
|
||
|
||
/************************************************************
|
||
* 函数功能:vlan getall操作类型校验
|
||
* 根据operate类型分别进set、get、getall校验
|
||
* 目前只有set校验
|
||
* 输入:
|
||
* 输出:
|
||
* 返回值:
|
||
************************************************************/
|
||
|
||
ret_code vlan_config_get_all_chk(uint source, pointer input)
|
||
{
|
||
return RET_OK;
|
||
}
|
||
|
||
/************************************************************
|
||
* 函数功能:vlan配置操作类型校验
|
||
* 根据operate类型分别进set、get、getall校验
|
||
* 目前只有set校验
|
||
* 输入:
|
||
* 输出:
|
||
* 返回值:
|
||
************************************************************/
|
||
ret_code vlan_config_chk(uint source,uint *config_type,
|
||
pointer input, int *input_len,
|
||
pointer output, int *output_len)
|
||
{
|
||
printf("[vlan]===config-chk begin.===\n");
|
||
int if_vl_num = 0, i, ret = RET_OK;
|
||
interface_vlan_info if_vlan_info[MAX_INTERFACES] = {0};
|
||
int oper_type;
|
||
|
||
ret = vlan_operate_parse(input, &oper_type);
|
||
if(ret != RET_OK){
|
||
goto out;
|
||
}
|
||
//*config_type = oper_type;
|
||
printf("[vlan]vlan_config_chk: operate_type=%d\n", oper_type);
|
||
if(oper_type == CM_CONFIG_SET){
|
||
printf("[vlan]vlan_config_chk: SET chk\n");
|
||
ret = vlan_config_set_chk(source, input);
|
||
}
|
||
else if(oper_type == CM_CONFIG_GET){
|
||
printf("[vlan]vlan_config_chk: GET chk\n");
|
||
ret = vlan_config_get_chk(source, input);
|
||
}
|
||
else if(oper_type == CM_CONFIG_GET_ALL){
|
||
printf("[vlan]vlan_config_chk: GET-ALL chk\n");
|
||
ret = vlan_config_get_all_chk(source, input);
|
||
}
|
||
else {
|
||
printf("[vlan]vlan_config_chk: oper_type is unknown(%d).\n", oper_type);
|
||
ret = RET_OPTYPE_ERR;
|
||
}
|
||
|
||
out:
|
||
printf("[vlan]vlan_config_chk: return ret=%d\n", ret);
|
||
return ret;
|
||
}
|
||
|
||
void vlan_set_struct_stub(interface_vlan_info *if_vlan_info, operation_type op_type, int *if_vlnum)
|
||
{
|
||
int vid, i;
|
||
*if_vlnum = 0;
|
||
int cnt = 0;
|
||
if(op_type == OP_ADD){
|
||
/* 设置ens38.100 */
|
||
memcpy(if_vlan_info[cnt].if_name, "ens38", strlen("ens38"));
|
||
if_vlan_info[cnt].op_type = op_type;
|
||
if_vlan_info[cnt].attr = LINK_TYPE_TRUNK;
|
||
if_vlan_info[cnt].if_model = INTERFACE_MODEL_ROUTE_FORWARD;
|
||
vid = 100;
|
||
vlan_bitmap_set(if_vlan_info[cnt].vlan_bitmap, vid);
|
||
cnt++;
|
||
|
||
/* 设置ens39.200, ens39.300 */
|
||
memcpy(if_vlan_info[cnt].if_name, "ens39", strlen("ens39"));
|
||
if_vlan_info[cnt].op_type = op_type;
|
||
if_vlan_info[cnt].attr = LINK_TYPE_TRUNK;
|
||
if_vlan_info[cnt].if_model = INTERFACE_MODEL_ROUTE_FORWARD;
|
||
vid = 200;
|
||
vlan_bitmap_set(if_vlan_info[cnt].vlan_bitmap, vid);
|
||
vid = 300;
|
||
vlan_bitmap_set(if_vlan_info[cnt].vlan_bitmap, vid);
|
||
cnt++;
|
||
for(i = 0; i < cnt; i++){
|
||
printf("[vlan-stub]vlan_set_struct_stub: ADD-->if_vlan_info[%d].if_name=%s\n", i, if_vlan_info[i].if_name);
|
||
}
|
||
}
|
||
else if(op_type == OP_DEL){
|
||
/* 删除ens39.200 */
|
||
memcpy(if_vlan_info[cnt].if_name, "ens39", strlen("ens39"));
|
||
if_vlan_info[cnt].op_type = op_type;
|
||
if_vlan_info[cnt].attr = LINK_TYPE_TRUNK;
|
||
if_vlan_info[cnt].if_model = INTERFACE_MODEL_ROUTE_FORWARD;
|
||
vid = 200;
|
||
vlan_bitmap_set(if_vlan_info[cnt].vlan_bitmap, vid);
|
||
cnt++;
|
||
}
|
||
else if(op_type == OP_MOD){
|
||
/* 修改ens39.300-->ens39.400 */
|
||
memcpy(if_vlan_info[cnt].if_name, "ens39", strlen("ens39"));
|
||
if_vlan_info[cnt].op_type = op_type;
|
||
if_vlan_info[cnt].attr = LINK_TYPE_TRUNK;
|
||
if_vlan_info[cnt].if_model = INTERFACE_MODEL_ROUTE_FORWARD;
|
||
vid = 400;
|
||
vlan_bitmap_set(if_vlan_info[cnt].vlan_bitmap, vid);
|
||
cnt++;
|
||
for(i = 0; i < cnt; i++){
|
||
printf("[vlan-stub]vlan_set_struct_stub: MOD-->if_vlan_info[%d].if_name=%s\n", i, if_vlan_info[i].if_name);
|
||
}
|
||
}
|
||
*if_vlnum = cnt;
|
||
return;
|
||
}
|
||
|
||
void vlan_config_stub1(void)
|
||
{
|
||
int if_vlnum, i;
|
||
interface_vlan_info if_vlan_info_add[MAX_INTERFACES] = {0};
|
||
interface_vlan_info if_vlan_info_del[MAX_INTERFACES] = {0};
|
||
interface_vlan_info if_vlan_info_mod[MAX_INTERFACES] = {0};
|
||
|
||
/* ADD */
|
||
vlan_set_struct_stub(if_vlan_info_add, OP_ADD, &if_vlnum);
|
||
for(i = 0; i < if_vlnum; i++){
|
||
interface_vlan_set(&if_vlan_info_add[i]);
|
||
}
|
||
|
||
/* DEL */
|
||
vlan_set_struct_stub(if_vlan_info_del, OP_DEL, &if_vlnum);
|
||
for(i = 0; i < if_vlnum; i++){
|
||
interface_vlan_set(&if_vlan_info_del[i]);
|
||
}
|
||
|
||
/* MOD */
|
||
vlan_set_struct_stub(if_vlan_info_add, OP_MOD, &if_vlnum);
|
||
for(i = 0; i < if_vlnum; i++){
|
||
interface_vlan_set(&if_vlan_info_mod[i]);
|
||
}
|
||
return;
|
||
}
|
||
|
||
void vlan_config_stub(operation_type op_type)
|
||
{
|
||
int if_vlnum, i;
|
||
interface_vlan_info if_vlan_info[MAX_INTERFACES] = {0};
|
||
|
||
vlan_set_struct_stub(if_vlan_info, op_type, &if_vlnum);
|
||
for(i = 0; i < if_vlnum; i++){
|
||
interface_vlan_set(&if_vlan_info[i]);
|
||
}
|
||
|
||
return;
|
||
}
|
||
|
||
void vlan_config_format_json_stub(int *interface)
|
||
{
|
||
int i, vid;
|
||
for(i = 0; i < MAX_INTERFACES; i++){
|
||
if(!(interface[i])){
|
||
continue;
|
||
}
|
||
printf("[vlan]vlan_config_format_json_stub: g_if_vlan_info[%d].if_name=%s, attr=%d, if_model=%d, op_type=%d, vlan=\n",
|
||
i, g_if_vlan_info[i].if_name, g_if_vlan_info[i].attr,
|
||
g_if_vlan_info[i].if_model, g_if_vlan_info[i].op_type);
|
||
for(vid = 0; vid < MAX_VLAN;vid++){
|
||
if(vlan_bitmap_check(g_if_vlan_info[i].vlan_bitmap, vid)){
|
||
printf("%d,", vid);
|
||
}
|
||
}
|
||
printf("\n");
|
||
}
|
||
return;
|
||
}
|
||
|
||
void vlan_config_get_stub(void)
|
||
{
|
||
int interface[MAX_INTERFACES] = {0};
|
||
interface[1] = 1;
|
||
printf("[vlan]vlan_config_get_stub:start.\n");
|
||
/* 根据对应interface下标,去获取全局g_if_vlan_info信息 */
|
||
vlan_config_format_json_stub(interface);
|
||
|
||
return;
|
||
}
|
||
|
||
void vlan_config_get_all_stub(uint source)
|
||
{
|
||
int interface[MAX_INTERFACES] = {0};
|
||
int i = 0;
|
||
|
||
/* WEB下发,g_if_vlan_info对应的node是有数据的
|
||
只需将有数据的节点node返回到interface里即可*/
|
||
if(source == CONFIG_FROM_WEB){
|
||
printf("[vlan]vlan_config_get_all: CONFIG_FROM_WEB.\n");
|
||
for(i = 0; i < MAX_INTERFACES; i++){
|
||
//if(get_ifnode_from_global(g_if_vlan_info[i].if_name) != -1)
|
||
/* 不为空串才给interface置1 */
|
||
if(strcmp(g_if_vlan_info[i].if_name, "")){
|
||
interface[i] = 1;
|
||
printf("[vlan]get_all_stub: interface[%d].\n", i);
|
||
}
|
||
}
|
||
}
|
||
|
||
/* 配置恢复g_if_vlan_info里是空的,需要先从
|
||
配置文件将数据恢复到内存g_if_vlan_info[]中
|
||
然后再将有数据的节点node放入interface*/
|
||
else if(source == CONFIG_FROM_RECOVER1){
|
||
printf("[vlan]vlan_config_get_all: CONFIG_FROM_RECOVER1.\n");
|
||
vlan_get_from_conf_file(interface);
|
||
}
|
||
vlan_config_format_json_stub(interface);
|
||
return;
|
||
}
|
||
|