source: asp3_tinet_ecnl_rx/trunk/asp3_dcre/tinet/net/net_buf.c@ 337

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

ASP3版ECNLを追加

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 13.3 KB
Line 
1/*
2 * TINET (TCP/IP Protocol Stack)
3 *
4 * Copyright (C) 2001-2017 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_endian.h>
60#include <net/net_buf.h>
61#include <net/net_count.h>
62
63#include <netinet/in.h>
64#include <netinet/in_var.h>
65#include <netinet/ip.h>
66#include <netinet/ip_var.h>
67#include <netinet/tcp.h>
68#include <netinet/tcp_var.h>
69
70/*
71 * 関数
72 */
73
74extern const char *itron_strerror (ER ercd);
75
76/*
77 * 変数
78 */
79
80static T_NET_BUF_ENTRY net_buf_table[] = {
81
82#if defined(NUM_MPF_NET_BUF6_65536) && NUM_MPF_NET_BUF6_65536 > 0
83 {
84 MPF_NET_BUF6_65536,
85 IF_IP6_HDR_SIZE + 65536,
86
87#if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF
88
89 NUM_MPF_NET_BUF6_65536,
90
91#endif /* of #if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF */
92
93 },
94#endif /* of #if defined(NUM_MPF_NET_BUF6_65536) && NUM_MPF_NET_BUF6_65536 > 0 */
95
96#if defined(NUM_MPF_NET_BUF6_REASSM) && NUM_MPF_NET_BUF6_REASSM > 0
97
98 {
99 MPF_NET_BUF_REASSM,
100 IP6_CFG_FRAG_REASSM_SIZE,
101
102#if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF
103
104 NUM_MPF_NET_BUF6_REASSM,
105
106#endif /* of #if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF */
107
108 },
109
110#else /* of #if defined(NUM_MPF_NET_BUF6_REASSM) && NUM_MPF_NET_BUF6_REASSM > 0 */
111
112#if defined(NUM_MPF_NET_BUF4_REASSM) && NUM_MPF_NET_BUF4_REASSM > 0
113
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
126#endif /* of #if defined(NUM_MPF_NET_BUF4_REASSM) && NUM_MPF_NET_BUF4_REASSM > 0 */
127
128#endif /* of #if defined(NUM_MPF_NET_BUF6_REASSM) && NUM_MPF_NET_BUF6_REASSM > 0 */
129
130#if defined(NUM_MPF_NET_BUF_IF_PDU) && NUM_MPF_NET_BUF_IF_PDU > 0
131 {
132 MPF_NET_BUF_IF_PDU,
133 IF_PDU_SIZE,
134
135#if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF
136
137 NUM_MPF_NET_BUF_IF_PDU,
138
139#endif /* of #if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF */
140
141 },
142#endif /* of #if defined(NUM_MPF_NET_BUF_IF_PDU) && NUM_MPF_NET_BUF_IF_PDU > 0 */
143
144#if defined(NUM_MPF_NET_BUF_IPV6_MMTU) && NUM_MPF_NET_BUF_IPV6_MMTU > 0
145 {
146 MPF_NET_BUF_IPV6_MMTU,
147 IF_HDR_SIZE + IPV6_MMTU,
148
149#if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF
150
151 NUM_MPF_NET_BUF_IPV6_MMTU,
152
153#endif /* of #if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF */
154
155 },
156#endif /* of #if defined(NUM_MPF_NET_BUF_IPV6_MMTU) && NUM_MPF_NET_BUF_IPV6_MMTU > 0 */
157
158#if defined(NUM_MPF_NET_BUF_1024) && NUM_MPF_NET_BUF_1024 > 0
159 {
160 MPF_NET_BUF_1024,
161 UINT_C(1024),
162
163#if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF
164
165 NUM_MPF_NET_BUF_1024,
166
167#endif /* of #if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF */
168
169 },
170#endif /* of #if defined(NUM_MPF_NET_BUF_1024) && NUM_MPF_NET_BUF_1024 > 0 */
171
172#if defined(NUM_MPF_NET_BUF_IP_MSS) && NUM_MPF_NET_BUF_IP_MSS > 0
173 {
174 MPF_NET_BUF_IP_MSS,
175 IF_HDR_SIZE + IP4_MSS,
176
177#if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF
178
179 NUM_MPF_NET_BUF_IP_MSS,
180
181#endif /* of #if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF */
182
183 },
184#endif /* of #if defined(NUM_MPF_NET_BUF_IP_MSS) && NUM_MPF_NET_BUF_IP_MSS > 0 */
185
186#if defined(NUM_MPF_NET_BUF_512) && NUM_MPF_NET_BUF_512 > 0
187 {
188 MPF_NET_BUF_512,
189 UINT_C(512),
190
191#if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF
192
193 NUM_MPF_NET_BUF_512,
194
195#endif /* of #if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF */
196
197 },
198#endif /* of #if defined(NUM_MPF_NET_BUF_512) && NUM_MPF_NET_BUF_512 > 0 */
199
200#if defined(NUM_MPF_NET_BUF_256) && NUM_MPF_NET_BUF_256 > 0
201 {
202 MPF_NET_BUF_256,
203 UINT_C(256),
204
205#if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF
206
207 NUM_MPF_NET_BUF_256,
208
209#endif /* of #if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF */
210
211 },
212#endif /* of #if defined(NUM_MPF_NET_BUF_256) && NUM_MPF_NET_BUF_256 > 0 */
213
214#if defined(NUM_MPF_NET_BUF_128) && NUM_MPF_NET_BUF_128 > 0
215 {
216 MPF_NET_BUF_128,
217 UINT_C(128),
218
219#if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF
220
221 NUM_MPF_NET_BUF_128,
222
223#endif /* of #if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF */
224
225 },
226#endif /* of #if defined(NUM_MPF_NET_BUF_128) && NUM_MPF_NET_BUF_128 > 0 */
227
228#if defined(_IP4_CFG)
229
230#if defined(NUM_MPF_NET_BUF_64) && NUM_MPF_NET_BUF_64 > 0
231 {
232 MPF_NET_BUF_64,
233 UINT_C(64),
234
235#if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF
236
237 NUM_MPF_NET_BUF_64,
238
239#endif /* of #if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF */
240
241 },
242#endif /* of #if defined(NUM_MPF_NET_BUF_64) && NUM_MPF_NET_BUF_64 > 0 */
243
244#endif /* of #if defined(_IP4_CFG) */
245
246#if defined(NUM_MPF_NET_BUF_CSEG) && NUM_MPF_NET_BUF_CSEG > 0
247 {
248 MPF_NET_BUF_CSEG,
249 IF_HDR_SIZE + IP_HDR_SIZE + TCP_HDR_SIZE,
250
251#if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF
252
253 NUM_MPF_NET_BUF_CSEG,
254
255#endif /* of #if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF */
256
257 },
258#endif /* of #if defined(NUM_MPF_NET_BUF_CSEG) && NUM_MPF_NET_BUF_CSEG > 0 */
259
260 };
261
262#if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF
263
264/*
265 * nbuf_get_tbl -- ネットワークバッファ管理表を獲得する。
266 *
267 * 注意: ネットワーク統計情報の計測用
268 */
269
270const T_NET_BUF_ENTRY *
271nbuf_get_tbl (void)
272{
273 return net_buf_table;
274 }
275
276/*
277 * nbuf_get_tbl_size -- ネットワークバッファ管理エントリ数を獲得する。
278 *
279 * 注意: ネットワーク統計情報の計測用
280 */
281
282uint_t
283nbuf_get_tbl_size (void)
284{
285 return sizeof(net_buf_table) / sizeof(T_NET_BUF_ENTRY);
286 }
287
288#endif /* of #if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF */
289
290/*
291 * tget_net_buf_up -- 大きなサイズの方向に探索して、ネットワークバッファを獲得する。
292 */
293
294static ER
295tget_net_buf_up (T_NET_BUF **buf, uint_t minlen, uint_t maxlen, TMO tmout)
296{
297 int_t ix, req_ix;
298 ER error = E_OK;
299
300 /* 最適なサイズの固定長メモリプールを探す。*/
301 ix = sizeof(net_buf_table) / sizeof(T_NET_BUF_ENTRY);
302 while (ix -- > 0 && minlen > net_buf_table[ix].size)
303 ;
304 req_ix = ix;
305
306 NET_COUNT_NET_BUF(net_buf_table[req_ix].requests, 1);
307
308 while (1) {
309 if ((error = tget_mpf((ID)net_buf_table[ix].index, (void*)buf, ix == 0 ? tmout : TMO_POL)) == E_OK) {
310 (*buf)->idix = (uint8_t)ix;
311 (*buf)->len = (uint16_t)minlen;
312 (*buf)->flags = 0;
313
314#if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF
315 NET_COUNT_NET_BUF(net_buf_table[ix].allocs, 1);
316 net_buf_table[ix].busies ++;
317#endif
318 return error;
319 }
320 else if (ix == 0 || net_buf_table[ix].size > maxlen)
321 break;
322 ix --;
323 }
324
325 syslog(LOG_WARNING, "[BUF] busy, up index:%d,%d[%4d], len:%4d.",
326 (uint16_t)req_ix, ix, net_buf_table[req_ix].size, minlen);
327 *buf = NULL;
328 NET_COUNT_NET_BUF(net_buf_table[req_ix].errors, 1);
329 return error;
330 }
331
332/*
333 * tget_net_buf_down -- 小さなサイズの方向に探索して、ネットワークバッファを獲得する。
334 */
335
336static ER
337tget_net_buf_down (T_NET_BUF **buf, uint_t minlen, uint_t maxlen, TMO tmout)
338{
339 int_t ix, req_ix;
340 ER error = E_OK;
341
342 /* 最適なサイズの固定長メモリプールを探す。*/
343 ix = sizeof(net_buf_table) / sizeof(T_NET_BUF_ENTRY);
344 while (ix -- > 0 && maxlen > net_buf_table[ix].size)
345 ;
346 req_ix = ix;
347
348 NET_COUNT_NET_BUF(net_buf_table[req_ix].requests, 1);
349
350 while (1) {
351 if ((error = tget_mpf((ID)net_buf_table[ix].index, (void*)buf,
352 ix == sizeof(net_buf_table) / sizeof(T_NET_BUF_ENTRY) - 1 ? tmout : TMO_POL)) == E_OK) {
353 (*buf)->idix = (uint8_t)ix;
354 (*buf)->len = net_buf_table[ix].size;
355 (*buf)->flags = 0;
356
357#if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF
358 NET_COUNT_NET_BUF(net_buf_table[ix].allocs, 1);
359 net_buf_table[ix].busies ++;
360#endif
361 return error;
362 }
363 ix ++;
364 if (ix == sizeof(net_buf_table) / sizeof(T_NET_BUF_ENTRY) || net_buf_table[ix].size < minlen)
365 break;
366 }
367
368 syslog(LOG_WARNING, "[BUF] busy, down index:%d,%d[%4d], len:%4d.",
369 (uint16_t)req_ix, ix, net_buf_table[req_ix].size, minlen);
370 *buf = NULL;
371 NET_COUNT_NET_BUF(net_buf_table[req_ix].errors, 1);
372 return error;
373 }
374
375/*
376 * tget_net_buf_ex -- ネットワークバッファを獲得する(拡張機能)。
377 */
378
379ER
380tget_net_buf_ex (T_NET_BUF **buf, uint_t minlen, uint_t maxlen, ATR nbatr, TMO tmout)
381{
382 /* 最小サイズが最大サイズを超えていたらエラー */
383 if ((nbatr & NBA_SEARCH_DESCENT) != 0 && minlen > maxlen) {
384 syslog(LOG_WARNING, "[NET BUF] E_PAR, minlen=%4d > maxlen=%4d.", minlen, maxlen);
385 return E_PAR;
386 }
387
388 /* 割当て可能な最大のサイズを超えていたらエラー */
389 if (minlen > net_buf_table[0].size || maxlen > net_buf_table[0].size) {
390 syslog(LOG_WARNING, "[NET BUF] E_PAR, minlen=%4d or maxlen=%4d > %4d",
391 minlen, maxlen, net_buf_table[0].size);
392 return E_PAR;
393 }
394
395#if defined(SUPPORT_TCP) && defined(TCP_CFG_SWBUF_CSAVE)
396
397 /* TCP で予約したネットワークバッファを取り出す。*/
398 if ((nbatr & NBA_RESERVE_TCP) != 0) {
399 if ((*buf = TCP_PULL_RES_NBUF(nbatr)) != NULL) {
400 return E_OK;
401 }
402 }
403
404#endif /* of #if defined(SUPPORT_TCP) && defined(TCP_CFG_SWBUF_CSAVE) */
405
406 if ((nbatr & NBA_SEARCH_DESCENT) != 0)
407 return tget_net_buf_down(buf, minlen, maxlen, tmout);
408 else if ((nbatr & NBA_SEARCH_ASCENT) != 0)
409 return tget_net_buf_up(buf, minlen, (uint_t)net_buf_table[0].size, tmout);
410 else {
411 syslog(LOG_WARNING, "[NET BUF] E_PAR, nbatr=%08x.", nbatr);
412 return E_PAR;
413 }
414 }
415
416/*
417 * tget_net_buf -- ネットワークバッファを獲得する(互換)。
418 */
419
420ER
421tget_net_buf (T_NET_BUF **buf, uint_t len, TMO tmout)
422{
423 return tget_net_buf_ex(buf, len, (uint_t)net_buf_table[0].size, NBA_SEARCH_ASCENT, tmout);
424 }
425
426/*
427 * rel_net_buf -- ネットワークバッファを返却する。
428 */
429
430ER
431rel_net_buf (T_NET_BUF *buf)
432{
433 ER error = E_OK;
434
435 /* ネットワークバッファの ID の正当性を検証する。*/
436 if ((int_t)buf->idix >= (int_t)(sizeof(net_buf_table) / sizeof(T_NET_BUF_ENTRY))) {
437 syslog(LOG_WARNING, "[NET BUF] E_ID, ID=%d.", buf->idix);
438 error = E_ID;
439 }
440 else {
441
442#if defined(SUPPORT_TCP) && defined(TCP_CFG_SWBUF_CSAVE)
443
444 /* TCP で、ネットワークバッファを予約する。*/
445 if (TCP_PUSH_RES_NBUF(buf) == NULL)
446 return E_OK;
447
448#endif /* of #if defined(SUPPORT_TCP) && defined(TCP_CFG_SWBUF_CSAVE) */
449
450 /* 固定メモリプールに返す。*/
451
452#if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF
453 net_buf_table[buf->idix].busies --;
454#endif
455 if ((error = rel_mpf((ID)net_buf_table[buf->idix].index, buf)) != E_OK) {
456 syslog(LOG_WARNING, "[NET BUF] %s, ID=%d.", itron_strerror(error), buf->idix);
457 }
458 }
459 return error;
460 }
461
462/*
463 * rus_net_buf -- ネットワークバッファを再利用する。
464 */
465
466ER
467rus_net_buf (T_NET_BUF *buf)
468{
469 ER error = E_OK;
470
471 if (buf->idix >= sizeof(net_buf_table) / sizeof(T_NET_BUF_ENTRY)) {
472 syslog(LOG_WARNING, "[NET BUF] E_ID, ID=%d.", buf->idix);
473 error = E_ID;
474 }
475 else {
476 buf->len = net_buf_table[buf->idix].size;
477 buf->flags = 0;
478 error = E_OK;
479 }
480 return error;
481 }
482
483/*
484 * net_buf_siz -- ネットワークバッファのサイズを返す。
485 */
486
487ER_UINT
488net_buf_siz (T_NET_BUF *buf)
489{
490 if (buf->idix >= sizeof(net_buf_table) / sizeof(T_NET_BUF_ENTRY)) {
491 syslog(LOG_WARNING, "[BUF SIZ] E_ID, ID=%d.", buf->idix);
492 return E_ID;
493 }
494 else
495 return (ER_UINT)net_buf_table[buf->idix].size;
496 }
497
498/*
499 * net_buf_max_siz -- ネットワークバッファの最大サイズを返す。
500 */
501
502uint_t
503net_buf_max_siz (void)
504{
505 return (uint_t)net_buf_table[0].size;
506 }
Note: See TracBrowser for help on using the repository browser.