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

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

arm向けASP3版ECNLを追加

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 13.4 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#ifdef IF_ETHER_MULTI_NIC
314 (*buf)->conn_pos = 0;
315#endif
316#if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF
317 NET_COUNT_NET_BUF(net_buf_table[ix].allocs, 1);
318 net_buf_table[ix].busies ++;
319#endif
320 return error;
321 }
322 else if (ix == 0 || net_buf_table[ix].size > maxlen)
323 break;
324 ix --;
325 }
326
327 syslog(LOG_WARNING, "[BUF] busy, up index:%d,%d[%4d], len:%4d.",
328 (uint16_t)req_ix, ix, net_buf_table[req_ix].size, minlen);
329 *buf = NULL;
330 NET_COUNT_NET_BUF(net_buf_table[req_ix].errors, 1);
331 return error;
332 }
333
334/*
335 * tget_net_buf_down -- 小さなサイズの方向に探索して、ネットワークバッファを獲得する。
336 */
337
338static ER
339tget_net_buf_down (T_NET_BUF **buf, uint_t minlen, uint_t maxlen, TMO tmout)
340{
341 int_t ix, req_ix;
342 ER error = E_OK;
343
344 /* 最適なサイズの固定長メモリプールを探す。*/
345 ix = sizeof(net_buf_table) / sizeof(T_NET_BUF_ENTRY);
346 while (ix -- > 0 && maxlen > net_buf_table[ix].size)
347 ;
348 req_ix = ix;
349
350 NET_COUNT_NET_BUF(net_buf_table[req_ix].requests, 1);
351
352 while (1) {
353 if ((error = tget_mpf((ID)net_buf_table[ix].index, (void*)buf,
354 ix == sizeof(net_buf_table) / sizeof(T_NET_BUF_ENTRY) - 1 ? tmout : TMO_POL)) == E_OK) {
355 (*buf)->idix = (uint8_t)ix;
356 (*buf)->len = net_buf_table[ix].size;
357 (*buf)->flags = 0;
358#ifdef IF_ETHER_MULTI_NIC
359 (*buf)->conn_pos = 0;
360#endif
361#if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF
362 NET_COUNT_NET_BUF(net_buf_table[ix].allocs, 1);
363 net_buf_table[ix].busies ++;
364#endif
365 return error;
366 }
367 ix ++;
368 if (ix == sizeof(net_buf_table) / sizeof(T_NET_BUF_ENTRY) || net_buf_table[ix].size < minlen)
369 break;
370 }
371
372 syslog(LOG_WARNING, "[BUF] busy, down index:%d,%d[%4d], len:%4d.",
373 (uint16_t)req_ix, ix, net_buf_table[req_ix].size, minlen);
374 *buf = NULL;
375 NET_COUNT_NET_BUF(net_buf_table[req_ix].errors, 1);
376 return error;
377 }
378
379/*
380 * tget_net_buf_ex -- ネットワークバッファを獲得する(拡張機能)。
381 */
382
383ER
384tget_net_buf_ex (T_NET_BUF **buf, uint_t minlen, uint_t maxlen, ATR nbatr, TMO tmout)
385{
386 /* 最小サイズが最大サイズを超えていたらエラー */
387 if ((nbatr & NBA_SEARCH_DESCENT) != 0 && minlen > maxlen) {
388 syslog(LOG_WARNING, "[NET BUF] E_PAR, minlen=%4d > maxlen=%4d.", minlen, maxlen);
389 return E_PAR;
390 }
391
392 /* 割当て可能な最大のサイズを超えていたらエラー */
393 if (minlen > net_buf_table[0].size || maxlen > net_buf_table[0].size) {
394 syslog(LOG_WARNING, "[NET BUF] E_PAR, minlen=%4d or maxlen=%4d > %4d",
395 minlen, maxlen, net_buf_table[0].size);
396 return E_PAR;
397 }
398
399#if defined(SUPPORT_TCP) && defined(TCP_CFG_SWBUF_CSAVE)
400
401 /* TCP で予約したネットワークバッファを取り出す。*/
402 if ((nbatr & NBA_RESERVE_TCP) != 0) {
403 if ((*buf = TCP_PULL_RES_NBUF(nbatr)) != NULL) {
404 return E_OK;
405 }
406 }
407
408#endif /* of #if defined(SUPPORT_TCP) && defined(TCP_CFG_SWBUF_CSAVE) */
409
410 if ((nbatr & NBA_SEARCH_DESCENT) != 0)
411 return tget_net_buf_down(buf, minlen, maxlen, tmout);
412 else if ((nbatr & NBA_SEARCH_ASCENT) != 0)
413 return tget_net_buf_up(buf, minlen, (uint_t)net_buf_table[0].size, tmout);
414 else {
415 syslog(LOG_WARNING, "[NET BUF] E_PAR, nbatr=%08x.", nbatr);
416 return E_PAR;
417 }
418 }
419
420/*
421 * tget_net_buf -- ネットワークバッファを獲得する(互換)。
422 */
423
424ER
425tget_net_buf (T_NET_BUF **buf, uint_t len, TMO tmout)
426{
427 return tget_net_buf_ex(buf, len, (uint_t)net_buf_table[0].size, NBA_SEARCH_ASCENT, tmout);
428 }
429
430/*
431 * rel_net_buf -- ネットワークバッファを返却する。
432 */
433
434ER
435rel_net_buf (T_NET_BUF *buf)
436{
437 ER error = E_OK;
438
439 /* ネットワークバッファの ID の正当性を検証する。*/
440 if ((int_t)buf->idix >= (int_t)(sizeof(net_buf_table) / sizeof(T_NET_BUF_ENTRY))) {
441 syslog(LOG_WARNING, "[NET BUF] E_ID, ID=%d.", buf->idix);
442 error = E_ID;
443 }
444 else {
445
446#if defined(SUPPORT_TCP) && defined(TCP_CFG_SWBUF_CSAVE)
447
448 /* TCP で、ネットワークバッファを予約する。*/
449 if (TCP_PUSH_RES_NBUF(buf) == NULL)
450 return E_OK;
451
452#endif /* of #if defined(SUPPORT_TCP) && defined(TCP_CFG_SWBUF_CSAVE) */
453
454 /* 固定メモリプールに返す。*/
455
456#if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF
457 net_buf_table[buf->idix].busies --;
458#endif
459 if ((error = rel_mpf((ID)net_buf_table[buf->idix].index, buf)) != E_OK) {
460 syslog(LOG_WARNING, "[NET BUF] %s, ID=%d.", itron_strerror(error), buf->idix);
461 }
462 }
463 return error;
464 }
465
466/*
467 * rus_net_buf -- ネットワークバッファを再利用する。
468 */
469
470ER
471rus_net_buf (T_NET_BUF *buf)
472{
473 ER error = E_OK;
474
475 if (buf->idix >= sizeof(net_buf_table) / sizeof(T_NET_BUF_ENTRY)) {
476 syslog(LOG_WARNING, "[NET BUF] E_ID, ID=%d.", buf->idix);
477 error = E_ID;
478 }
479 else {
480 buf->len = net_buf_table[buf->idix].size;
481 buf->flags = 0;
482 error = E_OK;
483 }
484 return error;
485 }
486
487/*
488 * net_buf_siz -- ネットワークバッファのサイズを返す。
489 */
490
491ER_UINT
492net_buf_siz (T_NET_BUF *buf)
493{
494 if (buf->idix >= sizeof(net_buf_table) / sizeof(T_NET_BUF_ENTRY)) {
495 syslog(LOG_WARNING, "[BUF SIZ] E_ID, ID=%d.", buf->idix);
496 return E_ID;
497 }
498 else
499 return (ER_UINT)net_buf_table[buf->idix].size;
500 }
501
502/*
503 * net_buf_max_siz -- ネットワークバッファの最大サイズを返す。
504 */
505
506uint_t
507net_buf_max_siz (void)
508{
509 return (uint_t)net_buf_table[0].size;
510 }
Note: See TracBrowser for help on using the repository browser.