summaryrefslogtreecommitdiffstats
path: root/stacks/lwip_stack/lwip_src/common
diff options
context:
space:
mode:
authorsharath reddy <bs.reddy@huawei.com>2019-06-04 11:53:49 +0530
committersharath reddy <bs.reddy@huawei.com>2019-06-04 20:38:30 +0530
commit2a42ad20b9730706ad371ae3787d4597c4e42276 (patch)
treefa01cd312586ea007468e7233f94c0ce53d75873 /stacks/lwip_stack/lwip_src/common
parenta826fe833d3f2a8fe2673fa05811fe1a22baf045 (diff)
Feature: 19.04 part-2DMM-2
Change-Id: I0b52a6bb67c25c7955d58e29eb81a3cc9efea9e9 Signed-off-by: sharath reddy <bs.reddy@huawei.com>
Diffstat (limited to 'stacks/lwip_stack/lwip_src/common')
-rw-r--r--stacks/lwip_stack/lwip_src/common/rb_tree.c389
-rw-r--r--stacks/lwip_stack/lwip_src/common/rb_tree.h110
-rw-r--r--stacks/lwip_stack/lwip_src/common/spl_def.h138
-rw-r--r--stacks/lwip_stack/lwip_src/common/spl_opt.h329
-rw-r--r--stacks/lwip_stack/lwip_src/common/spl_rti.c91
-rw-r--r--stacks/lwip_stack/lwip_src/common/stackx_app_res.c951
-rw-r--r--stacks/lwip_stack/lwip_src/common/stackx_app_res.h103
-rw-r--r--stacks/lwip_stack/lwip_src/common/stackx_common.c351
-rw-r--r--stacks/lwip_stack/lwip_src/common/stackx_common.h44
-rw-r--r--stacks/lwip_stack/lwip_src/common/stackx_common_opt.h147
-rw-r--r--stacks/lwip_stack/lwip_src/common/stackx_debug.h70
-rw-r--r--stacks/lwip_stack/lwip_src/common/stackx_err.h68
-rw-r--r--stacks/lwip_stack/lwip_src/common/stackx_ip_addr.c276
-rw-r--r--stacks/lwip_stack/lwip_src/common/stackx_ip_addr.h82
-rw-r--r--stacks/lwip_stack/lwip_src/common/stackx_ip_tos.h145
-rw-r--r--stacks/lwip_stack/lwip_src/common/stackx_netbuf.h43
-rw-r--r--stacks/lwip_stack/lwip_src/common/stackx_pbuf.c220
-rw-r--r--stacks/lwip_stack/lwip_src/common/stackx_pbuf.h80
-rw-r--r--stacks/lwip_stack/lwip_src/common/stackx_pbuf_comm.h109
-rw-r--r--stacks/lwip_stack/lwip_src/common/stackx_spl_msg.h241
-rw-r--r--stacks/lwip_stack/lwip_src/common/stackx_spl_share.c192
-rw-r--r--stacks/lwip_stack/lwip_src/common/stackx_spl_share.h444
-rw-r--r--stacks/lwip_stack/lwip_src/common/stackx_tcp_opt.h42
-rw-r--r--stacks/lwip_stack/lwip_src/common/stackx_tx_box.c62
-rw-r--r--stacks/lwip_stack/lwip_src/common/stackx_tx_box.h39
-rw-r--r--stacks/lwip_stack/lwip_src/common/stackx_types.h68
-rw-r--r--stacks/lwip_stack/lwip_src/common/stackxopts.h53
27 files changed, 4887 insertions, 0 deletions
diff --git a/stacks/lwip_stack/lwip_src/common/rb_tree.c b/stacks/lwip_stack/lwip_src/common/rb_tree.c
new file mode 100644
index 0000000..aecdd37
--- /dev/null
+++ b/stacks/lwip_stack/lwip_src/common/rb_tree.c
@@ -0,0 +1,389 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#include "rb_tree.h"
+
+static void __rb_rotate_right(struct rb_node *node, struct rb_root *root)
+{
+ struct rb_node *left = node->rb_left;
+ struct rb_node *parent = rb_parent(node);
+
+ if ((node->rb_left = left->rb_right))
+ {
+ rb_set_parent(left->rb_right, node);
+ }
+
+ left->rb_right = node;
+
+ rb_set_parent(left, parent);
+
+ if (parent)
+ {
+ if (node == parent->rb_right)
+ {
+ parent->rb_right = left;
+ }
+ else
+ {
+ parent->rb_left = left;
+ }
+ }
+ else
+ {
+ root->rb_node = left;
+ }
+
+ rb_set_parent(node, left);
+}
+
+static void __rb_rotate_left(struct rb_node *node, struct rb_root *root)
+{
+ struct rb_node *parent = rb_parent(node);
+
+ struct rb_node *right = node->rb_right;
+
+ if ((node->rb_right = right->rb_left))
+ {
+ rb_set_parent(right->rb_left, node);
+ }
+
+ right->rb_left = node;
+ rb_set_parent(right, parent);
+
+ if (parent) /* judge parent node */
+ {
+ if (node == parent->rb_left)
+ {
+ parent->rb_left = right;
+ }
+ else
+ {
+ parent->rb_right = right;
+ }
+ }
+ else
+ {
+ root->rb_node = right;
+ }
+
+ rb_set_parent(node, right);
+}
+
+static void
+__rb_erase_color(struct rb_node *rb_tree_node,
+ struct rb_node *rb_tree_parent, struct rb_root *rb_tree_root)
+{
+ struct rb_node *rb_tree_other;
+
+ while ((!rb_tree_node || rb_is_black(rb_tree_node))
+ && (rb_tree_node != rb_tree_root->rb_node))
+ {
+ if (rb_tree_parent == NULL)
+ {
+ break;
+ }
+
+ if (rb_tree_parent->rb_left == rb_tree_node)
+ {
+ rb_tree_other = rb_tree_parent->rb_right;
+ if (rb_is_red(rb_tree_other))
+ {
+ rb_set_black(rb_tree_other);
+ rb_set_red(rb_tree_parent);
+ __rb_rotate_left(rb_tree_parent, rb_tree_root);
+ rb_tree_other = rb_tree_parent->rb_right;
+ }
+
+ if ((!rb_tree_other->rb_left
+ || rb_is_black(rb_tree_other->rb_left))
+ && (!rb_tree_other->rb_right
+ || rb_is_black(rb_tree_other->rb_right)))
+ {
+ rb_set_red(rb_tree_other);
+ rb_tree_node = rb_tree_parent;
+ rb_tree_parent = rb_parent(rb_tree_node);
+ }
+ else
+ {
+ if (!rb_tree_other->rb_right
+ || rb_is_black(rb_tree_other->rb_right))
+ {
+ rb_set_black(rb_tree_other->rb_left);
+ rb_set_red(rb_tree_other);
+ __rb_rotate_right(rb_tree_other, rb_tree_root);
+ rb_tree_other = rb_tree_parent->rb_right;
+ }
+
+ rb_set_color(rb_tree_other, rb_color(rb_tree_parent));
+ rb_set_black(rb_tree_parent);
+ rb_set_black(rb_tree_other->rb_right);
+ __rb_rotate_left(rb_tree_parent, rb_tree_root);
+ rb_tree_node = rb_tree_root->rb_node;
+ break;
+ }
+ }
+ else
+ {
+ rb_tree_other = rb_tree_parent->rb_left;
+ if (rb_is_red(rb_tree_other))
+ {
+ rb_set_black(rb_tree_other);
+ rb_set_red(rb_tree_parent);
+ __rb_rotate_right(rb_tree_parent, rb_tree_root);
+ rb_tree_other = rb_tree_parent->rb_left;
+ }
+
+ if ((!rb_tree_other->rb_left
+ || rb_is_black(rb_tree_other->rb_left))
+ && (!rb_tree_other->rb_right
+ || rb_is_black(rb_tree_other->rb_right)))
+ {
+ rb_set_red(rb_tree_other);
+ rb_tree_node = rb_tree_parent;
+ rb_tree_parent = rb_parent(rb_tree_node);
+ }
+ else
+ {
+ if (!rb_tree_other->rb_left
+ || rb_is_black(rb_tree_other->rb_left))
+ {
+ rb_set_black(rb_tree_other->rb_right);
+ rb_set_red(rb_tree_other);
+ __rb_rotate_left(rb_tree_other, rb_tree_root);
+ rb_tree_other = rb_tree_parent->rb_left;
+ }
+
+ rb_set_color(rb_tree_other, rb_color(rb_tree_parent));
+ rb_set_black(rb_tree_parent);
+ rb_set_black(rb_tree_other->rb_left);
+ __rb_rotate_right(rb_tree_parent, rb_tree_root);
+ rb_tree_node = rb_tree_root->rb_node;
+ break;
+ }
+ }
+ }
+
+ if (rb_tree_node)
+ {
+ rb_set_black(rb_tree_node);
+ }
+}
+
+void
+rb_insert_color(struct rb_node *rb_tree_node, struct rb_root *rb_tree_root)
+{
+ struct rb_node *rb_tree_parent, *rb_tree_gparent;
+
+ if (!rb_tree_node || !rb_tree_root)
+ return;
+
+ while ((rb_tree_parent = rb_parent(rb_tree_node))
+ && rb_is_red(rb_tree_parent))
+ {
+ rb_tree_gparent = rb_parent(rb_tree_parent);
+
+ if (rb_tree_parent == rb_tree_gparent->rb_left)
+ {
+ {
+ register struct rb_node *rb_tree_uncle =
+ rb_tree_gparent->rb_right;
+ if (rb_tree_uncle && rb_is_red(rb_tree_uncle))
+ {
+ rb_set_black(rb_tree_uncle);
+ rb_set_black(rb_tree_parent);
+ rb_set_red(rb_tree_gparent);
+ rb_tree_node = rb_tree_gparent;
+ continue;
+ }
+ }
+
+ if (rb_tree_parent->rb_right == rb_tree_node)
+ {
+ register struct rb_node *rb_tree_tmp;
+ __rb_rotate_left(rb_tree_parent, rb_tree_root);
+ rb_tree_tmp = rb_tree_parent;
+ rb_tree_parent = rb_tree_node;
+ rb_tree_node = rb_tree_tmp;
+ }
+
+ rb_set_black(rb_tree_parent);
+ rb_set_red(rb_tree_gparent);
+ __rb_rotate_right(rb_tree_gparent, rb_tree_root);
+ }
+ else
+ {
+ {
+ register struct rb_node *rb_tree_uncle =
+ rb_tree_gparent->rb_left;
+ if (rb_tree_uncle && rb_is_red(rb_tree_uncle))
+ {
+ rb_set_black(rb_tree_uncle);
+ rb_set_black(rb_tree_parent);
+ rb_set_red(rb_tree_gparent);
+ rb_tree_node = rb_tree_gparent;
+ continue;
+ }
+ }
+
+ if (rb_tree_parent->rb_left == rb_tree_node)
+ {
+ register struct rb_node *rb_tree_tmp;
+ __rb_rotate_right(rb_tree_parent, rb_tree_root);
+ rb_tree_tmp = rb_tree_parent;
+ rb_tree_parent = rb_tree_node;
+ rb_tree_node = rb_tree_tmp;
+ }
+
+ rb_set_black(rb_tree_parent);
+ rb_set_red(rb_tree_gparent);
+ __rb_rotate_left(rb_tree_gparent, rb_tree_root);
+ }
+ }
+
+ rb_set_black(rb_tree_root->rb_node);
+}
+
+void rb_erase(struct rb_node *node, struct rb_root *root)
+{
+ struct rb_node *child, *parent;
+ int color;
+
+ if (!node || !root)
+ return;
+
+ if (!node->rb_left)
+ {
+ child = node->rb_right;
+ }
+ else if (!node->rb_right)
+ {
+ child = node->rb_left;
+ }
+ else
+ {
+ struct rb_node *old = node, *left;
+
+ node = node->rb_right;
+ while ((left = node->rb_left) != NULL)
+ {
+ node = left;
+ }
+
+ if (rb_parent(old))
+ {
+ if (rb_parent(old)->rb_left == old)
+ {
+ rb_parent(old)->rb_left = node;
+ }
+ else
+ {
+ rb_parent(old)->rb_right = node;
+ }
+ }
+ else
+ {
+ root->rb_node = node;
+ }
+
+ child = node->rb_right;
+ parent = rb_parent(node);
+ color = rb_color(node);
+
+ if (parent == old)
+ {
+ parent = node;
+ }
+ else
+ {
+ if (child)
+ {
+ rb_set_parent(child, parent);
+ }
+
+ parent->rb_left = child;
+
+ node->rb_right = old->rb_right;
+ rb_set_parent(old->rb_right, node);
+ }
+
+ node->rb_parent_color = old->rb_parent_color;
+ node->rb_left = old->rb_left;
+ rb_set_parent(old->rb_left, node);
+
+ goto color;
+ }
+
+ parent = rb_parent(node);
+ color = rb_color(node);
+
+ if (child)
+ {
+ rb_set_parent(child, parent);
+ }
+
+ if (parent)
+ {
+ if (parent->rb_left == node)
+ {
+ parent->rb_left = child;
+ }
+ else
+ {
+ parent->rb_right = child;
+ }
+ }
+ else
+ {
+ root->rb_node = child;
+ }
+
+ color:
+ if (color == RB_BLACK)
+ {
+ __rb_erase_color(child, parent, root);
+ }
+}
+
+struct rb_node *rb_next(const struct rb_node *node)
+{
+ struct rb_node *parent;
+
+ if (!node)
+ return NULL;
+
+ if (rb_parent(node) == node)
+ {
+ return NULL;
+ }
+
+ if (node->rb_right)
+ {
+ node = node->rb_right;
+ while (node->rb_left)
+ {
+ node = node->rb_left;
+ }
+
+ return (struct rb_node *) node;
+ }
+
+ while ((parent = rb_parent(node)) && (node == parent->rb_right))
+ {
+ node = parent;
+ }
+
+ return parent;
+}
diff --git a/stacks/lwip_stack/lwip_src/common/rb_tree.h b/stacks/lwip_stack/lwip_src/common/rb_tree.h
new file mode 100644
index 0000000..ce156e8
--- /dev/null
+++ b/stacks/lwip_stack/lwip_src/common/rb_tree.h
@@ -0,0 +1,110 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef _UNX_RBTREE_H
+#define _UNX_RBTREE_H
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+extern "C" {
+/* *INDENT-ON* */
+#endif
+#include <stdint.h>
+#include "types.h"
+#include "common_pal_bitwide_adjust.h"
+
+#define rb_parent(a) ((struct rb_node *)((a)->rb_parent_color & ~3))
+#define rb_color(a) ((a)->rb_parent_color & 1)
+
+struct rb_node
+{
+ union
+ {
+ unsigned long rb_parent_color;
+ u64 rb_parent_color_a;
+ };
+
+#define RB_RED 0
+#define RB_BLACK 1
+ union
+ {
+ struct rb_node *rb_right;
+ u64 rb_right_a;
+ };
+
+ union
+ {
+ struct rb_node *rb_left;
+ u64 rb_left_a;
+ };
+};
+
+#define rb_set_red(c) do { (c)->rb_parent_color &= ~1; } while (0)
+#define rb_set_black(c) do { (c)->rb_parent_color |= 1; } while (0)
+
+/* The alignment might seem pointless, but allegedly CRIS needs it */
+
+struct rb_root
+{
+ union
+ {
+ struct rb_node *rb_node;
+ u64 rb_node_a;
+ };
+};
+
+#define rb_is_red(e) (!rb_color(e))
+#define rb_is_black(e) rb_color(e)
+
+static inline void rb_set_color(struct rb_node *rb1, int color2)
+{
+ rb1->rb_parent_color = (rb1->rb_parent_color & ~1) | color2;
+}
+
+static inline void rb_set_parent(struct rb_node *rb1, struct rb_node *pa)
+{
+ rb1->rb_parent_color = (rb1->rb_parent_color & 3) | (unsigned long) pa;
+}
+
+#define RB_ROOT (struct rb_root) { NULL, }
+
+extern void rb_erase(struct rb_node *, struct rb_root *);
+
+extern void rb_insert_color(struct rb_node *, struct rb_root *);
+
+extern struct rb_node *rb_next(const struct rb_node *);
+
+#define rb_entry(ptr, type, member) container_of(ptr, type, member)
+
+#define RB_EMPTY_ROOT(root1) ((root1)->rb_node == NULL)
+#define RB_CLEAR_NODE(node2) (rb_set_parent(node2, node2))
+#define RB_EMPTY_NODE(node1) (rb_parent(node1) == node1)
+
+static inline void
+rb_link_node(struct rb_node *node1, struct rb_node *parent1,
+ struct rb_node **rb_link1)
+{
+ node1->rb_left = node1->rb_right = NULL;
+ node1->rb_parent_color = (unsigned long) parent1;
+ *rb_link1 = node1;
+}
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+}
+/* *INDENT-ON* */
+#endif
+#endif /* _UNX_RBTREE_H */
diff --git a/stacks/lwip_stack/lwip_src/common/spl_def.h b/stacks/lwip_stack/lwip_src/common/spl_def.h
new file mode 100644
index 0000000..06eb5b2
--- /dev/null
+++ b/stacks/lwip_stack/lwip_src/common/spl_def.h
@@ -0,0 +1,138 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef __STACKX_DEF_H__
+#define __STACKX_DEF_H__
+
+/* arch.h might define NULL already */
+//#include "lwip/arch.h"
+#include "spl_opt.h"
+#include "stackx_types.h"
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+extern "C" {
+/* *INDENT-ON* */
+#endif
+
+#define STACKX_MAX(x, y) (((x) > (y)) ? (x) : (y))
+#define STACKX_MIN(x, y) (((x) < (y)) ? (x) : (y))
+
+/* Endianess-optimized shifting of two u8_t to create one u16_t */
+#if BYTE_ORDER == LITTLE_ENDIAN
+#define STACKX_MAKE_U16(a, b) ((a << 8) | b)
+#else
+#define STACKX_MAKE_U16(a, b) ((b << 8) | a)
+#endif
+
+#ifndef STACKX_PLATFORM_BYTESWAP
+#define STACKX_PLATFORM_BYTESWAP 0
+#endif
+
+#ifndef STACKX_PREFIX_BYTEORDER_FUNCS
+
+/* workaround for naming collisions on some platforms */
+
+#ifdef spl_htons
+#undef spl_htons
+#endif /* htons */
+#ifdef spl_htonl
+#undef spl_htonl
+#endif /* spl_htonl */
+#ifdef spl_ntohs
+#undef spl_ntohs
+#endif /* spl_ntohs */
+#ifdef spl_ntohl
+#undef spl_ntohl
+#endif /* spl_ntohl */
+
+#define spl_htons(x) stackx_htons(x)
+#define spl_ntohs(x) stackx_ntohs(x)
+#define spl_htonl(x) stackx_htonl(x)
+#define spl_ntohl(x) stackx_ntohl(x)
+#endif /* STACKX_PREFIX_BYTEORDER_FUNCS */
+
+#if BYTE_ORDER == BIG_ENDIAN
+#define stackx_htons(x) (x)
+#define stackx_ntohs(x) (x)
+#define stackx_htonl(x) (x)
+#define stackx_ntohl(x) (x)
+#define SPL_PP_HTONS(x) (x)
+#define SPL_PP_NTOHS(x) (x)
+#define SPL_PP_HTONL(x) (x)
+#define SPL_PP_NTOHL(x) (x)
+#else /* BYTE_ORDER != BIG_ENDIAN */
+#if STACKX_PLATFORM_BYTESWAP
+#define stackx_htons(x) STACKX_PLATFORM_HTONS(x)
+#define stackx_ntohs(x) STACKX_PLATFORM_HTONS(x)
+#define stackx_htonl(x) STACKX_PLATFORM_HTONL(x)
+#define stackx_ntohl(x) STACKX_PLATFORM_HTONL(x)
+#else /* STACKX_PLATFORM_BYTESWAP */
+ /**
+ * Convert an u16_t from host- to network byte order.
+ *
+ * @param n u16_t in host byte order
+ * @return n in network byte order
+ */
+static inline u16_t stackx_htons(u16_t x)
+{
+ return ((x & 0xff) << 8) | ((x & 0xff00) >> 8);
+}
+
+static inline u16_t stackx_ntohs(u16_t x)
+{
+ return stackx_htons(x);
+}
+
+ /**
+ * Convert an u32_t from host- to network byte order.
+ *
+ * @param n u32_t in host byte order
+ * @return n in network byte order
+ */
+static inline u32_t stackx_htonl(u32_t x)
+{
+ return ((x & 0xff) << 24) |
+ ((x & 0xff00) << 8) |
+ ((x & 0xff0000UL) >> 8) | ((x & 0xff000000UL) >> 24);
+}
+
+static inline u32_t stackx_ntohl(u32_t x)
+{
+ return stackx_htonl(x);
+}
+#endif /* STACKX_PLATFORM_BYTESWAP */
+
+/* These macros should be calculated by the preprocessor and are used
+ with compile-time constants only (so that there is no little-endian
+ overhead at runtime). */
+#define SPL_PP_HTONS(x) ((((x) & 0xff) << 8) | (((x) & 0xff00) >> 8))
+#define SPL_PP_NTOHS(x) SPL_PP_HTONS(x)
+#define SPL_PP_HTONL(x) ((((x) & 0xff) << 24) | \
+ (((x) & 0xff00) << 8) | \
+ (((x) & 0xff0000UL) >> 8) | \
+ (((x) & 0xff000000UL) >> 24))
+#define SPL_PP_NTOHL(x) SPL_PP_HTONL(x)
+
+#endif /* BYTE_ORDER == BIG_ENDIAN */
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+}
+/* *INDENT-ON* */
+#endif
+
+#endif /* __STACKX_DEF_H__ */
diff --git a/stacks/lwip_stack/lwip_src/common/spl_opt.h b/stacks/lwip_stack/lwip_src/common/spl_opt.h
new file mode 100644
index 0000000..98e6466
--- /dev/null
+++ b/stacks/lwip_stack/lwip_src/common/spl_opt.h
@@ -0,0 +1,329 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef __STACKX_OPT_H__
+#define __STACKX_OPT_H__
+
+#include "stackxopts.h"
+#include "stackx_debug.h"
+#include "compiling_check.h"
+
+#define PBUF_VLAN_HLEN 0
+
+//#define SIZEOF_ETH_HDR (14)
+
+#ifndef STACKX_NETIF_API
+#define STACKX_NETIF_API 1
+#endif
+
+/*
+ ------------------------------------
+ ---------- Thread options ----------
+ ------------------------------------
+ */
+
+#define PTIMER_THREAD_NAME "ptimer_thread"
+
+/**
+ * TCPIP_THREAD_NAME: The name assigned to the main tcpip thread.
+ */
+#ifndef TCPIP_THREAD_NAME
+#define TCPIP_THREAD_NAME "spl_tcpip_thread"
+#endif
+
+#ifndef TCPIP_THREAD_STACKSIZE
+#define TCPIP_THREAD_STACKSIZE 0
+#endif
+
+#ifndef INT_MAX
+#define INT_MAX 2147483647
+#endif
+
+#ifndef INT_64_MAX
+#define INT_64_MAX 9223372036854775807
+#endif
+
+#ifndef RECV_BUFSIZE_DEFAULT
+#define RECV_BUFSIZE_DEFAULT INT_MAX
+#endif
+
+/*
+ ----------------------------------------
+ ---------- Statistics options ----------
+ ----------------------------------------
+ */
+
+/*
+ ---------------------------------------
+ ---------- Debugging options ----------
+ ---------------------------------------
+ */
+
+#ifndef STACKX_DBG_TYPES_ON
+#define STACKX_DBG_TYPES_ON STACKX_DBG_ON //ON
+#endif
+
+#ifndef INTERRUPT_DEBUG
+#define INTERRUPT_DEBUG STACKX_DBG_ON //ON
+#endif
+
+#ifndef TESTSOCKET_DEBUG
+#define TESTSOCKET_DEBUG STACKX_DBG_ON //ON
+#endif
+
+#ifndef ETHARP_DEBUG
+#define ETHARP_DEBUG STACKX_DBG_ON
+#endif
+
+#ifndef NETIF_DEBUG
+#define NETIF_DEBUG STACKX_DBG_ON
+#endif
+
+#ifndef PBUF_DEBUG
+#define PBUF_DEBUG STACKX_DBG_ON
+#endif
+
+#ifndef API_LIB_DEBUG
+#define API_LIB_DEBUG STACKX_DBG_ON
+#endif
+
+#ifndef API_MSG_DEBUG
+#define API_MSG_DEBUG STACKX_DBG_ON
+#endif
+
+#ifndef SOCKETS_DEBUG
+#define SOCKETS_DEBUG STACKX_DBG_ON
+#endif
+
+#ifndef NS_EPOLL_DBG
+#define NS_EPOLL_DBG STACKX_DBG_ON
+#endif
+
+#ifndef ICMP_DEBUG
+#define ICMP_DEBUG STACKX_DBG_ON
+#endif
+
+#ifndef IGMP_DEBUG
+#define IGMP_DEBUG STACKX_DBG_ON
+#endif
+
+#ifndef INET_DEBUG
+#define INET_DEBUG STACKX_DBG_ON
+#endif
+
+#ifndef IP_DEBUG
+#define IP_DEBUG STACKX_DBG_ON
+#endif
+
+#ifndef IP_REASS_DEBUG
+#define IP_REASS_DEBUG STACKX_DBG_ON
+#endif
+
+#ifndef RAW_DEBUG
+#define RAW_DEBUG STACKX_DBG_ON
+#endif
+
+#ifndef MEMP_DEBUG
+#define MEMP_DEBUG STACKX_DBG_ON
+#endif
+
+#ifndef SYS_DEBUG
+#define SYS_DEBUG STACKX_DBG_OFF
+#endif
+
+#ifndef TIMERS_DEBUG
+#define TIMERS_DEBUG STACKX_DBG_ON
+#endif
+
+#ifndef TCP_DEBUG
+#define TCP_DEBUG STACKX_DBG_ON
+#endif
+
+#ifndef TCP_TEST_DEBUG
+#define TCP_TEST_DEBUG STACKX_DBG_ON
+#endif
+
+#ifndef TCP_INPUT_DEBUG
+#define TCP_INPUT_DEBUG STACKX_DBG_ON
+#endif
+
+#ifndef TCP_RTO_DEBUG
+#define TCP_RTO_DEBUG STACKX_DBG_ON
+#endif
+
+#ifndef TCP_FR_DEBUG
+#define TCP_FR_DEBUG STACKX_DBG_ON
+#endif
+
+#ifndef TCP_FLOW_CTL_DEBUG
+#define TCP_FLOW_CTL_DEBUG STACKX_DBG_ON
+#endif
+
+#ifndef TCP_CWND_DEBUG
+#define TCP_CWND_DEBUG STACKX_DBG_ON
+#endif
+
+#ifndef TCP_WND_DEBUG
+#define TCP_WND_DEBUG STACKX_DBG_ON
+#endif
+
+#ifndef TCP_OUTPUT_DEBUG
+#define TCP_OUTPUT_DEBUG STACKX_DBG_ON
+#endif
+
+#ifndef TCP_RST_DEBUG
+#define TCP_RST_DEBUG STACKX_DBG_ON
+#endif
+
+#ifndef UDP_DEBUG
+#define UDP_DEBUG STACKX_DBG_ON
+#endif
+
+#ifndef TCPIP_DEBUG
+#define TCPIP_DEBUG STACKX_DBG_ON
+#endif
+
+#ifndef NEW_RING_DEBUG
+#define NEW_RING_DEBUG STACKX_DBG_ON
+#endif
+
+#ifndef PACKET_DISPATCH
+#define PACKET_DISPATCH 1
+#endif
+
+#ifndef NETSTAT_SWITCH
+#define NETSTAT_SWITCH 1
+#endif
+
+#ifndef DISTRIBUTOR_DEBUG
+
+#define DISTRIBUTOR_DEBUG STACKX_DBG_ON
+#endif
+#define PBUF_REF_DEBUG STACKX_DBG_ON
+
+#ifndef CONTEXT_TIMER_DEBUG
+#define CONTEXT_TIMER_DEBUG STACKX_DBG_OFF
+#endif
+
+#if (DISTRIBUTOR_DEBUG == STACKX_DBG_ON)
+#define PD_DISTRIBUTOR_DEBUG
+
+#define DISTRIBUTOR_SINGLE
+#ifdef DISTRIBUTOR_SINGLE
+
+#ifndef __STACKX_DEBUG_H__
+#define STACKX_DBG_OFF 0x80U
+#define STACKX_DBG_ON 0x00U
+#endif
+
+#ifndef ETHARP_DEBUG
+#define ETHARP_DEBUG STACKX_DBG_ON
+#endif
+#ifndef NETIF_DEBUG
+#define NETIF_DEBUG STACKX_DBG_ON
+#endif
+#ifndef PBUF_DEBUG
+#define PBUF_DEBUG STACKX_DBG_ON
+#endif
+#ifndef API_LIB_DEBUG
+#define API_LIB_DEBUG STACKX_DBG_ON
+#endif
+#ifndef API_MSG_DEBUG
+#define API_MSG_DEBUG STACKX_DBG_ON
+#endif
+#ifndef ICMP_DEBUG
+#define ICMP_DEBUG STACKX_DBG_ON
+#endif
+#ifndef IGMP_DEBUG
+#define IGMP_DEBUG STACKX_DBG_ON
+#endif
+#ifndef INET_DEBUG
+#define INET_DEBUG STACKX_DBG_ON
+#endif
+#ifndef IP_DEBUG
+#define IP_DEBUG STACKX_DBG_ON
+#endif
+#ifndef IP_REASS_DEBUG
+#define IP_REASS_DEBUG STACKX_DBG_ON
+#endif
+#ifndef RAW_DEBUG
+#define RAW_DEBUG STACKX_DBG_ON
+#endif
+#ifndef MEMP_DEBUG
+#define MEMP_DEBUG STACKX_DBG_ON
+#endif
+#ifndef SYS_DEBUG
+#define SYS_DEBUG STACKX_DBG_ON
+#endif
+#ifndef TIMERS_DEBUG
+#define TIMERS_DEBUG STACKX_DBG_ON
+#endif
+#ifndef TCP_DEBUG
+#define TCP_DEBUG STACKX_DBG_ON
+#endif
+#ifndef TCP_TEST_DEBUG
+#define TCP_TEST_DEBUG STACKX_DBG_ON
+#endif
+#ifndef TCP_INPUT_DEBUG
+#define TCP_INPUT_DEBUG STACKX_DBG_ON
+#endif
+#ifndef TCP_FR_DEBUG
+#define TCP_FR_DEBUG STACKX_DBG_ON
+#endif
+#ifndef TCP_RTO_DEBUG
+#define TCP_RTO_DEBUG STACKX_DBG_ON
+#endif
+#ifndef TCP_CWND_DEBUG
+#define TCP_CWND_DEBUG STACKX_DBG_ON
+#endif
+#ifndef TCP_WND_DEBUG
+#define TCP_WND_DEBUG STACKX_DBG_ON
+#endif
+#ifndef TCP_OUTPUT_DEBUG
+#define TCP_OUTPUT_DEBUG STACKX_DBG_ON
+#endif
+#ifndef TCP_RST_DEBUG
+#define TCP_RST_DEBUG STACKX_DBG_ON
+#endif
+#ifndef UDP_DEBUG
+#define UDP_DEBUG STACKX_DBG_ON
+#endif
+#ifndef TCPIP_DEBUG
+#define TCPIP_DEBUG STACKX_DBG_ON
+#endif
+
+#define SC_DPDK_INFO STACKX_DBG_ON
+#define SOCK_INFO STACKX_DBG_ON
+#ifndef STACKX_DBG_OFF
+#define STACKX_DBG_OFF 0x00U
+#endif
+
+#ifndef NS_EPOLL_DBG
+#define NS_EPOLL_DBG STACKX_DBG_ON
+#endif
+
+#ifndef DFX_DBG
+#define DFX_DBG STACKX_DBG_ON
+#endif
+
+#endif
+#endif /* DISTRIBUTOR_DEBUG */
+
+#ifndef STACKX_FLOW_CTL
+#define STACKX_FLOW_CTL 0
+#endif
+
+#endif /* __STACKX_OPT_H__ */
diff --git a/stacks/lwip_stack/lwip_src/common/spl_rti.c b/stacks/lwip_stack/lwip_src/common/spl_rti.c
new file mode 100644
index 0000000..d15d25f
--- /dev/null
+++ b/stacks/lwip_stack/lwip_src/common/spl_rti.c
@@ -0,0 +1,91 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#include <stdlib.h>
+#include "types.h"
+#include "nstack_securec.h"
+#include "nsfw_init_api.h"
+#include "nstack_log.h"
+#include "nsfw_maintain_api.h"
+#include "nsfw_mem_api.h"
+#include "nsfw_rti.h"
+#include "nsfw_msg.h"
+#ifdef HAL_LIB
+#else
+#include "common_pal_bitwide_adjust.h"
+#endif
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+extern "C"{
+/* *INDENT-ON* */
+#endif /* __cplusplus */
+
+char g_dfx_switch = 1;
+
+struct rti_queue *g_nsfw_rti_primary_stat = NULL;
+
+void nsfw_rti_stat(nsfw_rti_stat_type_t statType, const data_com_msg * m)
+{
+ if (!g_nsfw_rti_primary_stat || !m)
+ {
+ return;
+ }
+
+ struct rti_queue *primary_stat = ADDR_SHTOL(g_nsfw_rti_primary_stat);
+
+ switch (statType)
+ {
+ case NSFW_STAT_PRIMARY_DEQ:
+ if ((m->param.major_type >= MAX_MAJOR_TYPE)
+ || (m->param.minor_type >= MAX_MINOR_TYPE))
+ {
+ return;
+ }
+ /*call_msg_fun() is only called in nStackMain, no reentrance risk, ++ operation is ok */
+ primary_stat->tcpip_msg_deq[m->param.major_type]++;
+ if (0 == m->param.major_type) //SPL_TCPIP_NEW_MSG_API
+ {
+ primary_stat->api_msg_deq[m->param.minor_type]++;
+ }
+ break;
+ case NSFW_STAT_PRIMARY_ENQ_FAIL:
+ if ((m->param.major_type >= MAX_MAJOR_TYPE)
+ || (m->param.minor_type >= MAX_MINOR_TYPE))
+ {
+ return;
+ }
+ __sync_fetch_and_add(&primary_stat->tcpip_msg_enq_fail
+ [m->param.major_type], 1);
+ if (0 == m->param.major_type) //SPL_TCPIP_NEW_MSG_API
+ {
+ __sync_fetch_and_add(&primary_stat->api_msg_enq_fail
+ [m->param.minor_type], 1);
+ }
+ break;
+ case NSFW_STAT_PRIMARY_ENQ:
+ //not use
+ break;
+ default:
+ break;
+ }
+}
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+}
+/* *INDENT-ON* */
+#endif /* __cplusplus */
diff --git a/stacks/lwip_stack/lwip_src/common/stackx_app_res.c b/stacks/lwip_stack/lwip_src/common/stackx_app_res.c
new file mode 100644
index 0000000..84c1451
--- /dev/null
+++ b/stacks/lwip_stack/lwip_src/common/stackx_app_res.c
@@ -0,0 +1,951 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#include "stackx_app_res.h"
+#include "nstack_securec.h"
+#include "common_pal_bitwide_adjust.h"
+#include "nstack_log.h"
+#include "stackx_common.h"
+#include "nsfw_maintain_api.h"
+#include "stackx_tx_box.h"
+#include "nsfw_msg_api.h"
+#include "nsfw_recycle_api.h"
+#include "common_mem_mbuf.h"
+#include "stackx_pbuf.h"
+#include "nsfw_mt_config.h"
+#include "nsfw_mem_api.h"
+#include "spl_opt.h"
+#include "nsfw_shmem_mng.h"
+#define SPL_MAX_MSG_NUM (MBOX_RING_SIZE*8*MAX_THREAD_NUM)
+
+spl_app_res_group *g_spl_app_res_group = NULL;
+
+spl_app_res_group_array *g_res_group_array = NULL;
+
+#ifdef SYS_MEM_RES_STAT
+mpool_handle g_app_tx_pool[SBR_TX_POOL_NUM];
+#endif
+
+/***************************************************
+* description:
+***************************************************/
+int spl_init_group_array()
+{
+ g_res_group_array =
+ (spl_app_res_group_array *) sbr_create_mzone(SPL_RES_GROUP_ARRAY,
+ sizeof
+ (spl_app_res_group_array));
+ if (!g_res_group_array)
+ {
+ NSPOL_LOGERR("create g_res_group_array failed");
+ return -1;
+ }
+
+ u32 i;
+ for (i = 0; i < SBR_TX_POOL_NUM; ++i)
+ {
+ g_res_group_array->pid_array[i] = 0;
+ }
+
+ for (i = 0; i < MAX_THREAD_NUM; ++i)
+ {
+ g_res_group_array->res_group[i] = NULL;
+ }
+
+ g_res_group_array->thread_num = 0;
+ return 0;
+}
+
+/***************************************************
+* description:
+***************************************************/
+int sbr_attach_group_array()
+{
+ g_res_group_array =
+ (spl_app_res_group_array *) sbr_lookup_mzone(SPL_RES_GROUP_ARRAY);
+ if (!g_res_group_array)
+ {
+ NSPOL_LOGERR("attach g_res_group_array failed");
+ return -1;
+ }
+
+ return 0;
+}
+
+/***************************************************
+* description:
+***************************************************/
+int spl_add_instance_res_group(u32 thread_index, spl_app_res_group * group)
+{
+ if (thread_index >= MAX_THREAD_NUM)
+ {
+ NSPOL_LOGERR
+ ("thread_index >= MAX_THREAD_NUM]thread_index=%u, MAX_THREAD_NUM=%u",
+ thread_index, MAX_THREAD_NUM);
+ return -1;
+ }
+
+ if (g_res_group_array->res_group[thread_index] != NULL)
+ {
+ NSPOL_LOGERR
+ ("g_res_group_array in thread_index is not NULL, this can not happen");
+ return -1;
+ }
+
+ g_res_group_array->res_group[thread_index] = group;
+ __sync_add_and_fetch(&g_res_group_array->thread_num, 1);
+ return 0;
+}
+
+/***************************************************
+* description:
+***************************************************/
+int spl_add_mbox(mring_handle mbox_array[], u32 array_size)
+{
+ if (array_size != SPL_MSG_BOX_NUM)
+ {
+ NSPOL_LOGERR("array_size must be %u, but not", SPL_MSG_BOX_NUM);
+ return -1;
+ }
+
+ u32 i;
+ for (i = 0; i < array_size; ++i)
+ {
+ g_spl_app_res_group->mbox_array[i] = mbox_array[i];
+ }
+
+ return 0;
+}
+
+/*****************************************************************************
+* Prototype : spl_create_group
+* Description : create group
+* Input : None
+* Output : None
+* Return Value : int
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+spl_app_res_group *spl_create_group()
+{
+ spl_app_res_group *group =
+ (spl_app_res_group *) sbr_create_mzone(SPL_APP_RES_GROUP_NAME,
+ sizeof(spl_app_res_group));
+ if (!group)
+ {
+ NSPOL_LOGERR("Create app_res_group zone fail]name=%s, size=%u",
+ SPL_APP_RES_GROUP_NAME, sizeof(spl_app_res_group));
+ return NULL;
+ }
+
+ group->msg_pool = NULL;
+ group->conn_pool = NULL;
+ group->conn_array = NULL;
+ group->recv_ring_pool = NULL;
+
+ u32 i;
+ for (i = 0; i < SBR_TX_POOL_NUM; ++i)
+ {
+ group->tx_pool_array[i] = NULL;
+ }
+
+ for (i = 0; i < SPL_MSG_BOX_NUM; ++i)
+ {
+ group->mbox_array[i] = NULL;
+ }
+
+ group->extend_member_bit = 0;
+
+ NSPOL_LOGINF(SC_DPDK_INFO,
+ "Create app_res_group zone ok]name=%s, size=%u",
+ SPL_APP_RES_GROUP_NAME, sizeof(spl_app_res_group));
+ MEM_STAT(SPL_APP_RES, SPL_APP_RES_GROUP_NAME, NSFW_SHMEM,
+ sizeof(spl_app_res_group));
+ return group;
+}
+
+/*****************************************************************************
+* Prototype : _spl_create_ring_pool
+* Description : create ring pool
+* Input : char* pool_name
+* char* array_name
+* nsfw_mpool_type type
+* Output : None
+* Return Value : static inline mring_handle
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+static inline mring_handle
+_spl_create_ring_pool(char *pool_name, char *array_name,
+ nsfw_mpool_type type, u32 num, u32 ring_size)
+{
+ mring_handle pool = sbr_create_ring(pool_name, num - 1);
+
+ if (!pool)
+ {
+ return NULL;
+ }
+
+ NSPOL_LOGINF(SC_DPDK_INFO, "Create ring pool ok]name=%s, num=%u, size=%d",
+ pool_name, num, nsfw_mem_get_len(pool, NSFW_MEM_RING));
+ MEM_STAT(SPL_APP_RES, pool_name, NSFW_SHMEM,
+ nsfw_mem_get_len(pool, NSFW_MEM_RING));
+
+ mring_handle *array = malloc(num * sizeof(mring_handle));
+ if (!array)
+ {
+ NSPOL_LOGERR("malloc fail]size=%u", num * sizeof(mring_handle));
+ return NULL;
+ }
+
+ if (sbr_create_multi_ring(array_name, ring_size - 1, num,
+ array, type) != 0)
+ {
+ free(array);
+ return NULL;
+ }
+
+ NSPOL_LOGINF(SC_DPDK_INFO,
+ "Create multi rings ok]name=%s, ring_size=%u, ring_num=%u, total_mem=%d",
+ array_name, ring_size, num,
+ (nsfw_mem_get_len(array[0], NSFW_MEM_RING) * num));
+ MEM_STAT(SPL_APP_RES, array_name, NSFW_SHMEM,
+ nsfw_mem_get_len(array[0], NSFW_MEM_RING) * num);
+
+ unsigned int i = 0;
+ while (i < num)
+ {
+ if (nsfw_mem_ring_enqueue(pool, (void *) array[i]) != 1)
+ {
+ NSPOL_LOGERR("nsfw_mem_ring_enqueue failed,this can not happen");
+ free(array);
+ return NULL;
+ }
+
+ i++;
+ }
+
+ free(array);
+ return pool;
+}
+
+/*****************************************************************************
+* Prototype : spl_create_ring_pool
+* Description : create ring pool
+* Input : None
+* Output : None
+* Return Value : int
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+int spl_create_ring_pool(spl_app_res_group * group)
+{
+ group->recv_ring_pool =
+ _spl_create_ring_pool(SPL_RECV_RING_POOL_NAME,
+ SPL_RECV_RING_ARRAY_NAME, NSFW_MRING_SPSC,
+ CUR_CFG_SOCKET_NUM, SPL_MAX_RING_SIZE);
+ if (!group->recv_ring_pool)
+ {
+ NSPOL_LOGERR("Create recv ring pool failed");
+ return -1;
+ }
+
+ NSPOL_LOGINF(SC_DPDK_INFO, "Create recv ring pool ok]name=%s",
+ SPL_RECV_RING_POOL_NAME);
+ return 0;
+}
+
+int spl_force_netconn_free(void *data)
+{
+ spl_netconn_t *conn = (spl_netconn_t *) data;
+ if (TRUE == conn->res_chk.alloc_flag)
+ {
+ if (NULL != conn->recycle.accept_from)
+ {
+ return FALSE;
+ }
+
+ if (TRUE != nsfw_pidinfo_empty(&conn->recycle.pid_info))
+ {
+ return FALSE;
+ }
+ }
+ ss_reset_conn(conn);
+ (void) res_free(&conn->res_chk);
+
+ if (nsfw_mem_ring_enqueue(ss_get_conn_pool(conn), (void *) conn) != 1)
+ {
+ NSSBR_LOGERR("nsfw_mem_ring_enqueue failed,this can not happen");
+ }
+ NSFW_LOGINF("force free conn]conn=%p", conn);
+ return TRUE;
+}
+
+/*****************************************************************************
+* Prototype : spl_create_netconn_pool
+* Description : create netconn pool
+* Input : None
+* Output : None
+* Return Value : int
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+int spl_create_netconn_pool(spl_app_res_group * group)
+{
+ spl_netconn_t **conn_array =
+ (spl_netconn_t **) sbr_create_mzone(SPL_CONN_ARRAY_NAME,
+ sizeof(spl_netconn_t *) *
+ CUR_CFG_SOCKET_NUM);
+
+ if (!conn_array)
+ {
+ return -1;
+ }
+
+ NSPOL_LOGINF(SC_DPDK_INFO, "Create connn_array zone ok]name=%s, size=%zu",
+ SPL_CONN_ARRAY_NAME,
+ sizeof(spl_netconn_t *) * CUR_CFG_SOCKET_NUM);
+ mring_handle pool =
+ sbr_create_pool(SPL_CONN_POOL_NAME, CUR_CFG_SOCKET_NUM - 1,
+ SBR_FD_NETCONN_SIZE);
+
+ if (!pool)
+ {
+ return -1;
+ }
+
+ NSPOL_LOGINF(SC_DPDK_INFO,
+ "Create conn_pool ok]name=%s, num=%u, total_mem=%d",
+ SPL_CONN_POOL_NAME, CUR_CFG_SOCKET_NUM,
+ nsfw_mem_get_len(pool, NSFW_MEM_SPOOL));
+
+ sbr_recycle_group *recycle_group =
+ (sbr_recycle_group *) sbr_create_mzone(SPL_RECYCLE_GROUP,
+ sizeof(sbr_recycle_group));
+ if (!recycle_group)
+ {
+ return -1;
+ }
+
+ NSPOL_LOGINF(SC_DPDK_INFO,
+ "Create recycle_group zone ok]name=%s, size=%u",
+ SPL_RECYCLE_GROUP, sizeof(sbr_recycle_group));
+
+ recycle_group->conn_array = conn_array;
+ recycle_group->conn_num = spl_get_conn_num();
+ recycle_group->conn_pool = pool;
+ recycle_group->extend_member_bit = 0;
+ recycle_group->msg_pool = group->msg_pool;
+
+ spl_netconn_t *conn = NULL;
+ unsigned int i = 0;
+ while (i < CUR_CFG_SOCKET_NUM)
+ {
+ if (nsfw_mem_ring_dequeue(pool, (void **) &conn) != 1)
+ {
+ NSPOL_LOGERR("nsfw_mem_ring_dequeue failed,this can not happen");
+ return -1;
+ }
+
+ ss_reset_conn(conn);
+ conn->recycle.group = recycle_group;
+
+ if (nsfw_mem_ring_dequeue(group->recv_ring_pool, &conn->recv_ring) !=
+ 1)
+ {
+ NSPOL_LOGERR("nsfw_mem_ring_dequeue failed,this can not happen");
+ return -1;
+ }
+
+ conn_array[i] = conn;
+
+ if (nsfw_mem_ring_enqueue(pool, (void *) conn) != 1)
+ {
+ NSPOL_LOGERR("nsfw_mem_ring_enqueue failed,this can not happen");
+ return -1;
+ }
+
+ i++;
+ }
+
+ group->conn_pool = pool;
+ group->conn_array = conn_array;
+
+ MEM_STAT(SPL_APP_RES, SPL_RECYCLE_GROUP, NSFW_SHMEM,
+ sizeof(sbr_recycle_group));
+ MEM_STAT(SPL_APP_RES, SPL_CONN_ARRAY_NAME, NSFW_SHMEM,
+ sizeof(spl_netconn_t *) * CUR_CFG_SOCKET_NUM);
+ MEM_STAT(SPL_APP_RES, SPL_CONN_POOL_NAME, NSFW_SHMEM,
+ nsfw_mem_get_len(group->conn_pool, NSFW_MEM_SPOOL));
+ return 0;
+}
+
+int spl_force_msg_free(void *data)
+{
+ data_com_msg *m = (data_com_msg *) data;
+ if (NULL == m)
+ {
+ return FALSE;
+ }
+
+ NSFW_LOGINF("force free msg]msg=%p", data);
+ (void) res_free(&m->param.res_chk);
+ m->param.recycle_pid = 0;
+ if (nsfw_mem_ring_enqueue(m->param.msg_from, (void *) m) != 1)
+ {
+ NSFW_LOGERR("nsfw_mem_ring_enqueue failed,this can not happen");
+ }
+ return TRUE;
+}
+
+/*****************************************************************************
+* Prototype : spl_create_msg_pool
+* Description : create msg pool
+* Input : None
+* Output : None
+* Return Value : int
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+int spl_create_msg_pool(spl_app_res_group * group)
+{
+ mring_handle pool =
+ sbr_create_pool(SPL_MSG_POOL_NAME, SPL_MAX_MSG_NUM - 1, MAX_MSG_SIZE);
+
+ if (!pool)
+ {
+ return -1;
+ }
+
+ data_com_msg *m = NULL;
+ unsigned int i = 0;
+ while (i < SPL_MAX_MSG_NUM)
+ {
+ if (nsfw_mem_ring_dequeue(pool, (void **) &m) != 1)
+ {
+ NSPOL_LOGERR("nsfw_mem_ring_dequeue failed,this can not happen");
+ return -1;
+ }
+
+ m->param.msg_from = pool;
+ m->param.recycle_pid = 0;
+ sys_sem_init(&m->param.op_completed);
+
+ if (nsfw_mem_ring_enqueue(pool, (void *) m) != 1)
+ {
+ NSPOL_LOGERR("nsfw_mem_ring_enqueue failed,this can not happen");
+ return -1;
+ }
+
+ i++;
+ }
+
+ group->msg_pool = pool;
+
+ NSPOL_LOGINF(SC_DPDK_INFO,
+ "Create app msg pool ok]name=%s, num=%u, size=%u, total_mem=%d",
+ SPL_MSG_POOL_NAME, SPL_MAX_MSG_NUM, MAX_MSG_SIZE,
+ nsfw_mem_get_len(group->msg_pool, NSFW_MEM_SPOOL));
+ MEM_STAT(SPL_APP_RES, SPL_MSG_POOL_NAME, NSFW_SHMEM,
+ nsfw_mem_get_len(group->msg_pool, NSFW_MEM_SPOOL));
+ return 0;
+}
+
+/*****************************************************************************
+* Prototype : spl_regist_recycle
+* Description : regist recycle
+* Input : None
+* Output : None
+* Return Value : int
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+int spl_regist_recycle(spl_app_res_group * group)
+{
+ void *ret =
+ nsfw_recycle_reg_obj(NSFW_REC_PRO_DEFALUT, NSFW_REC_SBR_SOCKET, NULL);
+
+ if (!ret)
+ {
+ NSSBR_LOGERR("failed");
+ return -1;
+ }
+
+ if (NULL == group)
+ {
+ NSSBR_LOGERR("g_spl_app_res_group null");
+ return -1;
+ }
+
+ nsfw_res_scn_cfg scn_cfg = { NSFW_RES_SCAN_SPOOL, 90, 3, 16,
+ CUR_CFG_SOCKET_NUM / 128, CUR_CFG_SOCKET_NUM - 1,
+ SBR_FD_NETCONN_SIZE,
+ offsetof(spl_netconn_t, res_chk),
+ (void *) group->conn_pool,
+ (void *) group->conn_pool,
+ spl_force_netconn_free
+ };
+
+ (void) nsfw_res_mgr_reg(&scn_cfg);
+
+ nsfw_res_scn_cfg scn_cfg_msg = { NSFW_RES_SCAN_SPOOL, 60, 3, 16,
+ SPL_MAX_MSG_NUM / 128, SPL_MAX_MSG_NUM,
+ MAX_MSG_SIZE,
+ offsetof(data_com_msg, param.res_chk),
+ (void *) group->msg_pool,
+ (void *) group->msg_pool,
+ spl_force_msg_free
+ };
+ (void) nsfw_res_mgr_reg(&scn_cfg_msg);
+
+ return 0;
+}
+
+void spl_reg_tx_pool_mgr(mpool_handle pool_array[], u32 num)
+{
+ u32 loop;
+ for (loop = 0; loop < num; loop++)
+ {
+ (void) spl_reg_res_txrx_mgr(pool_array[loop]); // will only return 0, no need to check return value
+ }
+
+ return;
+}
+
+/*****************************************************************************
+* Prototype : sbr_create_tx_pool
+* Description : create tx pool,spl call this fun
+* Input : None
+* Output : None
+* Return Value : int
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+int spl_create_tx_pool(mpool_handle pool_array[], u32 array_size)
+{
+ data_com_msg *tx_msg_array =
+ (data_com_msg *) sbr_create_mzone(SBR_TX_MSG_ARRAY_NAME,
+ (size_t) sizeof(data_com_msg) *
+ SBR_TX_MSG_NUM);
+
+ if (!tx_msg_array)
+ {
+ NSSBR_LOGERR("Create tx_msg_array zone fail]name=%s, num=%u, size=%u",
+ SBR_TX_MSG_ARRAY_NAME, SBR_TX_MSG_NUM,
+ (size_t) sizeof(data_com_msg) * SBR_TX_MSG_NUM);
+ return -1;
+ }
+
+ MEM_STAT(SBR_TX_POOL_NAME, SBR_TX_MSG_ARRAY_NAME, NSFW_SHMEM,
+ (size_t) sizeof(data_com_msg) * SBR_TX_MSG_NUM);
+ NSSBR_LOGINF
+ ("Create tx_msg_array zone ok]name=%s, ptr=%p, num=%u, size=%u",
+ SBR_TX_MSG_ARRAY_NAME, tx_msg_array, SBR_TX_MSG_NUM,
+ sizeof(data_com_msg) * SBR_TX_MSG_NUM);
+
+ mpool_handle mp;
+ int ret;
+ char tx_pool_name[64];
+ u32 loop;
+ for (loop = 0; loop < array_size; loop++)
+ {
+ ret =
+ sprintf_s(tx_pool_name, sizeof(tx_pool_name), "%s_%d",
+ SBR_TX_POOL_NAME, loop);
+ if (-1 == ret)
+ {
+ NSSBR_LOGERR("SPRINTF_S failed]ret=%d", ret);
+ return -1;
+ }
+
+ nsfw_mem_mbfpool pool_param;
+ if (strcpy_s
+ (pool_param.stname.aname, NSFW_MEM_NAME_LENTH, tx_pool_name) != 0)
+ {
+ NSSBR_LOGERR("STRCPY_S failed]name=%s", tx_pool_name);
+ return -1;
+ }
+
+ pool_param.isocket_id = -1;
+ pool_param.stname.entype = NSFW_SHMEM;
+ pool_param.enmptype = NSFW_MRING_MPMC;
+ pool_param.uscash_size = 0;
+ pool_param.uspriv_size = 0;
+ pool_param.usdata_room = TX_MBUF_MAX_LEN;
+ pool_param.usnum = SBR_TX_POOL_MBUF_NUM - 1;
+
+ mp = nsfw_mem_mbfmp_create(&pool_param);
+ if (!mp)
+ {
+ NSSBR_LOGERR("Create tx_mbuf_pool fail]name=%s, num=%u, room=%u",
+ tx_pool_name, SBR_TX_POOL_MBUF_NUM,
+ pool_param.usdata_room);
+ return -1;
+ }
+ else
+ {
+ struct common_mem_mbuf *mbuf = NULL;
+ struct spl_pbuf *buf = NULL;
+ int i = 0;
+ while (i < (int) SBR_TX_POOL_MBUF_NUM)
+ {
+ mbuf = nsfw_shmem_mbfalloc(mp);
+ if (!mbuf)
+ {
+ NSSBR_LOGERR
+ ("nsfw_mem_mbf_alloc failed,this can not happen");
+ return -1;
+ }
+
+ buf =
+ (struct spl_pbuf *) ((char *) mbuf +
+ sizeof(struct common_mem_mbuf));
+ int idx = loop * (int) SBR_TX_POOL_MBUF_NUM + i;
+ sys_sem_init(&tx_msg_array[idx].param.op_completed);
+ tx_msg_array[idx].param.msg_from = NULL;
+ buf->msg = (void *) &tx_msg_array[idx];
+ (void) res_free(&buf->res_chk); //no need to check return value, as it will do free operation depends on alloc_flag
+
+ if (nsfw_shmem_mbffree(mbuf) < 0)
+ {
+ NSSBR_LOGERR
+ ("nsfw_mem_mbf_free failed,this can not happen");
+ return -1;
+ }
+
+ i++;
+ }
+
+ pool_array[loop] = mp;
+#ifdef SYS_MEM_RES_STAT
+ g_app_tx_pool[loop] = mp;
+#endif
+ }
+ }
+
+ spl_reg_tx_pool_mgr(pool_array, array_size);
+
+ NSSBR_LOGINF("Create all tx_mbuf_pool ok]pool_num=%d, total_mem=%d",
+ array_size, nsfw_mem_get_len(pool_array[0],
+ NSFW_MEM_MBUF) * array_size);
+ MEM_STAT(SBR_TX_POOL_NAME, SBR_TX_POOL_NAME, NSFW_SHMEM,
+ nsfw_mem_get_len(pool_array[0], NSFW_MEM_MBUF) * array_size);
+ return 0;
+}
+
+spl_app_res_group *spl_create_res_group()
+{
+ spl_app_res_group *group = spl_create_group();
+ if (NULL == group)
+ {
+ NSPOL_LOGERR("spl_create_group failed");
+ return NULL;
+ }
+
+ NSPOL_LOGDBG(SC_DPDK_INFO, "spl_create_group ok");
+
+ if (spl_create_ring_pool(group) != 0)
+ {
+ NSPOL_LOGERR("spl_create_ring_pool failed");
+ return NULL;
+ }
+
+ NSPOL_LOGDBG(SC_DPDK_INFO, "spl_create_ring_pool ok");
+
+ if (spl_create_msg_pool(group) != 0)
+ {
+ NSPOL_LOGERR("spl_create_msg_pool failed");
+ return NULL;
+ }
+
+ NSPOL_LOGDBG(SC_DPDK_INFO, "spl_create_msg_pool ok");
+
+ if (spl_create_netconn_pool(group) != 0)
+ {
+ NSPOL_LOGERR("spl_create_netconn_pool failed");
+ return NULL;
+ }
+
+ NSPOL_LOGDBG(SC_DPDK_INFO, "spl_create_netconn_pool ok");
+
+ if (spl_regist_recycle(group) != 0)
+ {
+ NSPOL_LOGERR("spl_regist_recycle failed");
+ return NULL;
+ }
+
+ NSPOL_LOGDBG(SC_DPDK_INFO, "spl_regist_recycle ok");
+
+ if (spl_create_tx_pool(group->tx_pool_array, SBR_TX_POOL_NUM) != 0)
+ {
+ NSPOL_LOGERR("spl_create_tx_pool failed");
+ return NULL;
+ }
+
+ NSPOL_LOGDBG(SC_DPDK_INFO, "spl_create_tx_pool ok");
+
+ return group;
+}
+
+/*****************************************************************************
+* Prototype : spl_init_app_res
+* Description : init app res
+* Input : None
+* Output : None
+* Return Value : int
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+int spl_init_app_res()
+{
+ g_spl_app_res_group = spl_create_res_group();
+ if (NULL == g_spl_app_res_group)
+ {
+ NSPOL_LOGERR("spl_create_group failed");
+ return -1;
+ }
+
+ return spl_add_instance_res_group(0, g_spl_app_res_group);
+}
+
+/*****************************************************************************
+* Prototype : spl_get_conn_array
+* Description : get conn array
+* Input : u32 pid
+* Output : None
+* Return Value : spl_netconn_t**
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+spl_netconn_t **spl_get_conn_array(u32 pid)
+{
+ return (spl_netconn_t **) ADDR_SHTOL(g_spl_app_res_group->conn_array);
+}
+
+/*****************************************************************************
+* Prototype : spl_get_conn_pool
+* Description : get conn pool
+* Input : None
+* Output : None
+* Return Value : mring_handle
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+mring_handle spl_get_conn_pool()
+{
+ return (mring_handle) ADDR_SHTOL(g_spl_app_res_group->conn_pool);
+}
+
+/*****************************************************************************
+* Prototype : spl_get_msg_pool
+* Description : get msg pool
+* Input : None
+* Output : None
+* Return Value : mring_handle
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+mring_handle spl_get_msg_pool()
+{
+ return (mring_handle) ADDR_SHTOL(g_spl_app_res_group->msg_pool);
+}
+
+/*****************************************************************************
+* Prototype : spl_recycle_msg
+* Description : recycle msg
+* Input : void *data
+* void* argv
+* Output : None
+* Return Value : static int
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+static int spl_recycle_msg(void *data, void *argv)
+{
+ if (!data)
+ {
+ NSPOL_LOGERR("data is NULL]data=%p,pid=%p", data, argv);
+ return -1;
+ }
+
+ data_com_msg *m = (data_com_msg *) data;
+ u64 pid_64 = (u64) argv;
+ u32 pid = (u32) pid_64;
+ if (pid == m->param.recycle_pid)
+ {
+ ASYNC_MSG_FREE(m);
+ }
+
+ return 0;
+}
+
+/*****************************************************************************
+* Prototype : spl_recycle_msg_pool
+* Description : recycle msg pool
+* Input : u32 pid
+* Output : None
+* Return Value : void
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+void spl_recycle_msg_pool(u32 pid)
+{
+ mring_handle msg_pool = spl_get_msg_pool();
+ if (!msg_pool)
+ {
+ NSPOL_LOGERR("msg_pool is NULL,this can not happen]pid=%u", pid);
+ return;
+ }
+
+ u64 pid_64 = pid;
+ (void) nsfw_mem_sp_iterator(msg_pool, 0, SPL_MAX_MSG_NUM, spl_recycle_msg,
+ (void *) pid_64);
+}
+
+/*****************************************************************************
+* Prototype : spl_get_conn_num
+* Description : get conn num
+* Input : None
+* Output : None
+* Return Value : u32
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+u32 spl_get_conn_num()
+{
+ return CUR_CFG_SOCKET_NUM;
+}
+
+/***************************************************
+* description:
+***************************************************/
+int sbr_malloc_tx_pool(u32 pid, mpool_handle pool[], u32 pool_num)
+{
+ int loop;
+ for (loop = 0; loop < SBR_TX_POOL_NUM; loop++)
+ {
+ if ((0 == g_res_group_array->pid_array[loop])
+ &&
+ __sync_bool_compare_and_swap(&g_res_group_array->pid_array[loop],
+ 0, pid))
+ {
+ u32 i;
+ for (i = 0; i < g_res_group_array->thread_num && i < pool_num;
+ ++i)
+ {
+ spl_app_res_group *group =
+ (spl_app_res_group *)
+ ADDR_SHTOL(g_res_group_array->res_group[i]);
+ pool[i] = ADDR_SHTOL(group->tx_pool_array[loop]);
+ }
+
+ NSSBR_LOGINF("get tx pool]pid=%d,loop=%d.", pid, loop);
+ return 0;
+ }
+ }
+
+ for (loop = 0; loop < SBR_TX_POOL_NUM; loop++)
+ {
+ NSSBR_LOGERR("no free pool]loop=%d,pid=%d", loop,
+ g_res_group_array->pid_array[loop]);
+ }
+
+ return -1;
+}
+
+/***************************************************
+* description:
+***************************************************/
+void spl_free_tx_pool(u32 pid)
+{
+ int loop;
+ for (loop = 0; loop < SBR_TX_POOL_NUM; loop++)
+ {
+ if (pid == g_res_group_array->pid_array[loop])
+ {
+ u32 i;
+ for (i = 0; i < g_res_group_array->thread_num; ++i)
+ {
+ (void)
+ nsfw_shmem_mbuf_recycle(g_res_group_array->res_group
+ [i]->tx_pool_array[loop]);
+ }
+
+ if (!__sync_bool_compare_and_swap
+ (&g_res_group_array->pid_array[loop], pid, 0))
+ {
+ NSSBR_LOGERR("free tx_pool failed]loop=%d,pid=%d", loop, pid);
+ }
+ else
+ {
+ NSSBR_LOGDBG("free tx_pool ok]loop=%d,pid=%d", loop, pid);
+ }
+
+ break;
+ }
+ }
+}
+
+/***************************************************
+* description:
+***************************************************/
+mring_handle sbr_get_instance_conn_pool(u32 thread_index)
+{
+ if (thread_index >= g_res_group_array->thread_num)
+ {
+ return NULL;
+ }
+
+ spl_app_res_group *group =
+ (spl_app_res_group *)
+ ADDR_SHTOL(g_res_group_array->res_group[thread_index]);
+ return ADDR_SHTOL(group->conn_pool);
+}
+
+/***************************************************
+* description:
+***************************************************/
+mring_handle *ss_get_instance_msg_box(u16 thread_index, u16 idx)
+{
+ if (thread_index >= g_res_group_array->thread_num)
+ {
+ thread_index = 0;
+ }
+
+ if (idx >= SPL_MSG_BOX_NUM)
+ {
+ idx = 0;
+ }
+
+ spl_app_res_group *group =
+ (spl_app_res_group *)
+ ADDR_SHTOL(g_res_group_array->res_group[thread_index]);
+ return ADDR_SHTOL(group->mbox_array[idx]);
+}
diff --git a/stacks/lwip_stack/lwip_src/common/stackx_app_res.h b/stacks/lwip_stack/lwip_src/common/stackx_app_res.h
new file mode 100644
index 0000000..776edb4
--- /dev/null
+++ b/stacks/lwip_stack/lwip_src/common/stackx_app_res.h
@@ -0,0 +1,103 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef STACKX_APP_RES_H
+#define STACKX_APP_RES_H
+#include "types.h"
+#include "nsfw_mem_api.h"
+#include "stackxopts.h"
+#include "stackx_spl_share.h"
+#include "nsfw_mt_config.h"
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+extern "C" {
+/* *INDENT-ON* */
+#endif
+
+#define SPL_RES_GROUP_ARRAY "spl_res_group_array"
+
+#define SPL_APP_RES "spl_app_res"
+#define SPL_APP_RES_GROUP_NAME "spl_app_res_group"
+#define SPL_TX_POOL_NAME "spl_tx_pool"
+#define SPL_CONN_POOL_NAME "spl_conn_pool"
+#define SPL_CONN_ARRAY_NAME "spl_conn_array"
+#define SPL_DFX_ARRAY_NAME "spl_dfx_array"
+#define SPL_MSG_POOL_NAME "spl_msg_pool"
+#define SPL_RECYCLE_GROUP "spl_recycle_group"
+#define SPL_RECV_RING_POOL_NAME "spl_recv_ring_pool"
+#define SPL_RECV_RING_ARRAY_NAME "spl_recv_array"
+
+#define SBR_TX_POOL_NUM APP_POOL_NUM
+#define SBR_TX_POOL_MBUF_NUM TX_MBUF_POOL_SIZE
+#define SBR_TX_MSG_NUM (SBR_TX_POOL_NUM * SBR_TX_POOL_MBUF_NUM)
+
+#define SBR_TX_POOL_ARRAY_NAME "sbr_tx_pool_array"
+#define SBR_TX_POOL_NAME "sbr_tx_pool"
+#define SBR_TX_MSG_ARRAY_NAME "sbr_tx_msg_array"
+
+#define SPL_MAX_MSG_NUM (MBOX_RING_SIZE*8*MAX_THREAD_NUM)
+
+typedef struct
+{
+ PRIMARY_ADDR mring_handle msg_pool;
+ PRIMARY_ADDR mring_handle conn_pool;
+ PRIMARY_ADDR spl_netconn_t **conn_array;
+ PRIMARY_ADDR mring_handle recv_ring_pool;
+ PRIMARY_ADDR mpool_handle tx_pool_array[SBR_TX_POOL_NUM];
+ PRIMARY_ADDR mring_handle mbox_array[SPL_MSG_BOX_NUM];
+ i64 extend_member_bit;
+} spl_app_res_group;
+
+typedef struct
+{
+ u32 pid_array[SBR_TX_POOL_NUM];
+ PRIMARY_ADDR spl_app_res_group *res_group[MAX_THREAD_NUM];
+ u16 thread_num;
+} spl_app_res_group_array;
+
+extern spl_app_res_group *g_spl_app_res_group;
+extern spl_app_res_group_array *g_res_group_array;
+
+/* call it main thread */
+int spl_init_group_array();
+
+/* call these in tcpip thread */
+int spl_init_app_res();
+spl_netconn_t **spl_get_conn_array(u32 pid);
+mring_handle spl_get_conn_pool();
+mring_handle spl_get_msg_pool();
+void spl_recycle_msg_pool(u32 pid);
+u32 spl_get_conn_num();
+void spl_free_tx_pool(u32 pid);
+int spl_add_mbox(mring_handle mbox_array[], u32 array_size);
+int spl_add_instance_res_group(u32 thread_index, spl_app_res_group * group);
+
+/* call these in app */
+int sbr_malloc_tx_pool(u32 pid, mpool_handle pool[], u32 pool_num);
+int sbr_attach_group_array();
+mring_handle sbr_get_instance_conn_pool(u32 thread_index);
+
+/* call these in app and spl */
+mring_handle *ss_get_instance_msg_box(u16 thread_index, u16 index);
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+}
+/* *INDENT-ON* */
+#endif
+
+#endif
diff --git a/stacks/lwip_stack/lwip_src/common/stackx_common.c b/stacks/lwip_stack/lwip_src/common/stackx_common.c
new file mode 100644
index 0000000..30567ee
--- /dev/null
+++ b/stacks/lwip_stack/lwip_src/common/stackx_common.c
@@ -0,0 +1,351 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#include <stdarg.h>
+#include <stddef.h>
+#include "stackx_common.h"
+#include "nstack_securec.h"
+#include "nstack_log.h"
+#include "types.h"
+#include "stackx_types.h"
+
+int spl_snprintf(char *buffer, int buflen, const char *format, ...)
+{
+ int len;
+ va_list ap;
+
+ if ((NULL == buffer) || (0 >= buflen))
+ {
+ return -1;
+ }
+
+ if (format == NULL)
+ {
+ buffer[0] = '\0';
+ return -1;
+ }
+
+ (void) va_start(ap, format);
+ len = vsnprintf_s(buffer, buflen, buflen - 1, format, ap);
+ if (-1 == len)
+ {
+ va_end(ap);
+ return -1;
+ }
+
+ va_end(ap);
+ if ((len >= buflen) && (buflen > 0) && (buffer != NULL))
+ {
+ buffer[buflen - 1] = '\0';
+ }
+
+ return len;
+}
+
+/*****************************************************************************
+* Prototype : sbr_create_mzone
+* Description : create mzone
+* Input : const char* name
+* size_t size
+* Output : None
+* Return Value : mzone_handle
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+mzone_handle sbr_create_mzone(const char *name, size_t size)
+{
+ if (!name)
+ {
+ NSFW_LOGERR("name is NULL");
+ return NULL;
+ }
+
+ mzone_handle zone;
+ nsfw_mem_zone param;
+
+ param.isocket_id = -1;
+ param.lenth = size;
+ param.stname.entype = NSFW_SHMEM;
+
+ if (strcpy_s(param.stname.aname, NSFW_MEM_NAME_LENTH, name) != 0)
+ {
+ NSFW_LOGERR("STRCPY_S failed]name=%s", name);
+ return NULL;
+ }
+
+ zone = nsfw_mem_zone_create(&param);
+ if (!zone)
+ {
+ NSFW_LOGERR("nsfw_mem_zone_create failed]name=%s, size:%zu", name,
+ size);
+ return NULL;
+ }
+
+ return zone;
+}
+
+/*****************************************************************************
+* Prototype : sbr_lookup_mzone
+* Description : lookup mzone
+* Input : const char* name
+* Output : None
+* Return Value : mzone_handle
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+mzone_handle sbr_lookup_mzone(const char *name)
+{
+ if (!name)
+ {
+ NSFW_LOGERR("name is NULL");
+ return NULL;
+ }
+
+ mzone_handle zone;
+ nsfw_mem_name param;
+
+ param.entype = NSFW_SHMEM;
+ param.enowner = NSFW_PROC_MAIN;
+ if (strcpy_s(param.aname, NSFW_MEM_NAME_LENTH, name) != 0)
+ {
+ NSFW_LOGERR("STRCPY_S failed]name=%s", name);
+ return NULL;
+ }
+
+ zone = nsfw_mem_zone_lookup(&param);
+ if (!zone)
+ {
+ NSFW_LOGERR("nsfw_mem_zone_lookup failed]name=%s", name);
+ return NULL;
+ }
+
+ return zone;
+}
+
+/*****************************************************************************
+* Prototype : sbr_create_pool
+* Description : create pool
+* Input : const char* name
+* i32 num
+* u16 size
+* Output : None
+* Return Value : mring_handle
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+mring_handle sbr_create_pool(const char *name, i32 num, u16 size)
+{
+ if (!name)
+ {
+ NSFW_LOGERR("name is NULL");
+ return NULL;
+ }
+
+ nsfw_mem_sppool param;
+ if (EOK != memset_s(&param, sizeof(param), 0, sizeof(param)))
+ {
+ NSFW_LOGERR("memset error]name=%s", name);
+ return NULL;
+ }
+
+ param.enmptype = NSFW_MRING_MPMC;
+ param.useltsize = size;
+ param.usnum = num;
+ param.stname.entype = NSFW_SHMEM;
+ param.isocket_id = -1;
+ if (strcpy_s(param.stname.aname, NSFW_MEM_NAME_LENTH, name) != 0)
+ {
+ NSFW_LOGERR("STRCPY_S failed]name=%s", name);
+ return NULL;
+ }
+
+ mring_handle ring = nsfw_mem_sp_create(&param);
+ if (!ring)
+ {
+ NSFW_LOGERR("Create pool failed]name=%s, num=%d, size=%u", name, num,
+ size);
+ }
+
+ return ring;
+}
+
+/*****************************************************************************
+* Prototype : sbr_create_ring
+* Description : create ring
+* Input : const char* name
+* i32 num
+* Output : None
+* Return Value : mring_handle
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+mring_handle sbr_create_ring(const char *name, i32 num)
+{
+ if (!name)
+ {
+ NSFW_LOGERR("name is NULL");
+ return NULL;
+ }
+
+ nsfw_mem_mring param;
+ if (EOK != memset_s(&param, sizeof(param), 0, sizeof(param)))
+ {
+ NSFW_LOGERR("memset error]name=%s", name);
+ return NULL;
+ }
+
+ param.enmptype = NSFW_MRING_MPMC;
+ param.isocket_id = -1;
+ param.usnum = num;
+ param.stname.entype = NSFW_SHMEM;
+
+ if (strcpy_s(param.stname.aname, NSFW_MEM_NAME_LENTH, name) != 0)
+ {
+ NSFW_LOGERR("STRCPY_S failed]name=%s", name);
+ return NULL;
+ }
+
+ mring_handle ring = nsfw_mem_ring_create(&param);
+ if (!ring)
+ {
+ NSFW_LOGERR("Create ring failed]name=%s, num=%d", name, num);
+ }
+
+ return ring;
+}
+
+/*****************************************************************************
+* Prototype : sbr_create_multi_ring
+* Description : create multi ring
+* Input : const char* name
+* u32 ring_size
+* i32 ring_num
+* mring_handle* array
+* nsfw_mpool_type type
+* Output : None
+* Return Value : int
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+int
+sbr_create_multi_ring(const char *name, u32 ring_size, i32 ring_num,
+ mring_handle * array, nsfw_mpool_type type)
+{
+ if (!name)
+ {
+ NSFW_LOGERR("name is NULL");
+ return -1;
+ }
+
+ if (!array)
+ {
+ NSFW_LOGERR("array is NULL");
+ return -1;
+ }
+
+ nsfw_mem_mring param;
+
+ if (EOK != memset_s(&param, sizeof(param), 0, sizeof(param)))
+ {
+ NSSBR_LOGERR("Error to memset]name=%s", name);
+ return -1;
+ }
+
+ param.enmptype = type;
+ param.stname.entype = NSFW_SHMEM;
+ if (strcpy_s(param.stname.aname, NSFW_MEM_NAME_LENTH, name) != 0)
+ {
+ NSSBR_LOGERR("STRCPY_S failed]name=%s", name);
+ return -1;
+ }
+
+ param.usnum = ring_size;
+ param.isocket_id = -1;
+ if (nsfw_mem_sp_ring_create(&param, array, ring_num) != 0)
+ {
+ NSSBR_LOGERR("Create ring pool failed]name=%s, ring_num=%d", name,
+ ring_num);
+ return -1;
+ }
+
+ return 0;
+}
+
+/*****************************************************************************
+* Prototype : sbr_lookup_ring
+* Description : lookup ring
+* Input : const char* name
+* Output : None
+* Return Value : mring_handle
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+mring_handle sbr_lookup_ring(const char *name)
+{
+ nsfw_mem_name param;
+
+ param.entype = NSFW_SHMEM;
+ param.enowner = NSFW_PROC_MAIN;
+ if (strcpy_s(param.aname, NSFW_MEM_NAME_LENTH, name) != 0)
+ {
+ NSFW_LOGERR("STRCPY_S failed]name=%s", name);
+ return NULL;
+ }
+
+ mring_handle ring = nsfw_mem_ring_lookup(&param);
+ if (!ring)
+ {
+ NSFW_LOGERR("lookup ring failed]name=%s", name);
+ }
+
+ return ring;
+}
+
+int sbr_timeval2msec(struct timeval *pTime, u64 * msec)
+{
+ if ((pTime->tv_sec < 0) || (pTime->tv_usec < 0))
+ {
+ NSFW_LOGERR("time->tv_sec is nagative");
+ return -1;
+ }
+
+ if (STACKX_MAX_U64_NUM / 1000 < (u64_t) pTime->tv_sec)
+ {
+ NSFW_LOGERR("tout.tv_sec is too large]tout.tv_sec=%lu",
+ pTime->tv_sec);
+ return -1;
+ }
+
+ u64 sec2msec = 1000 * pTime->tv_sec;
+ u64 usec2msec = pTime->tv_usec / 1000;
+
+ if (STACKX_MAX_U64_NUM - sec2msec < usec2msec)
+ {
+ NSFW_LOGERR
+ ("nsec2msec plus sec2usec is too large]usec2msec=%lu,usec2msec=%lu",
+ usec2msec, sec2msec);
+ return -1;
+ }
+
+ *msec = sec2msec + usec2msec;
+ return 0;
+}
diff --git a/stacks/lwip_stack/lwip_src/common/stackx_common.h b/stacks/lwip_stack/lwip_src/common/stackx_common.h
new file mode 100644
index 0000000..1293c9e
--- /dev/null
+++ b/stacks/lwip_stack/lwip_src/common/stackx_common.h
@@ -0,0 +1,44 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef STACKX_COMMON_H
+#define STACKX_COMMON_H
+#include "nsfw_mem_api.h"
+//#include "lwip/cc.h"
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+extern "C" {
+/* *INDENT-ON* */
+#endif
+
+int spl_snprintf(char *buffer, int buflen, const char *format, ...);
+mzone_handle sbr_create_mzone(const char *name, size_t size);
+mzone_handle sbr_lookup_mzone(const char *name);
+mring_handle sbr_create_pool(const char *name, i32 num, u16 size);
+mring_handle sbr_create_ring(const char *name, i32 num);
+int sbr_create_multi_ring(const char *name, u32 ring_size, i32 ring_num,
+ mring_handle * array, nsfw_mpool_type type);
+mring_handle sbr_lookup_ring(const char *name);
+int sbr_timeval2msec(struct timeval *pTime, u64 * msec);
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+}
+/* *INDENT-ON* */
+#endif
+
+#endif
diff --git a/stacks/lwip_stack/lwip_src/common/stackx_common_opt.h b/stacks/lwip_stack/lwip_src/common/stackx_common_opt.h
new file mode 100644
index 0000000..f911ba3
--- /dev/null
+++ b/stacks/lwip_stack/lwip_src/common/stackx_common_opt.h
@@ -0,0 +1,147 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef STACKX_COMMON_OPT_H
+#define STACKX_COMMON_OPT_H
+#include <sys/ioctl.h>
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+extern "C" {
+/* *INDENT-ON* */
+#endif
+
+#ifndef O_NONBLOCK
+#define O_NONBLOCK 0X800 /* nonblocking I/O */
+#endif
+
+#if !defined (FIONREAD) || !defined (FIONBIO)
+#define IOC_VOID 0x20000000UL /* no parameters */
+#define IOC_OUT 0x40000000UL /* copy out parameters */
+#define IOC_IN 0x80000000UL /* copy in parameters */
+#define IOCPARM_MASK 0x7fU /* parameters must be < 128 bytes */
+#define IOC_INOUT (IOC_IN | IOC_OUT) /* 0x20000000 distinguishes new & old ioctl's */
+#define _IO(x, y) (((x) << 8) | (y) | IOC_VOID)
+#define _IOR(x, y, t) (IOC_OUT | (((long)sizeof(t) & IOCPARM_MASK) << 16) | ((x) << 8) | (y))
+#define _IOW(x, y, t) (IOC_IN | (((long)sizeof(t) & IOCPARM_MASK) << 16) | ((x) << 8) | (y))
+#endif
+
+#ifndef FIONREAD
+#define FIONREAD _IOR('f', 127, unsigned long)
+#endif
+
+#ifndef FIONBIO
+#define FIONBIO _IOW('f', 126, unsigned long)
+#endif
+
+#ifndef F_GETFL
+#define F_GETFL 3
+#endif
+
+#ifndef F_SETFL
+#define F_SETFL 4
+#endif
+
+#ifndef SPL_SHUT_RD
+#define SPL_SHUT_RD 0
+#define SPL_SHUT_WR 1
+#define SPL_SHUT_RDWR 2
+#endif
+
+/* Flags for struct netconn.flags (u8_t) */
+
+/** TCP: when data passed to netconn_write doesn't fit into the send buffer,
+ this temporarily stores whether to wake up the original application task
+ if data couldn't be sent in the first try. */
+#define SPL_NETCONN_FLAG_WRITE_DELAYED 0x01
+
+/** Should this netconn avoid blocking? */
+#define SPL_NETCONN_FLAG_NON_BLOCKING 0x02
+
+/** Was the last connect action a non-blocking one? */
+#define SPL_NETCONN_FLAG_IN_NONBLOCKING_CONNECT 0x04
+
+/** If this is set, a TCP netconn must call netconn_recved() to update
+ the TCP receive window (done automatically if not set). */
+#define SPL_NETCONN_FLAG_NO_AUTO_RECVED 0x08
+
+/** If a nonblocking write has been rejected before, poll_tcp needs to
+ check if the netconn is writable again */
+#define SPL_NETCONN_FLAG_CHECK_WRITESPACE 0x10
+
+/* For the netconn API, these values are use as a bitmask! */
+#define SPL_NETCONN_SHUT_RD 1
+#define SPL_NETCONN_SHUT_WR 2
+#define SPL_NETCONN_SHUT_RDWR (SPL_NETCONN_SHUT_RD | SPL_NETCONN_SHUT_WR)
+#define STACKX_TIMER_THREAD_SUPPORT 1
+
+/* Flags for netconn_write (u8_t) */
+#define SPL_NETCONN_NOFLAG 0x00
+#define SPL_NETCONN_NOCOPY 0x00
+#define SPL_NETCONN_COPY 0x01
+#define SPL_NETCONN_MORE 0x02
+#define SPL_NETCONN_DONTBLOCK 0x04
+
+#define SPL_TCP_NODELAY 0x01
+#define SPL_TCP_KEEPALIVE 0x02
+#define SPL_TCP_KEEPIDLE 0x04
+#define SPL_TCP_KEEPINTVL 0x05
+#define SPL_TCP_KEEPCNT 0x06
+#define SPL_TCP_LINGER2 0x08
+#define SPL_TCP_DEFER_ACCEPT 0x09
+#define SPL_TCP_INFO 0x0B
+
+typedef enum spl_netconn_type
+{
+ SPL_NETCONN_INVALID = 0,
+ SPL_NETCONN_TCP = 0x10,
+ SPL_NETCONN_UDP = 0x20,
+ SPL_NETCONN_UDPLITE = 0x21,
+ SPL_NETCONN_UDPNOCHKSUM = 0x22,
+ SPL_NETCONN_RAW = 0x40,
+} spl_netconn_type_t;
+
+typedef enum spl_netconn_state
+{
+ SPL_NETCONN_NONE,
+ SPL_NETCONN_WRITE,
+ SPL_NETCONN_LISTEN,
+ SPL_NETCONN_CONNECT,
+ SPL_NETCONN_CLOSE,
+} spl_netconn_state_t;
+
+typedef enum spl_tcp_state
+{
+ SPL_CLOSED = 0,
+ SPL_LISTEN = 1,
+ SPL_SYN_SENT = 2,
+ SPL_SYN_RCVD = 3,
+ SPL_ESTABLISHED = 4,
+ SPL_FIN_WAIT_1 = 5,
+ SPL_FIN_WAIT_2 = 6,
+ SPL_CLOSE_WAIT = 7,
+ SPL_CLOSING = 8,
+ SPL_LAST_ACK = 9,
+ SPL_TIME_WAIT = 10
+} spl_tcp_state_t;
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+}
+/* *INDENT-ON* */
+#endif
+
+#endif
diff --git a/stacks/lwip_stack/lwip_src/common/stackx_debug.h b/stacks/lwip_stack/lwip_src/common/stackx_debug.h
new file mode 100644
index 0000000..bdad724
--- /dev/null
+++ b/stacks/lwip_stack/lwip_src/common/stackx_debug.h
@@ -0,0 +1,70 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef __STACKX_DEBUG_H__
+#define __STACKX_DEBUG_H__
+
+//#include "lwip/arch.h"
+#include <pthread.h>
+
+#include <sys/syscall.h>
+
+#include "nstack_log.h"
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+extern "C" {
+/* *INDENT-ON* */
+#endif
+
+/** lower two bits indicate dbug level
+ * - 0 all
+ * - 1 warning
+ * - 2 serious
+ * - 3 severe
+ */
+#define STACKX_DBG_LEVEL_ALL 0x00
+#define STACKX_DBG_LEVEL_OFF STACKX_DBG_LEVEL_ALL /* compatibility define only */
+#define STACKX_DBG_LEVEL_WARNING 0x01 /* bad checksums, dropped packets, ... */
+#define STACKX_DBG_LEVEL_SERIOUS 0x02 /* memory allocation failures, ... */
+#define STACKX_DBG_LEVEL_SEVERE 0x03
+#define STACKX_DBG_MASK_LEVEL 0x00
+
+/** flag to enable that dbug message */
+#define STACKX_DBG_ON NS_LOG_STACKPOOL_ON
+
+/** flag to disable that dbug message */
+#define STACKX_DBG_OFF NS_LOG_STACKPOOL_OFF
+
+/** flag for indicating a tracing_message (to follow program flow) */
+#define STACKX_DBG_TRACE NS_LOG_STACKPOOL_TRACE
+
+/** flag for indicating a state dbug message (to follow module states) */
+#define STACKX_DBG_STATE NS_LOG_STACKPOOL_STATE
+
+/** flag for indicating newly added code, not thoroughly tested yet */
+#define STACKX_DBG_FRESH NS_LOG_STACKPOOL_FRESH
+
+/** flag for to halt after printing this dbug message */
+#define STACKX_DBG_HALT NS_LOG_STACKPOOL_HALT
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+}
+/* *INDENT-ON* */
+#endif
+
+#endif /* __STACKX_DEBUG_H__ */
diff --git a/stacks/lwip_stack/lwip_src/common/stackx_err.h b/stacks/lwip_stack/lwip_src/common/stackx_err.h
new file mode 100644
index 0000000..1d0fc20
--- /dev/null
+++ b/stacks/lwip_stack/lwip_src/common/stackx_err.h
@@ -0,0 +1,68 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef STACKX_ERR_H
+#define STACKX_ERR_H
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+extern "C" {
+/* *INDENT-ON* */
+#endif
+
+#define ERR_OK 0 /* No error, everything OK. */
+#define ERR_MEM -1 /* Out of memory error. */
+#define ERR_BUF -2 /* Buffer error. */
+#define ERR_TIMEOUT -3 /* Timeout. */
+#define ERR_RTE -4 /* Routing problem. */
+#define ERR_INPROGRESS -5 /* Operation in progress */
+#define ERR_VAL -6 /* Illegal value. */
+#define ERR_WOULDBLOCK -7 /* Operation would block. */
+#define ERR_USE -8 /* Address in use. */
+#define ERR_ISCONN -9 /* Already connected. */
+
+#define SPL_ERR_IS_FATAL(e) ((e) < ERR_ISCONN)
+
+#define ERR_ABRT -10 /* Connection aborted. */
+#define ERR_RST -11 /* Connection reset. */
+#define ERR_CLSD -12 /* Connection closed. */
+#define ERR_CONN -13 /* Not connected. */
+
+#define ERR_ARG -14 /* Illegal argument. */
+
+#define ERR_IF -15 /* Low-level netif error */
+#define ERR_ALREADY -16 /* previous connect attemt has not yet completed */
+#define ERR_PROTOTYPE -17 /* prototype error or some other generic error.
+ the operation is not allowed on current socket */
+
+#define ERR_CALLBACK -18 /* callback error */
+#define ERR_CANTASSIGNADDR -19 /* Cannot assign requested address */
+#define ERR_CONTAINER_ID -20 /*Illegal container id */
+#define ERR_NOTSOCK -21 /*not a socket */
+
+#define ERR_CLOSE_WAIT -22 /*closed in established state */
+
+#define ERR_EPROTONOSUPPORT -23 /* Protocol not supported */
+
+#define ERR_FAULTRECOVERY -24 /*SPL just recovered from a fatal fault */
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+}
+/* *INDENT-ON* */
+#endif
+
+#endif
diff --git a/stacks/lwip_stack/lwip_src/common/stackx_ip_addr.c b/stacks/lwip_stack/lwip_src/common/stackx_ip_addr.c
new file mode 100644
index 0000000..86f0b39
--- /dev/null
+++ b/stacks/lwip_stack/lwip_src/common/stackx_ip_addr.c
@@ -0,0 +1,276 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#include <stdint.h>
+#include <stddef.h>
+#include "stackx_ip_addr.h"
+#include "nstack_log.h"
+#include "spl_def.h"
+
+/* Here for now until needed in other places in stackx*/
+#ifndef isprint
+#define in_range(c, lo, up) ((u8)c >= lo && (u8)c <= up)
+#define isprint(c) in_range(c, 0x20, 0x7f)
+#define isdigit(c) in_range(c, '0', '9')
+#define isxdigit(c) (isdigit(c) || in_range(c, 'a', 'f') || in_range(c, 'A', 'F'))
+#define islower(c) in_range(c, 'a', 'z')
+#define isspace(c) (c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' || c == '\v')
+#endif
+
+/**
+ * Ascii internet address interpretation routine.
+ * The value returned is in network order.
+ *
+ * @param cp IPaddress in ascii represenation (e.g. "127.0.0.1")
+ * @return ipaddress in network order
+ */
+u32 spl_ipaddr_addr(const char *cp)
+{
+ spl_ip_addr_t val;
+
+ if (spl_ipaddr_aton(cp, &val))
+ {
+ return ip4_addr_get_u32(&val);
+ }
+
+ return (SPL_IPADDR_NONE);
+}
+
+/**
+ * Check whether "cp" is a valid ascii representation
+ * of an Internet address and convert to a binary address.
+ * Returns 1 if the address is valid, 0 if not.
+ * This replaces inet_addr, the return value from which
+ * cannot distinguish between failure and a local broad cast address.
+ *
+ * @param cp IPaddress in ascii represenation (e.g. "127.0.0.1")
+ * @param addr pointer to which to save the ipaddress in network order
+ * @return 1 if cp could be converted to addr, 0 on failure
+ */
+int spl_ipaddr_aton(const char *cp, spl_ip_addr_t * addr)
+{
+ u32 val;
+ u8 base;
+ char c;
+ u32 parts[4];
+ u32 *pp = parts;
+
+ if (cp == NULL)
+ {
+ return 0;
+ }
+
+ c = *cp;
+ for (;;)
+ {
+ /*
+ * Get number up to ``.''.
+ * Values are specified as for C:
+ * 0x=hex, 0=octal, 1-9=decimal.
+ */
+ if (!isdigit(c))
+ {
+ return (0);
+ }
+
+ val = 0;
+ base = 10;
+ if (c == '0')
+ {
+ c = *++cp;
+ if ((c == 'x') || (c == 'X'))
+ {
+ base = 16;
+ c = *++cp;
+ }
+ else
+ {
+ base = 8;
+ }
+ }
+
+ for (;;)
+ {
+ if (isdigit(c))
+ {
+ val = (val * base) + (int) (c - '0');
+ c = *++cp;
+ }
+ else if ((base == 16) && isxdigit(c))
+ {
+ val = (val << 4) | (int) (c + 10 - (islower(c) ? 'a' : 'A'));
+ c = *++cp;
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ if (c == '.')
+ {
+ /*
+ * Internet format:
+ * a.b.c.d
+ * a.b.c (with c treated as 16 bits)
+ * a.b (with b treated as 24 bits)
+ */
+ if (pp >= parts + 3)
+ {
+ return (0);
+ }
+
+ *pp++ = val;
+ c = *++cp;
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ /*
+ * Check for trailing characters.
+ */
+ if ((c != '\0') && !isspace(c))
+ {
+ return (0);
+ }
+
+ /*
+ * Concoct the address according to
+ * the number of parts specified.
+ */
+ switch (pp - parts + 1)
+ {
+ case 0:
+ return (0); /* initial nondigit */
+
+ case 1: /* a -- 32 bits */
+ break;
+
+ case 2: /* a.b -- 8.24 bits */
+ if (val > 0xffffffUL)
+ {
+ return (0);
+ }
+
+ val |= parts[0] << 24;
+ break;
+
+ case 3: /* a.b.c -- 8.8.16 bits */
+ if (val > 0xffff)
+ {
+ return (0);
+ }
+
+ val |= (parts[0] << 24) | (parts[1] << 16);
+ break;
+
+ case 4: /* a.b.c.d -- 8.8.8.8 bits */
+ if (val > 0xff)
+ {
+ return (0);
+ }
+
+ val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
+ break;
+ default:
+ NSPOL_LOGERR("unhandled");
+
+ return (0);
+ }
+
+ if (addr)
+ {
+ ip4_addr_set_u32(addr, spl_htonl(val));
+ }
+
+ return (1);
+}
+
+/**
+ * Convert numeric IPaddress into decimal dotted ASCII representation.
+ * returns ptr to static buffer; not reentrant!
+ *
+ * @param addr ipaddress in network order to convert
+ * @return pointer to a global static (!) buffer that holds the ASCII
+ * represenation of addr
+ */
+char *spl_ipaddr_ntoa(const spl_ip_addr_t * addr)
+{
+ static char str[16];
+
+ return spl_ipaddr_ntoa_r(addr, str, 16);
+}
+
+/**
+ * Same as spl_ipaddr_ntoa, but reentrant since a user-supplied buffer is used.
+ *
+ * @param addr ipaddress in network order to convert
+ * @param buf target buffer where the string is stored
+ * @param buflen length of buf
+ * @return either pointer to buf which now holds the ASCII
+ * representation of addr or NULL if buf was too small
+ */
+char *spl_ipaddr_ntoa_r(const spl_ip_addr_t * addr, char *buf, int buflen)
+{
+ u32 s_addr;
+ char inv[3];
+ char *rp;
+ u8 *ap;
+ u8 rem;
+ u8 n;
+ u8 i;
+ int len = 0;
+
+ s_addr = ip4_addr_get_u32(addr);
+
+ rp = buf;
+ ap = (u8 *) & s_addr;
+ for (n = 0; n < 4; n++)
+ {
+ i = 0;
+ do
+ {
+ rem = *ap % (u8) 10;
+ *ap /= (u8) 10;
+ inv[i++] = '0' + rem;
+ }
+ while (*ap);
+
+ while (i--)
+ {
+ if (len++ >= buflen)
+ {
+ return NULL;
+ }
+
+ *rp++ = inv[i];
+ }
+
+ if (len++ >= buflen)
+ {
+ return NULL;
+ }
+
+ *rp++ = '.';
+ ap++;
+ }
+
+ *--rp = 0;
+ return buf;
+}
diff --git a/stacks/lwip_stack/lwip_src/common/stackx_ip_addr.h b/stacks/lwip_stack/lwip_src/common/stackx_ip_addr.h
new file mode 100644
index 0000000..43dcb3a
--- /dev/null
+++ b/stacks/lwip_stack/lwip_src/common/stackx_ip_addr.h
@@ -0,0 +1,82 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef STACKX_IP_ADDR_H
+#define STACKX_IP_ADDR_H
+#include "types.h"
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+extern "C" {
+/* *INDENT-ON* */
+#endif
+
+/* This is the aligned version of ip_addr_t,
+ used as local variable, on the stack, etc. */
+typedef struct spl_ip_addr
+{
+ u32 addr;
+} spl_ip_addr_t;
+
+/** 127.0.0.1 */
+#define IPADDR_LOOPBACK ((u32_t)0x7f000001UL)
+
+/** 0.0.0.0 */
+#define IPADDR_ANY ((u32_t)0x00000000UL)
+
+/** 255.255.255.255 */
+#define IPADDR_BROADCAST ((u32_t)0xffffffffUL)
+
+/** 255.255.255.255 */
+#define SPL_IPADDR_NONE ((u32)0xffffffffUL)
+
+/** Set address to IPADDR_ANY (no need for spl_htonl()) */
+#define spl_ip_addr_set_any(ipaddr) ((ipaddr)->addr = IPADDR_ANY)
+
+/** Set complete address to zero */
+#define spl_ip_addr_set_zero(ipaddr) ((ipaddr)->addr = 0)
+
+/** IPv4 only: set the IPaddress given as an u32_t */
+#define ip4_addr_set_u32(dest_ipaddr, src_u32) ((dest_ipaddr)->addr = (src_u32))
+
+/** IPv4 only: get the IPaddress as an u32_t */
+#define ip4_addr_get_u32(src_ipaddr) ((src_ipaddr)->addr)
+
+#define inet_addr_to_ipaddr(target_ipaddr, source_inaddr) (ip4_addr_set_u32(target_ipaddr, (source_inaddr)->s_addr))
+#define inet_addr_from_ipaddr(target_inaddr, source_ipaddr) ((target_inaddr)->s_addr = ip4_addr_get_u32(source_ipaddr))
+
+/** For backwards compatibility */
+#define spl_ip_ntoa(ipaddr) spl_ipaddr_ntoa(ipaddr)
+
+u32 spl_ipaddr_addr(const char *cp);
+int spl_ipaddr_aton(const char *cp, spl_ip_addr_t * addr);
+
+/** returns ptr to static buffer; not reentrant! */
+char *spl_ipaddr_ntoa(const spl_ip_addr_t * addr);
+char *spl_ipaddr_ntoa_r(const spl_ip_addr_t * addr, char *buf, int buflen);
+
+#define spl_inet_addr(cp) spl_ipaddr_addr(cp)
+#define spl_inet_aton(cp, paddr) spl_ipaddr_aton(cp, (spl_ip_addr_t*)(paddr))
+#define spl_inet_ntoa(paddr) spl_ipaddr_ntoa((spl_ip_addr_t*)&(paddr))
+#define spl_inet_ntoa_r(addr, buf, buflen) spl_ipaddr_ntoa_r((spl_ip_addr_t*)&(addr), buf, buflen)
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+}
+/* *INDENT-ON* */
+#endif
+
+#endif
diff --git a/stacks/lwip_stack/lwip_src/common/stackx_ip_tos.h b/stacks/lwip_stack/lwip_src/common/stackx_ip_tos.h
new file mode 100644
index 0000000..5a646ae
--- /dev/null
+++ b/stacks/lwip_stack/lwip_src/common/stackx_ip_tos.h
@@ -0,0 +1,145 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef STACKX_IP_TOS_H
+#define STACKX_IP_TOS_H
+#include "types.h"
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+extern "C" {
+/* *INDENT-ON* */
+#endif
+
+/*
+ * The Type of Service provides an indication of the abstract
+ * parameters of the quality of service desired. These parameters are
+ * to be used to guide the selection of the actual service parameters
+ * when transmitting a datagram through a particular network. Several
+ * networks offer service precedence, which somehow treats high
+ * precedence traffic as more important than other traffic (generally
+ * by accepting only traffic above a certain precedence at time of high
+ * load). The major choice is a three way tradeoff between low-delay,
+ * high-reliability, and high-throughput.
+ * The use of the Delay, Throughput, and Reliability indications may
+ * increase the cost (in some sense) of the service. In many networks
+ * better performance for one of these parameters is coupled with worse
+ * performance on another. Except for very unusual cases at most two
+ * of these three indications should be set.
+ */
+#define IPTOS_LOWCOST 0x02
+#define IPTOS_RELIABILITY 0x04
+#define IPTOS_THROUGHPUT 0x08
+#define IPTOS_LOWDELAY 0x10
+#define IPTOS_TOS_MASK 0x1E
+#define IPTOS_MINCOST IPTOS_LOWCOST
+#define IPTOS_TOS(tos) ((tos) & IPTOS_TOS_MASK)
+
+/*
+ * The Network Control precedence designation is intended to be used
+ * within a network only. The actual use and control of that
+ * designation is up to each network. The Internetwork Control
+ * designation is intended for use by gateway control originators only.
+ * If the actual use of these precedence designations is of concern to
+ * a particular network, it is the responsibility of that network to
+ * control the access to, and use of, those precedence designations.
+ */
+#define IPTOS_PREC_ROUTINE 0x00
+#define IPTOS_PREC_PRIORITY 0x20
+#define IPTOS_PREC_IMMEDIATE 0x40
+#define IPTOS_PREC_FLASH 0x60
+#define IPTOS_PREC_FLASHOVERRIDE 0x80
+#define IPTOS_PREC_CRITIC_ECP 0xa0
+#define IPTOS_PREC_INTERNETCONTROL 0xc0
+#define IPTOS_PREC_MASK 0xe0
+#define IPTOS_PREC_NETCONTROL 0xe0
+#define IPTOS_PREC(tos) ((tos) & IPTOS_PREC_MASK)
+
+#define IPTOS_RT_MASK (IPTOS_TOS_MASK & ~3)
+
+#define TC_PRIO_BESTEFFORT 0
+#define TC_PRIO_FILLER 1
+#define TC_PRIO_BULK 2
+#define TC_PRIO_INTERACTIVE_BULK 4
+#define TC_PRIO_INTERACTIVE 6
+#define TC_PRIO_CONTROL 7
+#define TC_PRIO_MAX 15
+
+#define ECN_OR_COST(class ) TC_PRIO_ ## class
+
+static u8 stackx_ip_tos2prio[(IPTOS_TOS_MASK >> 1) + 1] = {
+ TC_PRIO_BESTEFFORT,
+ ECN_OR_COST(FILLER),
+ TC_PRIO_BESTEFFORT,
+ ECN_OR_COST(BESTEFFORT),
+ TC_PRIO_BULK,
+ ECN_OR_COST(BULK),
+ TC_PRIO_BULK,
+ ECN_OR_COST(BULK),
+ TC_PRIO_INTERACTIVE,
+ ECN_OR_COST(INTERACTIVE),
+ TC_PRIO_INTERACTIVE,
+ ECN_OR_COST(INTERACTIVE),
+ TC_PRIO_INTERACTIVE_BULK,
+ ECN_OR_COST(INTERACTIVE_BULK),
+ TC_PRIO_INTERACTIVE_BULK,
+ ECN_OR_COST(INTERACTIVE_BULK)
+};
+
+static inline char stackx_rt_tos2priority(u8 tos)
+{
+ return stackx_ip_tos2prio[IPTOS_TOS(tos) >> 1];
+}
+
+typedef enum
+{
+ STACKX_PRIM,
+ STACKX_HIGH,
+ STACKX_MEDIUM,
+ STACKX_LOW
+} stackx_prio;
+
+static inline stackx_prio stackx_get_prio(u8 tos)
+{
+ if (0 == tos)
+ {
+ return STACKX_PRIM;
+ }
+ char prio = stackx_rt_tos2priority(tos);
+ if ((TC_PRIO_INTERACTIVE == prio))
+ {
+ return STACKX_HIGH;
+ }
+ else if ((TC_PRIO_BESTEFFORT == prio)
+ || (TC_PRIO_INTERACTIVE_BULK == prio))
+ {
+ return STACKX_MEDIUM;
+ }
+ else if ((TC_PRIO_BULK == prio) || (TC_PRIO_FILLER == prio))
+ {
+ return STACKX_LOW;
+ }
+
+ return STACKX_PRIM;
+}
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+}
+/* *INDENT-ON* */
+#endif
+
+#endif
diff --git a/stacks/lwip_stack/lwip_src/common/stackx_netbuf.h b/stacks/lwip_stack/lwip_src/common/stackx_netbuf.h
new file mode 100644
index 0000000..67f0925
--- /dev/null
+++ b/stacks/lwip_stack/lwip_src/common/stackx_netbuf.h
@@ -0,0 +1,43 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef STACKX_NETBUF_H
+#define STACKX_NETBUF_H
+#include "stackx_pbuf.h"
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+extern "C" {
+/* *INDENT-ON* */
+#endif
+
+typedef struct spl_netbuf
+{
+ struct spl_pbuf *p;
+ spl_ip_addr_t addr;
+ u16 port;
+} spl_netbuf;
+
+#define netbuf_fromaddr(buf) (&((buf)->addr))
+#define netbuf_fromport(buf) ((buf)->port)
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+}
+/* *INDENT-ON* */
+#endif
+
+#endif
diff --git a/stacks/lwip_stack/lwip_src/common/stackx_pbuf.c b/stacks/lwip_stack/lwip_src/common/stackx_pbuf.c
new file mode 100644
index 0000000..b1478b8
--- /dev/null
+++ b/stacks/lwip_stack/lwip_src/common/stackx_pbuf.c
@@ -0,0 +1,220 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#include "stackx_spl_share.h"
+#include "stackx_pbuf.h"
+#include "common_mem_mbuf.h"
+#include "nstack_securec.h"
+#include "nsfw_maintain_api.h"
+#include "stackx_tcp_opt.h"
+#ifdef HAL_LIB
+#else
+#include "rte_memcpy.h"
+#endif
+#include "nsfw_shmem_mng.h"
+/*****************************************************************************
+* Prototype : sbr_malloc_pbuf
+* Description : malloc spl_pbuf,use it in app
+* Input : mpool_handle mp
+* u16 len
+* u32 mbuf_data_size
+* u16 offset
+* Output : None
+* Return Value : struct pbuf*
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+struct spl_pbuf *sbr_malloc_pbuf(mpool_handle mp, u16 len, u32 mbuf_data_size,
+ u16 offset)
+{
+ if ((len < offset) || (len > mbuf_data_size))
+ {
+ NSSBR_LOGERR("len is invalid]len=%u", len);
+ return NULL;
+ }
+
+ struct common_mem_mbuf *mbuf = NULL;
+ struct spl_pbuf *buf = NULL;
+
+ mbuf = nsfw_shmem_mbfalloc(mp);
+ if (unlikely(mbuf == NULL))
+ {
+ NS_LOG_CTRL(LOG_CTRL_HUGEPAGE_ALLOC_FAIL, LOGSBR, "NSSBR", NSLOG_WAR,
+ "alloc mbuf failed");
+ return NULL;
+ }
+
+ mbuf->data_len = len;
+ mbuf->next = NULL;
+ mbuf->nb_segs = 1;
+ mbuf->pkt_len = len;
+ buf =
+ (struct spl_pbuf *) ((char *) mbuf + sizeof(struct common_mem_mbuf));
+ res_alloc(&buf->res_chk);
+ buf->next = 0;
+ void *tmp = common_pktmbuf_mtod(mbuf, void *);
+ buf->payload = (void *) (ADDR_LTOSH(tmp) + offset);
+ buf->tot_len = len - offset;
+ buf->len = len - offset;
+ buf->type = SPL_PBUF_HUGE;
+ buf->flags = 0;
+ buf->freeNext = NULL;
+ buf->conn_a = 0;
+ buf->proto_type = SPL_PBUF_PROTO_NONE;
+ NSSBR_LOGDBG("malloc pbuf ok]buf=%p,PRIMARY_ADDR=%p", buf,
+ ADDR_LTOSH(buf));
+ return buf;
+}
+
+u32_t
+spl_pbuf_copy_partial(struct spl_pbuf * buf, void *dataptr, u32_t len,
+ u32_t offset)
+{
+ struct spl_pbuf *p = buf;
+ u32_t buf_copy_len;
+ u32_t copied_total = 0;
+ char *databuf = (char *) dataptr;
+
+ /* Note some systems use byte copy if dataptr or one of the pbuf payload pointers are unaligned. */
+ for (p = buf; len != 0 && p != NULL;
+ p = PTR_SHTOL(struct spl_pbuf *, p->next_a))
+ {
+ if (offset != 0 && offset >= p->len)
+ {
+ /* don't copy from this buffer -> on to the next */
+ offset -= p->len;
+ }
+ else if (p->len - offset > len)
+ {
+ /* copy from this buffer. maybe only partially. */
+ (void) common_memcpy(databuf, ADDR_SHTOL(p->payload_a + offset),
+ len);
+ copied_total += len;
+ break;
+ }
+ else
+ {
+ buf_copy_len = p->len - offset;
+ /* copy the necessary parts of the buffer */
+ (void) common_memcpy(databuf, ADDR_SHTOL(p->payload_a + offset),
+ buf_copy_len);
+
+ copied_total += buf_copy_len;
+ databuf += buf_copy_len;
+ len -= buf_copy_len;
+ offset = 0;
+ }
+ }
+
+ return copied_total;
+}
+
+int spl_tx_force_buf_free(void *data)
+{
+ struct common_mem_mbuf *mbuf = data;
+ if (NULL == mbuf)
+ {
+ return FALSE;
+ }
+
+ struct spl_pbuf *p_buf =
+ (struct spl_pbuf *) (((char *) mbuf) +
+ sizeof(struct common_mem_mbuf));
+ u8 tempflag = p_buf->res_chk.u8Reserve;
+ if ((mbuf->refcnt == 0) || (tempflag & DPDK_SEND_FLAG))
+ {
+ return FALSE;
+ }
+
+ NSFW_LOGINF("free mbuf]%p", data);
+ (void) nsfw_shmem_mbffree((mbuf_handle) mbuf);
+ return TRUE;
+}
+
+int spl_force_buf_free(void *data)
+{
+ struct common_mem_mbuf *mbuf = data;
+
+ if (NULL == mbuf || (mbuf->refcnt == 0))
+ {
+ return FALSE;
+ }
+
+ NSFW_LOGINF("free mbuf]%p", data);
+ (void) nsfw_shmem_mbffree((mbuf_handle) mbuf);
+ return TRUE;
+}
+
+int spl_reg_res_tx_mgr(mpool_handle * pool)
+{
+ struct common_mem_mempool *mp = (struct common_mem_mempool *) pool;
+ if (NULL == mp)
+ {
+ return 0;
+ }
+
+ nsfw_res_scn_cfg scn_cfg = { NSFW_RES_SCAN_MBUF, 60, 3, 16,
+ mp->size / 128, mp->size,
+ mp->elt_size,
+ sizeof(struct common_mem_mbuf) + offsetof(struct spl_pbuf, res_chk),
+ mp,
+ mp->pool_data,
+ spl_tx_force_buf_free
+ };
+ (void) nsfw_res_mgr_reg(&scn_cfg);
+ return 0;
+}
+
+int spl_reg_res_rxmt_mgr(mpool_handle * pool)
+{
+ struct common_mem_mempool *mp = (struct common_mem_mempool *) pool;
+ if (NULL == mp)
+ {
+ return 0;
+ }
+
+ nsfw_res_scn_cfg scn_cfg = { NSFW_RES_SCAN_MBUF, 60, 3, 16,
+ mp->size / 128, mp->size,
+ mp->elt_size,
+ sizeof(struct common_mem_mbuf) + offsetof(struct spl_pbuf, res_chk),
+ mp,
+ mp->pool_data,
+ spl_tx_force_buf_free
+ }; /*Can use same function for time */
+ (void) nsfw_res_mgr_reg(&scn_cfg);
+ return 0;
+}
+
+int spl_reg_res_txrx_mgr(mpool_handle * pool)
+{
+ struct common_mem_mempool *mp = (struct common_mem_mempool *) pool;
+ if (NULL == mp)
+ {
+ return 0;
+ }
+
+ nsfw_res_scn_cfg scn_cfg = { NSFW_RES_SCAN_MBUF, 60, 3, 16,
+ mp->size / 128, mp->size,
+ mp->elt_size,
+ sizeof(struct common_mem_mbuf) + offsetof(struct spl_pbuf, res_chk),
+ mp,
+ mp->pool_data,
+ spl_force_buf_free
+ };
+ (void) nsfw_res_mgr_reg(&scn_cfg);
+ return 0;
+}
diff --git a/stacks/lwip_stack/lwip_src/common/stackx_pbuf.h b/stacks/lwip_stack/lwip_src/common/stackx_pbuf.h
new file mode 100644
index 0000000..21a2abb
--- /dev/null
+++ b/stacks/lwip_stack/lwip_src/common/stackx_pbuf.h
@@ -0,0 +1,80 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef STACKX_PBUF_H
+#define STACKX_PBUF_H
+
+#include "common_mem_base_type.h"
+#include "common_mem_mbuf.h"
+#include "nsfw_mem_api.h"
+#include "stackx_pbuf_comm.h"
+#ifdef HAL_LIB
+#else
+#include "common_pal_bitwide_adjust.h"
+#endif
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+extern "C" {
+/* *INDENT-ON* */
+#endif
+
+#define NEED_ACK_FLAG 0x01 /* This spl_pbuf may have multiple references. */
+#define PBUF_FREE_FLAG 0x04 /* This spl_pbuf has been free. */
+#define DPDK_SEND_FLAG 0x10 /* This spl_pbuf has been sent to DPDK. */
+#define LOOP_SEND_FLAG 0x40 /* This spl_pbuf has been looped to IP layer and not received by app layer yet. */
+
+struct spl_pbuf *sbr_malloc_pbuf(mpool_handle mp, u16 len,
+ u32 mbuf_data_size, u16 offset);
+void sbr_free_pbuf(struct spl_pbuf *p);
+u32 spl_pbuf_copy_partial(struct spl_pbuf *p, void *dataptr, u32_t len,
+ u32_t offset);
+int spl_reg_res_txrx_mgr(mpool_handle * pool);
+int spl_reg_res_tx_mgr(mpool_handle * pool);
+
+/* release buf hold by app on abnormal exit */
+/*
+ *For TX mbuf: recycle_flg can be: MBUF_UNUSED, MBUF_HLD_BY_APP, MBUF_HLD_BY_SPL.
+ *For TX mbuf: recycle_flg can be: MBUF_UNSUED, app pid.
+ */
+static inline void pbuf_set_recycle_flg(struct spl_pbuf *p, uint32_t flg)
+{
+ uint32_t *recycle_flg;
+ struct spl_pbuf *q = p;
+ struct common_mem_mbuf *m;
+
+ while (q != NULL)
+ {
+ m = (struct common_mem_mbuf *) ((char *) q -
+ sizeof(struct common_mem_mbuf));
+#ifdef HAL_LIB
+#else
+ recycle_flg =
+ (uint32_t *) ((char *) (m->buf_addr) + RTE_PKTMBUF_HEADROOM -
+ sizeof(uint32_t));
+#endif
+ *recycle_flg = flg;
+ q = (struct spl_pbuf *) ADDR_SHTOL(q->next_a);
+ }
+}
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+}
+/* *INDENT-ON* */
+#endif
+
+#endif
diff --git a/stacks/lwip_stack/lwip_src/common/stackx_pbuf_comm.h b/stacks/lwip_stack/lwip_src/common/stackx_pbuf_comm.h
new file mode 100644
index 0000000..a73565b
--- /dev/null
+++ b/stacks/lwip_stack/lwip_src/common/stackx_pbuf_comm.h
@@ -0,0 +1,109 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef STACKX_PBUF_COMM_H
+#define STACKX_PBUF_COMM_H
+#include "types.h"
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+extern "C" {
+/* *INDENT-ON* */
+#endif
+
+#define SPL_PBUF_TRANSPORT_HLEN 20
+#define SPL_PBUF_UDP_HLEN 8
+#define SPL_PBUF_IP_HLEN 20
+
+#define SPL_PBUF_VLAN_HLEN 0
+
+#ifndef SPL_PBUF_LINK_HLEN
+#define SPL_PBUF_LINK_HLEN (14 + SPL_PBUF_VLAN_HLEN)
+#endif
+
+typedef enum spl_pbuf_layer
+{
+ SPL_PBUF_TRANSPORT,
+ SPL_PBUF_UDP,
+ SPL_PBUF_IP,
+ SPL_PBUF_LINK,
+ SPL_PBUF_RAW,
+ SPL_PBUF_MAX_LAYER,
+} spl_pbuf_layer;
+
+typedef enum spl_pbuf_type
+{
+ SPL_PBUF_RAM, /* pbuf data is stored in RAM */
+ SPL_PBUF_ROM, /* pbuf data is stored in ROM */
+ SPL_PBUF_REF, /* pbuf comes from the pbuf pool */
+ SPL_PBUF_POOL, /* pbuf payload refers to RAM */
+ SPL_PBUF_HUGE /* pbuf is stored in HugePage memory in struct common_mem_mbuf */
+} spl_pbuf_type;
+
+enum spl_pbuf_proto
+{
+ SPL_PBUF_PROTO_NONE,
+ SPL_PBUF_TCP_SEND,
+ SPL_PBUF_TCP_RECV
+} spl_pbuf_proto;
+
+typedef struct spl_pbuf
+{
+ /** next pbuf in singly linked pbuf chain */
+ union
+ {
+ struct spl_pbuf *next;
+ u64 next_a;
+ };
+
+ /** pointer to the actual data in the buffer */
+ union
+ {
+ void *payload;
+ u64 payload_a;
+ };
+
+ union
+ {
+ void *msg;
+ u64 msg_a;
+ };
+
+ union
+ {
+ void *conn;
+ u64 conn_a;
+ };
+
+ struct spl_pbuf *freeNext; // This pointer will point to next pbuf you want to free in stackx
+
+ u32 tot_len;
+ u32 len;
+ int proto_type;
+ u16 ref;
+ u8 type;
+ u8 flags;
+ nsfw_res res_chk;
+
+} spl_pbuf;
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+}
+/* *INDENT-ON* */
+#endif
+
+#endif
diff --git a/stacks/lwip_stack/lwip_src/common/stackx_spl_msg.h b/stacks/lwip_stack/lwip_src/common/stackx_spl_msg.h
new file mode 100644
index 0000000..d3b3c2e
--- /dev/null
+++ b/stacks/lwip_stack/lwip_src/common/stackx_spl_msg.h
@@ -0,0 +1,241 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef STACKX_SPL_MSG_H
+#define STACKX_SPL_MSG_H
+#include "nsfw_msg.h"
+#include "stackx_ip_addr.h"
+#include "stackx_spl_share.h"
+#include "stackx_common_opt.h"
+#include <sys/socket.h>
+#include <netinet/tcp.h>
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+extern "C" {
+/* *INDENT-ON* */
+#endif
+
+enum spl_tcpip_msg_type
+{
+ SPL_TCPIP_NEW_MSG_API,
+#if STACKX_TIMER_THREAD_SUPPORT
+ SPL_TCPIP_MSG_TIMER,
+#endif
+#if STACKX_NETIF_API
+ SPL_TCPIP_MSG_NETIFAPI,
+#endif
+ SPL_TCPIP_MSG_CALLBACK,
+ SPL_TCPIP_MSG_IP_MODULE,
+
+ SPL_TCPIP_MSG_MAX, //the number of enum
+ SPL_TCPIP_MSG_BOTTOM = MAX_MAJOR_TYPE //the max number of enum
+};
+
+enum api_msg_type
+{
+ SPL_API_DO_NEWCONN = 0,
+ SPL_API_DO_DELCON,
+ SPL_API_DO_RECV,
+ SPL_API_DO_GETADDR,
+ SPL_API_DO_BIND,
+ SPL_API_DO_CONNECT,
+ SPL_API_DO_LISTEN,
+ SPL_API_DO_CLOSE,
+ SPL_API_DO_SET_SOCK_OPT,
+ SPL_API_DO_GET_SOCK_OPT,
+ SPL_API_DO_SEND,
+ SPL_API_DO_WRITE,
+ SPL_API_DO_POST,
+ SPL_API_DO_SHOW,
+ SPL_API_DO_EXTREN_SOCK_SET,
+ SPL_API_DO_ENABLE_TRACE,
+ SPL_API_GET_PROTOCOL,
+ SPL_API_DO_IOCTL_OPT,
+ SPL_API_DO_GETSOCK_NAME,
+ SPL_API_DO_DUMP_L4,
+ SPL_API_DO_PBUF_FREE,
+ SPL_API_DO_APP_TOUCH, /* app send its version info to nStackMain */
+
+ SPL_API_MSG_MAX, //the number of enum
+ SPL_API_MSG_BOTTOM = MAX_MINOR_TYPE //the max number of enum
+};
+
+/* TODO: move thes to apporpriate file */
+#define TCP_RTO_MAX ((unsigned)(120*1000)) /* 120s */
+#define TCP_RTO_MIN ((unsigned)(200)) /* 200ms */
+
+#define TCP_TIMEOUT_INIT ((unsigned)(1*1000)) /* RFC6298 2.1 initial RTO value */
+#define CONN_TCP_MEM_MIN_LINE ((TX_MBUF_POOL_SIZE)/1024) //conn level : min value of send_buf
+#define CONN_TCP_MEM_DEF_LINE ((TX_MBUF_POOL_SIZE)/128) //conn level : default value of send_buf
+#define CONN_TCP_MEM_MAX_LINE ((TX_MBUF_POOL_SIZE)/12)
+
+#define SOF_DEBUG 0x01U
+#define SOF_ACCEPTCONN 0x02U
+#define SOF_DONTROUTE 0x10U
+#define SOF_USELOOPBACK 0x40U
+#define SOF_LINGER 0x80U
+#define SOF_OOBINLINE 0x0100U
+#define SOF_REUSEPORT 0x0200U
+
+/* General structure for calling APIs*/
+typedef struct api_param_t
+{
+ data_com_msg *m;
+ i64 comm_private_data;
+} api_param;
+
+/* SPL_API_DO_SEND */
+typedef struct
+{
+ PRIMARY_ADDR struct spl_pbuf *p;
+ spl_ip_addr_t local_ip;
+ spl_ip_addr_t addr;
+ spl_ip_addr_t srcAddr;
+ u16 port;
+ u16 srcPort;
+ u16 toport_chksum;
+ u8 tos;
+ u8 pad;
+ u8 flags;
+ i64 extend_member_bit;
+} msg_send_buf;
+
+/* SPL_API_DO_BIND */
+typedef struct
+{
+ spl_ip_addr_t ipaddr;
+ u16 port;
+ i64 extend_member_bit;
+} msg_bind;
+
+/* SPL_API_DO_CLOSE */
+typedef struct
+{
+ long time_started;
+ u8 shut;
+ i64 extend_member_bit;
+} msg_close;
+
+/* SPL_API_DO_CONNECT */
+typedef struct
+{
+ spl_ip_addr_t local_ip;
+ spl_ip_addr_t ipaddr;
+ u16 port;
+ i64 extend_member_bit;
+} msg_connect;
+
+/* SPL_API_DO_DELCON */
+typedef struct
+{
+ PRIMARY_ADDR struct spl_netconn *conn;
+ PRIMARY_ADDR struct spl_pbuf *buf;
+ long time_started;
+ pid_t pid;
+ u8 shut;
+ u8 msg_box_ref; /* use it for priority */
+ u8 notify_omc; /* bool */
+ i64 extend_member_bit;
+} msg_delete_netconn;
+
+/* SPL_API_DO_WRITE */
+typedef struct msg_write_buf_T
+{
+ PRIMARY_ADDR struct spl_pbuf *p;
+ struct msg_write_buf_T *next;
+ size_t len;
+ u8 apiflags;
+ i64 extend_member_bit;
+} msg_write_buf;
+
+/* SPL_API_DO_LISTEN */
+typedef struct
+{
+ mring_handle conn_pool;
+ u8 backlog;
+ i64 extend_member_bit;
+} msg_listen;
+
+/* SPL_API_DO_NEWCONN */
+typedef struct
+{
+ PRIMARY_ADDR struct spl_netconn *conn;
+ spl_netconn_type_t type;
+ u8 proto;
+ int socket;
+ i64 extend_member_bit;
+} msg_new_netconn;
+
+/* SPL_API_DO_RECV */
+typedef struct
+{
+ PRIMARY_ADDR struct spl_pbuf *p;
+ u32 len;
+ i64 extend_member_bit;
+} msg_recv_buf;
+
+/* SPL_API_DO_GETSOCK_NAME */
+typedef struct
+{
+ struct sockaddr sock_addr;
+ u8 cmd;
+ i64 extend_member_bit;
+} msg_getaddrname;
+
+/* SPL_API_DO_GET_SOCK_OPT,SPL_API_DO_SET_SOCK_OPT */
+typedef struct
+{
+ int level;
+ int optname;
+ PRIMARY_ADDR mring_handle msg_box; /* IP_TOS, spl will get new msg box for app */
+ union
+ {
+ int int_optval;
+ //struct in_addr inaddr_optval;
+ //struct linger _linger;
+ struct timeval timeval_optval;
+ struct tcp_info tpinfo;
+ //ipmreq ipmreq_optval; //Multicast support later
+ } optval;
+
+ u32 optlen;
+ i64 extend_member_bit;
+} msg_setgetsockopt;
+
+/* SPL_API_DO_PBUF_FREE */
+typedef struct
+{
+ PRIMARY_ADDR struct spl_pbuf *buf;
+ i64 extend_member_bit;
+} msg_free_buf;
+
+/* app send its version info to nStackMain */
+#define NSTACK_VERSION_LEN 128
+/* SPL_API_DO_APP_TOUCH */
+typedef struct
+{
+ u32_t hostpid;
+ char app_version[NSTACK_VERSION_LEN];
+} msg_app_touch;
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+}
+/* *INDENT-ON* */
+#endif
+
+#endif
diff --git a/stacks/lwip_stack/lwip_src/common/stackx_spl_share.c b/stacks/lwip_stack/lwip_src/common/stackx_spl_share.c
new file mode 100644
index 0000000..a0cb5f3
--- /dev/null
+++ b/stacks/lwip_stack/lwip_src/common/stackx_spl_share.c
@@ -0,0 +1,192 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#include "stackx_spl_msg.h"
+#include "stackx_spl_share.h"
+#include "nstack_log.h"
+#include "nsfw_msg_api.h"
+#include "nsfw_recycle_api.h"
+
+/*****************************************************************************
+* Prototype : ss_reset_conn_recycle
+* Description : reset conn recycle
+* Input : netconn_recycle* recycle
+* Output : None
+* Return Value : static inline void
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+static inline void ss_reset_conn_recycle(netconn_recycle * recycle)
+{
+ recycle->accept_from = NULL;
+ recycle->is_listen_conn = 0;
+ (void) nsfw_pidinfo_init(&recycle->pid_info);
+ recycle->fork_ref = 0;
+ recycle->delay_msg = NULL;
+ recycle->delay_flag = SS_DELAY_STOPPED;
+}
+
+/*****************************************************************************
+* Prototype : ss_reset_conn
+* Description : reset conn
+* Input : spl_netconn_t* conn
+* Output : None
+* Return Value : void
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+void ss_reset_conn(spl_netconn_t * conn)
+{
+ conn->recv_obj = 0;
+ conn->private_data = 0;
+ conn->msg_box = NULL;
+ conn->snd_buf = 0;
+ conn->epoll_flag = 0;
+ conn->recv_avail_prod = 0;
+ conn->recv_avail_cons = 0;
+ conn->rcvevent = 0;
+ conn->state = SPL_NETCONN_NONE;
+ conn->sendevent = 0;
+ conn->errevent = 0;
+ conn->shut_status = 0xFFFF;
+ conn->flags = 0;
+ conn->last_err = 0;
+ conn->CanNotReceive = 0;
+ conn->bind_thread_index = 0;
+ conn->tcp_sndbuf = 0;
+ conn->tcp_wmem_alloc_cnt = 0;
+ conn->tcp_wmem_sbr_free_cnt = 0;
+ conn->tcp_wmem_spl_free_cnt = 0;
+ conn->mss = 0;
+ conn->remote_port = 0;
+ conn->remote_ip.addr = 0;
+ conn->local_ip.addr = 0;
+ conn->local_port = 0;
+ conn->type = SPL_NETCONN_INVALID;
+ conn->tcp_state = SPL_CLOSED;
+ ss_reset_conn_recycle(&conn->recycle);
+ conn->extend_member_bit = 0;
+ conn->epInfo = NULL;
+}
+
+/*****************************************************************************
+* Prototype : ss_init_conn
+* Description : init conn
+* Input : spl_netconn_t* conn
+* Output : None
+* Return Value : void
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+static inline void
+ss_init_conn(spl_netconn_t * conn, mring_handle pool, spl_netconn_type_t type)
+{
+ res_alloc(&conn->res_chk);
+
+ conn->type = type;
+ conn->recycle.fork_ref = 1;
+ conn->recv_ring_valid = 1;
+ sys_sem_init(&conn->close_completed);
+ NSSBR_LOGINF("malloc conn ok]conn=%p,pool=%p", conn, pool);
+}
+
+/*****************************************************************************
+* Prototype : ss_malloc_conn
+* Description : malloc conn, only used in spl
+* Input : mring_handle pool
+* netconn_type_t type
+* Output : None
+* Return Value : spl_netconn_t*
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+spl_netconn_t *ss_malloc_conn(mring_handle pool, spl_netconn_type_t type)
+{
+ spl_netconn_t *conn = NULL;
+
+ if (nsfw_mem_ring_dequeue(pool, (void **) &conn) != 1)
+ {
+ NSSBR_LOGERR("malloc conn failed");
+ return NULL;
+ }
+
+ ss_init_conn(conn, pool, type);
+ return conn;
+}
+
+/*****************************************************************************
+* Prototype : ss_malloc_conn_app
+* Description : malloc conn, only used in app
+* Input : mring_handle pool
+* netconn_type_t type
+* Output : None
+* Return Value : spl_netconn_t*
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+spl_netconn_t *ss_malloc_conn_app(mring_handle pool, spl_netconn_type_t type)
+{
+ spl_netconn_t *conn = NULL;
+
+ if (nsfw_mem_ring_dequeue(pool, (void **) &conn) != 1)
+ {
+ NSSBR_LOGERR("malloc conn failed");
+ return NULL;
+ }
+
+ if (ss_add_pid(conn, get_sys_pid()) < 0)
+ {
+ NSSBR_LOGERR("ss_add_pid failed]conn=%p", conn);
+ }
+
+ ss_init_conn(conn, pool, type);
+ return conn;
+}
+
+/*****************************************************************************
+* Prototype : ss_free_conn
+* Description : free conn
+* Input : spl_netconn_t* conn
+* mring_handle pool
+* Output : None
+* Return Value : void
+* Calls :
+* Called By :
+*
+*****************************************************************************/
+void ss_free_conn(spl_netconn_t * conn)
+{
+ ss_reset_conn(conn);
+
+ if (res_free(&conn->res_chk))
+ {
+ NSFW_LOGERR("conn refree!]conn=%p", conn);
+ return;
+ }
+
+ mring_handle pool = ss_get_conn_pool(conn);
+ if (nsfw_mem_ring_enqueue(pool, (void *) conn) != 1)
+ {
+ NSSBR_LOGERR("nsfw_mem_ring_enqueue failed,this can not happen");
+ }
+
+ NSSBR_LOGINF("free conn ok]conn=%p,pool=%p", conn, pool);
+}
diff --git a/stacks/lwip_stack/lwip_src/common/stackx_spl_share.h b/stacks/lwip_stack/lwip_src/common/stackx_spl_share.h
new file mode 100644
index 0000000..3dcaf70
--- /dev/null
+++ b/stacks/lwip_stack/lwip_src/common/stackx_spl_share.h
@@ -0,0 +1,444 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef STACKX_SPL_SHARE_H
+#define STACKX_SPL_SHARE_H
+#include "types.h"
+#include "common_mem_api.h"
+#include "nsfw_mem_api.h"
+#include "common_pal_bitwide_adjust.h"
+#include "stackx_ip_addr.h"
+#include <sys/types.h>
+#include "spl_opt.h"
+#include "stackx_ip_tos.h"
+#include "stackx_common_opt.h"
+#include "stackx_tx_box.h"
+#include "pidinfo.h"
+//#include "stackx_dfx_api.h"
+#include "compiling_check.h"
+#include "nsfw_msg.h"
+#include "stackx_spl_msg.h"
+#include "nsfw_hal_api.h"
+#include "stackx_types.h"
+#include <errno.h>
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+extern "C" {
+/* *INDENT-ON* */
+#endif
+
+#define MSG_PRIO_QUEUE_NUM 3
+COMPAT_PROTECT_RETURN(MSG_PRIO_QUEUE_NUM, 3);
+
+#define SPL_MSG_BOX_NUM (MSG_PRIO_QUEUE_NUM + 1)
+
+#define SBR_FD_NETCONN_SIZE (256 * 3)
+COMPAT_PROTECT_RETURN(SBR_FD_NETCONN_SIZE, 256 * 3);
+
+#define SS_NETCONN_SIZE (256 * 2)
+#define SBR_FD_SIZE (SBR_FD_NETCONN_SIZE - SS_NETCONN_SIZE)
+
+typedef struct
+{
+ PRIMARY_ADDR mring_handle msg_pool;
+ PRIMARY_ADDR mring_handle conn_pool;
+ PRIMARY_ADDR struct spl_netconn **conn_array;
+ u32 conn_num;
+ i64 extend_member_bit;
+} sbr_recycle_group;
+
+typedef enum
+{
+ SS_DELAY_STARTED,
+ SS_DELAY_STOPPING,
+ SS_DELAY_STOPPED,
+ SS_DELAY_AGAIN
+} ss_delay_flag;
+
+typedef enum
+{
+ NORMAL_RECV_RING = 0,
+ CUSTOM_RECV_RING = 1,
+} recv_ring_type;
+
+typedef struct
+{
+ PRIMARY_ADDR sbr_recycle_group *group;
+ PRIMARY_ADDR struct spl_netconn *accept_from; /* for recycle fd in listen */
+ void *delay_msg;
+ nsfw_pidinfo pid_info;
+ volatile i16 fork_ref;
+ i8 is_listen_conn;
+ i8 delay_flag;
+} netconn_recycle;
+
+typedef struct spl_netconn
+{
+ i64 recv_obj;
+ i64 comm_pcb_data; /* only used by spl */
+ i64 private_data; /* only used by spl */
+ PRIMARY_ADDR mring_handle msg_box;
+ PRIMARY_ADDR mring_handle recv_ring;
+ volatile u32 snd_buf;
+ volatile i32 epoll_flag;
+ /*here using prod/cons to instead recv_avail, avoid atomic oper. */
+ volatile u32_t recv_avail_prod; /*the product of recv_avail */
+ volatile u32_t recv_avail_cons; /*the consume of recv_avail */
+ volatile i32 rcvevent;
+ spl_netconn_state_t state;
+ u16 sendevent;
+ u16 errevent;
+ volatile u16 shut_status;
+ u8 flags;
+ i8 last_err;
+ u8 CanNotReceive;
+ u8 recv_ring_valid;
+ u16 bind_thread_index;
+ u16 mss;
+ sys_sem_st close_completed;
+ mring_handle conn_pool; /* where the conn in pcb is from */
+
+ void *epInfo;
+
+ /* The following shared field access rules: protocol stack process
+ * is responsible for writing, socket api process read only
+ */
+ i32 send_bufsize;
+ i32 tcp_sndbuf;
+ u32 tcp_wmem_alloc_cnt;
+ u32 tcp_wmem_sbr_free_cnt;
+ volatile u32 tcp_wmem_spl_free_cnt;
+ u16 remote_port;
+ u16 local_port;
+ spl_ip_addr_t remote_ip;
+ spl_ip_addr_t local_ip;
+ spl_netconn_type_t type;
+ spl_tcp_state_t tcp_state;
+
+ /* for recycle */
+ netconn_recycle recycle;
+ nsfw_res res_chk;
+ i64 extend_member_bit;
+} spl_netconn_t; /* sizeof(spl_netconn_t) need < SS_NETCONN_SIZE */
+SIZE_OF_TYPE_PLUS8_NOT_LARGER_THAN_RETURN(spl_netconn_t, SS_NETCONN_SIZE);
+
+typedef struct
+{
+ /**
+ * it will increase after every restart which used for
+ * tell different runnings.
+ */
+ u32 running_ref_no;
+
+ /* only increased when fault to restart */
+ u32 fault_ref_no;
+
+ /* the procedures before upgrade are finished successfully */
+ u32 prepare_upgrade_done;
+
+} spl_init_info_t;
+
+typedef struct netifExt
+{
+ struct netifExt *next;
+ u16_t id;
+ char if_name[HAL_MAX_NIC_NAME_LEN];
+ hal_hdl_t hdl;
+ u16_t num_packets_recv;
+} netifExt;
+
+static inline mring_handle ss_get_msg_pool(spl_netconn_t * sh)
+{
+ sbr_recycle_group *group =
+ (sbr_recycle_group *) ADDR_SHTOL(sh->recycle.group);
+ return ADDR_SHTOL(group->msg_pool);
+}
+
+static inline mring_handle ss_get_conn_pool(spl_netconn_t * sh)
+{
+ sbr_recycle_group *group =
+ (sbr_recycle_group *) ADDR_SHTOL(sh->recycle.group);
+ return ADDR_SHTOL(group->conn_pool);
+}
+
+static inline int ss_is_nonblock_flag(spl_netconn_t * sh)
+{
+ return (sh->flags & SPL_NETCONN_FLAG_NON_BLOCKING) != 0;
+}
+
+static inline int ss_get_nonblock_flag(spl_netconn_t * sh)
+{
+ return ss_is_nonblock_flag(sh) ? O_NONBLOCK : 0;
+}
+
+static inline void ss_set_nonblock_flag(spl_netconn_t * sh, u32 flag)
+{
+ if (flag)
+ {
+ sh->flags |= SPL_NETCONN_FLAG_NON_BLOCKING;
+ }
+ else
+ {
+ sh->flags &= ~SPL_NETCONN_FLAG_NON_BLOCKING;
+ }
+}
+
+static inline int ss_get_last_errno(spl_netconn_t * sh)
+{
+ return sh->last_err;
+}
+
+static inline i32 ss_get_recv_event(spl_netconn_t * sh)
+{
+ return sh->rcvevent;
+}
+
+static inline int ss_can_not_recv(spl_netconn_t * sh)
+{
+ return sh->CanNotReceive;
+}
+
+static inline int ss_is_shut_rd(spl_netconn_t * sh)
+{
+ int status = sh->shut_status;
+ return ((SPL_SHUT_RD == status) || (SPL_SHUT_RDWR == status));
+}
+
+static inline void ss_set_shut_status(spl_netconn_t * sh, u16 how)
+{
+ sh->shut_status = how;
+}
+
+static inline u16 ss_get_shut_status(spl_netconn_t * sh)
+{
+ return sh->shut_status;
+}
+
+static inline void ss_sub_recv_event(spl_netconn_t * sh)
+{
+ __sync_fetch_and_sub(&sh->rcvevent, 1);
+}
+
+static inline void ss_add_recv_event(spl_netconn_t * sh)
+{
+ __sync_fetch_and_add(&sh->rcvevent, 1);
+}
+
+static inline i64 ss_get_recv_obj(spl_netconn_t * sh)
+{
+ return sh->recv_obj;
+}
+
+static inline i64 ss_get_private_data(spl_netconn_t * sh)
+{
+ return sh->private_data;
+}
+
+static inline i64 ss_get_comm_private_data(spl_netconn_t * sh)
+{
+ return sh->comm_pcb_data;
+}
+
+static inline int ss_recv_ring_valid(spl_netconn_t * sh)
+{
+ return sh->recv_ring_valid;
+}
+
+static inline mring_handle ss_get_recv_ring(spl_netconn_t * sh)
+{
+ return (mring_handle) ADDR_SHTOL(sh->recv_ring);
+}
+
+static inline void ss_set_send_event(spl_netconn_t * sh, u16 value)
+{
+ sh->sendevent = value;
+}
+
+static inline int ss_is_noautorecved_flag(spl_netconn_t * sh)
+{
+ return (sh->flags & SPL_NETCONN_FLAG_NO_AUTO_RECVED) != 0;
+}
+
+static inline int ss_get_noautorecved_flag(spl_netconn_t * sh)
+{
+ return ss_is_noautorecved_flag(sh) ? SPL_NETCONN_FLAG_NO_AUTO_RECVED : 0;
+}
+
+static inline void ss_set_noautorecved_flag(spl_netconn_t * sh, u8 flag)
+{
+ if (flag)
+ {
+ sh->flags |= SPL_NETCONN_FLAG_NO_AUTO_RECVED;
+ }
+ else
+ {
+ sh->flags &= ~SPL_NETCONN_FLAG_NO_AUTO_RECVED;
+ }
+}
+
+static inline void ss_set_state(spl_netconn_t * sh, spl_netconn_state_t state)
+{
+ sh->state = state;
+}
+
+static inline int ss_is_write_state(spl_netconn_t * sh)
+{
+ return (SPL_NETCONN_WRITE == sh->state);
+}
+
+static inline int ss_is_listen_state(spl_netconn_t * sh)
+{
+ return (SPL_NETCONN_LISTEN == sh->state);
+}
+
+static inline void ss_sub_recv_avail(spl_netconn_t * sh, int value)
+{
+ sh->recv_avail_cons += value;
+}
+
+static inline i32 ss_get_recv_avail(spl_netconn_t * sh)
+{
+ return sh->recv_avail_prod - sh->recv_avail_cons;
+}
+
+static inline u16 ss_get_mss(spl_netconn_t * sh)
+{
+ return sh->mss;
+}
+
+static inline spl_ip_addr_t *ss_get_remote_ip(spl_netconn_t * sh)
+{
+ return &(sh->remote_ip);
+}
+
+static inline u16 ss_get_remote_port(spl_netconn_t * sh)
+{
+ return sh->remote_port;
+}
+
+static inline spl_tcp_state_t ss_get_tcp_state(spl_netconn_t * sh)
+{
+ return sh->tcp_state;
+}
+
+static inline u16 ss_get_bind_thread_index(spl_netconn_t * sh)
+{
+ return sh->bind_thread_index;
+}
+
+static inline void
+ss_set_bind_thread_index(spl_netconn_t * sh, u16 bind_thread_index)
+{
+ sh->bind_thread_index = bind_thread_index;
+}
+
+static inline void ss_set_msg_box(spl_netconn_t * sh, mring_handle box)
+{
+ sh->msg_box = (mring_handle) ADDR_LTOSH(box);
+}
+
+static inline mring_handle ss_get_msg_box(spl_netconn_t * sh)
+{
+ return (mring_handle) ADDR_SHTOL(sh->msg_box);
+}
+
+static inline spl_ip_addr_t *ss_get_local_ip(spl_netconn_t * sh)
+{
+ return &sh->local_ip;
+}
+
+static inline void ss_set_local_ip(spl_netconn_t * sh, u32 addr)
+{
+ if (!sh)
+ {
+ return;
+ }
+ sh->local_ip.addr = addr;
+}
+
+static inline u16 ss_get_local_port(spl_netconn_t * sh)
+{
+ return sh->local_port;
+}
+
+static inline void ss_set_local_port(spl_netconn_t * sh, u16 local_port)
+{
+ sh->local_port = local_port;
+}
+
+static inline void
+ss_set_accept_from(spl_netconn_t * sh, spl_netconn_t * accept_from)
+{
+ sh->recycle.accept_from = accept_from;
+}
+
+static inline void
+ss_set_is_listen_conn(spl_netconn_t * sh, i8 is_listen_conn)
+{
+ sh->recycle.is_listen_conn = is_listen_conn;
+}
+
+static inline i32 ss_inc_fork_ref(spl_netconn_t * sh)
+{
+ return __sync_add_and_fetch(&sh->recycle.fork_ref, 1);
+}
+
+static inline i32 ss_dec_fork_ref(spl_netconn_t * sh)
+{
+ return __sync_sub_and_fetch(&sh->recycle.fork_ref, 1);
+}
+
+static inline i32 ss_get_fork_ref(spl_netconn_t * sh)
+{
+ return sh->recycle.fork_ref;
+}
+
+static inline int ss_add_pid(spl_netconn_t * sh, pid_t pid)
+{
+ return nsfw_add_pid(&sh->recycle.pid_info, pid);
+}
+
+static inline int ss_del_pid(spl_netconn_t * sh, pid_t pid)
+{
+ return nsfw_del_pid(&sh->recycle.pid_info, pid);
+}
+
+static inline int ss_is_pid_exist(spl_netconn_t * sh, pid_t pid)
+{
+ return nsfw_pid_exist(&sh->recycle.pid_info, pid);
+}
+
+static inline int ss_is_pid_array_empty(spl_netconn_t * sh)
+{
+ return nsfw_pidinfo_empty(&sh->recycle.pid_info);
+}
+
+spl_netconn_t *ss_malloc_conn(mring_handle pool, spl_netconn_type_t type);
+spl_netconn_t *ss_malloc_conn_app(mring_handle pool, spl_netconn_type_t type);
+void ss_free_conn(spl_netconn_t * conn);
+void ss_reset_conn(spl_netconn_t * conn);
+
+typedef void (*ss_close_conn_fun) (void *close_data, u32 delay_sec);
+int ss_recycle_conn(void *close_data, ss_close_conn_fun close_conn);
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+}
+/* *INDENT-ON* */
+#endif
+
+#endif
diff --git a/stacks/lwip_stack/lwip_src/common/stackx_tcp_opt.h b/stacks/lwip_stack/lwip_src/common/stackx_tcp_opt.h
new file mode 100644
index 0000000..cac3dcb
--- /dev/null
+++ b/stacks/lwip_stack/lwip_src/common/stackx_tcp_opt.h
@@ -0,0 +1,42 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef __STACKX_TCP_OPT_H__
+#define __STACKX_TCP_OPT_H__
+
+#include "spl_opt.h"
+
+/* TCP Options flags */
+#define TF_ACK_DELAY ((u32_t)0x01U) /* Delayed ACK. */
+#define TF_ACK_NOW ((u32_t)0x02U) /* Immediate ACK. */
+#define TF_WINDOWSCALING ((u32_t)0x40U) /* Window scaling option enabled */
+#define TF_INFR ((u32_t)0x04U) /* In fast recovery. */
+#define TF_TIMESTAMP ((u32_t)0x08U) /* Timestamp option enabled */
+#define TF_RXCLOSED ((u32_t)0x10U) /* rx closed by tcp_shutdown */
+#define TF_FIN ((u32_t)0x20U) /* Connection was closed locally (FIN segment enqueued). */
+#define TF_NODELAY ((u32_t)0x100U) /* Disable Nagle algorithm */
+#define TF_NAGLEMEMERR ((u32_t)0x80U)
+
+/* TCP segment Options flags */
+#define TF_SEG_OPTS_MSS (u8_t)0x01U /* Include MSS option. */
+#define TF_SEG_OPTS_TS (u8_t)0x02U /* Include timestamp option. */
+#define TF_SEG_OPTS_WS (u8_t)0x08U /* Include window scaling option. */
+
+#define STACKX_TCP_OPT_LENGTH(flags) \
+ (flags & TF_SEG_OPTS_MSS ? 4 : 0) + \
+ (flags & TF_SEG_OPTS_TS ? 12 : 0) + \
+ (flags & TF_SEG_OPTS_WS ? 4 : 0)
+#endif
diff --git a/stacks/lwip_stack/lwip_src/common/stackx_tx_box.c b/stacks/lwip_stack/lwip_src/common/stackx_tx_box.c
new file mode 100644
index 0000000..e7694ae
--- /dev/null
+++ b/stacks/lwip_stack/lwip_src/common/stackx_tx_box.c
@@ -0,0 +1,62 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#include "stackxopts.h"
+#include "nstack_log.h"
+#include "stackx_tx_box.h"
+#include "nsfw_mt_config.h"
+
+#define MZ_STACKX_RING_NAME "VppTCP_Ring"
+#define MZ_STACKX_PRIORITY_RING_NAME "VppTCP_Priority%u_Ring"
+
+/*
+ * Given the stackx ring name template above, get the queue name
+ */
+const char *get_stackx_ring_name()
+{
+ /* buffer for return value. Size calculated by %u being replaced
+ * by maximum 3 digits (plus an extra byte for safety) */
+ static char rbuffer[sizeof(MZ_STACKX_RING_NAME) + 16];
+
+ int retVal =
+ spl_snprintf(rbuffer, sizeof(rbuffer) - 1, MZ_STACKX_RING_NAME);
+
+ if (-1 == retVal)
+ {
+ NSPOL_LOGERR("spl_snprintf failed]");
+ return NULL;
+ }
+
+ return rbuffer;
+}
+
+const char *get_stackx_priority_ring_name(unsigned priority)
+{
+ /* buffer for return value. Size calculated by %u being replaced
+ * by maximum 3 digits (plus an extra byte for safety) */
+ static char prbuffer[sizeof(MZ_STACKX_PRIORITY_RING_NAME) + 32];
+
+ int retVal = spl_snprintf(prbuffer, sizeof(prbuffer) - 1,
+ MZ_STACKX_PRIORITY_RING_NAME, priority);
+
+ if (-1 == retVal)
+ {
+ NSPOL_LOGERR("spl_snprintf failed]");
+ return NULL;
+ }
+
+ return prbuffer;
+}
diff --git a/stacks/lwip_stack/lwip_src/common/stackx_tx_box.h b/stacks/lwip_stack/lwip_src/common/stackx_tx_box.h
new file mode 100644
index 0000000..611ecfe
--- /dev/null
+++ b/stacks/lwip_stack/lwip_src/common/stackx_tx_box.h
@@ -0,0 +1,39 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef STACKX_TX_BOX_H
+#define STACKX_TX_BOX_H
+#include "sys/types.h"
+#include "nsfw_mem_api.h"
+#include "stackx_common.h"
+#include "nsfw_mt_config.h"
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+extern "C" {
+/* *INDENT-ON* */
+#endif
+
+const char *get_stackx_ring_name();
+const char *get_stackx_priority_ring_name(unsigned priority);
+
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+}
+/* *INDENT-ON* */
+#endif
+
+#endif
diff --git a/stacks/lwip_stack/lwip_src/common/stackx_types.h b/stacks/lwip_stack/lwip_src/common/stackx_types.h
new file mode 100644
index 0000000..6c78a20
--- /dev/null
+++ b/stacks/lwip_stack/lwip_src/common/stackx_types.h
@@ -0,0 +1,68 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef STACKX_TYPES_H
+#define STACKX_TYPES_H
+
+#include <sys/time.h>
+#include <sys/types.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#if 1
+#ifndef STACKX_MAX_S16_NUM
+#define STACKX_MAX_S16_NUM ((s16_t)0x7fff)
+#endif
+
+#ifndef STACKX_MAX_U16_NUM
+#define STACKX_MAX_U16_NUM ((u16_t)0xFfff)
+#endif
+
+#ifndef STACKX_MAX_U32_NUM
+#define STACKX_MAX_U32_NUM ((u32_t)0xffffffff)
+#endif
+
+#ifndef STACKX_MAX_S32_NUM
+#define STACKX_MAX_S32_NUM ((s32_t)0x7fffffff)
+#endif
+
+#ifndef STACKX_MAX_U64_NUM
+#define STACKX_MAX_U64_NUM ((u64_t)0xffffffffffffffff)
+#endif
+
+#ifndef STACKX_MAX_S64_NUM
+#define STACKX_MAX_S64_NUM ((s64_t)0x7fffffffffffffff)
+#endif
+#endif
+
+#if 1
+typedef uint64_t u64_t;
+typedef int64_t s64_t;
+
+typedef uint32_t u32_t;
+typedef int32_t s32_t;
+
+typedef uint16_t u16_t;
+typedef int16_t s16_t;
+
+typedef uint8_t u8_t;
+typedef int8_t s8_t;
+
+typedef uintptr_t mem_ptr_t;
+#endif
+
+#endif
diff --git a/stacks/lwip_stack/lwip_src/common/stackxopts.h b/stacks/lwip_stack/lwip_src/common/stackxopts.h
new file mode 100644
index 0000000..6c95499
--- /dev/null
+++ b/stacks/lwip_stack/lwip_src/common/stackxopts.h
@@ -0,0 +1,53 @@
+/*
+*
+* Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at:
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef STACKX_OPTS_H
+#define STACKX_OPTS_H
+
+struct memory_statics
+{
+ char name[120];
+ long size;
+};
+
+extern u32 g_type;
+extern struct memory_statics memory_used_size[80];
+
+#define DPDK_MEMORY_COUNT(memory, len)\
+{\
+ if (g_type < MAX_MEMORY_USED_SIZE)\
+ {\
+ const char * ptr_memory = memory;\
+ if (ptr_memory && EOK != strcpy_s(memory_used_size[g_type].name, sizeof(memory_used_size[g_type].name), ptr_memory))\
+ {\
+ NSPOL_LOGERR("STRCPY_S failed.");\
+ }\
+ memory_used_size[g_type].size =(long) len;\
+ g_type++;\
+ }\
+}
+
+#define SPL_MAX_UDP_MSG_LEN (0xFFFF -28)
+#define RECV_MAX_POOL 4
+#define MAX_TRY_GET_MEMORY_TIMES 4
+#define MAX_MEMORY_USED_SIZE 80
+#define SPL_IP_HLEN 20
+#define SPL_TCP_HLEN 20
+#define SPL_TCP_MAX_OPTION_LEN 40
+#define SPL_FRAME_MTU 1500
+#define SPL_TCP_SEND_MAX_SEG_PER_MSG 5
+
+#endif