summaryrefslogtreecommitdiff
path: root/stack/src/device.c
diff options
context:
space:
mode:
authorQiuwen Lu <[email protected]>2016-10-25 17:19:59 +0800
committerQiuwen Lu <[email protected]>2016-10-25 17:19:59 +0800
commit287e3ee0fc3ea5256cd33aef0d7c5d2487b841cf (patch)
treecb0cb9469568b9d3d2a3e6092e2d55cae1cd242d /stack/src/device.c
parentc1002e8d6fe90c753b7e6198476391b22d14194a (diff)
增加协议栈实现,在Service中完成协议栈初始化流程。修改了mr_device的open方式,集中打开参数。
Diffstat (limited to 'stack/src/device.c')
-rw-r--r--stack/src/device.c193
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