source: asp3_tinet_ecnl_arm/trunk/asp3_dcre/tinet/net/net_buf.c@ 364

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

TINETとSocket APIなどを更新

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