/*
* Copyright (C) 2010 Ruijie Network. All rights reserved.
*/
/*
* vlan.c
* Original Author: chenjieping, 2010-4-22
*
* vlan和port的组织相关函数
* History
*/
#include "vlan.h"
/**
* vid_to_vlan - 查找对应vlan
* @vid:待查找vlan的id
*
* 已知vid,搜索并返回对应的vlan_t
*
* 搜索成功返回指向对应vlan_t的指针,否则返回NULL
*/
vlan_t *vid_to_vlan(int vid)
{
int hash;
vlan_t *pos;
struct list_head *n;
/*非法vid*/
if (vid < MIN_VID || vid > MAX_VID) {
printf("非法vid。\n");
return NULL;
}
hash = vid % HASH_MASK;
/*哈希表为空*/
if (list_empty(&vlan_hash[hash])) {
return NULL;
}
/*查找哈希表*/
list_for_each_entry_safe(pos, n, &vlan_hash[hash], vlan_list, vlan_t) {
/*查找成功*/
if (pos->vid == vid) {
return pos;
}
}
/* 查找失败*/
return NULL;
}
/**
* pid_to_port - 查找对应port
* @pid:待查找port的id
*
* 已知pid,搜索并返回对应的port_t
*
* 搜索成功返回指向对应port_t的指针,否则返回NULL
*/
port_t *pid_to_port(int pid)
{
int hash;
port_t *pos;
struct list_head *n;
/*非法pid*/
if ((pid < MIN_PID_1) || (pid > MAX_PID_2) || (pid > MAX_PID_1 && pid < MIN_PID_2)) {
printf("非法pid。\n");
return NULL;
}
hash = pid % HASH_MASK;
/*哈希表为空*/
if (list_empty(&port_hash[hash])) {
return NULL;
}
/*查找哈希表*/
list_for_each_entry_safe(pos, n, &port_hash[hash], port_list, port_t) {
/*查找成功*/
if (pos->pid == pid) {
return pos;
}
}
/*查找失败*/
return NULL;
}
/**
* 开辟新port结点
*/
static port_t *new_port(int pid, int speed, int duplex)
{
port_t *port;
port = (port_t *)malloc(sizeof(port_t));
if (port == NULL) {
printf("内存分配失败。\n");
free(port);
exit(1);
}
port->pid = pid;
port->speed = speed;
port->duplex = duplex;
return port;
}
/**
* add_port - 添加port
* @pid:待添加port的id
*
* 添加相应pid的port
*
* 添加成功返回0,否则返回非0
*/
int add_port(int pid, int speed, int duplex)
{
int hash;
port_t *pos;
port_t *port;
struct list_head *n;
port = pid_to_port(pid);
/*如果port存在,修改参数*/
if(port != NULL) {
port->speed = speed;
port->duplex = duplex;
return SUCCESS;
}
/*检查接口数是否达到上限*/
if (phy_port_cnt == phy_port_num) {
printf("接口数已达上限\n");
return FAIL;
}
/*创建新port结点*/
port = new_port(pid, speed, duplex);
hash = pid % HASH_MASK;
/*查找插入位置*/
list_for_each_entry_safe(pos, n, &port_hash[hash], port_list, port_t) {
if (pos->pid < pid) {
continue;
}
break;
}
/*将port结点添加到哈希表中*/
list_add(&port->port_list, pos->port_list.prev);
phy_port_cnt++;
return SUCCESS;
}
/**
* delete_port - 删除port
* @pid:待删除port的id
*
* 删除pid对应的port
*
* 删除成功返回0,否则返回非0
*/
int delete_port(int pid)
{
int i;
vlan_t *pos;
port_t *port;
struct list_head *n;
port = pid_to_port(pid);
/*接口不存在*/
if (port == NULL) {
printf("接口不存在。\n");
return FAIL;
}
/*将port从各vlan的port表中删除*/
for (i = 0; i < HASH_SIZE; i++) {
list_for_each_entry_safe(pos, n, &vlan_hash[i], vlan_list, vlan_t) {
if (pid <= MAX_PID_1) {
pos->port_in_1[pid] = NULL;
} else {
pos->port_in_2[pid - MIN_PID_2] = NULL;
}
}
}
/*从哈希表中删除*/
list_del(&port->port_list);
free(port);
phy_port_cnt--;
return SUCCESS;
}
/*开辟新vlan结点*/
static vlan_t *new_vlan(int vid, char *name)
{
vlan_t *vlan;
vlan = (vlan_t *)malloc(sizeof(vlan_t));
if (vlan == NULL) {
printf("内存分配失败\n");
free(vlan);
exit(1);
}
vlan->vid = vid;
vlan->name = strdup(name);
memset(vlan->port_in_1, 0, sizeof(vlan->port_in_1));
memset(vlan->port_in_2, 0, sizeof(vlan->port_in_2));
return vlan;
}
/**
* create_vlan - 创建vlan
* @vid:待创建vlan的id
*
* 创建一个指定vid的vlan
*
* 创建成功返回0,否则返回非0
*/
int create_vlan(int vid, char *name)
{
int hash;
vlan_t *pos;
vlan_t *vlan;
struct list_head *n;
if (vid == 0) {
printf("不允许创建 vid = 0的vlan\n");
return FAIL;
}
vlan = vid_to_vlan(vid);
/*vlan原本存在,进行修改*/
if (vlan != NULL) {
free(vlan->name);
vlan->name = strdup(name);
return SUCCESS;
}
/*vlan数目是否达到上限*/
if (vlan_cnt == VLAN_NUM) {
printf("vlan数已达上限\n");
return FAIL;
}
/*闯将新vlan结点*/
vlan = new_vlan(vid, name);
hash = vid % HASH_MASK;
/*查找插入位置*/
list_for_each_entry_safe(pos, n, &vlan_hash[hash], vlan_list, vlan_t) {
if (pos->vid < vid) {
continue;
}
break;
}
/*插入哈希表中*/
list_add(&vlan->vlan_list, pos->vlan_list.prev);
vlan_cnt++;
return SUCCESS;
}
/**
* destory_vlan - 删除vlan
* @vid:待删除vlan的id
*
* 删除指定vlan
*/
void destory_vlan(int vid)
{
vlan_t *vlan;
vlan = vid_to_vlan(vid);
if (vlan == NULL) {
printf("vlan不存在\n");
return;
}
vlan_cnt--;
list_del(&vlan->vlan_list);
free(vlan);
}
/**
* is_contain - port和vlan关系检查
* @vid:vlan的id
* @pid:port的id
*
* 查询一个port是否是一个vlan的成员,是的话返回1,否则返回0
*/
int is_contain(int vid, int pid)
{
vlan_t *vlan;
vlan = vid_to_vlan(vid);
if (vlan == NULL) {
printf("vlan不存在\n");
return 0;
}
/*搜索相应port表*/
if ((pid <= MAX_PID_1 && vlan->port_in_1[pid] != NULL)
|| (pid >= MIN_PID_2 && vlan->port_in_2[pid - MIN_PID_2] != NULL)) {
return 1;
}
return 0;
}
/**
* for_each_vlan
* @pid:指定port
* @operation:函数指针
*
* 对一个port所属的所有成员调用函数operation
*/
void for_each_vlan(int pid, void (* operation)(int pid, int vid))
{
int i;
vlan_t *pos;
port_t *port;
struct list_head *n;
port = pid_to_port(pid);
if (port == NULL) {
printf("接口不存在\n");
exit(1);
}
for (i = 0; i < HASH_SIZE; i++) {
list_for_each_entry_safe(pos, n, &vlan_hash[i], vlan_list, vlan_t) {
if ((pid <= MAX_PID_1 && pos->port_in_1[pid] != NULL)
|| (pid >= MIN_PID_2 && pos->port_in_2[pid - MIN_PID_2] != NULL)) {
(*operation)(pid, pos->vid);
}
}
}
}
/**
* for_each_port
* @vid:指定vlan
* @operation:函数指针
*
* 对一个vlan的所有成员调用函数operation
*/
void for_each_port(int vid, void (* operation)(int pid, int vid))
{
int i;
vlan_t *vlan;
vlan = vid_to_vlan(vid);
if (vlan == NULL) {
printf("vlan不存在\n");
exit(1);
}
for (i = MIN_PID_1; i <= MAX_PID_1; i++) {
if (vlan->port_in_1[i] != NULL) {
(* operation)(i, vid);
}
}
for (i = 0; i <= MAX_PID_2 - MIN_PID_2; i++) {
if (vlan->port_in_2[i] != NULL) {
(* operation)(i + MIN_PID_2, vid);
}
}
}
/**
* add_port_to_vlan - 将一个port加入某一个vlan
* @vid:指定vlan的id
* @pid:指定port的id
*
* 将一个port加入某一个vlan,如果该vlan不存在,创建它
*
* 添加成功,返回0,否则返回非0
*/
int add_port_to_vlan(int vid, int pid)
{
vlan_t *vlan;
port_t *port;
port = pid_to_port(pid);
if (port == NU
没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
1.VLAN 一个系统中最多可以有4096个VLAN, VLAN以vid来标识, vid的取值范围为0~4095 vid=0的VLAN用作特殊用途,不允许用户创建。 允许创建VLAN数量是系统的一个配置项(宏定义),一般不会小于200. VLAN是系统运行过程中由用户手工创建的,因此虽然系统中允许的的数量 可能很大,但有效的VLAN数量不会很多,一般在几十个以内。 2.PORT 一个系统中的port的数量在1K以内, port以pid来标识, pid分布在两个区间内,[0, 512],[2048, 2048 + 128], port数量是一个固定值,启动时由系数检测,调用add_port()创建相应的数据结构 3.关系 一个port可以属于多个VLAN,一个VLAN可以包含多个port。
资源推荐
资源详情
资源评论
收起资源包目录
vlan.rar (6个子文件)
vlan
main.c 4KB
vlan 与 port详细设计.doc 37KB
makefile 107B
vlan.h 2KB
list.h 5KB
vlan.c 9KB
共 6 条
- 1
资源评论
- 09kobe2019-10-22很好,可以编译通过
- ry82132018-07-14haikeyi ,可以编译通过
- hado882014-07-30很好很~~~~可以编译
- csdn_FL2018-09-12请问在linux下怎么编译运行
snakesword
- 粉丝: 1
- 资源: 6
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功