summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorQiuwen Lu <[email protected]>2016-11-28 14:42:36 +0800
committerQiuwen Lu <[email protected]>2016-11-28 14:42:36 +0800
commita561c804ef22a5e2e5055dc4254ae013ddc5dc45 (patch)
tree4858b0ad06ce86fe5fe1e1e30f03921ecafd478d
parent2fcd29356903c0a6c042d509f885fe53295207f3 (diff)
重构协议栈设备管理体系,增加普通路由、IP报文构建等功能
-rw-r--r--include/marsio_buffer_user_api.h13
-rw-r--r--service/include/sc_common.h2
-rw-r--r--service/src/core.c1
-rw-r--r--service/src/register.c35
-rw-r--r--stack/CMakeLists.txt4
-rw-r--r--stack/include/sk_common.h5
-rw-r--r--stack/include/sk_device.h45
-rw-r--r--stack/include/sk_ip.h9
-rw-r--r--stack/include/sk_protocol_arp.h18
-rw-r--r--stack/include/sk_protocol_common.h7
-rw-r--r--stack/include/sk_protocol_icmp.h4
-rw-r--r--stack/include/sk_protocol_raw.h6
-rw-r--r--stack/include/sk_route.h42
-rw-r--r--stack/include/sk_stack.h15
-rw-r--r--stack/src/dest.c0
-rw-r--r--stack/src/device.c172
-rw-r--r--stack/src/feedback.c16
-rw-r--r--stack/src/ip.c49
-rw-r--r--stack/src/neigh.c9
-rw-r--r--stack/src/protocol-arp.c16
-rw-r--r--stack/src/protocol-common.c8
-rw-r--r--stack/src/protocol-icmp.c89
-rw-r--r--stack/src/route.c185
-rw-r--r--stack/src/rxtx.c59
-rw-r--r--stack/src/stack.c68
25 files changed, 607 insertions, 270 deletions
diff --git a/include/marsio_buffer_user_api.h b/include/marsio_buffer_user_api.h
index a8c0844..6041a98 100644
--- a/include/marsio_buffer_user_api.h
+++ b/include/marsio_buffer_user_api.h
@@ -11,7 +11,7 @@ extern "C" {
#include <stdint.h>
-typedef void marsio_buf_t;
+typedef void marsio_buff_t;
int marsio_buff_malloc(marsio_buff_t *m[], unsigned int nb_buff,unsigned int flags,int thread_seq);
void marsio_buff_free(marsio_buff_t *m[], unsigned int nb_buff);
@@ -42,27 +42,18 @@ marsio_buff_t *marsio_buff_getnext_pkt(marsio_buff_t *m);
void marsio_buff_append_pkt(marsio_buff_t *previous, marsio_buff_t *next);
void marsio_buff_append_seg(marsio_buff_t *previous, marsio_buff_t *next);
-
uint16_t marsio_buff_headroom(const marsio_buff_t *m);
uint16_t marsio_buff_tailroom(const marsio_buff_t *m);
uint32_t marsio_get_pkt_type(marsio_buff_t *m);
-
-
-
-
-
marsio_buff_t *marsio_buff_dup(marsio_buff_t *m);
uint32_t marsio_buff_pkt_len(marsio_buff_t *m);
-
-
-void marsio_buff_append_pkt(marsio_buff_t *previous, marsio_buff_t *next);
marsio_buff_t *marsio_buff_getnext(marsio_buff_t *m);
-#ifdef __cplusplus
+#ifdef __cplusplusW
}
#endif
diff --git a/service/include/sc_common.h b/service/include/sc_common.h
index d73507b..cb73199 100644
--- a/service/include/sc_common.h
+++ b/service/include/sc_common.h
@@ -100,4 +100,6 @@ struct sc_instance
struct mr_core_instance * core_instance;
/* Э��ջȫ�־�� */
struct sk_instance * sk_instance;
+ /* Э��ջ����Ӧ�þ�� */
+ struct sk_app_instance * sk_serv_instance;
}; \ No newline at end of file
diff --git a/service/src/core.c b/service/src/core.c
index 99f27b2..5f62cea 100644
--- a/service/src/core.c
+++ b/service/src/core.c
@@ -206,7 +206,6 @@ void sc_instance_ctx_init(struct sc_instance * instance)
void sc_stage_init(struct sc_instance * instance)
{
- sk_instance_init(instance->sk_instance);
return;
}
diff --git a/service/src/register.c b/service/src/register.c
index 72b562b..2405e1e 100644
--- a/service/src/register.c
+++ b/service/src/register.c
@@ -48,8 +48,11 @@ static int sc_stack_instance_register(struct sc_instance * instance)
assert(g_cfg != NULL && g_ctx != NULL);
// 初始化协议栈全局句柄
- instance->sk_instance = sk_instance_create(&instance->sk_param, instance->core_instance);
+ instance->sk_instance = sk_instance_create(instance->core_instance, &instance->sk_param);
g_ctx->ctx_stack = instance->sk_instance;
+
+ // 初始化服务进程句柄
+ instance->sk_serv_instance = sk_app_instance_create(instance->sk_instance, instance->procsym);
return 0;
}
@@ -141,18 +144,40 @@ static int __sk_dev_register(struct sc_instance * instance,
struct rte_mempool * direct_pool = mr_device_direct_pool_get(sc_dev->dev);
struct rte_mempool * indirect_pool = mr_device_direct_pool_get(sc_dev->dev);
assert(direct_pool != NULL && indirect_pool != NULL);
+
+ sc_dev->sk_dev_param.direct_pktmbuf_pool = direct_pool;
+ sc_dev->sk_dev_param.indirect_pktmbuf_pool = indirect_pool;
- sc_dev->sk_dev = sk_device_create(instance->sk_instance, &sc_dev->sk_dev_param,
- direct_pool, indirect_pool, sc_param->nr_serv_thread);
+ // 创建设备
+ int ret = sk_device_create(instance->sk_instance, &sc_dev->sk_dev_param);
- if(unlikely(sc_dev->sk_dev == NULL))
+ if(unlikely(ret < 0))
{
MR_LOG(WARNING, SERVICE, "StackDevice %s create failed. \n", sc_dev->sk_dev_param.symbol);
return -1;
}
+
+ // 打开设备,主应用只启用自循环收发队列,不启用TCP/UDP队列
+ struct sk_dev_open_param dev_open_param;
+ snprintf(dev_open_param.symbol, sizeof(dev_open_param.symbol), "%s", sc_dev->symbol);
+ dev_open_param.mode = SK_DEV_MODE_SERV;
+ dev_open_param.nr_loop_rxstream = sc_param->nr_serv_thread;
+ dev_open_param.nr_loop_txstream = sc_param->nr_serv_thread;
+ dev_open_param.nr_tcp_rxstream = 0;
+ dev_open_param.nr_tcp_txstream = 0;
+ dev_open_param.nr_udp_rxstream = 0;
+ dev_open_param.nr_udp_txstream = 0;
+
+ struct sk_dev_desc * dev_desc = sk_device_open(instance->sk_serv_instance, &dev_open_param);
+ if (unlikely(dev_desc == NULL))
+ {
+ MR_LOG(WARNING, SERVICE, "StackDevice %s open failed. \n", sc_dev->sk_dev_param.symbol);
+ return -2;
+ }
+ sc_dev->sk_dev = dev_desc;
sc_dev->en_sk_dev = 1;
- MR_LOG(WARNING, SERVICE, "StackDevice %s created. \n", sc_dev->sk_dev_param.symbol);
+ MR_LOG(INFO, SERVICE, "StackDevice %s created. \n", sc_dev->sk_dev_param.symbol);
return 0;
}
diff --git a/stack/CMakeLists.txt b/stack/CMakeLists.txt
index 6b37830..201027a 100644
--- a/stack/CMakeLists.txt
+++ b/stack/CMakeLists.txt
@@ -6,8 +6,8 @@ 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/rxtx.c src/protocol-common.c
- src/protocol-arp.c src/protocol-tcp.c src/protocol-udp.c)
+add_library(stack src/stack.c src/device.c src/neigh.c src/rxtx.c src/route.c src/ip.c
+ src/protocol-common.c src/protocol-arp.c src/protocol-icmp.c src/protocol-tcp.c src/protocol-udp.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/sk_common.h b/stack/include/sk_common.h
index 3c284e3..91cbe73 100644
--- a/stack/include/sk_common.h
+++ b/stack/include/sk_common.h
@@ -6,7 +6,10 @@ enum _drop_location
SK_FREE_ARP_REPLY_DONE,
SK_FREE_ARP_REPLY_NOT_LOCAL,
SK_FREE_ARP_REQUEST_DONE,
- SK_FREE_ARP_REQUEST_REPLY_FAILED
+ SK_FREE_ARP_REQUEST_REPLY_FAILED,
+ SK_FREE_ICMP_UNDEFINED_TYPE,
+ SK_FREE_ICMP_CANNOT_HANDLE_TYPE,
+ SK_FREE_ICMP_REPLY_NO_DESTINFO
};
static inline void sk_packet_free(struct rte_mbuf * mbuf, thread_id_t sid, unsigned drop_location)
diff --git a/stack/include/sk_device.h b/stack/include/sk_device.h
index 4119c09..1ba5d34 100644
--- a/stack/include/sk_device.h
+++ b/stack/include/sk_device.h
@@ -38,22 +38,18 @@ struct sk_dev_param
unsigned int sz_rx_loop_buffer;
// ��ѭ����������С
unsigned int sz_tx_loop_buffer;
+
+ // �����ڴ����Դ
+ struct rte_mempool * direct_pktmbuf_pool;
+ struct rte_mempool * indirect_pktmbuf_pool;
};
struct sk_dev_open_param
{
// �豸����
char symbol[MR_SYMBOL_MAX];
- // RawЭ��ʹ��
- unsigned int en_raw;
- // TCPЭ��ʹ��
- unsigned int en_tcp;
- // UDPЭ��ʹ��
- unsigned int en_udp;
- // RawЭ�����߳���
- unsigned int nr_raw_rxstream;
- // RawЭ�鷢�߳���
- unsigned int nr_raw_txstream;
+ // ����ģʽ�������̻�ӽ��̣�
+ unsigned int mode;
// TCPЭ�����߳���
unsigned int nr_tcp_rxstream;
// TCPЭ�鷢�߳���
@@ -62,6 +58,10 @@ struct sk_dev_open_param
unsigned int nr_udp_rxstream;
// UDPЭ�鷢�߳���
unsigned int nr_udp_txstream;
+ // ��ѭ������������
+ unsigned int nr_loop_rxstream;
+ // ��ѭ������������
+ unsigned int nr_loop_txstream;
};
// �豸������Ϣ
@@ -85,6 +85,8 @@ struct sk_dev_info
struct in_addr in_addr;
// ��������
struct in_addr in_mask;
+ // ����
+ struct in_addr in_gateway;
// ����MAC��ַ
struct ether_addr mac_addr;
};
@@ -105,14 +107,16 @@ enum sk_dev_sid_type
struct sk_dev_desc
{
-#define SK_DEV_MODE_SERV 0
-#define SK_DEV_MODE_APP 1
+#define SK_DEV_MODE_SERV 0
+#define SK_DEV_MODE_APP 1
// ������һ��
TAILQ_ENTRY(sk_dev_desc) next;
+ // ������Ӧ�þ��
+ struct sk_app_instance * app_instance_;
// ģʽ�������̻�ӽ��̣�
unsigned int mode;
- // �򿪲�����������û�У�
+ // �򿪲���
struct sk_dev_open_param open_param;
// �豸��Ϣ���
struct sk_dev_info * dev_info;
@@ -120,6 +124,7 @@ struct sk_dev_desc
struct rte_mempool * direct_pool;
// �豸�ڴ��
struct rte_mempool * indirect_pool;
+
// ��ѭ�����Ļ����������ձ��������д�����
struct rte_ring * rx_loop_buffer[MR_SID_MAX];
// ��ѭ�����Ļ��������ڷ����������д�����
@@ -145,18 +150,17 @@ TAILQ_HEAD(sk_dev_info_list, sk_dev_info);
TAILQ_HEAD(sk_dev_desc_list, sk_dev_desc);
struct sk_instance;
-struct sk_slave_instance;
+struct sk_app_instance;
struct sk_dev_info * sk_device_lookup(struct sk_instance * instance, const char * symbol);
-struct sk_dev_desc * sk_device_desc_lookup(struct sk_dev_desc_list * desc_list, const char * symbol);
+struct sk_dev_desc * sk_device_desc_lookup(struct sk_app_instance* app_instance, const char * symbol);
// �豸��Ϣ������
int sk_device_iterate(struct sk_instance * instance, struct sk_dev_info ** dev_info);
// ����һ��Э��ջ�豸
-struct sk_dev_desc * sk_device_create(struct sk_instance* instance, struct sk_dev_param* param,
- struct rte_mempool* direct_pool, struct rte_mempool* indirect_pool, unsigned nr_serv_thread);
+int sk_device_create(struct sk_instance* instance, struct sk_dev_param* param);
// ����Э��ջ�豸
int sk_device_destory(struct sk_dev_info * devinfo);
@@ -167,6 +171,9 @@ int sk_device_attach(struct sk_dev_desc * dev_desc, enum sk_dev_sid_type type,
void sk_device_deattach(struct sk_dev_desc * dev_desc, enum sk_dev_sid_type type,
thread_id_t sid);
+struct sk_dev_desc * sk_device_open(struct sk_app_instance * app_instance,
+ struct sk_dev_open_param * open_param);
+
// ����Э��ջ��IP��ַ
int sk_device_set_inaddr(struct sk_dev_info * dev_info, struct in_addr in_addr,
struct in_addr in_mask);
@@ -185,7 +192,7 @@ int sk_device_enable(struct sk_dev_info * devinfo);
int sk_device_disable(struct sk_dev_info * devinfo);
// ���ķ��ͣ�ͨ����ѭ�����У�
-static inline int sk_device_serv_packet_send(struct sk_dev_desc * dev_desc, thread_id_t sid,
+static inline int sk_device_loop_packet_send(struct sk_dev_desc * dev_desc, thread_id_t sid,
struct rte_mbuf * mbufs[], int nr_mbufs)
{
return rte_ring_enqueue_burst(dev_desc->tx_loop_buffer[sid], (void **)mbufs, nr_mbufs);
@@ -207,7 +214,7 @@ static inline int sk_device_local_inaddr_filter(struct sk_dev_info * dev_info, s
int sk_device_mamanger_init(struct sk_instance * instance);
-int sk_device_manager_slave_init(struct sk_instance * instance, struct sk_slave_instance * slave_instance);
+int sk_device_manager_slave_init(struct sk_instance * instance, struct sk_app_instance * slave_instance);
#ifdef __cplusplus
diff --git a/stack/include/sk_ip.h b/stack/include/sk_ip.h
new file mode 100644
index 0000000..1d3ca29
--- /dev/null
+++ b/stack/include/sk_ip.h
@@ -0,0 +1,9 @@
+#pragma once
+
+#include <rte_mbuf.h>
+#include <rte_ip.h>
+#include <sk_stack.h>
+#include <stdint.h>
+
+void sk_ip_packet_construct(struct sk_app_instance * app_instance, struct rte_mbuf * mbuf,
+ struct sk_destinfo * destinfo, uint8_t l4_proto); \ No newline at end of file
diff --git a/stack/include/sk_protocol_arp.h b/stack/include/sk_protocol_arp.h
index 6c3adfd..6a1daf3 100644
--- a/stack/include/sk_protocol_arp.h
+++ b/stack/include/sk_protocol_arp.h
@@ -1,10 +1,10 @@
-#pragma once
-
-#include <rte_mbuf.h>
-#include <sk_device.h>
-
-void protocol_serv_arp_entry(struct sk_dev_desc* dev_desc,
- thread_id_t sid, struct rte_mbuf* mbufs_in[], int nr_mbufs_in);
-
-int protocol_serv_arp_request_send(struct sk_dev_desc* dev_desc, thread_id_t sid,
+#pragma once
+
+#include <rte_mbuf.h>
+#include <sk_device.h>
+
+int protocol_serv_arp_entry(struct sk_dev_desc* dev_desc,
+ thread_id_t sid, struct rte_mbuf* mbufs_in[], int nr_mbufs_in);
+
+int protocol_serv_arp_request_send(struct sk_dev_desc* dev_desc, thread_id_t sid,
struct in_addr in_addr); \ No newline at end of file
diff --git a/stack/include/sk_protocol_common.h b/stack/include/sk_protocol_common.h
index f6fd553..9a0c59e 100644
--- a/stack/include/sk_protocol_common.h
+++ b/stack/include/sk_protocol_common.h
@@ -6,6 +6,9 @@
int protocol_common_dev_desc_init(struct sk_instance * instance,
struct sk_dev_desc * dev_desc, const char * protosym, struct rtdev_desc ** rtdev_desc);
-int protocol_common_dev_desc_slave_init(struct sk_slave_instance * slave_instance,
+int protocol_common_dev_desc_slave_init(struct sk_app_instance * slave_instance,
struct sk_dev_desc * dev_desc, const char * protosym, struct rtdev_app_desc ** rtdev_app_desc,
- unsigned int nr_rxstream, unsigned int nr_txstream); \ No newline at end of file
+ unsigned int nr_rxstream, unsigned int nr_txstream);
+
+#define PROTOCOL_ENTRY_RET_IS_MINE 0
+#define PROTOCOL_ENTRY_RET_NOT_MINE 1 \ No newline at end of file
diff --git a/stack/include/sk_protocol_icmp.h b/stack/include/sk_protocol_icmp.h
index 11790ca..46e8a73 100644
--- a/stack/include/sk_protocol_icmp.h
+++ b/stack/include/sk_protocol_icmp.h
@@ -2,5 +2,5 @@
#include <mr_common.h>
-void protocol_serv_icmp_entry(struct sk_dev_desc* dev_desc, thread_id_t sid,
- struct rte_mbuf* mbufs_in[], int nr_mbufs_in);
+int protocol_serv_icmp_entry(struct sk_dev_desc* dev_desc, thread_id_t sid,
+ struct rte_mbuf* mbufs_in[], int nr_mbufs_in);
diff --git a/stack/include/sk_protocol_raw.h b/stack/include/sk_protocol_raw.h
deleted file mode 100644
index 9ae46f6..0000000
--- a/stack/include/sk_protocol_raw.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#pragma once
-
-int protocol_raw_dev_desc_init(struct sk_instance * instance, struct sk_dev_desc * dev_desc);
-
-int protocol_raw_dev_desc_slave_init(struct sk_slave_instance * slave_instance,
- struct sk_dev_desc * dev_desc); \ No newline at end of file
diff --git a/stack/include/sk_route.h b/stack/include/sk_route.h
new file mode 100644
index 0000000..afc5dee
--- /dev/null
+++ b/stack/include/sk_route.h
@@ -0,0 +1,42 @@
+#pragma once
+
+
+#include <netinet/in.h>
+#include <sk_device.h>
+
+struct sk_route_tbl;
+
+struct sk_route_tbl * route_tbl_create(const char * symbol, unsigned max_rules);
+
+void route_tbl_set_default_hop(struct sk_route_tbl * tbl_object, struct sk_dev_info * dev_info);
+
+struct sk_dev_info * route_tbl_get_default_hop(struct sk_route_tbl * tbl_object);
+
+int route_tbl_insert(struct sk_route_tbl * tbl_object, struct in_addr in_addr,
+ struct in_addr in_mask, struct sk_dev_info * dev_info);
+
+struct sk_dev_info * route_tbl_lookup(struct sk_route_tbl * tbl_object, struct in_addr in_addr,
+ char * result_is_gateway);
+
+
+/* Ŀ����Ϣ���� */
+struct sk_destinfo
+{
+ /* ԴIP��ַ */
+ struct in_addr s_in_addr;
+ /* Ŀ��IP��ַ */
+ struct in_addr d_in_addr;
+ /* ԴMAC��ַ */
+ struct ether_addr s_eth_addr;
+ /* Ŀ��MAC��ַ */
+ struct ether_addr d_eth_addr;
+ /* Ŀ���豸��Ϣ������ */
+ struct sk_dev_info * d_dev_info;
+ /* Ŀ���豸����ʱ������ */
+ struct sk_dev_desc * d_dev_desc;
+};
+
+void sk_destinfo_destory(struct sk_destinfo * destinfo);
+
+struct sk_destinfo * sk_destinfo_create_by_route(struct sk_app_instance * app_instance,
+ struct in_addr d_in_addr); \ No newline at end of file
diff --git a/stack/include/sk_stack.h b/stack/include/sk_stack.h
index 9012459..d862fd0 100644
--- a/stack/include/sk_stack.h
+++ b/stack/include/sk_stack.h
@@ -1,6 +1,7 @@
#pragma once
#include <sk_device.h>
#include <sk_neigh.h>
+#include <sk_route.h>
#ifndef MR_STACK_DEFAULT_SZ_DELIVER_RING
#define MR_STACK_DEFAULT_SZ_DELIVER_RING 1024
@@ -55,13 +56,15 @@ struct sk_instance
struct mr_core_instance * core_instance;
// Э��ջ�豸��Ϣ
struct sk_dev_info_list dev_info_list;
- // Э��ջ�豸���
- struct sk_dev_desc_list dev_desc_list;
// �ھ���ϵͳ���
struct neighbour_manager * neigh_manager;
+ // Ĭ��·�ɱ�
+ struct sk_route_tbl * default_route;
+ // IP�����
+ rte_atomic16_t ip_counter;
};
-struct sk_slave_instance
+struct sk_app_instance
{
// Ӧ������
char appsym[MR_SYMBOL_MAX];
@@ -71,11 +74,9 @@ struct sk_slave_instance
struct sk_dev_desc_list dev_desc_list;
};
-struct sk_instance * sk_instance_create(struct sk_param * param, struct mr_core_instance * core_instance);
-
-struct sk_slave_instance * sk_slave_instance_create(const char* appsym, struct sk_instance * instance);
+struct sk_instance * sk_instance_create(struct mr_core_instance * core_instance, struct sk_param * param);
-int sk_instance_init(struct sk_instance * instance);
+struct sk_app_instance * sk_app_instance_create(struct sk_instance * instance, const char* appsym);
int sk_serv_device_rx_bulk(struct sk_dev_desc * dev_desc, thread_id_t sid,
struct rte_mbuf * mbufs_in[], struct rte_mbuf * mbufs_out[], int nr_mbufs_in, int * nr_mbufs_out);
diff --git a/stack/src/dest.c b/stack/src/dest.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/stack/src/dest.c
diff --git a/stack/src/device.c b/stack/src/device.c
index e2634cb..e949cd7 100644
--- a/stack/src/device.c
+++ b/stack/src/device.c
@@ -9,6 +9,8 @@
*/
#include <sys/queue.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
#include <rte_ether.h>
#include <mr_rtdev.h>
#include <mr_rawio.h>
@@ -17,9 +19,6 @@
#include <sk_stack.h>
#include <sk_device.h>
#include <assert.h>
-#include <sk_protocol_raw.h>
-#include <sk_protocol_tcp.h>
-#include <sk_protocol_udp.h>
struct sk_dev_info * sk_device_lookup(struct sk_instance * instance, const char * symbol)
{
@@ -33,10 +32,10 @@ struct sk_dev_info * sk_device_lookup(struct sk_instance * instance, const char
return NULL;
}
-struct sk_dev_desc * sk_device_desc_lookup(struct sk_dev_desc_list * desc_list, const char * symbol)
+struct sk_dev_desc * sk_device_desc_lookup(struct sk_app_instance* app_instance, const char * symbol)
{
struct sk_dev_desc * dev_desc_iter;
- TAILQ_FOREACH(dev_desc_iter, desc_list, next)
+ TAILQ_FOREACH(dev_desc_iter, &app_instance->dev_desc_list, next)
{
if (strcmp(dev_desc_iter->dev_info->symbol, symbol) == 0)
return dev_desc_iter;
@@ -84,61 +83,35 @@ static void sk_dev_desc_delete(struct sk_dev_desc * dev_desc)
return;
}
-static int __sk_device_create_loop_buffer(struct sk_instance * instance,
- struct sk_dev_param * param, struct sk_dev_info * devinfo,
- struct sk_dev_desc * dev_desc)
+static int __sk_device_create_loop_buffer(const char * prefix, const char * devsym,
+ unsigned int nr_stream, unsigned int sz_tunnel, struct rte_ring * object[])
{
- for (int i = 0; i < instance->param.nr_serv_thread; i++)
+ for (int i = 0; i < nr_stream; i++)
{
- char str_rx_loop_buffer[MR_SYMBOL_MAX];
- snprintf(str_rx_loop_buffer, sizeof(str_rx_loop_buffer),
- "skd-%s-rxl-%d", devinfo->symbol, i);
+ char str_loop_buffer[MR_SYMBOL_MAX];
+ snprintf(str_loop_buffer, sizeof(str_loop_buffer), "%s-%s-%d", prefix, devsym, i);
- char str_tx_loop_buffer[MR_SYMBOL_MAX];
- snprintf(str_tx_loop_buffer, sizeof(str_tx_loop_buffer),
- "skd-%s-txl-%d", devinfo->symbol, i);
+ object[i] = rte_ring_create(str_loop_buffer, sz_tunnel, SOCKET_ID_ANY,
+ RING_F_SC_DEQ | RING_F_SP_ENQ);
- dev_desc->rx_loop_buffer[i] = rte_ring_create(str_rx_loop_buffer,
- param->sz_rx_loop_buffer, SOCKET_ID_ANY, RING_F_SC_DEQ | RING_F_SP_ENQ);
-
- if (dev_desc->rx_loop_buffer[i] == NULL)
- {
- MR_LOG(WARNING, STACK, "Cannot create rx loop buffer for sk-dev %s(sym=%s,"
- "size=%d): %s .\n", devinfo->symbol, str_rx_loop_buffer,
- param->sz_rx_loop_buffer, __str_errno());
- goto err_out;
- }
-
- dev_desc->tx_loop_buffer[i] = rte_ring_create(str_tx_loop_buffer,
- param->sz_tx_loop_buffer, SOCKET_ID_ANY, RING_F_SC_DEQ | RING_F_SP_ENQ);
-
- if (dev_desc->tx_loop_buffer[i] == NULL)
+ if (object[i] == NULL)
{
- MR_LOG(WARNING, STACK, "Cannot create tx loop buffer for sk-dev %s(sym=%s,"
- "size=%d): %s.\n", devinfo->symbol, str_tx_loop_buffer,
- param->sz_tx_loop_buffer, __str_errno());
+ MR_LOG(WARNING, STACK, "Create loop buffer for sk-dev %s(sym=%s, size=%d) failed. : %s\n",
+ devsym, str_loop_buffer, sz_tunnel, __str_errno());
goto err_out;
}
}
-
+
return 0;
err_out:
-
- for (int i = 0; i < instance->param.nr_serv_thread; i++)
- {
- if (dev_desc->rx_loop_buffer[i] != NULL)
- rte_ring_free(dev_desc->rx_loop_buffer[i]);
- if (dev_desc->tx_loop_buffer[i] != NULL)
- rte_ring_free(dev_desc->tx_loop_buffer[i]);
- }
+ for (int i = 0; i < nr_stream; i++) if (object[i] != NULL) rte_ring_free(object[i]);
return -1;
}
// 创建一个协议栈设备
-struct sk_dev_desc * sk_device_create(struct sk_instance* instance, struct sk_dev_param* param,
- struct rte_mempool* direct_pool, struct rte_mempool* indirect_pool, unsigned nr_serv_thread)
+int sk_device_create(struct sk_instance* instance, struct sk_dev_param* param)
{
// 检查设备是否已经存在,不允许重复创建
struct sk_dev_info * dev_info = sk_device_lookup(instance, param->symbol);
@@ -157,78 +130,105 @@ struct sk_dev_desc * sk_device_create(struct sk_instance* instance, struct sk_de
goto err_out;
}
- // 写参数
snprintf(dev_info->symbol, sizeof(dev_info->symbol), "%s", param->symbol);
dev_info->param = *param;
dev_info->instance_ = instance;
dev_info->in_addr = param->in_addr;
dev_info->in_mask = param->in_mask;
+ dev_info->in_gateway = param->in_gateway;
dev_info->mac_addr = param->mac_addr;
dev_info->mtu = param->mtu;
dev_info->promisc = 0;
- assert(direct_pool != NULL && indirect_pool != NULL);
+ int ret = route_tbl_insert(instance->default_route, dev_info->in_addr,
+ dev_info->in_mask, dev_info);
- struct sk_dev_desc * dev_desc = rte_zmalloc(NULL, sizeof(struct sk_dev_desc), 0);
- if (unlikely(dev_desc == NULL))
+ if (unlikely(ret < 0)) goto err_out;
+
+ // 设置默认网关,默认网关只能有一个。若以前设置过,此处不生效
+ if (dev_info->in_gateway.s_addr != 0 &&
+ route_tbl_get_default_hop(instance->default_route) != NULL)
{
- MR_LOG(WARNING, STACK, "Cannot alloc memory for sk-dev %s desc. Failed. \n",
- dev_info->symbol);
- goto err_out;
+ MR_LOG(WARNING, STACK, "Duplicated default gateway setting, "
+ "not available(see at device %s setting)\n", dev_info->symbol);
}
+
+ if (dev_info->in_gateway.s_addr != 0 &&
+ route_tbl_get_default_hop(instance->default_route) == NULL)
+ {
+ route_tbl_set_default_hop(instance->default_route, dev_info);
+ }
+
+ char str_in_addr[INET_ADDRSTRLEN];
+ char str_in_mask[INET_ADDRSTRLEN];
+ inet_ntop(AF_INET, &dev_info->in_addr, str_in_addr, sizeof(str_in_addr));
+ inet_ntop(AF_INET, &dev_info->in_mask, str_in_mask, sizeof(str_in_mask));
+ MR_LOG(NOTICE, STACK, "Stack device %s(in_addr=%s, in_mask=%s) created. \n",
+ dev_info->symbol, str_in_addr, str_in_mask);
- dev_desc->dev_info = dev_info;
- dev_desc->direct_pool = direct_pool;
- dev_desc->indirect_pool = indirect_pool;
-
- int ret = __sk_device_create_loop_buffer(instance, param, dev_info, dev_desc);
- if (unlikely(ret < 0)) goto err_out;
-
- // 加入到协议栈设备链表中
TAILQ_INSERT_TAIL(&instance->dev_info_list, dev_info, next);
- // 加入协议栈描述符列表
- TAILQ_INSERT_TAIL(&instance->dev_desc_list, dev_desc, next);
- // TODO: 详细的日志输出
- MR_LOG(NOTICE, STACK, "Sk-device %s created. \n", dev_info->symbol);
- return dev_desc;
-
+ return 0;
+
err_out:
MR_LOG(ERR, STACK, "Sk-device %s create failed. \n", dev_info->symbol);
if (dev_info) rte_free(dev_info);
return NULL;
}
-// 打开一个协议栈设备(在从进程)
-int sk_device_open(struct sk_slave_instance * slave_instance,
+// 打开一个协议栈设备
+struct sk_dev_desc * sk_device_open(struct sk_app_instance * app_instance,
struct sk_dev_open_param * open_param)
{
- struct sk_instance * instance = slave_instance->instance;
- struct sk_dev_info * devinfo = sk_device_lookup(instance, open_param->symbol);
+ struct sk_instance * instance = app_instance->instance;
+ struct sk_param * instance_param = &instance->param;
- if (unlikely(devinfo == NULL))
+ struct sk_dev_info * dev_info = sk_device_lookup(instance, open_param->symbol);
+
+ if (unlikely(dev_info == NULL))
{
- MR_LOG(ERR, STACK, "StackDevice %s does not existed. failed. \n",
+ MR_LOG(ERR, STACK, "Stack Device %s does not existed. failed. \n",
open_param->symbol);
- return -EEXIST;
+ return NULL;
}
struct sk_dev_desc * dev_desc = rte_zmalloc(NULL, sizeof(struct sk_dev_desc), 0);
if (unlikely(dev_desc == NULL))
{
- MR_LOG(ERR, STACK, "Cannot alloc memory for sk-dev %s desc. Failed. \n",
- devinfo->symbol);
- return -ENOMEM;
+ MR_LOG(WARNING, STACK, "Cannot alloc memory for sk-dev %s desc. Failed. \n",
+ dev_info->symbol);
+ goto err_out;
}
- TAILQ_INSERT_TAIL(&slave_instance->dev_desc_list, dev_desc, next);
+ dev_desc->dev_info = dev_info;
+ dev_desc->direct_pool = dev_info->param.direct_pktmbuf_pool;
+ dev_desc->indirect_pool = dev_info->param.indirect_pktmbuf_pool;
+ dev_desc->app_instance_ = app_instance;
+ assert(dev_desc->direct_pool != NULL && dev_desc->indirect_pool != NULL);
+
+ int ret = 0;
+
+ if(open_param->nr_loop_rxstream)
+ {
+ ret = __sk_device_create_loop_buffer("skd-rx", dev_info->symbol,
+ open_param->nr_loop_rxstream, instance_param->sz_loop_ring, dev_desc->rx_loop_buffer);
+ if (ret < 0) goto err_out;
+ }
+
+ if(open_param->nr_loop_txstream)
+ {
+ ret = __sk_device_create_loop_buffer("skd-tx", dev_info->symbol,
+ open_param->nr_loop_txstream, instance_param->sz_loop_ring, dev_desc->tx_loop_buffer);
+ if (ret < 0) goto err_out;
+ }
- MR_LOG(ERR, STACK, "Sk-device %s opened. \n", devinfo->symbol);
- return 0;
+ TAILQ_INSERT_TAIL(&app_instance->dev_desc_list, dev_desc, next);
+ MR_LOG(ERR, STACK, "Sk-device %s opened. \n", dev_info->symbol);
+ return dev_desc;
err_out:
- MR_LOG(ERR, STACK, "Sk-device %s open failed. \n", devinfo->symbol);
+ MR_LOG(ERR, STACK, "Sk-device %s open failed. \n", dev_info->symbol);
if (dev_desc != NULL) rte_free(dev_desc);
- return -1;
+ return NULL;
}
int sk_device_attach(struct sk_dev_desc * dev_desc, enum sk_dev_sid_type type,
@@ -255,7 +255,6 @@ void sk_device_deattach(struct sk_dev_desc * dev_desc, enum sk_dev_sid_type type
rte_spinlock_lock(&dev_desc->sid_alloc_lock);
}
-
// 销毁协议栈设备
int sk_device_destory(struct sk_dev_info * devinfo)
{
@@ -304,15 +303,4 @@ int sk_device_enable(struct sk_dev_info * devinfo)
int sk_device_disable(struct sk_dev_info * devinfo)
{
return 0;
-}
-
-/* 以下为内部初始化、注销处理流程。*/
-int sk_device_mamanger_init(struct sk_instance * instance)
-{
- return 0;
-}
-
-int sk_device_manager_slave_init(struct sk_instance * instance, struct sk_slave_instance * slave_instance)
-{
- return 0;
} \ No newline at end of file
diff --git a/stack/src/feedback.c b/stack/src/feedback.c
new file mode 100644
index 0000000..ac0c0b2
--- /dev/null
+++ b/stack/src/feedback.c
@@ -0,0 +1,16 @@
+/* T1/T2 UDP���ݻش�ר�ýӿ�
+ */
+
+#include <marsio_buffer_user_api.h>
+
+int marsio_feedback_send_burst(struct sk_destinfo * destinfo, uint32_t hash,
+ marsio_buff_t * buffer[], int nr_buffer, uint64_t flags)
+{
+ return 0;
+}
+
+int marsio_feedback_send_chain(struct sk_destinfo * destinfo, uint32_t hash,
+ marsio_buff_t * chain, uint64_t flags)
+{
+ return 0;
+} \ No newline at end of file
diff --git a/stack/src/ip.c b/stack/src/ip.c
new file mode 100644
index 0000000..8ec6c12
--- /dev/null
+++ b/stack/src/ip.c
@@ -0,0 +1,49 @@
+/* \brief Э��ջIP�㱨�Ĵ���
+ *
+ * \author Lu Qiuwen<[email protected]>
+ * \date 2016-11-28
+ */
+
+#include <rte_ip.h>
+#include <mr_common.h>
+#include <sk_stack.h>
+#include <sk_device.h>
+
+#define __IP_VERSION_IHL(version, len) (version << 4 | len << 0)
+#define __IP_TTL 75
+
+uint16_t __get_ip_counter(struct sk_app_instance * app_instance, struct sk_destinfo * destinfo)
+{
+ return rte_atomic16_add_return(&app_instance->instance->ip_counter, 1);
+}
+
+void sk_ip_packet_construct(struct sk_app_instance * app_instance, struct rte_mbuf * mbuf,
+ struct sk_destinfo * destinfo, uint8_t l4_proto)
+{
+ struct ipv4_hdr * ip_hdr = (struct ipv4_hdr *)rte_pktmbuf_prepend(mbuf, sizeof(struct ipv4_hdr));
+ uint16_t datalen = rte_pktmbuf_pkt_len(mbuf);
+ assert(ip_hdr != NULL);
+
+ uint16_t ip_counter = __get_ip_counter(app_instance, destinfo);
+ ip_hdr->version_ihl = __IP_VERSION_IHL(4, sizeof(struct ipv4_hdr) / 4);
+ ip_hdr->type_of_service = 0;
+ ip_hdr->total_length = rte_cpu_to_be_16(datalen);
+ ip_hdr->packet_id = rte_cpu_to_be_16(ip_counter);
+ ip_hdr->fragment_offset = 0;
+ ip_hdr->time_to_live = __IP_TTL;
+ ip_hdr->next_proto_id = l4_proto;
+ ip_hdr->hdr_checksum = 0;
+ ip_hdr->src_addr = destinfo->s_in_addr.s_addr;
+ ip_hdr->dst_addr = destinfo->d_in_addr.s_addr;
+
+ mbuf->l3_len = sizeof(struct ipv4_hdr);
+ mbuf->ol_flags |= PKT_TX_IPV4 | PKT_TX_IP_CKSUM;
+
+ struct ether_hdr * ether_hdr = (struct ether_hdr *)rte_pktmbuf_prepend(mbuf, sizeof(struct ether_hdr));
+ assert(ether_hdr != NULL);
+
+ ether_addr_copy(&destinfo->s_eth_addr, &ether_hdr->s_addr);
+ ether_addr_copy(&destinfo->d_eth_addr, &ether_hdr->d_addr);
+ ether_hdr->ether_type = rte_cpu_to_be_16(ETHER_TYPE_IPv4);
+ return;
+} \ No newline at end of file
diff --git a/stack/src/neigh.c b/stack/src/neigh.c
index e52bcbc..377ec38 100644
--- a/stack/src/neigh.c
+++ b/stack/src/neigh.c
@@ -252,7 +252,7 @@ exit:
return ret;
}
-static void __neigh_handle_in_no_queue(struct sk_instance * sk_instance,
+static void __neigh_handle_in_no_queue(struct sk_app_instance * app_instance,
thread_id_t sid, struct neighbour_manager * object)
{
if (rte_atomic16_read(&object->in_none_list_len) == 0) return;
@@ -264,8 +264,7 @@ static void __neigh_handle_in_no_queue(struct sk_instance * sk_instance,
// ��ÿһ����In-None�б��е�Neigh����ARP����
TAILQ_FOREACH(neigh_iter, &object->in_none_list, next)
{
- dev_desc = sk_device_desc_lookup(&sk_instance->dev_desc_list,
- neigh_iter->dev_info->symbol);
+ dev_desc = sk_device_desc_lookup(app_instance, neigh_iter->dev_info->symbol);
assert(dev_desc != NULL);
protocol_serv_arp_request_send(dev_desc, sid, neigh_iter->in_addr);
@@ -280,8 +279,8 @@ static void __neigh_handle_in_no_queue(struct sk_instance * sk_instance,
rte_rwlock_write_unlock(&object->rwlock);
}
-void neighbour_manager_loop_entry(struct sk_instance * sk_instance,
+void neighbour_manager_loop_entry(struct sk_app_instance * app_instance,
thread_id_t sid, struct neighbour_manager * object)
{
- __neigh_handle_in_no_queue(sk_instance, sid, object);
+ __neigh_handle_in_no_queue(app_instance, sid, object);
} \ No newline at end of file
diff --git a/stack/src/protocol-arp.c b/stack/src/protocol-arp.c
index 59126ef..74e9379 100644
--- a/stack/src/protocol-arp.c
+++ b/stack/src/protocol-arp.c
@@ -85,7 +85,7 @@ static void arp_request_entry(struct sk_dev_desc * dev_desc, thread_id_t sid,
reply_arp_hdr->arp_data.arp_tip = s_in_addr->s_addr;
// 写应答包到线路
- int ret = sk_device_serv_packet_send(dev_desc, sid, &reply_mbuf, 1);
+ int ret = sk_device_loop_packet_send(dev_desc, sid, &reply_mbuf, 1);
if (ret != 1) sk_packet_free(reply_mbuf, sid, SK_FREE_ARP_REQUEST_REPLY_FAILED);
goto done;
@@ -99,14 +99,19 @@ done:
return;
}
-void protocol_serv_arp_entry(struct sk_dev_desc * dev_desc,
+int protocol_serv_arp_entry(struct sk_dev_desc* dev_desc,
thread_id_t sid, struct rte_mbuf* mbufs_in[], int nr_mbufs_in)
{
+ int handled_packets = 0;
+
for (int i = 0; i < nr_mbufs_in; i++)
{
struct rte_mbuf * mbuf = mbufs_in[i];
if (unlikely(mbuf == NULL)) continue;
+ struct ether_hdr * eth_hdr = rte_pktmbuf_mtod(mbuf, struct ether_hdr *);
+ if (eth_hdr->ether_type != ntohs(ETHER_TYPE_ARP)) continue;
+
struct arp_hdr * arp_hdr = rte_pktmbuf_mtod_offset(
mbuf, struct arp_hdr *, sizeof(struct ether_hdr));
@@ -116,9 +121,12 @@ void protocol_serv_arp_entry(struct sk_dev_desc * dev_desc,
arp_reply_entry(dev_desc, sid, mbuf, arp_hdr);
else
sk_packet_free(mbuf, sid, SK_FREE_ARP_UNDEFINED_TYPE);
+
+ handled_packets++;
+ mbufs_in[i] = NULL;
}
- return;
+ return handled_packets;
}
int protocol_serv_arp_request_send(struct sk_dev_desc* dev_desc, thread_id_t sid,
@@ -157,7 +165,7 @@ int protocol_serv_arp_request_send(struct sk_dev_desc* dev_desc, thread_id_t sid
memset(&arp_hdr->arp_data.arp_tha, 0, sizeof(arp_hdr->arp_data.arp_tha));
// 写数据包到线路
- int ret = sk_device_serv_packet_send(dev_desc, sid, &req_mbuf, 1);
+ int ret = sk_device_loop_packet_send(dev_desc, sid, &req_mbuf, 1);
if (unlikely(ret != 1)) rte_pktmbuf_free(req_mbuf);
return 0;
} \ No newline at end of file
diff --git a/stack/src/protocol-common.c b/stack/src/protocol-common.c
index 5295c8a..b16079d 100644
--- a/stack/src/protocol-common.c
+++ b/stack/src/protocol-common.c
@@ -32,17 +32,17 @@ int protocol_common_dev_desc_init(struct sk_instance * instance,
return 0;
}
-int protocol_common_dev_desc_slave_init(struct sk_slave_instance * slave_instance,
+int protocol_common_dev_desc_slave_init(struct sk_app_instance * app_instance,
struct sk_dev_desc * dev_desc, const char * protosym, struct rtdev_app_desc ** rtdev_app_desc,
- unsigned int nr_rxstream, unsigned int nr_txstream)
+ unsigned int nr_rxstream, unsigned int nr_txstream)
{
char rtdevsym[MR_SYMBOL_MAX];
snprintf(rtdevsym, sizeof(rtdevsym), "%s-%s", dev_desc->dev_info->symbol, protosym);
struct rtdev_app_desc * _rtdev_app_desc;
// ��������ʱ�豸
- _rtdev_app_desc = mr_rt_device_open(slave_instance->instance->core_instance,
- dev_desc->dev_info->symbol, slave_instance->appsym, nr_rxstream, nr_txstream);
+ _rtdev_app_desc = mr_rt_device_open(app_instance->instance->core_instance,
+ dev_desc->dev_info->symbol, app_instance->appsym, nr_rxstream, nr_txstream);
// ����ʧ��
if (_rtdev_app_desc == NULL)
diff --git a/stack/src/protocol-icmp.c b/stack/src/protocol-icmp.c
index e1d80ef..86b9eed 100644
--- a/stack/src/protocol-icmp.c
+++ b/stack/src/protocol-icmp.c
@@ -1,9 +1,80 @@
-
-#include <sk_device.h>
-#include <sk_stack.h>
-
-void protocol_serv_icmp_entry(struct sk_dev_desc* dev_desc, thread_id_t sid,
- struct rte_mbuf* mbufs_in[], int nr_mbufs_in)
-{
- return;
-} \ No newline at end of file
+
+
+#include <rte_icmp.h>
+#include <mr_common.h>
+#include <sk_device.h>
+#include <sk_stack.h>
+#include <sk_common.h>
+#include <sk_route.h>
+#include <sk_ip.h>
+
+static void icmp_echo_request_entry(struct sk_dev_desc* dev_desc, thread_id_t sid,
+ struct rte_mbuf * mbuf, struct in_addr s_in_addr, struct in_addr d_in_addr)
+{
+ struct icmp_hdr * icmp_hdr = rte_pktmbuf_mtod(mbuf, struct icmp_hdr *);
+
+ uint32_t cksum;
+ icmp_hdr->icmp_type = IP_ICMP_ECHO_REPLY;
+ cksum = ~icmp_hdr->icmp_cksum & 0xffff;
+ cksum += ~htons(IP_ICMP_ECHO_REQUEST << 8) & 0xffff;
+ cksum += htons(IP_ICMP_ECHO_REPLY << 8);
+ cksum = (cksum & 0xffff) + (cksum >> 16);
+ cksum = (cksum & 0xffff) + (cksum >> 16);
+ icmp_hdr->icmp_cksum = cksum;
+
+ struct sk_app_instance * app_instance = dev_desc->app_instance_;
+ struct sk_destinfo * destinfo = sk_destinfo_create_by_route(app_instance, s_in_addr);
+ if(unlikely(destinfo == NULL))
+ {
+ sk_packet_free(mbuf, sid, SK_FREE_ICMP_REPLY_NO_DESTINFO);
+ return;
+ }
+
+ sk_ip_packet_construct(app_instance, mbuf, destinfo, IPPROTO_ICMP);
+ sk_device_loop_packet_send(dev_desc, sid, &mbuf, 1);
+ return;
+}
+
+int protocol_serv_icmp_entry(struct sk_dev_desc* dev_desc, thread_id_t sid,
+ struct rte_mbuf* mbufs_in[], int nr_mbufs_in)
+{
+ int handled_packets = 0;
+ struct in_addr s_in_addr;
+ struct in_addr d_in_addr;
+
+ for (int i = 0; i < nr_mbufs_in; i++)
+ {
+ struct rte_mbuf * mbuf = mbufs_in[i];
+ if (unlikely(mbuf == NULL)) continue;
+
+ // ������IPv4����
+ if (!RTE_ETH_IS_IPV4_HDR(mbuf->packet_type)) continue;
+
+ // ��IPv4��������
+ struct ipv4_hdr * ip_hdr = rte_pktmbuf_mtod_offset(mbuf, struct ipv4_hdr *,
+ sizeof(struct ether_hdr));
+
+ if (ip_hdr->next_proto_id != IPPROTO_ICMP) continue;
+
+ s_in_addr.s_addr = ip_hdr->src_addr;
+ d_in_addr.s_addr = ip_hdr->dst_addr;
+
+ rte_pktmbuf_adj(mbuf, sizeof(struct ether_hdr) + sizeof(struct ipv4_hdr));
+ struct icmp_hdr * icmp_hdr = rte_pktmbuf_mtod(mbuf, struct icmp_hdr *);
+
+ // ICMP��������
+ if (icmp_hdr->icmp_type == IP_ICMP_ECHO_REQUEST)
+ {
+ icmp_echo_request_entry(dev_desc, sid, mbuf, s_in_addr, d_in_addr);
+ }
+ else // �������Ͳ�����
+ {
+ sk_packet_free(mbuf, sid, SK_FREE_ICMP_CANNOT_HANDLE_TYPE);
+ }
+
+ mbufs_in[i] = NULL;
+ handled_packets++;
+ }
+
+ return handled_packets;
+}
diff --git a/stack/src/route.c b/stack/src/route.c
new file mode 100644
index 0000000..6afabdc
--- /dev/null
+++ b/stack/src/route.c
@@ -0,0 +1,185 @@
+
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <sk_device.h>
+#include <rte_lpm.h>
+#include <rte_malloc.h>
+#include <sk_stack.h>
+#include <sk_route.h>
+
+struct sk_route_tbl
+{
+ struct rte_lpm * lpm;
+ unsigned int nr_next_device;
+ struct sk_dev_info * next_device[MR_DEVICE_MAX];
+ struct sk_dev_info * default_device;
+};
+
+struct sk_route_tbl * route_tbl_create(const char * symbol, unsigned max_rules)
+{
+ struct sk_route_tbl * tbl_object = rte_zmalloc(symbol, sizeof(struct sk_route_tbl), 0);
+ if(unlikely(tbl_object == NULL))
+ {
+ MR_LOG(WARNING, STACK, "Cannot alloc memory for route table. \n");
+ return NULL;
+ }
+
+ struct rte_lpm_config _lpm_config;
+ _lpm_config.max_rules = max_rules;
+ _lpm_config.number_tbl8s = max_rules / 8;
+ _lpm_config.flags = 0;
+
+ tbl_object->lpm = rte_lpm_create(symbol, SOCKET_ID_ANY, &_lpm_config);
+ if(unlikely(tbl_object->lpm == NULL))
+ {
+ MR_LOG(ERR, STACK, "Unable to create the LPM table(symbol=%s, max_rules=%d). \n",
+ symbol, max_rules);
+ goto error;
+ }
+
+ return tbl_object;
+
+error:
+ if (tbl_object != NULL) rte_free(tbl_object);
+ return NULL;
+}
+
+void route_tbl_set_default_hop(struct sk_route_tbl * tbl_object, struct sk_dev_info * dev_info)
+{
+ assert(tbl_object != NULL);
+ tbl_object->default_device = dev_info;
+}
+
+struct sk_dev_info * route_tbl_get_default_hop(struct sk_route_tbl * tbl_object)
+{
+ assert(tbl_object != NULL);
+ return tbl_object->default_device;
+}
+
+static inline int __mask_to_depth(uint32_t mask)
+{
+ int count = 0;
+ while (mask)
+ {
+ ++count;
+ mask = (mask - 1)&mask;
+ }
+ return count;
+}
+
+int route_tbl_insert(struct sk_route_tbl * tbl_object, struct in_addr in_addr,
+ struct in_addr in_mask, struct sk_dev_info * dev_info)
+{
+ int next_hop_id = -1;
+
+ for(int i = 0; i < tbl_object->nr_next_device; i++)
+ {
+ if (tbl_object->next_device[i] != dev_info) continue;
+ next_hop_id = i;
+ }
+
+ if(next_hop_id < 0)
+ {
+ tbl_object->next_device[tbl_object->nr_next_device] = dev_info;
+ next_hop_id = tbl_object->nr_next_device;
+ tbl_object->nr_next_device++;
+ }
+
+ assert(next_hop_id < RTE_DIM(tbl_object->next_device));
+ int ret = rte_lpm_add(tbl_object->lpm, in_addr.s_addr, __mask_to_depth(
+ in_mask.s_addr), next_hop_id);
+
+ char str_in_addr[INET_ADDRSTRLEN];
+ char str_in_mask[INET_ADDRSTRLEN];
+ inet_ntop(AF_INET, &in_addr, str_in_addr, sizeof(str_in_addr));
+ inet_ntop(AF_INET, &in_mask, str_in_mask, sizeof(str_in_mask));
+
+ if(unlikely(ret < 0))
+ {
+ MR_LOG(WARNING, STACK, "Insert route tbl rules(in_addr=%s, "
+ "in_mask=%s, next_hop=%s) failed: %s\n", str_in_addr, str_in_mask,
+ tbl_object->next_device[next_hop_id]->symbol, __str_errno());
+ return ret;
+ }
+
+ MR_LOG(INFO, STACK, "RouteTableRule(in_addr=%s, in_mask=%s, next_hop=%s) inserted. \n",
+ str_in_addr, str_in_mask, tbl_object->next_device[next_hop_id]->symbol);
+
+ return 0;
+}
+
+struct sk_dev_info * route_tbl_lookup(struct sk_route_tbl * tbl_object, struct in_addr in_addr,
+ char * result_is_gateway)
+{
+ uint32_t next_hop;
+ int ret = rte_lpm_lookup(tbl_object->lpm, in_addr.s_addr, &next_hop);
+ if (ret == -EINVAL) return NULL;
+ if (ret == -ENOENT) return tbl_object->default_device;
+ if (ret == 0) return tbl_object->next_device[next_hop];
+ return NULL;
+}
+
+void sk_destinfo_destory(struct sk_destinfo * destinfo)
+{
+ rte_free(destinfo);
+}
+
+struct sk_destinfo * sk_destinfo_create_by_route(struct sk_app_instance * app_instance,
+ struct in_addr d_in_addr)
+{
+ struct sk_instance * instance = app_instance->instance;
+ struct sk_destinfo * destinfo = rte_zmalloc(NULL, sizeof(struct sk_destinfo), 0);
+ if (destinfo == NULL) return destinfo;
+
+ char str_in_addr[INET_ADDRSTRLEN];
+ inet_ntop(AF_INET, &d_in_addr, str_in_addr, sizeof(str_in_addr));
+
+ struct in_addr query_in_addr = d_in_addr;
+ struct ether_addr d_eth_addr = {0};
+ struct sk_dev_info * dev_info = NULL;
+ struct sk_dev_desc * dev_desc = NULL;
+
+ char is_gateway = 0;
+ dev_info = route_tbl_lookup(instance->default_route, d_in_addr, &is_gateway);
+ if (dev_info == NULL)
+ {
+ MR_LOG(ERR, STACK, "No route to host %s. \n", str_in_addr);
+ goto errout;
+ }
+
+ // ��ѯ�����豸�Ƿ��
+ dev_desc = sk_device_desc_lookup(app_instance, dev_info->symbol);
+ if(dev_desc == NULL)
+ {
+ MR_LOG(ERR, STACK, "Stack Device %s is not open. \n", dev_info->symbol);
+ goto errout;
+ }
+
+ // �Ƿ������أ�����·�ɲ�ѯ���ص�MAC��ַ
+ if (is_gateway) query_in_addr = dev_info->in_gateway;
+ int ret = neigh_query(instance->neigh_manager, query_in_addr, &d_eth_addr, &dev_info);
+ if (ret == 0) goto success;
+
+ // û���ھӽڵ㻺�棬����һ���µĽڵ㣬���β�ѯʧ��
+ ret = neigh_create_or_update(instance->neigh_manager, query_in_addr, NULL, dev_info, 0);
+ if(ret < 0)
+ {
+ MR_LOG(ERR, STACK, "Request neighbour for host %s failed. \n", str_in_addr);
+ goto errout;
+ }
+
+ goto errout;
+
+success:
+ destinfo->d_in_addr = d_in_addr;
+ destinfo->s_in_addr = dev_info->in_addr;
+ destinfo->s_eth_addr = dev_info->mac_addr;
+ destinfo->d_eth_addr = d_eth_addr;
+ destinfo->d_dev_info = dev_info;
+ destinfo->d_dev_desc = dev_desc;
+ return destinfo;
+
+errout:
+ if (destinfo != NULL) rte_free(destinfo);
+ return NULL;
+} \ No newline at end of file
diff --git a/stack/src/rxtx.c b/stack/src/rxtx.c
index 715efe4..d71e4eb 100644
--- a/stack/src/rxtx.c
+++ b/stack/src/rxtx.c
@@ -15,34 +15,6 @@
#include <sk_protocol_tcp.h>
#include <sk_protocol_icmp.h>
-
-struct packet_holder
-{
- struct rte_mbuf * packets[MR_BURST_MAX];
- unsigned int nr_packets;
-};
-
-enum sk_packet_type
-{
- __PACKET_TYPE_ARP = 0,
- __PACKET_TYPE_ICMP = 1,
- __PACKET_TYPE_TCP = 2,
- __PACKET_TYPE_UDP = 3,
- __PACKET_TYPE_FRAG = 4,
- __PACKET_TYPE_ELSE = 5,
- __PACKET_TYPE_MAX
-};
-
-static inline enum sk_packet_type __get_packet_type(struct rte_mbuf * mbuf)
-{
- if (mbuf->packet_type & RTE_PTYPE_L2_ETHER_ARP) return __PACKET_TYPE_ARP;
- if (mbuf->packet_type & RTE_PTYPE_L4_ICMP) return __PACKET_TYPE_ICMP;
- if (mbuf->packet_type & RTE_PTYPE_L4_TCP) return __PACKET_TYPE_TCP;
- if (mbuf->packet_type & RTE_PTYPE_L4_UDP) return __PACKET_TYPE_UDP;
- if (mbuf->packet_type & RTE_PTYPE_L4_FRAG) return __PACKET_TYPE_FRAG;
- return __PACKET_TYPE_ELSE;
-}
-
int sk_serv_device_tx_bulk(struct sk_dev_desc * dev_desc, thread_id_t sid,
struct rte_mbuf * mbufs_out[], int nr_mbufs_max)
{
@@ -59,25 +31,15 @@ int sk_serv_device_tx_bulk(struct sk_dev_desc * dev_desc, thread_id_t sid,
int sk_serv_device_rx_bulk(struct sk_dev_desc * dev_desc, thread_id_t sid,
struct rte_mbuf * mbufs_in[], struct rte_mbuf * mbufs_out[], int nr_mbufs_in, int * nr_mbufs_out)
{
- struct packet_holder packets[__PACKET_TYPE_MAX];
- for (int i = 0; i < __PACKET_TYPE_MAX; i++) packets[i].nr_packets = 0;
-
- // ���ķ��࣬���ݱ���Э���ǩ
- for(int i = 0; i < nr_mbufs_in; i++)
- {
- enum sk_packet_type index = __get_packet_type(mbufs_in[i]);
- packets[index].packets[packets[index].nr_packets++] = mbufs_in[i];
- }
-
// ARP���Ĵ���
- protocol_serv_arp_entry(dev_desc, sid, packets[__PACKET_TYPE_ARP].packets,
- packets[__PACKET_TYPE_ARP].nr_packets);
-
-#if 0
+ int nr_handled;
+ nr_handled = protocol_serv_arp_entry(dev_desc, sid, mbufs_in, nr_mbufs_in);
+
// ICMP���Ĵ���
- protocol_serv_icmp_entry(dev_desc, sid, packets[__PACKET_TYPE_ICMP].packets,
- packets[__PACKET_TYPE_TCP].nr_packets);
+ nr_handled += protocol_serv_icmp_entry(dev_desc, sid, mbufs_in, nr_mbufs_in);
+
+#if 0
// TCP���Ĵ���
protocol_serv_tcp_entry(dev_desc, sid, packets[__PACKET_TYPE_TCP].packets,
packets[__PACKET_TYPE_TCP].nr_packets);
@@ -87,14 +49,5 @@ int sk_serv_device_rx_bulk(struct sk_dev_desc * dev_desc, thread_id_t sid,
packets[__PACKET_TYPE_UDP].nr_packets);
#endif
-
- // �޷������ı��ģ����ظ��ϲ�
- for(int i = 0; i < packets[__PACKET_TYPE_ELSE].nr_packets; i++)
- {
- mbufs_out[i] = packets[__PACKET_TYPE_ELSE].packets[i];
- assert(i <= nr_mbufs_in);
- }
-
- *nr_mbufs_out = packets[__PACKET_TYPE_ELSE].nr_packets;
return 0;
} \ No newline at end of file
diff --git a/stack/src/stack.c b/stack/src/stack.c
index 05f6b2b..86f7560 100644
--- a/stack/src/stack.c
+++ b/stack/src/stack.c
@@ -10,30 +10,8 @@
#include <sk_neigh.h>
#include <sk_device.h>
-int sk_instance_init(struct sk_instance * instance)
-{
- struct sk_param * param = &instance->param;
-
- int ret = sk_device_mamanger_init(instance);
- if(ret < 0)
- {
- MR_LOG(ERR, STACK, "Stack device manager init failed.\n");
- return -1;
- }
-
- ret = neighbour_mamanger_init(instance->neigh_manager, param->servsym,
- param->nr_neigh_max_neigh, param->t_neigh_timeout, param->t_neigh_arp_send);
-
- if (unlikely(ret < 0))
- {
- MR_LOG(WARNING, STACK, "Neighbour manager init failed. \n");
- return -2;
- }
-
- return 0;
-}
-
-struct sk_instance * sk_instance_create(struct sk_param * param, struct mr_core_instance * core_instance)
+struct sk_instance * sk_instance_create(struct mr_core_instance * core_instance,
+ struct sk_param * param)
{
struct sk_instance * instance;
@@ -41,8 +19,7 @@ struct sk_instance * sk_instance_create(struct sk_param * param, struct mr_core_
instance = rte_zmalloc(NULL, sizeof(struct sk_instance), 0);
if(unlikely(instance == NULL))
{
- MR_LOG(WARNING, STACK, "StackInstanceCreate, "
- "Cannot alloc memory for stack instance. \n");
+ MR_LOG(WARNING, STACK, "Cannot alloc memory for stack instance. \n");
goto errout;
}
@@ -50,7 +27,6 @@ struct sk_instance * sk_instance_create(struct sk_param * param, struct mr_core_
instance->param = *param;
instance->core_instance = core_instance;
TAILQ_INIT(&instance->dev_info_list);
- TAILQ_INIT(&instance->dev_desc_list);
// 初始化邻居管理器
struct neighbour_manager * neigh_manager;
@@ -58,12 +34,29 @@ struct sk_instance * sk_instance_create(struct sk_param * param, struct mr_core_
if(unlikely(neigh_manager == NULL))
{
- MR_LOG(WARNING, STACK, "StackInstanceCreate, "
- "Cannot alloc memory for neighbour manager. \n");
+ MR_LOG(WARNING, STACK, "Cannot alloc memory for neighbour manager. \n");
goto errout;
}
instance->neigh_manager = neigh_manager;
+
+ int ret = neighbour_mamanger_init(instance->neigh_manager, param->servsym,
+ param->nr_neigh_max_neigh, param->t_neigh_timeout, param->t_neigh_arp_send);
+
+ if (unlikely(ret < 0))
+ {
+ MR_LOG(WARNING, STACK, "Neighbour manager init failed. \n");
+ goto errout;
+ }
+
+ // 初始化默认路由表
+ instance->default_route = route_tbl_create("StackDefaultR", 4096);
+ if(unlikely(instance->default_route == NULL))
+ {
+ MR_LOG(WARNING, STACK, "Cannot create default route table. \n");
+ goto errout;
+ }
+
return instance;
errout:
@@ -72,20 +65,19 @@ errout:
return NULL;
}
-struct sk_slave_instance * sk_slave_instance_create(const char* appsym, struct sk_instance * instance)
+struct sk_app_instance * sk_app_instance_create(struct sk_instance * instance, const char* appsym)
{
- struct sk_slave_instance * slave_instance;
+ struct sk_app_instance * app_instance;
- slave_instance = rte_zmalloc(NULL, sizeof(struct sk_instance), 0);
- if (unlikely(slave_instance == NULL))
+ app_instance = rte_zmalloc(NULL, sizeof(struct sk_instance), 0);
+ if (unlikely(app_instance == NULL))
{
MR_LOG(WARNING, STACK, "Cannot alloc memory for stack slave instance. \n");
return NULL;
}
- slave_instance->instance = instance;
- snprintf(slave_instance->appsym, sizeof(slave_instance->appsym), "%s", appsym);
- TAILQ_INIT(&slave_instance->dev_desc_list);
-
- return slave_instance;
+ app_instance->instance = instance;
+ snprintf(app_instance->appsym, sizeof(app_instance->appsym), "%s", appsym);
+ TAILQ_INIT(&app_instance->dev_desc_list);
+ return app_instance;
} \ No newline at end of file