source: azure_iot_hub/trunk/asp3_dcre/tinet/net/net_buf.c@ 389

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

ビルドが通るよう更新

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 14.8 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
334#if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF
335 NET_COUNT_NET_BUF(net_buf_table[ix].allocs, 1);
336 net_buf_table[ix].busies ++;
337#endif
338 return error;
339 }
340 ix --;
341 if (ix < 0 || net_buf_table[ix].size > maxlen)
342 break;
343 }
344
345 syslog(LOG_WARNING, "[BUF] busy, up index:%d,%d[%4d], len:%4d.",
346 (uint16_t)req_ix, ix, net_buf_table[req_ix].size, minlen);
347 *buf = NULL;
348 NET_COUNT_NET_BUF(net_buf_table[req_ix].errors, 1);
349 return error;
350 }
351
352/*
353 * tget_net_buf_down -- 小さなサイズの方向に探索して、ネットワークバッファを獲得する。
354 */
355
356static ER
357tget_net_buf_down (T_NET_BUF **buf, uint_t minlen, uint_t maxlen, TMO tmout)
358{
359 int_t ix, req_ix;
360 ER error = E_OK;
361
362 /* 最適なサイズの固定長メモリプールを探す。*/
363 ix = sizeof(net_buf_table) / sizeof(T_NET_BUF_ENTRY);
364 while (ix -- > 0 && maxlen > net_buf_table[ix].size)
365 ;
366 req_ix = ix;
367
368 NET_COUNT_NET_BUF(net_buf_table[req_ix].requests, 1);
369
370 while (1) {
371 if ((error = tget_mpf((ID)net_buf_table[ix].index, (void **)buf,
372 ix == sizeof(net_buf_table) / sizeof(T_NET_BUF_ENTRY) - 1 ? tmout : TMO_POL)) == E_OK) {
373 (*buf)->idix = (uint8_t)ix;
374 (*buf)->len = net_buf_table[ix].size;
375 (*buf)->flags = 0;
376#ifdef IF_ETHER_MULTI_NIC
377 (*buf)->conn_pos = 0;
378#endif
379
380#if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF
381 NET_COUNT_NET_BUF(net_buf_table[ix].allocs, 1);
382 net_buf_table[ix].busies ++;
383#endif
384 return error;
385 }
386 ix ++;
387 if (ix == sizeof(net_buf_table) / sizeof(T_NET_BUF_ENTRY) || net_buf_table[ix].size < minlen)
388 break;
389 }
390
391 syslog(LOG_WARNING, "[BUF] busy, down index:%d,%d[%4d], len:%4d.",
392 (uint16_t)req_ix, ix, net_buf_table[req_ix].size, minlen);
393 *buf = NULL;
394 NET_COUNT_NET_BUF(net_buf_table[req_ix].errors, 1);
395 return error;
396 }
397
398/*
399 * tget_net_buf_ex -- ネットワークバッファを獲得する(拡張機能)。
400 */
401
402ER
403tget_net_buf_ex (T_NET_BUF **buf, uint_t minlen, uint_t maxlen, ATR nbatr, TMO tmout)
404{
405 /* 最小サイズが最大サイズを超えていたらエラー */
406 if ((nbatr & NBA_SEARCH_DESCENT) != 0 && minlen > maxlen) {
407 syslog(LOG_WARNING, "[NET BUF] E_PAR, minlen=%4d > maxlen=%4d.", minlen, maxlen);
408 return E_PAR;
409 }
410
411 /* 割当て可能な最大のサイズを超えていたらエラー */
412 if (minlen > net_buf_table[0].size || maxlen > net_buf_table[0].size) {
413 syslog(LOG_WARNING, "[NET BUF] E_PAR, minlen=%4d or maxlen=%4d > %4d",
414 minlen, maxlen, net_buf_table[0].size);
415 return E_PAR;
416 }
417
418#if defined(SUPPORT_TCP) && defined(TCP_CFG_SWBUF_CSAVE)
419
420 /* TCP で予約したネットワークバッファを取り出す。*/
421 if ((nbatr & NBA_RESERVE_TCP) != 0) {
422 if ((*buf = TCP_PULL_RES_NBUF(nbatr)) != NULL) {
423 return E_OK;
424 }
425 }
426
427#endif /* of #if defined(SUPPORT_TCP) && defined(TCP_CFG_SWBUF_CSAVE) */
428
429 if ((nbatr & NBA_SEARCH_DESCENT) != 0)
430 return tget_net_buf_down(buf, minlen, maxlen, tmout);
431 else if ((nbatr & NBA_SEARCH_ASCENT) != 0)
432 return tget_net_buf_up(buf, minlen, (uint_t)net_buf_table[0].size, tmout);
433 else {
434 syslog(LOG_WARNING, "[NET BUF] E_PAR, nbatr=%08x.", nbatr);
435 return E_PAR;
436 }
437 }
438
439/*
440 * tget_net_buf -- ネットワークバッファを獲得する(互換)。
441 */
442
443ER
444tget_net_buf (T_NET_BUF **buf, uint_t len, TMO tmout)
445{
446 return tget_net_buf_ex(buf, len, (uint_t)net_buf_table[0].size, NBA_SEARCH_ASCENT, tmout);
447 }
448
449/*
450 * rel_net_buf -- ネットワークバッファを返却する。
451 */
452
453ER
454rel_net_buf (T_NET_BUF *buf)
455{
456 ER error = E_OK;
457
458 /* ネットワークバッファの ID の正当性を検証する。*/
459 if ((int_t)buf->idix >= (int_t)(sizeof(net_buf_table) / sizeof(T_NET_BUF_ENTRY))) {
460 syslog(LOG_WARNING, "[NET BUF] E_ID, ID=%d.", buf->idix);
461 error = E_ID;
462 }
463 else {
464
465#if defined(SUPPORT_TCP) && defined(TCP_CFG_SWBUF_CSAVE)
466
467 /* TCP で、ネットワークバッファを予約する。*/
468 if (TCP_PUSH_RES_NBUF(buf) == NULL)
469 return E_OK;
470
471#endif /* of #if defined(SUPPORT_TCP) && defined(TCP_CFG_SWBUF_CSAVE) */
472
473 /* 固定メモリプールに返す。*/
474
475 int idix = buf->idix;
476#if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF
477 net_buf_table[idix].busies --;
478#endif
479 if ((error = rel_mpf((ID)net_buf_table[idix].index, buf)) != E_OK) {
480 syslog(LOG_WARNING, "[NET BUF] %s, ID=%d.", itron_strerror(error), idix);
481 }
482 }
483 return error;
484 }
485
486/*
487 * rus_net_buf -- ネットワークバッファを再利用する。
488 */
489
490ER
491rus_net_buf (T_NET_BUF *buf)
492{
493 ER error = E_OK;
494
495 if (buf->idix >= sizeof(net_buf_table) / sizeof(T_NET_BUF_ENTRY)) {
496 syslog(LOG_WARNING, "[NET BUF] E_ID, ID=%d.", buf->idix);
497 error = E_ID;
498 }
499 else {
500 buf->len = net_buf_table[buf->idix].size;
501 buf->flags = 0;
502 error = E_OK;
503 }
504 return error;
505 }
506
507/*
508 * net_buf_siz -- ネットワークバッファのサイズを返す。
509 */
510
511ER_UINT
512net_buf_siz (T_NET_BUF *buf)
513{
514 if (buf->idix >= sizeof(net_buf_table) / sizeof(T_NET_BUF_ENTRY)) {
515 syslog(LOG_WARNING, "[BUF SIZ] E_ID, ID=%d.", buf->idix);
516 return E_ID;
517 }
518 else
519 return (ER_UINT)net_buf_table[buf->idix].size;
520 }
521
522/*
523 * net_buf_max_siz -- ネットワークバッファの最大サイズを返す。
524 */
525
526uint_t
527net_buf_max_siz (void)
528{
529 return (uint_t)net_buf_table[0].size;
530 }
531
532#else
533#include <stdlib.h>
534
535/*
536 * tget_net_buf_ex -- ネットワークバッファを獲得する(拡張機能)。
537 */
538
539ER
540tget_net_buf_ex (T_NET_BUF **buf, uint_t minlen, uint_t maxlen, ATR nbatr, TMO tmout)
541{
542 uint_t len = (minlen > maxlen) ? minlen : maxlen;
543 *buf = (T_NET_BUF *)malloc(sizeof(T_NET_BUF) - sizeof(((T_NET_BUF *)0)->buf) + len);
544 if (*buf == NULL)
545 return E_NOMEM;
546
547 (*buf)->idix = 0;
548 (*buf)->len = (uint16_t)len;
549 (*buf)->flags = 0;
550
551 return E_OK;
552 }
553
554/*
555 * tget_net_buf -- ネットワークバッファを獲得する(互換)。
556 */
557
558ER
559tget_net_buf (T_NET_BUF **buf, uint_t len, TMO tmout)
560{
561 return tget_net_buf_ex(buf, len, len, NBA_SEARCH_ASCENT, tmout);
562 }
563
564
565/*
566 * rel_net_buf -- ネットワークバッファを返却する。
567 */
568
569ER
570rel_net_buf (T_NET_BUF *buf)
571{
572 free(buf);
573
574 return E_OK;
575 }
576
577
578/*
579 * net_buf_max_siz -- ネットワークバッファの最大サイズを返す。
580 */
581
582uint_t
583net_buf_max_siz (void)
584{
585 return (uint_t)IF_PDU_SIZE;
586 }
587
588#endif
Note: See TracBrowser for help on using the repository browser.