source: EcnlProtoTool/trunk/asp3_dcre/tinet/net/net_buf.c@ 321

Last change on this file since 321 was 321, checked in by coas-nagasima, 7 years ago

文字コードを設定

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 12.7 KB
Line 
1/*
2 * TINET (TCP/IP Protocol Stack)
3 *
4 * Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
5 * Tomakomai National College of Technology, JAPAN
6 *
7 * 上記著作権者は,以下の (1)~(4) の条件か,Free Software Foundation
8 * によって公表されている GNU General Public License の Version 2 に記
9 * 述されている条件を満たす場合に限り,本ソフトウェア(本ソフトウェア
10 * を改変したものを含む.以下同じ)を使用・複製・改変・再配布(以下,
11 * 利用と呼ぶ)することを無償で許諾する.
12 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
13 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
14 * スコード中に含まれていること.
15 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
16 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
17 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
18 * の無保証規定を掲載すること.
19 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
20 * 用できない形で再配布する場合には,次の条件を満たすこと.
21 * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
22 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
23 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
24 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
25 *
26 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
27 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,その適用可能性も
28 * 含めて,いかなる保証も行わない.また,本ソフトウェアの利用により直
29 * 接的または間接的に生じたいかなる損害に関しても,その責任を負わない.
30 *
31 * @(#) $Id$
32 */
33
34#ifdef TARGET_KERNEL_ASP
35
36#include <kernel.h>
37#include <sil.h>
38#include <t_syslog.h>
39#include "kernel_cfg.h"
40
41#endif /* of #ifdef TARGET_KERNEL_ASP */
42
43#ifdef TARGET_KERNEL_JSP
44
45#include <s_services.h>
46#include <t_services.h>
47#include "kernel_id.h"
48
49#endif /* of #ifdef TARGET_KERNEL_JSP */
50
51#include <tinet_defs.h>
52#include <tinet_config.h>
53
54#include <net/if.h>
55#include <net/if_loop.h>
56#include <net/if_ppp.h>
57#include <net/ethernet.h>
58#include <net/net.h>
59#include <net/net_buf.h>
60#include <net/net_count.h>
61
62#include <netinet/in.h>
63#include <netinet/in_var.h>
64#include <netinet6/in6.h>
65#include <netinet/ip.h>
66#include <netinet/ip_var.h>
67#include <netinet/ip6.h>
68#include <netinet6/ip6_var.h>
69#include <netinet/tcp.h>
70#include <netinet/tcp_timer.h>
71#include <netinet/tcp_var.h>
72
73/*
74 * 関数
75 */
76
77extern const char *itron_strerror (ER ercd);
78
79/*
80 * 変数
81 */
82
83static T_NET_BUF_ENTRY net_buf_table[] = {
84
85#if defined(NUM_MPF_NET_BUF6_65536) && NUM_MPF_NET_BUF6_65536 > 0
86 {
87 MPF_NET_BUF6_65536,
88 IF_IP6_HDR_SIZE + 65536,
89
90#if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF
91
92 NUM_MPF_NET_BUF6_65536,
93
94#endif /* of #if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF */
95
96 },
97#endif /* of #if defined(NUM_MPF_NET_BUF6_65536) && NUM_MPF_NET_BUF6_65536 > 0 */
98
99#if defined(NUM_MPF_NET_BUF6_REASSM) && NUM_MPF_NET_BUF6_REASSM > 0
100 {
101 MPF_NET_BUF_REASSM,
102 IP6_CFG_FRAG_REASSM_SIZE,
103
104#if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF
105
106 NUM_MPF_NET_BUF6_REASSM,
107
108#endif /* of #if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF */
109
110 },
111#endif /* of #if defined(NUM_MPF_NET_BUF6_REASSM) && NUM_MPF_NET_BUF6_REASSM > 0 */
112
113#if defined(NUM_MPF_NET_BUF4_REASSM) && NUM_MPF_NET_BUF4_REASSM > 0
114 {
115 MPF_NET_BUF_REASSM,
116 IP4_CFG_FRAG_REASSM_SIZE,
117
118#if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF
119
120 NUM_MPF_NET_BUF4_REASSM,
121
122#endif /* of #if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF */
123
124 },
125#endif /* of #if defined(NUM_MPF_NET_BUF4_REASSM) && NUM_MPF_NET_BUF4_REASSM > 0 */
126
127#if defined(NUM_MPF_NET_BUF_IF_PDU) && NUM_MPF_NET_BUF_IF_PDU > 0
128 {
129 MPF_NET_BUF_IF_PDU,
130 IF_PDU_SIZE,
131
132#if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF
133
134 NUM_MPF_NET_BUF_IF_PDU,
135
136#endif /* of #if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF */
137
138 },
139#endif /* of #if defined(NUM_MPF_NET_BUF_IF_PDU) && NUM_MPF_NET_BUF_IF_PDU > 0 */
140
141#if defined(NUM_MPF_NET_BUF_IPV6_MMTU) && NUM_MPF_NET_BUF_IPV6_MMTU > 0
142 {
143 MPF_NET_BUF_IPV6_MMTU,
144 IF_HDR_SIZE + IPV6_MMTU,
145
146#if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF
147
148 NUM_MPF_NET_BUF_IPV6_MMTU,
149
150#endif /* of #if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF */
151
152 },
153#endif /* of #if defined(NUM_MPF_NET_BUF_IPV6_MMTU) && NUM_MPF_NET_BUF_IPV6_MMTU > 0 */
154
155#if defined(NUM_MPF_NET_BUF_1024) && NUM_MPF_NET_BUF_1024 > 0
156 {
157 MPF_NET_BUF_1024,
158 UINT_C(1024),
159
160#if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF
161
162 NUM_MPF_NET_BUF_1024,
163
164#endif /* of #if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF */
165
166 },
167#endif /* of #if defined(NUM_MPF_NET_BUF_1024) && NUM_MPF_NET_BUF_1024 > 0 */
168
169#if defined(NUM_MPF_NET_BUF_IP_MSS) && NUM_MPF_NET_BUF_IP_MSS > 0
170 {
171 MPF_NET_BUF_IP_MSS,
172 IF_HDR_SIZE + IP4_MSS,
173
174#if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF
175
176 NUM_MPF_NET_BUF_IP_MSS,
177
178#endif /* of #if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF */
179
180 },
181#endif /* of #if defined(NUM_MPF_NET_BUF_IP_MSS) && NUM_MPF_NET_BUF_IP_MSS > 0 */
182
183#if defined(NUM_MPF_NET_BUF_512) && NUM_MPF_NET_BUF_512 > 0
184 {
185 MPF_NET_BUF_512,
186 UINT_C(512),
187
188#if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF
189
190 NUM_MPF_NET_BUF_512,
191
192#endif /* of #if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF */
193
194 },
195#endif /* of #if defined(NUM_MPF_NET_BUF_512) && NUM_MPF_NET_BUF_512 > 0 */
196
197#if defined(NUM_MPF_NET_BUF_256) && NUM_MPF_NET_BUF_256 > 0
198 {
199 MPF_NET_BUF_256,
200 UINT_C(256),
201
202#if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF
203
204 NUM_MPF_NET_BUF_256,
205
206#endif /* of #if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF */
207
208 },
209#endif /* of #if defined(NUM_MPF_NET_BUF_256) && NUM_MPF_NET_BUF_256 > 0 */
210
211#if defined(NUM_MPF_NET_BUF_128) && NUM_MPF_NET_BUF_128 > 0
212 {
213 MPF_NET_BUF_128,
214 UINT_C(128),
215
216#if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF
217
218 NUM_MPF_NET_BUF_128,
219
220#endif /* of #if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF */
221
222 },
223#endif /* of #if defined(NUM_MPF_NET_BUF_128) && NUM_MPF_NET_BUF_128 > 0 */
224
225#if defined(SUPPORT_INET4)
226
227#if defined(NUM_MPF_NET_BUF_64) && NUM_MPF_NET_BUF_64 > 0
228 {
229 MPF_NET_BUF_64,
230 UINT_C(64),
231
232#if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF
233
234 NUM_MPF_NET_BUF_64,
235
236#endif /* of #if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF */
237
238 },
239#endif /* of #if defined(NUM_MPF_NET_BUF_64) && NUM_MPF_NET_BUF_64 > 0 */
240
241#endif /* of #if defined(SUPPORT_INET4) */
242
243#if defined(NUM_MPF_NET_BUF_CSEG) && NUM_MPF_NET_BUF_CSEG > 0
244 {
245 MPF_NET_BUF_CSEG,
246 IF_HDR_SIZE + IP_HDR_SIZE + TCP_HDR_SIZE,
247
248#if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF
249
250 NUM_MPF_NET_BUF_CSEG,
251
252#endif /* of #if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF */
253
254 },
255#endif /* of #if defined(NUM_MPF_NET_BUF_CSEG) && NUM_MPF_NET_BUF_CSEG > 0 */
256
257 };
258
259#if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF
260
261/*
262 * nbuf_get_tbl -- ネットワークバッファ管理表を獲得する。
263 *
264 * 注意: ネットワーク統計情報の計測用
265 */
266
267const T_NET_BUF_ENTRY *
268nbuf_get_tbl (void)
269{
270 return net_buf_table;
271 }
272
273/*
274 * nbuf_get_tbl_size -- ネットワークバッファ管理エントリ数を獲得する。
275 *
276 * 注意: ネットワーク統計情報の計測用
277 */
278
279uint_t
280nbuf_get_tbl_size (void)
281{
282 return sizeof(net_buf_table) / sizeof(T_NET_BUF_ENTRY);
283 }
284
285#endif /* of #if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF */
286
287/*
288 * tget_net_buf_up -- 大きなサイズの方向に探索して、ネットワークバッファを獲得する。
289 */
290
291static ER
292tget_net_buf_up (T_NET_BUF **buf, uint_t minlen, uint_t maxlen, TMO tmout)
293{
294 int_t ix, req_ix;
295 ER error = E_OK;
296
297 /* 最適なサイズの固定長メモリプールを探す。*/
298 ix = sizeof(net_buf_table) / sizeof(T_NET_BUF_ENTRY);
299 while (ix -- > 0 && minlen > net_buf_table[ix].size)
300 ;
301 req_ix = ix;
302
303 NET_COUNT_NET_BUF(net_buf_table[req_ix].requests, 1);
304
305 while (1) {
306 if ((error = tget_mpf((ID)net_buf_table[ix].index, (void*)buf, ix == 0 ? tmout : TMO_POL)) == E_OK) {
307 (*buf)->idix = (uint8_t)ix;
308 (*buf)->len = (uint16_t)minlen;
309 (*buf)->flags = 0;
310 NET_COUNT_NET_BUF(net_buf_table[ix].allocs, 1);
311 return error;
312 }
313 else if (ix == 0 || net_buf_table[ix].size > maxlen)
314 break;
315 ix --;
316 }
317
318 syslog(LOG_WARNING, "[NET BUF] busy, index=%d, len=%4d.", (uint16_t)req_ix, minlen);
319 *buf = NULL;
320 NET_COUNT_NET_BUF(net_buf_table[req_ix].errors, 1);
321 return error;
322 }
323
324/*
325 * tget_net_buf_down -- 小さなサイズの方向に探索して、ネットワークバッファを獲得する。
326 */
327
328static ER
329tget_net_buf_down (T_NET_BUF **buf, uint_t minlen, uint_t maxlen, TMO tmout)
330{
331 int_t ix, req_ix;
332 ER error = E_OK;
333
334 /* 最適なサイズの固定長メモリプールを探す。*/
335 ix = sizeof(net_buf_table) / sizeof(T_NET_BUF_ENTRY);
336 while (ix -- > 0 && maxlen > net_buf_table[ix].size)
337 ;
338 req_ix = ix;
339
340 NET_COUNT_NET_BUF(net_buf_table[req_ix].requests, 1);
341
342 while (1) {
343 if ((error = tget_mpf((ID)net_buf_table[ix].index, (void*)buf,
344 ix == sizeof(net_buf_table) / sizeof(T_NET_BUF_ENTRY) - 1 ? tmout : TMO_POL)) == E_OK) {
345 (*buf)->idix = (uint8_t)ix;
346 (*buf)->len = net_buf_table[ix].size;
347 (*buf)->flags = 0;
348 NET_COUNT_NET_BUF(net_buf_table[ix].allocs, 1);
349 return error;
350 }
351 ix ++;
352 if (ix == sizeof(net_buf_table) / sizeof(T_NET_BUF_ENTRY) || net_buf_table[ix].size < minlen)
353 break;
354 }
355
356 syslog(LOG_WARNING, "[NET BUF] busy, index=%d, len=%4d.", (uint16_t)req_ix, maxlen);
357 *buf = NULL;
358 NET_COUNT_NET_BUF(net_buf_table[req_ix].errors, 1);
359 return error;
360 }
361
362/*
363 * tget_net_buf_ex -- ネットワークバッファを獲得する(拡張機能)。
364 */
365
366ER
367tget_net_buf_ex (T_NET_BUF **buf, uint_t minlen, uint_t maxlen, ATR nbatr, TMO tmout)
368{
369 /* 最小サイズが最大サイズを超えていたらエラー */
370 if ((nbatr & NBA_SEARCH_DESCENT) != 0 && minlen > maxlen) {
371 syslog(LOG_WARNING, "[NET BUF] E_PAR, minlen=%4d > maxlen=%4d.", minlen, maxlen);
372 return E_PAR;
373 }
374
375 /* 割当て可能な最大のサイズを超えていたらエラー */
376 if (minlen > net_buf_table[0].size || maxlen > net_buf_table[0].size) {
377 syslog(LOG_WARNING, "[NET BUF] E_PAR, minlen=%4d or maxlen=%4d > %4d",
378 minlen, maxlen, net_buf_table[0].size);
379 return E_PAR;
380 }
381
382 /* TCP で予約したネットワークバッファを取り出す。*/
383 if ((nbatr & NBA_RESERVE_TCP) != 0) {
384 if ((*buf = TCP_PULL_RES_NBUF(nbatr)) != NULL) {
385 return E_OK;
386 }
387 }
388
389 if ((nbatr & NBA_SEARCH_DESCENT) != 0)
390 return tget_net_buf_down(buf, minlen, maxlen, tmout);
391 else if ((nbatr & NBA_SEARCH_ASCENT) != 0)
392 return tget_net_buf_up(buf, minlen, (uint_t)net_buf_table[0].size, tmout);
393 else {
394 syslog(LOG_WARNING, "[NET BUF] E_PAR, nbatr=%08x.", nbatr);
395 return E_PAR;
396 }
397 }
398
399/*
400 * tget_net_buf -- ネットワークバッファを獲得する(互換)。
401 */
402
403ER
404tget_net_buf (T_NET_BUF **buf, uint_t len, TMO tmout)
405{
406 return tget_net_buf_ex(buf, len, (uint_t)net_buf_table[0].size, NBA_SEARCH_ASCENT, tmout);
407 }
408
409/*
410 * rel_net_buf -- ネットワークバッファを返却する。
411 */
412
413ER
414rel_net_buf (T_NET_BUF *buf)
415{
416 ER error = E_OK;
417
418 /* ネットワークバッファの ID の正当性を検証する。*/
419 if ((int_t)buf->idix >= (int_t)(sizeof(net_buf_table) / sizeof(T_NET_BUF_ENTRY))) {
420 syslog(LOG_WARNING, "[NET BUF] E_ID, ID=%d.", buf->idix);
421 error = E_ID;
422 }
423 else {
424
425 /* TCP で、ネットワークバッファを予約する。*/
426 if (TCP_PUSH_RES_NBUF(buf) == NULL)
427 return E_OK;
428
429 /* 固定メモリプールに返す。*/
430 if ((error = rel_mpf((ID)net_buf_table[buf->idix].index, buf)) != E_OK)
431 syslog(LOG_WARNING, "[NET BUF] %s, ID=%d.", itron_strerror(error), buf->idix);
432 }
433 return error;
434 }
435
436/*
437 * rus_net_buf -- ネットワークバッファを再利用する。
438 */
439
440ER
441rus_net_buf (T_NET_BUF *buf)
442{
443 ER error = E_OK;
444
445 if (buf->idix >= sizeof(net_buf_table) / sizeof(T_NET_BUF_ENTRY)) {
446 syslog(LOG_WARNING, "[NET BUF] E_ID, ID=%d.", buf->idix);
447 error = E_ID;
448 }
449 else {
450 buf->len = net_buf_table[buf->idix].size;
451 buf->flags = 0;
452 error = E_OK;
453 }
454 return error;
455 }
456
457/*
458 * net_buf_siz -- ネットワークバッファのサイズを返す。
459 */
460
461ER_UINT
462net_buf_siz (T_NET_BUF *buf)
463{
464 if (buf->idix >= sizeof(net_buf_table) / sizeof(T_NET_BUF_ENTRY)) {
465 syslog(LOG_WARNING, "[BUF SIZ] E_ID, ID=%d.", buf->idix);
466 return E_ID;
467 }
468 else
469 return (ER_UINT)net_buf_table[buf->idix].size;
470 }
471
472/*
473 * net_buf_max_siz -- ネットワークバッファの最大サイズを返す。
474 */
475
476uint_t
477net_buf_max_siz (void)
478{
479 return (uint_t)net_buf_table[0].size;
480 }
Note: See TracBrowser for help on using the repository browser.