diff options
| author | Qiuwen Lu <[email protected]> | 2016-10-25 17:19:59 +0800 |
|---|---|---|
| committer | Qiuwen Lu <[email protected]> | 2016-10-25 17:19:59 +0800 |
| commit | 287e3ee0fc3ea5256cd33aef0d7c5d2487b841cf (patch) | |
| tree | cb0cb9469568b9d3d2a3e6092e2d55cae1cd242d /stack/src/device.c | |
| parent | c1002e8d6fe90c753b7e6198476391b22d14194a (diff) | |
增加协议栈实现,在Service中完成协议栈初始化流程。修改了mr_device的open方式,集中打开参数。
Diffstat (limited to 'stack/src/device.c')
| -rw-r--r-- | stack/src/device.c | 193 |
1 files changed, 193 insertions, 0 deletions
diff --git a/stack/src/device.c b/stack/src/device.c new file mode 100644 index 0000000..9b04d62 --- /dev/null +++ b/stack/src/device.c @@ -0,0 +1,193 @@ +/* 简单数据通信用户态协议栈——设备管理器 +* +* 本模块提供协议栈使用的设备管理功能。负责管理真实(或虚拟)设备之: +* A. IP地址、子网掩码、默认网关等网络层信息; +* B. MTU、VLAN等数据链路层信息。 +* +* \author Lu Qiuwen<[email protected]> +* \date 2016-10-18 +*/ + +#include <sys/queue.h> +#include <rte_ether.h> +#include <mr_rtdev.h> +#include <mr_rawio.h> +#include <rte_malloc.h> + +#include <sk_stack.h> +#include <sk_device.h> +#include <assert.h> + + +struct sk_dev_info * mr_stack_device_lookup(struct mr_stack_instance * instance, const char * symbol) +{ + return NULL; +} + +int mr_stack_device_iterate(struct mr_stack_instance * instance, struct sk_dev_info ** dev_info) +{ + // 迭代器为空,从头开始迭代,否则查找迭代器下一个对象 + if(*dev_info == NULL) + { + *dev_info = TAILQ_FIRST(&instance->dev_info_list); + return 0; + } + else + { + *dev_info = TAILQ_NEXT(*dev_info, next); + } + + // 迭代到尾部,返回错误码 + if (*dev_info == NULL) return -ENOENT; + return 0; +} + +// 创建一个协议栈设备 +int mr_stack_device_create(struct mr_stack_instance * instance, struct sk_dev_param * param) +{ + // 检查设备是否已经存在,不允许重复创建 + struct sk_dev_info * devinfo = mr_stack_device_lookup(instance, param->symbol); + if(devinfo != NULL) + { + MR_LOG(INFO, STACK, "StackCreateDevice, StackDevice %s has been created. failed. \n", + param->symbol); + return -EEXIST; + } + + // 申请Info结构体的空间 + devinfo = rte_zmalloc(NULL, sizeof(struct sk_dev_info), 0); + if(unlikely(devinfo == NULL)) + { + MR_LOG(WARNING, STACK, "StackCreateDevice, Cannot alloc memory for device info.\n"); + return -ENOMEM; + } + + // 写参数 + snprintf(devinfo->symbol, sizeof(devinfo->symbol), "%s", param->symbol); + devinfo->param = *param; + devinfo->instance_ = instance; + devinfo->in_addr = param->in_addr; + devinfo->in_mask = param->in_mask; + devinfo->mac_addr = param->mac_addr; + devinfo->mtu = param->mtu; + devinfo->promisc = 0; + + // 加入到协议栈设备链表中 + TAILQ_INSERT_TAIL(&instance->dev_info_list, devinfo, next); + return 0; +} + +// 销毁协议栈设备 +int mr_stack_device_destory(struct sk_dev_info * devinfo) +{ + assert(0); + return 0; +} + +// 设置协议栈的IP地址 +int mr_stack_device_set_inaddr(struct sk_dev_info * dev_info, struct in_addr in_addr, + struct in_addr in_mask) +{ + dev_info->in_addr = in_addr; + dev_info->in_mask = in_mask; + return 0; +} + +// 读取协议栈设备的IP地址 +int mr_stack_device_get_inaddr(struct sk_dev_info * devinfo, + struct in_addr * in_addr, struct in_addr * in_mask) +{ + *in_addr = devinfo->in_addr; + *in_mask = devinfo->in_mask; + return 0; +} + +// 设置协议栈设备的MTU +int mr_stack_device_set_mtu(struct sk_dev_info * devinfo, unsigned int mtu) +{ + devinfo->mtu = mtu; + return 0; +} + +// 读取协议栈设备的MTU +int mr_stack_device_get_mtu(struct sk_dev_info * devinfo) +{ + return devinfo->mtu; +} + +// 启动设备 +int mr_stack_device_enable(struct sk_dev_info * devinfo) +{ + return 0; +} + +// 禁用设备 +int mr_stack_device_disable(struct sk_dev_info * devinfo) +{ + return 0; +} + +static struct sk_dev_desc * sk_dev_desc_new(struct sk_dev_info * dev_info, unsigned int mode) +{ + // 申请内存空间 + struct sk_dev_desc * dev_desc = rte_zmalloc(NULL, sizeof(struct sk_dev_desc), 0); + if(unlikely(dev_desc == NULL)) + { + MR_LOG(WARNING, STACK, "StackDevice, StackDeviceDescCreate, " + "Cannot alloc memory for device %s desc. Failed. \n", dev_info->symbol); + return NULL; + } + + // 各线程使用的资源放在线程初始化流程中进行,这里不进行。 + dev_desc->dev_info = dev_info; + return dev_desc; +} + +static void sk_dev_desc_delete(struct sk_dev_desc * dev_desc) +{ + // TODO:stream的释放 + + // 释放RX侧自循环缓冲区 + for(int i = 0; i < RTE_DIM(dev_desc->rx_loop_buffer); i++) + { + if (dev_desc->rx_loop_buffer[i] != NULL) + rte_ring_free(dev_desc->rx_loop_buffer[i]); + } + + // 释放TX侧自循环缓冲区 + for(int i = 0; i < RTE_DIM(dev_desc->tx_loop_buffer); i++) + { + if (dev_desc->tx_loop_buffer[i] != NULL) + rte_ring_free(dev_desc->tx_loop_buffer[i]); + } +} + +/* 以下为内部初始化、注销处理流程。*/ +int stack_device_init(struct mr_stack_instance * instance) +{ + // 创建主应用设备句柄,插入到句柄链表中 + struct sk_dev_info * dev_info_iter; + struct sk_dev_desc * dev_desc_iter; + + TAILQ_FOREACH(dev_info_iter, &instance->dev_info_list, next) + { + struct sk_dev_desc * dev_desc = sk_dev_desc_new(dev_info_iter, SK_DEV_MODE_SERV); + if (unlikely(dev_desc == NULL)) goto errout; + TAILQ_INSERT_TAIL(&instance->dev_desc_list, dev_desc, next); + } + + return 0; + +errout: + TAILQ_FOREACH(dev_desc_iter, &instance->dev_desc_list, next) + { + sk_dev_desc_delete(dev_desc_iter); + } + return -1; +} + +int stack_device_slave_init(struct mr_stack_instance * instance, + struct mr_stack_slave_instance * slave_instance) +{ + return 0; +}
\ No newline at end of file |
