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 | |
| parent | c1002e8d6fe90c753b7e6198476391b22d14194a (diff) | |
增加协议栈实现,在Service中完成协议栈初始化流程。修改了mr_device的open方式,集中打开参数。
Diffstat (limited to 'stack')
| -rw-r--r-- | stack/CMakeLists.txt | 12 | ||||
| -rw-r--r-- | stack/include/port_bitmap.h | 114 | ||||
| -rw-r--r-- | stack/include/sk_device.h | 124 | ||||
| -rw-r--r-- | stack/include/sk_neigh.h | 82 | ||||
| -rw-r--r-- | stack/include/sk_protocol_arp.h | 26 | ||||
| -rw-r--r-- | stack/include/sk_stack.h | 48 | ||||
| -rw-r--r-- | stack/src/arp.c | 67 | ||||
| -rw-r--r-- | stack/src/device.c | 193 | ||||
| -rw-r--r-- | stack/src/neigh.c | 230 | ||||
| -rw-r--r-- | stack/src/rxtx.c | 8 | ||||
| -rw-r--r-- | stack/src/stack.c | 33 | ||||
| -rw-r--r-- | stack/src/udp.c | 0 |
12 files changed, 937 insertions, 0 deletions
diff --git a/stack/CMakeLists.txt b/stack/CMakeLists.txt new file mode 100644 index 0000000..fb4feb1 --- /dev/null +++ b/stack/CMakeLists.txt @@ -0,0 +1,12 @@ +find_package(DPDK REQUIRED)
+include_directories(${CMAKE_SOURCE_DIR}/include)
+include_directories(${CMAKE_SOURCE_DIR}/include/extern)
+include_directories(${CMAKE_SOURCE_DIR}/include/internal)
+include_directories(${DPDK_INCLUDE_DIR})
+
+add_definitions(${DPDK_C_PREDEFINED})
+include_directories(include)
+add_library(stack src/stack.c src/device.c src/neigh.c src/arp.c)
+target_link_libraries(stack MESA_prof_load_static mruntime core)
+target_link_libraries(stack rt pthread dl)
+target_include_directories(stack INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/include/")
\ No newline at end of file diff --git a/stack/include/port_bitmap.h b/stack/include/port_bitmap.h new file mode 100644 index 0000000..4391b76 --- /dev/null +++ b/stack/include/port_bitmap.h @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2016 Intel Corporation. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef _PORT_BITMAP_H_ +#define _PORT_BITMAP_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <stdint.h> +#include <limits.h> +#include <rte_common.h> + +/* + * Simple implementation of bitmap for all possible UDP ports [0-UINT16_MAX]. + */ + +#define MAX_PORT_NUM (UINT16_MAX + 1) + +#define PORT_BLK(p) ((p) / (sizeof(uint32_t) * CHAR_BIT)) +#define PORT_IDX(p) ((p) % (sizeof(uint32_t) * CHAR_BIT)) + +#define MAX_PORT_BLK PORT_BLK(MAX_PORT_NUM) + +struct portmap +{ + uint32_t nb_set; /* number of bits set. */ + uint32_t blk; /* last block with free entry. */ + uint32_t bm[MAX_PORT_BLK]; +}; + +static inline void portmap_init(struct portmap *pbm, uint32_t blk) +{ + pbm->bm[0] = 1; + pbm->nb_set = 1; + pbm->blk = blk; +} + +static inline void portmap_set(struct portmap *pbm, uint16_t port) +{ + uint32_t i, b, v; + + i = PORT_BLK(port); + b = 1 << PORT_IDX(port); + v = pbm->bm[i]; + pbm->bm[i] = v | b; + pbm->nb_set += (v & b) == 0; +} + +static inline void portmap_clear(struct portmap *pbm, uint16_t port) +{ + uint32_t i, b, v; + + i = PORT_BLK(port); + b = 1 << PORT_IDX(port); + v = pbm->bm[i]; + pbm->bm[i] = v & ~b; + pbm->nb_set -= (v & b) != 0; +} + + +static inline uint32_t portmap_check(const struct portmap *pbm, uint16_t port) +{ + uint32_t i, v; + + i = PORT_BLK(port); + v = pbm->bm[i] >> PORT_IDX(port); + return v & 1; +} + +static inline uint16_t portmap_find_range(struct portmap *pbm, + uint32_t start_blk, uint32_t end_blk) +{ + uint32_t i, v; + uint16_t p; + + if (pbm->nb_set == MAX_PORT_NUM) + return 0; + + p = 0; + for (i = start_blk; i != end_blk; i++) { + i %= RTE_DIM(pbm->bm); + v = pbm->bm[i]; + if (v != UINT32_MAX) { + for (p = i * (sizeof(pbm->bm[0]) * CHAR_BIT); + (v & 1) != 0; v >>= 1, p++) + ; + + pbm->blk = i; + break; + } + } + return p; +} + +#ifdef __cplusplus +} +#endif + +#endif /* _PORT_BITMAP_H_ */ diff --git a/stack/include/sk_device.h b/stack/include/sk_device.h new file mode 100644 index 0000000..0af22e7 --- /dev/null +++ b/stack/include/sk_device.h @@ -0,0 +1,124 @@ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include <mr_common.h> +#include <sys/queue.h> +#include <rte_ether.h> +#include <mr_device.h> +#include <netinet/in.h> + +struct sk_dev_param +{ + // �豸���� + char symbol[MR_SYMBOL_MAX]; + // MTU + unsigned int mtu; + // IP��ַ + struct in_addr in_addr; + // �������� + struct in_addr in_mask; + // ���� + struct in_addr in_gateway; + // MAC��ַ + struct ether_addr mac_addr; + // RawЭ��ʹ�� + unsigned int en_raw; + // TCPЭ��ʹ�� + unsigned int en_tcp; + // UDPЭ��ʹ�� + unsigned int en_udp; + // ARPЭ��ʹ�� + unsigned int en_arp; + // ICMPЭ��ʹ�� + unsigned int en_icmp; + // ��ѭ����������С + unsigned int sz_rx_loop_buffer; + // ��ѭ����������С + unsigned int sz_tx_loop_buffer; +}; + +// �豸������Ϣ +struct sk_dev_info +{ + // Э��ջCTX + struct mr_stack_instance * instance_; + // �豸������һ�� + TAILQ_ENTRY(sk_dev_info) next; + // �豸���� + struct sk_dev_param param; + // �豸���� + char symbol[MR_SYMBOL_MAX]; + // �Ƿ����� + unsigned int enable; + // MTU��С + unsigned int mtu; + // �Ƿ����û���ģʽ + unsigned int promisc; + // ����IP��ַ + struct in_addr in_addr; + // �������� + struct in_addr in_mask; + // ����MAC��ַ + struct ether_addr mac_addr; +}; + +// �豸��������ӽ���ͨ�ã� +struct sk_dev_desc +{ + +#define SK_DEV_MODE_SERV 0 +#define SK_DEV_MODE_APP 1 + + // ������һ�� + TAILQ_ENTRY(sk_dev_desc) next; + // ģʽ�������̻�ӽ��̣� + unsigned int mode; + // �豸��Ϣ��� + struct sk_dev_info * dev_info; + // ��ѭ�����Ļ��������ڷ����������д����� + struct rte_ring * rx_loop_buffer[MR_SID_MAX]; + // ��ѭ�����Ļ����������ձ��������д����� + struct rte_ring * tx_loop_buffer[MR_SID_MAX]; + // TCPЭ�� Rt-Device Stream + struct mr_rtdev_stream * tcp_rtdev_stream[MR_SID_MAX]; + // UDPЭ�� Rt-Device Stream + struct mr_rtdev_stream * udp_rtdev_stream[MR_SID_MAX]; +}; + +TAILQ_HEAD(sk_dev_info_list, sk_dev_info); +TAILQ_HEAD(sk_dev_desc_list, sk_dev_desc); + +struct sk_dev_info * mr_stack_device_lookup(struct mr_stack_instance * instance, const char * symbol); + +// �豸��Ϣ������ +int mr_stack_device_iterate(struct mr_stack_instance * instance, struct sk_dev_info ** dev_info); + +// ����һ��Э��ջ�豸 +int mr_stack_device_create(struct mr_stack_instance * instance, struct sk_dev_param * param); + +// ����Э��ջ�豸 +int mr_stack_device_destory(struct sk_dev_info * devinfo); + +// ����Э��ջ��IP��ַ +int mr_stack_device_set_inaddr(struct sk_dev_info * dev_info, struct in_addr in_addr, + struct in_addr in_mask); + +// ��ȡЭ��ջ�豸��IP��ַ +int mr_stack_device_get_inaddr(struct sk_dev_info * devinfo, + struct in_addr * in_addr, struct in_addr * in_mask); + +// ����Э��ջ�豸��MTU +int mr_stack_device_set_mtu(struct sk_dev_info * devinfo, unsigned int mtu); +// ��ȡЭ��ջ�豸��MTU +int mr_stack_device_get_mtu(struct sk_dev_info * devinfo); +// �����豸 +int mr_stack_device_enable(struct sk_dev_info * devinfo); +// �����豸 +int mr_stack_device_disable(struct sk_dev_info * devinfo); + +#ifdef __cplusplus +} +#endif
\ No newline at end of file diff --git a/stack/include/sk_neigh.h b/stack/include/sk_neigh.h new file mode 100644 index 0000000..934ac9e --- /dev/null +++ b/stack/include/sk_neigh.h @@ -0,0 +1,82 @@ +#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rte_rwlock.h>
+#include <rte_atomic.h>
+#include <rte_timer.h>
+#include <rte_ether.h>
+
+#define SK_NEIGH_MAX_HDR 0x60
+
+struct sk_neigh_table
+{
+ struct rte_timer * event_timer;
+ struct rte_hash * neigh_tbl;
+ rte_rwlock_t neigh_tbl_lock;
+};
+
+struct sk_dest_info
+{
+ uint16_t mtu;
+ uint8_t l2_len;
+ uint8_t l3_len;
+ uint8_t hdr[SK_NEIGH_MAX_HDR];
+};
+
+#define NUD_INCOMPLETE 0x01
+#define NUD_REACHABLE 0x02
+#define NUD_STALE 0x04
+#define NUD_DELAY 0x08
+#define NUD_PROBE 0x10
+#define NUD_FAILED 0x20
+#define NUD_NOARP 0x40
+#define NUD_PERMANENT 0x80
+#define NUD_NONE 0x00
+
+#define NUD_IN_TIMER ( NUD_INCOMPLETE | NUD_REACHABLE | NUD_DELAY | NUD_PROBE )
+#define NUD_VALID ( NUD_PERMANENT | NUD_NOARP | NUD_REACHABLE | NUD_PROBE | NUD_STALE | NUD_DELAY )
+#define NUD_CONNECTED ( NUD_PERMANENT | NUD_NOARP | NUD_REACHABLE )
+
+struct sk_neighbour
+{
+ // ���ü���
+ rte_atomic16_t refcnt;
+ // ������
+ rte_rwlock_t rwlock;
+ // ��ʱ��
+ struct rte_timer timer;
+ // ״̬
+ unsigned int state;
+ // ��Ч��־λ
+ unsigned int dead;
+ // ������ʱ��
+ unsigned int update;
+ // �����豸
+ struct sk_dev_desc * dev;
+ // ��ѯ����
+ struct in_addr in_addr;
+ // ��ѯ���
+ struct ether_addr ether_addr;
+ // ���������Ϣ
+ struct sk_dest_info dest_info;
+};
+
+int neigh_update(struct sk_neighbour * neigh, const struct ether_addr * lladdr,
+ uint8_t state, uint32_t flags);
+
+int neigh_event_send(struct sk_neighbour * neigh, struct rte_mbuf * mbuf);
+
+struct sk_neighbour * neigh_create(struct sk_neigh_table * tbl,
+ struct in_addr in_addr, struct sk_dev_desc * dev);
+
+struct sk_neighbour * neigh_lookup(struct sk_neigh_table * tbl,
+ const void * pkey, int hold);
+
+int neigh_tbl_init(struct sk_neigh_table * tbl, const char * symbol, unsigned int nr_entries);
+
+#ifdef __cplusplus
+}
+#endif
\ No newline at end of file diff --git a/stack/include/sk_protocol_arp.h b/stack/include/sk_protocol_arp.h new file mode 100644 index 0000000..718a43c --- /dev/null +++ b/stack/include/sk_protocol_arp.h @@ -0,0 +1,26 @@ +#pragma once
+
+int protocol_arp_init(struct mr_stack_instance * instance);
+
+int protocol_arp_deinit(struct mr_stack_instance * instance);
+
+int protocol_arp_slave_init(struct mr_stack_instance * instance,
+ struct mr_stack_slave_instance * slave_instance);
+
+int protocol_arp_slave_deinit(struct mr_stack_instance * instance,
+ struct mr_stack_slave_instance * slave_instance);
+
+int protocol_arp_dev_init(struct sk_dev_desc * dev);
+
+int protocol_arp_dev_deinit(struct sk_dev_desc * dev);
+
+int protocol_arp_slave_dev_init(struct sk_dev_desc * dev);
+
+int protocol_arp_slave_dev_deinit(struct sk_dev_desc * dev);
+
+// ARP���Ĵ�����ں�����������̴�����
+int protocol_arp_entry(struct stack_dev_handle * dev_handle,
+ struct rte_mbuf * in_pkt[], struct rte_mbuf * out_pkt[],
+ unsigned int nr_in_pkt, unsigned int * nr_left_pkt);
+
+int protocol_arp_request_send(struct sk_dev_desc * dev, struct in_addr in_addr);
\ No newline at end of file diff --git a/stack/include/sk_stack.h b/stack/include/sk_stack.h new file mode 100644 index 0000000..8297502 --- /dev/null +++ b/stack/include/sk_stack.h @@ -0,0 +1,48 @@ +#pragma once +#include <sk_device.h> + +#ifndef MR_STACK_DEFAULT_SZ_DELIVER_RING +#define MR_STACK_DEFAULT_SZ_DELIVER_RING 1024 +#endif + +#ifndef MR_STACK_DEFAULT_SZ_DELIVER_BUFFER +#define MR_STACK_DEFAULT_SZ_DELIVER_BUFFER 128 +#endif + +#ifndef MR_STACK_DEFAULT_SZ_LOOP_RING +#define MR_STACK_DEFAULT_SZ_LOOP_RING 1024 +#endif + +struct mr_stack_param +{ + // �������� + char servsym[MR_SYMBOL_MAX]; + // �����߳�����������ע��Э��ջ�̡߳���Э��ջȡ���ĵ��̣߳� + unsigned int nr_serv_thread; + // �ַ����д�С + unsigned int sz_deliver_ring; + // �ַ����л�������С + unsigned int sz_deliver_buffer; + // ��ѭ�����д�С + unsigned int sz_loop_ring; +}; + +struct mr_stack_instance +{ + // Э��ջ���в��� + struct mr_stack_param param; + // Э��ջ�豸��Ϣ + struct sk_dev_info_list dev_info_list; + // Э��ջ�豸��� + struct sk_dev_desc_list dev_desc_list; +}; + +struct mr_stack_slave_instance +{ + // Э��ջ�豸��� + struct sk_dev_desc_list dev_desc_list; +}; + +struct mr_stack_instance * mr_stack_instance_create(struct mr_stack_param * param); + +struct mr_stack_slave_instance * mr_stack_slave_create();
\ No newline at end of file diff --git a/stack/src/arp.c b/stack/src/arp.c new file mode 100644 index 0000000..34131b8 --- /dev/null +++ b/stack/src/arp.c @@ -0,0 +1,67 @@ +/* \brief ��Э��ջARP/RARPЭ�鴦��ģ��
+*
+* ����ARP/RARPЭ�鱨������
+*
+* \author Lu Qiuwen<[email protected]>
+* \date 2016-10-21
+*/
+
+#include <mr_rtdev.h>
+#include <sk_stack.h>
+#include <sk_device.h>
+#include <rte_ip_frag.h>
+
+int protocol_arp_init(struct mr_stack_instance * instance)
+{
+ return 0;
+}
+
+int protocol_arp_deinit(struct mr_stack_instance * instance)
+{
+ return 0;
+}
+
+int protocol_arp_slave_init(struct mr_stack_instance * instance,
+ struct mr_stack_slave_instance * slave_instance)
+{
+ return 0;
+}
+
+int protocol_arp_slave_deinit(struct mr_stack_instance * instance,
+ struct mr_stack_slave_instance * slave_instance)
+{
+ return 0;
+}
+
+int protocol_arp_dev_init(struct sk_dev_desc * dev)
+{
+ return 0;
+}
+
+int protocol_arp_dev_deinit(struct sk_dev_desc * dev)
+{
+ return 0;
+}
+
+int protocol_arp_slave_dev_init(struct sk_dev_desc * dev)
+{
+ return 0;
+}
+
+int protocol_arp_slave_dev_deinit(struct sk_dev_desc * dev)
+{
+ return 0;
+}
+
+// ARP���Ĵ�����ں�����������̴�����
+int protocol_arp_entry(struct stack_dev_handle * dev_handle,
+ struct rte_mbuf * in_pkt[], struct rte_mbuf * out_pkt[],
+ unsigned int nr_in_pkt, unsigned int * nr_left_pkt)
+{
+ return 0;
+}
+
+int protocol_arp_request_send(struct sk_dev_desc * dev, struct in_addr in_addr)
+{
+ return 0;
+}
\ No newline at end of file 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 diff --git a/stack/src/neigh.c b/stack/src/neigh.c new file mode 100644 index 0000000..ac2ef3c --- /dev/null +++ b/stack/src/neigh.c @@ -0,0 +1,230 @@ +/* \brief ��Э��ջ�ھ���ϵͳ +* +* �����������ڽ�ͨ�ŵ��������Ϣ +* +* \author Lu Qiuwen<[email protected]> +* \date 2016-10-21 +*/ + + +#include <rte_hash.h> +#include <rte_rwlock.h> +#include <rte_atomic.h> +#include <rte_ether.h> +#include <rte_ip.h> +#include <rte_ip_frag.h> +#include <rte_timer.h> + +#include <sk_device.h> +#include <sk_protocol_arp.h> +#include <sk_neigh.h> +#include <rte_cycles.h> +#include <rte_hash_crc.h> + +#define __IP_VERSION_IHL(version, len) (version << 4 | len << 0) +#define __IP_TTL 75 + +// �����㱨��ͷ +static inline size_t __neigh_fill_ether_hdr(uint8_t * hdr, const struct ether_addr * src_addr, + const struct ether_addr * dst_addr, const uint16_t next_layer_type) +{ + struct ether_hdr * ether_hdr = (struct ether_hdr *)hdr; + ether_addr_copy(src_addr, ðer_hdr->s_addr); + ether_addr_copy(dst_addr, ðer_hdr->d_addr); + ether_hdr->ether_type = htons(next_layer_type); + return sizeof(struct ether_hdr); +} + +// ������㱨��ͷ +static inline size_t __neigh_fill_ipv4_hdr(uint8_t * hdr, const struct in_addr * src_addr, + const struct in_addr * dst_addr, uint16_t total_len, uint16_t pid, uint8_t next_proto) +{ + struct ipv4_hdr * ip_hdr = (struct ipv4_hdr *)hdr; + + ip_hdr->version_ihl = __IP_VERSION_IHL(4, sizeof(struct ipv4_hdr) / 4); + ip_hdr->type_of_service = 0; + ip_hdr->total_length = htons(total_len); + ip_hdr->packet_id = htons(pid); + ip_hdr->fragment_offset = 0; + ip_hdr->time_to_live = __IP_TTL; + ip_hdr->next_proto_id = next_proto; + ip_hdr->hdr_checksum = 0; + + ip_hdr->src_addr = src_addr->s_addr; + ip_hdr->dst_addr = dst_addr->s_addr; + return sizeof(struct ipv4_hdr); +} + +static inline void neigh_fill_destinfo(struct sk_neighbour * neigh) +{ + struct sk_dest_info * dest_info = &neigh->dest_info; + size_t ret; + + ret = __neigh_fill_ether_hdr(dest_info->hdr, + &neigh->dev->dev_info->mac_addr, &neigh->ether_addr, + ETHER_TYPE_IPv4); + neigh->dest_info.l2_len = ret; + + ret = __neigh_fill_ipv4_hdr(dest_info->hdr + ret, + &neigh->dev->dev_info->in_addr, + &neigh->in_addr, 0, 0, 0); + neigh->dest_info.l3_len = ret; + return; +} + +static void neigh_destory(struct sk_neighbour * neigh) +{ + return; +} + +static void neigh_probe(struct sk_neighbour * neigh) +{ + protocol_arp_request_send(neigh->dev, neigh->in_addr); +} + +static inline void neigh_hold(struct sk_neighbour * neigh) +{ + rte_atomic16_add(&neigh->refcnt, 1); + return; +} + +static inline void neigh_release(struct sk_neighbour * neigh) +{ + if (rte_atomic16_dec_and_test(&neigh->refcnt)) + neigh_destory(neigh); + return; +} + +static struct sk_neighbour * neigh_alloc(struct sk_neigh_table * tbl, struct sk_dev_desc * dev) +{ + struct sk_neighbour * neigh = rte_zmalloc(NULL, sizeof(struct sk_neighbour), 0); + if (unlikely(neigh == NULL)) + { + MR_LOG(INFO, STACK, "NeighSystem, NeighCreate, " + "Cannot alloc memory for neighbor structure. \n"); + return NULL; + } + + rte_rwlock_init(&neigh->rwlock); + rte_atomic16_init(&neigh->refcnt); + neigh->state = NUD_NONE; + neigh->dead = 1; + neigh->update = rte_rdtsc(); + neigh->dev = dev; + return neigh; +} + + +int neigh_update(struct sk_neighbour * neigh, const struct ether_addr * lladdr, + uint8_t state, uint32_t flags) +{ + rte_rwlock_write_lock(&neigh->rwlock); + struct sk_dev_desc * dev = neigh->dev; + uint8_t old_state = neigh->state; + + if((old_state & NUD_REACHABLE) && (state & NUD_REACHABLE)) + { + ether_addr_copy(lladdr, &neigh->ether_addr); + neigh_fill_destinfo(neigh); + neigh->dead = 0; + neigh->state = state; + } + + if((old_state & NUD_INCOMPLETE ) && (state & NUD_REACHABLE)) + { + ether_addr_copy(lladdr, &neigh->ether_addr); + neigh_fill_destinfo(neigh); + neigh->dead = 0; + neigh->state = state; + } + + rte_rwlock_write_unlock(&neigh->rwlock); + return 0; +} + +int neigh_event_send(struct sk_neighbour * neigh, struct rte_mbuf * mbuf) +{ + rte_rwlock_write_lock(&neigh->rwlock); + + if (neigh->state & (NUD_REACHABLE)) + goto out_unblock; + + if(neigh->state & NUD_NONE) + { + neigh_probe(neigh); + goto out_unblock; + } + + //TODO: ����״̬������ + +out_unblock: + rte_rwlock_write_unlock(&neigh->rwlock); + return 0; +} + +struct sk_neighbour * neigh_create(struct sk_neigh_table * tbl, + struct in_addr in_addr, struct sk_dev_desc * dev) +{ + struct sk_neighbour * neigh = neigh_alloc(tbl, dev); + if (unlikely(neigh == NULL)) return NULL; + + // Hashֵ��ΪIP��ַ������ֵ�����뵽Hash���� + hash_t hash = in_addr.s_addr; + rte_rwlock_write_lock(&tbl->neigh_tbl_lock); + rte_hash_add_key_with_hash(tbl->neigh_tbl, &hash, hash); + rte_rwlock_write_unlock(&tbl->neigh_tbl_lock); + + // ���������¼�������ARP���� + neigh_event_send(neigh, NULL); + neigh_hold(neigh); + return neigh; +} + +struct sk_neighbour * neigh_lookup(struct sk_neigh_table * tbl, + const void * pkey, int hold) +{ + hash_t hash = *(uint32_t *)pkey; + struct sk_neighbour * neigh; + + rte_rwlock_read_lock(&tbl->neigh_tbl_lock); + rte_hash_lookup_with_hash_data(tbl->neigh_tbl, &hash, hash, (void **)&neigh); + rte_rwlock_read_unlock(&tbl->neigh_tbl_lock); + + if (neigh == NULL) return NULL; + + if (hold) neigh_hold(neigh); + return neigh; +} + +int neigh_tbl_init(struct sk_neigh_table * tbl, const char * symbol, unsigned int nr_entries) +{ + char hash_tbl_symbol[MR_SYMBOL_MAX]; + snprintf(hash_tbl_symbol, sizeof(hash_tbl_symbol), "NTB-%s", symbol); + + struct rte_hash_parameters hash_params = + { + .name = hash_tbl_symbol, + .entries = nr_entries, + .key_len = sizeof(uint32_t), + .hash_func = rte_hash_crc, + .hash_func_init_val = 0, + }; + + tbl->neigh_tbl = rte_hash_create(&hash_params); + if (unlikely(tbl == NULL)) + { + MR_LOG(WARNING, STACK, "NeighSystem, NeighTblInit, " + "Create hash table %s failed(for NeighTable %s): %s. \n", + hash_tbl_symbol, symbol, rte_strerror(rte_errno)); + return -1; + } + + rte_rwlock_init(&tbl->neigh_tbl_lock); + return 0; +} + +int neigh_tbl_deinit(struct sk_neigh_table * tbl) +{ + rte_hash_reset(tbl->neigh_tbl); + return 0; +}
\ No newline at end of file diff --git a/stack/src/rxtx.c b/stack/src/rxtx.c new file mode 100644 index 0000000..6f3d376 --- /dev/null +++ b/stack/src/rxtx.c @@ -0,0 +1,8 @@ +/* \brief ��Э��ջԭʼ���Ĵ�������
+ *
+ * ģ�鴦������������Э��ջ�����ݱ��ĺ����������������ݱ���
+ *
+ * \author Lu Qiuwen<[email protected]>
+ * \date 2016-10-21
+ */
+
diff --git a/stack/src/stack.c b/stack/src/stack.c new file mode 100644 index 0000000..1197167 --- /dev/null +++ b/stack/src/stack.c @@ -0,0 +1,33 @@ +/* 简单数据通信用户态协议栈管理器 + * + * \author Lu Qiuwen<[email protected]> + * \date 2016-10-18 + */ + +#include <sk_stack.h> +#include <rte_ip_frag.h> + +struct mr_stack_instance * mr_stack_instance_create(struct mr_stack_param * param) +{ + struct mr_stack_instance * instance; + + // 分配空间 + instance = rte_zmalloc(NULL, sizeof(struct mr_stack_instance), 0); + if(unlikely(instance == NULL)) + { + MR_LOG(INFO, STACK, "StackInstanceCreate, " + "Cannot alloc memory for stack instance. \n"); + return NULL; + } + + // 初始化参数 + instance->param = *param; + TAILQ_INIT(&instance->dev_info_list); + TAILQ_INIT(&instance->dev_desc_list); + return instance; +} + +struct mr_stack_slave_instance * mr_stack_slave_create() +{ + return NULL; +}
\ No newline at end of file diff --git a/stack/src/udp.c b/stack/src/udp.c new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/stack/src/udp.c |
