secgateway/Platform/user/configm/config-server/vlan_config/vlan_config.c

2380 lines
67 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 "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;
}