summaryrefslogtreecommitdiff
path: root/stack/src/stack.c
blob: d13f284617e6682654f1bf7959c42ff74d2c95ce (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/* 简单数据通信用户态协议栈管理器
 * 
 * \author Lu Qiuwen<[email protected]>
 * \date 2016-10-18
 */

#include <mr_common.h>
#include <sk_stack.h>
#include <rte_ip_frag.h>
#include <sk_neigh.h>
#include <sk_device.h>
#include <mr_buffer.h>

int __instance_setup_ctrlzone(struct mr_core_instance * core_instance,
	const char * symbol, uint8_t size, uint8_t * id)
{
	uint8_t _id = 0;
	uint8_t _size = 0;

	int ret = mr_buffer_ctrlzone_lookup(core_instance, symbol, &_id, &_size);
	if (ret < 0)
	{
		MR_LOG(WARNING, STACK, "Lookup ctrlzone %s failed. "
			"Please setup the ctrlzone as size %d.", symbol, size);
		return -1;
	}

	if (_size < size)
	{
		MR_LOG(WARNING, STACK, "Ctrlzone %s's size is not enough, "
			"at least %d. Failed. ", symbol, size);
		return -2;
	}

	*id = _id;
	return 0;
}

struct sk_instance * sk_instance_create(struct mr_core_instance * core_instance, 
	struct sk_param * param)
{
	struct sk_instance * instance;

	// 分配空间
	instance = rte_zmalloc(NULL, sizeof(struct sk_instance), 0);
	if(unlikely(instance == NULL))
	{
		MR_LOG(WARNING, STACK, "Cannot alloc memory for stack instance. \n");
		goto errout;
	}

	// 初始化参数
	instance->param = *param;
	instance->core_instance = core_instance;
	TAILQ_INIT(&instance->dev_info_list);

	// 初始化邻居管理器
	struct neighbour_manager * neigh_manager;
	neigh_manager = rte_zmalloc(NULL, sizeof(struct neighbour_manager), 0);

	if(unlikely(neigh_manager == NULL))
	{
		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;
	}

	// 初始化报文控制域ID
	ret = __instance_setup_ctrlzone(core_instance, SK_CTRLZONE_PKTINFO_SYMBOL,
		SK_CTRLZONE_PKTINFO_SIZE, &instance->ctrlzone_id_pktinfo);

	if (ret < 0) goto errout;

	ret = __instance_setup_ctrlzone(core_instance, SK_CTRLZONE_SOQINFO_SYMBOL,
		SK_CTRLZONE_SOQINFO_SIZE, &instance->ctrlzone_id_soqinfo);
	
	if (ret < 0) goto errout;
	return instance;

errout:
	if (instance->neigh_manager) rte_free(instance->neigh_manager);
	if (instance) rte_free(instance);
	return NULL;
}

struct sk_app_instance * sk_app_instance_create(struct sk_instance * instance, const char* appsym)
{
	struct sk_app_instance * app_instance;

	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;
	}

	// 初始化内部句柄
	app_instance->instance = instance;
	snprintf(app_instance->appsym, sizeof(app_instance->appsym), "%s", appsym);
	TAILQ_INIT(&app_instance->dev_desc_list);

	// 内存池
	app_instance->def_direct_pktmbuf_pool = instance->param.def_direct_pktmbuf_pool;
	app_instance->def_indirect_pktmbuf_pool = instance->param.def_indirect_pktmbuf_pool;

	assert(app_instance->def_direct_pktmbuf_pool != NULL 
		&& app_instance->def_indirect_pktmbuf_pool != NULL);

	// 初始化UDP CTX
	rte_rwlock_init(&app_instance->udp_ctx.rwlock);
	portmap_init(&app_instance->udp_ctx.pbm_local, LPORT_START_BLK);	
	app_instance->udp_ctx.app_instance_ = app_instance;
	return app_instance;
}