1e41f4b71Sopenharmony_ci# New IP内核协议栈介绍
2e41f4b71Sopenharmony_ci
3e41f4b71Sopenharmony_ci
4e41f4b71Sopenharmony_ci## 基本概念
5e41f4b71Sopenharmony_ci
6e41f4b71Sopenharmony_ciNew IP在现有IP能力的基础上,以灵活轻量级报头和可变长多语义地址为基础,通过二三层协议融合,对协议去冗和压缩,减少冗余字节,实现高能效比,高净吞吐,提升通信效率。打造终端之间高效的横向通信,支撑超级终端的体验,实现异构网络的端到端互联。
7e41f4b71Sopenharmony_ci
8e41f4b71Sopenharmony_ci目前WiFi协议报文,三层报头和地址开销使得报文开销大,传输效率较低。
9e41f4b71Sopenharmony_ci
10e41f4b71Sopenharmony_ci![zh-cn_image-20220915162621809](figures/zh-cn_image-20220915162621809.png)
11e41f4b71Sopenharmony_ci
12e41f4b71Sopenharmony_ci```
13e41f4b71Sopenharmony_ciIPv4地址长度固定4字节,IPv6地址长度固定16字节。
14e41f4b71Sopenharmony_ciIPv4网络层报头长度20~60字节,IPv6网络层报头长度40字节。
15e41f4b71Sopenharmony_ci```
16e41f4b71Sopenharmony_ci
17e41f4b71Sopenharmony_ciNew IP支持**可变长多语义地址(最短1字节)**,**可变长定制化报头封装(最短5字节)**,通过精简报文头开销,提升数据传输效率。
18e41f4b71Sopenharmony_ci
19e41f4b71Sopenharmony_ciNew IP报头开销,相比IPv4节省25.9%,相比IPv6节省44.9%。
20e41f4b71Sopenharmony_ci
21e41f4b71Sopenharmony_ciNew IP载荷传输效率,相比IPv4提高最少1%,相比IPv6提高最少2.33%。
22e41f4b71Sopenharmony_ci
23e41f4b71Sopenharmony_ci| 对比场景        | 报头开销     | 载荷传输效率(WiFi MTU=1500B,BT MTU=255B) |
24e41f4b71Sopenharmony_ci| --------------- | ------------ | ------------------------------------------- |
25e41f4b71Sopenharmony_ci| IPv4 for WiFi   | 30+8+20=58 B | (1500-58)/1500=96.13%                       |
26e41f4b71Sopenharmony_ci| IPv6 for WiFi   | 30+8+40=78 B | (1500-78)/1500=94.8%                        |
27e41f4b71Sopenharmony_ci| New IP for WiFi | 30+8+5=43 B  | (1500-43)/1500=97.13%                       |
28e41f4b71Sopenharmony_ci
29e41f4b71Sopenharmony_ci## 可变长报头格式
30e41f4b71Sopenharmony_ci
31e41f4b71Sopenharmony_ciNew IP WiFi灵活极简报文头如下图所示,通过LLC Header中的EtherType = 0xEADD标识New IP报文。Bitmap是一组由0和1组成的二进制序列,每个二进制位的数值用于表示New IP报头中是否携带某个字段,即New IP报文头可以由用户根据业务场景自行定制报头中携带哪些字段。
32e41f4b71Sopenharmony_ci
33e41f4b71Sopenharmony_ci![zh-cn_image-20220915140627223](figures/zh-cn_image-20220915140627223.png)
34e41f4b71Sopenharmony_ci
35e41f4b71Sopenharmony_ci1)	Dispatch:指示封装子类,数值0b0表示其为极简封装子类,长度为1比特;(0b表示后面数值为二进制)。
36e41f4b71Sopenharmony_ci
37e41f4b71Sopenharmony_ci2)	Bitmap:变长,Bitmap默认为紧跟在Dispatch有效位后面的7比特,Bitmap字段长度可持续扩展。Bitmap最后一位置0表示Bitmap结束,最后一位置1表示Bitmap向后扩展1 Byte,直至最后一位置0。
38e41f4b71Sopenharmony_ci3)	Value: 标识字段的值,长度为1 Byte的整数倍,类型及长度由报头字段语义表确定。
39e41f4b71Sopenharmony_ci
40e41f4b71Sopenharmony_ci**Bitmap字段定义如下:**
41e41f4b71Sopenharmony_ci
42e41f4b71Sopenharmony_ci| 极简Bitmap标识               | Bitops | 携带字段的长度   | 置位策略       | 备注                                    |
43e41f4b71Sopenharmony_ci| ---------------------------- | ------ | ---------------- | -------------- | --------------------------------------- |
44e41f4b71Sopenharmony_ci| Bitmap 1st Byte:             | -      | -                | -              | 下面8bit是从高位到低位排列。            |
45e41f4b71Sopenharmony_ci| 标记位Dispatch               | 0      | -                | 置0            | 0:极简封装报头,1:非极简封装报头。    |
46e41f4b71Sopenharmony_ci| 报文头是否携带TTL            | 1      | 1 Byte           | 置1            | 剩余跳数。                              |
47e41f4b71Sopenharmony_ci| 报文头是否携带Total Length   | 2      | 2 Byte           | UDP置0,TCP置1 | New IP报文总长度(包含报头长度)。      |
48e41f4b71Sopenharmony_ci| 报文头是否携带Next Header    | 3      | 1 Byte           | 置1            | 协议类型。                              |
49e41f4b71Sopenharmony_ci| Reserve                      | 4      | 保留             | 置0            | 保留字段。                              |
50e41f4b71Sopenharmony_ci| 报文头是否携带Dest Address   | 5      | 变长(1~8 Byte) | 置1            | 目的地址。                              |
51e41f4b71Sopenharmony_ci| 报文头是否携带Source Address | 6      | 变长(1~8 Byte) | 由协议自行确定 | 源地址。                                |
52e41f4b71Sopenharmony_ci| 标记位,标志是否有2nd Byte   | 7      | -                | -              | 0:bitmap结束,1:后跟另外8bit bitmap。 |
53e41f4b71Sopenharmony_ci| Bitmap 2nd Byte:             | -      | -                | -              | 下面8bit是从高位到低位排列。            |
54e41f4b71Sopenharmony_ci| 报文头是否携带Header Length  | 0      | 1 Byte           | -              | New IP报头长度。                        |
55e41f4b71Sopenharmony_ci| Reserve                      | 1      | 保留             | 置0            | -                                       |
56e41f4b71Sopenharmony_ci| Reserve                      | 2      | 保留             | 置0            | -                                       |
57e41f4b71Sopenharmony_ci| Reserve                      | 3      | 保留             | 置0            | -                                       |
58e41f4b71Sopenharmony_ci| Reserve                      | 4      | 保留             | 置0            | -                                       |
59e41f4b71Sopenharmony_ci| Reserve                      | 5      | 保留             | 置0            | -                                       |
60e41f4b71Sopenharmony_ci| Reserve                      | 6      | 保留             | 置0            | -                                       |
61e41f4b71Sopenharmony_ci| 标记位,标志是否有3rd Byte   | 7      | -                | -              | 0:bitmap结束,1:后跟另外8bit bitmap。 |
62e41f4b71Sopenharmony_ci
63e41f4b71Sopenharmony_ciNew IP报头(极简封装)解析遇到新bitmap字段时的处理方法:
64e41f4b71Sopenharmony_ci
65e41f4b71Sopenharmony_ci仅解析当前版本协议中已定义的bitmap字段,从第一个未知语义的bitmap字段开始,跳过后面的所有bitmap字段,直接通过header length定位到报文开始位置并解析报文。如果报头中携带了未知语义的bitmap字段,且未携带header length字段,则丢弃该数据包。
66e41f4b71Sopenharmony_ci
67e41f4b71Sopenharmony_ci## 可变长地址格式
68e41f4b71Sopenharmony_ci
69e41f4b71Sopenharmony_ciNew IP支持可变长地址(IPv4/IPv6地址长度固定),支持自解析地址长度,报文头中可以不携带地址长度字段,New IP地址编码格式如下所示:
70e41f4b71Sopenharmony_ci
71e41f4b71Sopenharmony_ci| First Byte | Semantics                                                    | 地址段有效范围                                               |
72e41f4b71Sopenharmony_ci| ---------- | ------------------------------------------------------------ | ------------------------------------------------------------ |
73e41f4b71Sopenharmony_ci| 0x00       | Address is 0                                                 | 【1字节】0 ~ 220 (0x00 ~ 0xDC)                               |
74e41f4b71Sopenharmony_ci| 0x01       | Address is 1                                                 | -                                                            |
75e41f4b71Sopenharmony_ci| 0x02       | Address is 2                                                 | -                                                            |
76e41f4b71Sopenharmony_ci| ...        | ...                                                          | -                                                            |
77e41f4b71Sopenharmony_ci| 0xDC       | Address is 220                                               | -                                                            |
78e41f4b71Sopenharmony_ci| 0xDD       | An 16-bit address, which is 0 + 256 * (0xDD - 0xDD) + the last byte value | 【2字节】221 ~ 255 (0x**DD**DD ~ 0x**DD**FF)                 |
79e41f4b71Sopenharmony_ci| 0xDE       | An 16-bit address, which is 0 + 256 * (0xDE - 0xDD) + the last byte value | 【2字节】256 ~ 511 (0x**DE**00 ~ 0x**DE**FF)                 |
80e41f4b71Sopenharmony_ci| 0xDF       | An 16-bit address, which is 0 + 256 * (0xDF - 0xDD) + the last byte value | 【2字节】512 ~ 767 (0x**DF**00 ~ 0x**DF**FF)                 |
81e41f4b71Sopenharmony_ci| ...        | ...                                                          | -                                                            |
82e41f4b71Sopenharmony_ci| 0xF0       | An 16-bit address, which is 0 + 256 * (0xF0 - 0xDD) + the last byte value | 【2字节】4864 ~ 5119 (0x**F0**00 ~ 0x**F0**FF)               |
83e41f4b71Sopenharmony_ci| 0xF1       | An 16-bit address is followed                                | 【3字节】5120 ~ 65535 (0x**F1** 1400 ~ 0x**F1** FFFF)        |
84e41f4b71Sopenharmony_ci| 0xF2       | An 32-bit address is followed                                | 【5字节】65536 ~ 4,294,967,295 (0x**F2** 0001 0000 ~ 0x**F2** FFFF FFFF) |
85e41f4b71Sopenharmony_ci| 0xF3       | An 48-bit address is followed                                | 【7字节】4,294,967,296 ~ 281,474,976,710,655 (0x**F3** 0001 0000 0000 ~ 0x**F3** FFFF FFFF FFFF) |
86e41f4b71Sopenharmony_ci| 0xFE       | An 56-bit address is followed                                | 【8字节】0 ~ 72,057,594,037,927,935 (0x**FE**00 0000 0000 0000 ~ 0x**FE**FF FFFF FFFF FFFF) |
87e41f4b71Sopenharmony_ci
88e41f4b71Sopenharmony_ci
89e41f4b71Sopenharmony_ci
90e41f4b71Sopenharmony_ci## New IP配置指导
91e41f4b71Sopenharmony_ci
92e41f4b71Sopenharmony_ci### New IP使能
93e41f4b71Sopenharmony_ci
94e41f4b71Sopenharmony_ci目前只有rk3568开发板Linux 5.10内核上支持New IP内核协议栈,在rk3568开发板内核模块配置文件中搜索NEWIP,将其修改成“CONFIG_XXX=y”即可,New IP相关CONFIG如下。
95e41f4b71Sopenharmony_ci
96e41f4b71Sopenharmony_ci```
97e41f4b71Sopenharmony_ci# kernel/linux/config/linux-5.10/arch/arm64/configs/rk3568_standard_defconfig
98e41f4b71Sopenharmony_ciCONFIG_NEWIP=y          // 使能New IP内核协议栈
99e41f4b71Sopenharmony_ciCONFIG_NEWIP_HOOKS=y    // 使能New IP内核侵入式修改插桩函数注册,使能New IP的同时必须使用New IP HOOKS功能
100e41f4b71Sopenharmony_ciHCK_VENDOR_HOOKS=y      // 使能内核插桩基础框架(New IP依赖此配置项,rk3568开发板已默认开启)
101e41f4b71Sopenharmony_ci```
102e41f4b71Sopenharmony_ci
103e41f4b71Sopenharmony_ci代码编译完成后,通过下面命令可以确认New IP协议栈代码是否使能成功。
104e41f4b71Sopenharmony_ci
105e41f4b71Sopenharmony_ci```
106e41f4b71Sopenharmony_cifind out/ -name *nip*.o
107e41f4b71Sopenharmony_ci...
108e41f4b71Sopenharmony_ciout/kernel/OBJ/linux-5.10/net/newip/nip_addrconf_core.o
109e41f4b71Sopenharmony_ciout/kernel/OBJ/linux-5.10/net/newip/nip_hdr_decap.o
110e41f4b71Sopenharmony_ciout/kernel/OBJ/linux-5.10/net/newip/nip_addr.o
111e41f4b71Sopenharmony_ciout/kernel/OBJ/linux-5.10/net/newip/nip_checksum.o
112e41f4b71Sopenharmony_ciout/kernel/OBJ/linux-5.10/net/newip/tcp_nip_output.o
113e41f4b71Sopenharmony_ci...
114e41f4b71Sopenharmony_ci```
115e41f4b71Sopenharmony_ci
116e41f4b71Sopenharmony_ci备注:OpenHarmony linux内核要求所有原生内核代码侵入式修改,都要修改成插桩方式。例如下面IPv4,IPv6协议栈公共流程中增加New IP处理时,不能直接调用New IP函数,需要在公共流程中增加插桩点,New IP使能后在模块初始化时将xx功能函数注册到对应的函数指针上,下面公共流程就可以通过函数指针的形式调用到New IP的函数。
117e41f4b71Sopenharmony_ci
118e41f4b71Sopenharmony_ci```c
119e41f4b71Sopenharmony_ci/* 将New IP ehash函数注册到内核 */
120e41f4b71Sopenharmony_ci/* call the newip hook function in sk_ehashfn function (net\ipv4\inet_hashtables.c):
121e41f4b71Sopenharmony_ci */
122e41f4b71Sopenharmony_civoid nip_ninet_ehashfn(const struct sock *sk, u32 *ret)
123e41f4b71Sopenharmony_ci{
124e41f4b71Sopenharmony_ci	*ret = ninet_ehashfn(sock_net(sk), &sk->SK_NIP_RCV_SADDR,
125e41f4b71Sopenharmony_ci			     sk->sk_num, &sk->SK_NIP_DADDR, sk->sk_dport);
126e41f4b71Sopenharmony_ci}
127e41f4b71Sopenharmony_ci
128e41f4b71Sopenharmony_civoid nip_ninet_ehashfn_lhck_register(void)
129e41f4b71Sopenharmony_ci{
130e41f4b71Sopenharmony_ci	REGISTER_HCK_LITE_HOOK(nip_ninet_ehashfn_lhck, nip_ninet_ehashfn);
131e41f4b71Sopenharmony_ci}
132e41f4b71Sopenharmony_ci
133e41f4b71Sopenharmony_ci/* 下面是IPv4,IPv6协议栈总入口函数,在总入口函数内新增New IP协议栈相关处理 */
134e41f4b71Sopenharmony_cistatic u32 sk_ehashfn(const struct sock *sk)
135e41f4b71Sopenharmony_ci{
136e41f4b71Sopenharmony_ci    /* IPv6 */
137e41f4b71Sopenharmony_ci#if IS_ENABLED(CONFIG_IPV6)
138e41f4b71Sopenharmony_ci	if (sk->sk_family == AF_INET6 &&
139e41f4b71Sopenharmony_ci	    !ipv6_addr_v4mapped(&sk->sk_v6_daddr))
140e41f4b71Sopenharmony_ci		return inet6_ehashfn(sock_net(sk),
141e41f4b71Sopenharmony_ci				     &sk->sk_v6_rcv_saddr, sk->sk_num,
142e41f4b71Sopenharmony_ci				     &sk->sk_v6_daddr, sk->sk_dport);
143e41f4b71Sopenharmony_ci#endif
144e41f4b71Sopenharmony_ci
145e41f4b71Sopenharmony_ci	if (sk->sk_family == AF_NINET) {
146e41f4b71Sopenharmony_ci		u32 ret = 0;
147e41f4b71Sopenharmony_ci
148e41f4b71Sopenharmony_ci        /* New IP注册的ehash函数 */
149e41f4b71Sopenharmony_ci		CALL_HCK_LITE_HOOK(nip_ninet_ehashfn_lhck, sk, &ret);
150e41f4b71Sopenharmony_ci		return ret;
151e41f4b71Sopenharmony_ci	}
152e41f4b71Sopenharmony_ci    /* IPv4 */
153e41f4b71Sopenharmony_ci	return inet_ehashfn(sock_net(sk),
154e41f4b71Sopenharmony_ci			    sk->sk_rcv_saddr, sk->sk_num,
155e41f4b71Sopenharmony_ci			    sk->sk_daddr, sk->sk_dport);
156e41f4b71Sopenharmony_ci}
157e41f4b71Sopenharmony_ci```
158e41f4b71Sopenharmony_ci
159e41f4b71Sopenharmony_ci### New IP禁用
160e41f4b71Sopenharmony_ci
161e41f4b71Sopenharmony_ci在rk3568开发板内核模块配置文件中搜索NEWIP,将其“CONFIG_NEWIP=y”和“CONFIG_NEWIP_HOOKS=y”删除或使用#注释掉即可。
162e41f4b71Sopenharmony_ci
163e41f4b71Sopenharmony_ci```
164e41f4b71Sopenharmony_ci# kernel/linux/config/linux-5.10/arch/arm64/configs/rk3568_standard_defconfig
165e41f4b71Sopenharmony_ci# CONFIG_NEWIP is not set
166e41f4b71Sopenharmony_ci# CONFIG_NEWIP_HOOKS is not set
167e41f4b71Sopenharmony_ci```
168e41f4b71Sopenharmony_ci
169e41f4b71Sopenharmony_ci## New IP相关接口
170e41f4b71Sopenharmony_ci
171e41f4b71Sopenharmony_ci用户态应用程序调用Socket API创建New IP socket,采用New IP极简封装进行收发包,New IP协议socket接口列表如下:
172e41f4b71Sopenharmony_ci
173e41f4b71Sopenharmony_ci| 函数     | 输入                                                         | 输出                                           | 返回值           | 接口具体描述                                                 |
174e41f4b71Sopenharmony_ci| -------- | ------------------------------------------------------------ | ---------------------------------------------- | ---------------- | ------------------------------------------------------------ |
175e41f4b71Sopenharmony_ci| socket   | int **domain**, int type, int **protocol**                   | NA                                             | Socket句柄sockfd | 创建New IP 协议类型socket,并返回socket实例所对应的句柄。**domain参数填写 AF_NINET,表示创建New IP协议类型socket。protocol参数填写IPPROTO_TCP或IPPROTO_UDP**。 |
176e41f4b71Sopenharmony_ci| bind     | int sockfd, const **struct sockaddr_nin** *myaddr, socklen_t addrlen | NA                                             | int,返回错误码  | 将创建的socket绑定到指定的IP地址和端口上。**myaddr->sin_family填写AF_NINET**。 |
177e41f4b71Sopenharmony_ci| listen   | int socket, int backlog                                      | NA                                             | int,返回错误码  | 服务端监听New IP地址和端口。                                 |
178e41f4b71Sopenharmony_ci| connect  | int sockfd, const **struct sockaddr_nin** *addr, aocklen_t addrlen | NA                                             | int,返回错误码  | 客户端创建至服务端的连接。                                   |
179e41f4b71Sopenharmony_ci| accept   | int sockfd, **struct sockaddr_nin** *address, socklen_t *address_len | NA                                             | 返回socket的fd   | 服务端返回已建链成功的socket。                               |
180e41f4b71Sopenharmony_ci| send     | int sockfd, const void *msg, int len, unsigned int flags, const **struct sockaddr_nin** *dst_addr, int addrlen | NA                                             | int,返回错误码  | 用于socket已连接的New IP类型数据发送。                       |
181e41f4b71Sopenharmony_ci| recv     | int sockfd, size_t len, int flags, **struct sockaddr_nin** *src_addr, | void  **buf, int* *fromlen                     | int,返回错误码  | 用于socket已连接的New IP类型数据接收。                       |
182e41f4b71Sopenharmony_ci| close    | int sockfd                                                   | NA                                             | int,返回错误码  | 关闭socket,释放资源。                                       |
183e41f4b71Sopenharmony_ci| ioctl    | int sockfd, unsigned long cmd, ...                           | NA                                             | int,返回错误码  | 对New IP协议栈相关信息进行查询或更改。                       |
184e41f4b71Sopenharmony_ci| sendto   | int sockfd, const void *msg, int len, unsigned int flags, const **struct sockaddr** *dst_addr, int addrlen | NA                                             | int,返回错误码  | 用于socket无连接的New IP类型数据发送。                       |
185e41f4b71Sopenharmony_ci| recvfrom | int sockfd, size_t len, int flags,                           | void *buf, struct sockaddr *from, int *fromlen | int,返回错误码  | 用于socket无连接的New IP类型数据接收。                       |
186e41f4b71Sopenharmony_ci
187e41f4b71Sopenharmony_ciNew IP短地址结构如下:
188e41f4b71Sopenharmony_ci
189e41f4b71Sopenharmony_ci```c
190e41f4b71Sopenharmony_cienum nip_8bit_addr_index {
191e41f4b71Sopenharmony_ci	NIP_8BIT_ADDR_INDEX_0 = 0,
192e41f4b71Sopenharmony_ci	NIP_8BIT_ADDR_INDEX_1 = 1,
193e41f4b71Sopenharmony_ci	NIP_8BIT_ADDR_INDEX_2 = 2,
194e41f4b71Sopenharmony_ci	NIP_8BIT_ADDR_INDEX_3 = 3,
195e41f4b71Sopenharmony_ci	NIP_8BIT_ADDR_INDEX_4 = 4,
196e41f4b71Sopenharmony_ci	NIP_8BIT_ADDR_INDEX_5 = 5,
197e41f4b71Sopenharmony_ci	NIP_8BIT_ADDR_INDEX_6 = 6,
198e41f4b71Sopenharmony_ci	NIP_8BIT_ADDR_INDEX_7 = 7,
199e41f4b71Sopenharmony_ci	NIP_8BIT_ADDR_INDEX_MAX,
200e41f4b71Sopenharmony_ci};
201e41f4b71Sopenharmony_ci
202e41f4b71Sopenharmony_cienum nip_16bit_addr_index {
203e41f4b71Sopenharmony_ci	NIP_16BIT_ADDR_INDEX_0 = 0,
204e41f4b71Sopenharmony_ci	NIP_16BIT_ADDR_INDEX_1 = 1,
205e41f4b71Sopenharmony_ci	NIP_16BIT_ADDR_INDEX_2 = 2,
206e41f4b71Sopenharmony_ci	NIP_16BIT_ADDR_INDEX_3 = 3,
207e41f4b71Sopenharmony_ci	NIP_16BIT_ADDR_INDEX_MAX,
208e41f4b71Sopenharmony_ci};
209e41f4b71Sopenharmony_ci
210e41f4b71Sopenharmony_cienum nip_32bit_addr_index {
211e41f4b71Sopenharmony_ci	NIP_32BIT_ADDR_INDEX_0 = 0,
212e41f4b71Sopenharmony_ci	NIP_32BIT_ADDR_INDEX_1 = 1,
213e41f4b71Sopenharmony_ci	NIP_32BIT_ADDR_INDEX_MAX,
214e41f4b71Sopenharmony_ci};
215e41f4b71Sopenharmony_ci
216e41f4b71Sopenharmony_ci#define nip_addr_field8 v.u.field8
217e41f4b71Sopenharmony_ci#define nip_addr_field16 v.u.field16
218e41f4b71Sopenharmony_ci#define nip_addr_field32 v.u.field32
219e41f4b71Sopenharmony_ci
220e41f4b71Sopenharmony_ci#pragma pack(1)
221e41f4b71Sopenharmony_cistruct nip_addr_field {
222e41f4b71Sopenharmony_ci	union {
223e41f4b71Sopenharmony_ci		unsigned char   field8[NIP_8BIT_ADDR_INDEX_MAX];
224e41f4b71Sopenharmony_ci		unsigned short field16[NIP_16BIT_ADDR_INDEX_MAX]; /* big-endian */
225e41f4b71Sopenharmony_ci		unsigned int   field32[NIP_32BIT_ADDR_INDEX_MAX]; /* big-endian */
226e41f4b71Sopenharmony_ci	} u;
227e41f4b71Sopenharmony_ci};
228e41f4b71Sopenharmony_ci
229e41f4b71Sopenharmony_cistruct nip_addr {
230e41f4b71Sopenharmony_ci	unsigned char bitlen;	/* The address length is in bit (not byte) */
231e41f4b71Sopenharmony_ci	struct nip_addr_field v;
232e41f4b71Sopenharmony_ci};
233e41f4b71Sopenharmony_ci#pragma pack()
234e41f4b71Sopenharmony_ci
235e41f4b71Sopenharmony_ci/* The following structure must be larger than V4. System calls use V4.
236e41f4b71Sopenharmony_ci * If the definition is smaller than V4, the read process will have memory overruns
237e41f4b71Sopenharmony_ci * v4: include\linux\socket.h --> sockaddr (16Byte)
238e41f4b71Sopenharmony_ci */
239e41f4b71Sopenharmony_ci#define POD_SOCKADDR_SIZE 3
240e41f4b71Sopenharmony_cistruct sockaddr_nin {
241e41f4b71Sopenharmony_ci	unsigned short sin_family; /* [2Byte] AF_NINET */
242e41f4b71Sopenharmony_ci	unsigned short sin_port;   /* [2Byte] Transport layer port, big-endian */
243e41f4b71Sopenharmony_ci	struct nip_addr sin_addr;  /* [9Byte] NIP address */
244e41f4b71Sopenharmony_ci
245e41f4b71Sopenharmony_ci	unsigned char sin_zero[POD_SOCKADDR_SIZE]; /* [3Byte] Byte alignment */
246e41f4b71Sopenharmony_ci};
247e41f4b71Sopenharmony_ci```
248e41f4b71Sopenharmony_ci
249e41f4b71Sopenharmony_ci## New IP开发说明
250e41f4b71Sopenharmony_ci
251e41f4b71Sopenharmony_ci目前只在OpenHarmony Linux-5.10内核支持New IP内核协议栈,只能在用户态人工配置New IP地址和路由到内核,两台设备通过路由器WiFi连接。如果想配置New IP地址和路由后自动切换到New IP内核协议栈通信,应用可以参考下面蓝框中描述。
252e41f4b71Sopenharmony_ci
253e41f4b71Sopenharmony_ci![zh-cn_image-20221009112548444](figures/zh-cn_image-20221009112548444.png)
254e41f4b71Sopenharmony_ci
255e41f4b71Sopenharmony_ci上图中New IP地址,路由配置程序可以参考[代码仓examples代码](https://gitee.com/openharmony/kernel_linux_common_modules/tree/master/newip/examples),根据CPU硬件差异更改Makefile中CC定义编译成二级制文件后推送到开发板,参考上图命令给设备配置New IP地址和路由。
256e41f4b71Sopenharmony_ci
257e41f4b71Sopenharmony_ci| 文件名             | 功能                                                     |
258e41f4b71Sopenharmony_ci| ------------------ | -------------------------------------------------------- |
259e41f4b71Sopenharmony_ci| nip_addr.c         | New IP可变长地址配置demo代码(可配置任意有效New IP地址) |
260e41f4b71Sopenharmony_ci| nip_route.c        | New IP路由配置demo代码(可配置任意有效New IP地址)       |
261e41f4b71Sopenharmony_ci| check_nip_enable.c | 获取本机New IP能力                                       |
262e41f4b71Sopenharmony_ci
263e41f4b71Sopenharmony_ci设备1上查看New IP地址和路由:
264e41f4b71Sopenharmony_ci
265e41f4b71Sopenharmony_ci```sh
266e41f4b71Sopenharmony_ci# cat /proc/net/nip_addr
267e41f4b71Sopenharmony_ci01          wlan0
268e41f4b71Sopenharmony_ci# cat /proc/net/nip_route
269e41f4b71Sopenharmony_ci02      ff09       1 wlan0        # 到设备2的路由
270e41f4b71Sopenharmony_ci01      01      2149580801 wlan0  # 本机自发自收路由
271e41f4b71Sopenharmony_ci```
272e41f4b71Sopenharmony_ci
273e41f4b71Sopenharmony_ci设备2上查看New IP地址和路由:
274e41f4b71Sopenharmony_ci
275e41f4b71Sopenharmony_ci```sh
276e41f4b71Sopenharmony_ci# cat /proc/net/nip_addr
277e41f4b71Sopenharmony_ci02          wlan0
278e41f4b71Sopenharmony_ci# cat /proc/net/nip_route
279e41f4b71Sopenharmony_ci01      ff09       1 wlan0        # 到设备1的路由
280e41f4b71Sopenharmony_ci02      02      2149580801 wlan0  # 本机自发自收路由
281e41f4b71Sopenharmony_ci```
282e41f4b71Sopenharmony_ci
283e41f4b71Sopenharmony_ci## New IP收发包代码示例
284e41f4b71Sopenharmony_ci
285e41f4b71Sopenharmony_ciNew IP可变长地址配置,路由配置,UDP/TCP收发包demo代码链接如下,New IP协议栈用户态接口使用方法可以参考[代码仓examples代码](https://gitee.com/openharmony/kernel_linux_common_modules/tree/master/newip/examples)。demo代码内配置固定地址和路由,执行编译后二进制程序时不需要人工指定地址和路由。
286e41f4b71Sopenharmony_ci
287e41f4b71Sopenharmony_ci| 文件名                | 功能                           |
288e41f4b71Sopenharmony_ci| --------------------- | ------------------------------ |
289e41f4b71Sopenharmony_ci| nip_addr_cfg_demo.c   | New IP可变长地址配置demo代码   |
290e41f4b71Sopenharmony_ci| nip_route_cfg_demo.c  | New IP路由配置demo代码         |
291e41f4b71Sopenharmony_ci| nip_udp_server_demo.c | New IP UDP收发包服务端demo代码 |
292e41f4b71Sopenharmony_ci| nip_udp_client_demo.c | New IP UDP收发包客户端demo代码 |
293e41f4b71Sopenharmony_ci| nip_tcp_server_demo.c | New IP TCP收发包服务端demo代码 |
294e41f4b71Sopenharmony_ci| nip_tcp_client_demo.c | New IP TCP收发包客户端demo代码 |
295e41f4b71Sopenharmony_ci| nip_lib.c             | 接口索引获取等API接口demo代码  |
296e41f4b71Sopenharmony_ci
297e41f4b71Sopenharmony_ci**基础操作步骤:**
298e41f4b71Sopenharmony_ci
299e41f4b71Sopenharmony_ci![zh-cn_image-20220915165414926](figures/zh-cn_image-20220915165414926.png)
300e41f4b71Sopenharmony_ci
301e41f4b71Sopenharmony_ci1. 将demo代码拷贝到Linux编译机上,make clean,make all编译demo代码。
302e41f4b71Sopenharmony_ci
303e41f4b71Sopenharmony_ci2. 将编译生成二级制文件上传到设备1,设备2。
304e41f4b71Sopenharmony_ci
305e41f4b71Sopenharmony_ci3. 执行“ifconfig wlan0 up”开启网卡设备。
306e41f4b71Sopenharmony_ci
307e41f4b71Sopenharmony_ci4. 在设备1的shell下执行“./nip_addr_cfg_demo server”给服务端配置0xDE00(2字节)变长地址,在设备2的shell下执。行“./nip_addr_cfg_demo client”给客户端配置0x50(1字节)变长地址,通过“cat /proc/net/nip_addr”查看内核地址配置结果。
308e41f4b71Sopenharmony_ci
309e41f4b71Sopenharmony_ci5. 在设备1的shell下执行“./nip_route_cfg_demo server”给服务端配置路由,在设备2的shell下执行“./nip_route_cfg_demo client”给客户端配置路由,通过“cat /proc/net/nip_route”查看内核路由配置结果。
310e41f4b71Sopenharmony_ci
311e41f4b71Sopenharmony_ci以上步骤操作完成后,可以进行UDP/TCP收发包,收发包demo默认使用上面步骤中配置的地址和路由。
312e41f4b71Sopenharmony_ci
313e41f4b71Sopenharmony_ci
314e41f4b71Sopenharmony_ci
315e41f4b71Sopenharmony_ci**UDP收发包操作步骤:**
316e41f4b71Sopenharmony_ci
317e41f4b71Sopenharmony_ci先在服务端执行“./nip_udp_server_demo”,然后再在客户端执行“./nip_udp_client_demo”,客户端会发送10个New IP报文,服务端收到报文后再发送给客户端。
318e41f4b71Sopenharmony_ci
319e41f4b71Sopenharmony_ci```
320e41f4b71Sopenharmony_ci服务端shell窗口打印内容:
321e41f4b71Sopenharmony_ciReceived -- 1661826989 498038 NIP_UDP #      0 -- from 0x50:57605
322e41f4b71Sopenharmony_ciSending  -- 1661826989 498038 NIP_UDP #      0 -- to 0x50:57605
323e41f4b71Sopenharmony_ciReceived -- 1661826990  14641 NIP_UDP #      1 -- from 0x50:57605
324e41f4b71Sopenharmony_ciSending  -- 1661826990  14641 NIP_UDP #      1 -- to 0x50:57605
325e41f4b71Sopenharmony_ciReceived -- 1661826990 518388 NIP_UDP #      2 -- from 0x50:57605
326e41f4b71Sopenharmony_ciSending  -- 1661826990 518388 NIP_UDP #      2 -- to 0x50:57605
327e41f4b71Sopenharmony_ci...
328e41f4b71Sopenharmony_ciReceived -- 1661827011 590576 NIP_UDP #      9 -- from 0x50:37758
329e41f4b71Sopenharmony_ciSending  -- 1661827011 590576 NIP_UDP #      9 -- to 0x50:37758
330e41f4b71Sopenharmony_ci
331e41f4b71Sopenharmony_ci客户端sh窗口打印内容:
332e41f4b71Sopenharmony_ciReceived --1661827007  55221 NIP_UDP #      0 sock 3 success:     1/     1/no=     0
333e41f4b71Sopenharmony_ciReceived --1661827007 557926 NIP_UDP #      1 sock 3 success:     2/     2/no=     1
334e41f4b71Sopenharmony_ciReceived --1661827008  62653 NIP_UDP #      2 sock 3 success:     3/     3/no=     2
335e41f4b71Sopenharmony_ci...
336e41f4b71Sopenharmony_ciReceived --1661827011 590576 NIP_UDP #      9 sock 3 success:    10/    10/no=     9
337e41f4b71Sopenharmony_ci```
338e41f4b71Sopenharmony_ci
339e41f4b71Sopenharmony_ci
340e41f4b71Sopenharmony_ci
341e41f4b71Sopenharmony_ci**TCP收发包操作步骤:**
342e41f4b71Sopenharmony_ci
343e41f4b71Sopenharmony_ci先在服务端执行“./nip_tcp_server_demo”,然后再在客户端执行“./nip_tcp_client_demo”,客户端会发送10个New IP报文,服务端收到报文后再发送给客户端。
344e41f4b71Sopenharmony_ci
345e41f4b71Sopenharmony_ci```
346e41f4b71Sopenharmony_ci服务端shell窗口打印内容:
347e41f4b71Sopenharmony_ciReceived -- 1661760202 560605 NIP_TCP #      0 --:1024
348e41f4b71Sopenharmony_ciSending  -- 1661760202 560605 NIP_TCP #      0 --:1024
349e41f4b71Sopenharmony_ciReceived -- 1661760203  69254 NIP_TCP #      1 --:1024
350e41f4b71Sopenharmony_ciSending  -- 1661760203  69254 NIP_TCP #      1 --:1024
351e41f4b71Sopenharmony_ciReceived -- 1661760203 571604 NIP_TCP #      2 --:1024
352e41f4b71Sopenharmony_ciSending  -- 1661760203 571604 NIP_TCP #      2 --:1024
353e41f4b71Sopenharmony_ci...
354e41f4b71Sopenharmony_ciReceived -- 1661760207  86544 NIP_TCP #      9 --:1024
355e41f4b71Sopenharmony_ciSending  -- 1661760207  86544 NIP_TCP #      9 --:1024
356e41f4b71Sopenharmony_ci
357e41f4b71Sopenharmony_ci客户端shell窗口打印内容:
358e41f4b71Sopenharmony_ciReceived --1661760202 560605 NIP_TCP #      0 sock 3 success:     1/     1/no=     0
359e41f4b71Sopenharmony_ciReceived --1661760203  69254 NIP_TCP #      1 sock 3 success:     2/     2/no=     1
360e41f4b71Sopenharmony_ci...
361e41f4b71Sopenharmony_ciReceived --1661760207  86544 NIP_TCP #      9 sock 3 success:    10/    10/no=     9
362e41f4b71Sopenharmony_ci```
363e41f4b71Sopenharmony_ci
364e41f4b71Sopenharmony_ci## selinux规则说明
365e41f4b71Sopenharmony_ci
366e41f4b71Sopenharmony_ci用户态进程操作New IP socket需要添加selinux policy,否则操作会被拦截。
367e41f4b71Sopenharmony_ci
368e41f4b71Sopenharmony_ci```sh
369e41f4b71Sopenharmony_ci# base\security\selinux\sepolicy\ohos_policy\xxx\xxx.te
370e41f4b71Sopenharmony_ci# socket 基础操作
371e41f4b71Sopenharmony_ci# avc:  denied  { create } for  pid=540 comm="thread_xxx" scontext=u:r:thread_xxx:s0 tcontext=u:r:thread_xxx:s0 tclass=socket permissive=0
372e41f4b71Sopenharmony_ciallow thread_xxx thread_xxx:socket { create bind connect listen accept read write shutdown setopt getopt };
373e41f4b71Sopenharmony_ci
374e41f4b71Sopenharmony_ci# ioctl 操作
375e41f4b71Sopenharmony_ci# 操作码在 linux-xxx\include\uapi\linux\sockios.h 中定义
376e41f4b71Sopenharmony_ci# 0x8933 : name -> if_index mapping
377e41f4b71Sopenharmony_ci# 0x8916 : set PA address
378e41f4b71Sopenharmony_ci# 0x890B : add routing table entry
379e41f4b71Sopenharmony_ciallowxperm thread_xxx thread_xxx:socket ioctl { 0x8933 0x8916 0x890B };
380e41f4b71Sopenharmony_ci```
381e41f4b71Sopenharmony_ci
382e41f4b71Sopenharmony_ci## WireShark报文解析模板
383e41f4b71Sopenharmony_ci
384e41f4b71Sopenharmony_ciWireshark默认报文解析规则无法解析New IP报文,在WireShark配置中添加New IP报文解析模板可以实现New IP报文解析,[New IP报文解析模板](https://gitee.com/openharmony/kernel_linux_common_modules/blob/master/newip/tools/wireshark_cfg_for_newip.lua)详见代码仓。
385e41f4b71Sopenharmony_ci
386e41f4b71Sopenharmony_ci报文解析模板配置文件的方法:
387e41f4b71Sopenharmony_ci
388e41f4b71Sopenharmony_ci依次单击 Help -> About Wireshark -> Folders,打开Global Configuration目录,编辑init.lua文件。在末尾添加dofile(DATA_DIR..”newip.lua”),其中DATA_DIR即为newip.lua报文解析模板所在路径。
389e41f4b71Sopenharmony_ci
390e41f4b71Sopenharmony_ci![zh-cn_image-20220930141628922](figures/zh-cn_image-20220930141628922.png)
391e41f4b71Sopenharmony_ci
392e41f4b71Sopenharmony_ciNew IP报文解析模板添加样例:
393e41f4b71Sopenharmony_ci
394e41f4b71Sopenharmony_ci```
395e41f4b71Sopenharmony_ciNew IP报文解析模板存放路径:
396e41f4b71Sopenharmony_ciD:\tools\WireShark\wireshark_cfg_for_newip.lua
397e41f4b71Sopenharmony_ci
398e41f4b71Sopenharmony_ciWireShark配置文件路径:
399e41f4b71Sopenharmony_ciC:\Program Files\Wireshark\init.lua
400e41f4b71Sopenharmony_ci
401e41f4b71Sopenharmony_ciinit.lua文件最后增加下面配置(window 11)
402e41f4b71Sopenharmony_cidofile("D:\\tools\\WireShark\\wireshark_cfg_for_newip.lua")
403e41f4b71Sopenharmony_ci```
404e41f4b71Sopenharmony_ci
405e41f4b71Sopenharmony_ci### 报文解析样例
406e41f4b71Sopenharmony_ci
407e41f4b71Sopenharmony_ci#### ND请求
408e41f4b71Sopenharmony_ci
409e41f4b71Sopenharmony_ciNew IP邻居发现(Neighbor Discovery)请求报文格式如下,New IP极简报文头包含1字节的bitmap(0x76),bitmap标识后面携带TTL,报文总长度,上层协议类型,目的地址,源地址。New IP ND请求报文包含报文类型,操作码,校验和和请求地址。
410e41f4b71Sopenharmony_ci
411e41f4b71Sopenharmony_ci备注:New IP支持变长地址(1字节~8字节),下图中1字节地址仅表示当前报文头中携带的地址是1字节。
412e41f4b71Sopenharmony_ci
413e41f4b71Sopenharmony_ci![zh-cn_image-20221011144901470](figures/zh-cn_image-20221011144901470.png)
414e41f4b71Sopenharmony_ci
415e41f4b71Sopenharmony_ci![zh-cn_image-20221011143924648](figures/zh-cn_image-20221011143924648.png)
416e41f4b71Sopenharmony_ci
417e41f4b71Sopenharmony_ci#### ND应答
418e41f4b71Sopenharmony_ci
419e41f4b71Sopenharmony_ciNew IP邻居发现(Neighbor Discovery)应答报文格式如下,New IP极简报文头包含2字节的bitmap(0x77,0x00),bitmap1标识后面携带TTL,报文总长度,上层协议类型,目的地址,源地址。bitmap2是字节对齐不携带任何数据(rk3568开发板链路层数据发送要求数据长度是偶数字节)。New IP ND应答报文包含报文类型,操作码,校验和和邻居MAC地址长度,邻居MAC地址。
420e41f4b71Sopenharmony_ci
421e41f4b71Sopenharmony_ci备注:New IP支持变长地址(1字节~8字节),下图中1字节地址仅表示当前报文头中携带的地址是1字节。
422e41f4b71Sopenharmony_ci
423e41f4b71Sopenharmony_ci![zh-cn_image-20221011145157288](figures/zh-cn_image-20221011145157288.png)
424e41f4b71Sopenharmony_ci
425e41f4b71Sopenharmony_ci![zh-cn_image-20221011144751355](figures/zh-cn_image-20221011144751355.png)
426e41f4b71Sopenharmony_ci
427e41f4b71Sopenharmony_ci#### TCP握手
428e41f4b71Sopenharmony_ci
429e41f4b71Sopenharmony_ciTCP三次握手SYN报文格式如下,New IP极简报文头包含2字节的bitmap(0x77,0x00),bitmap1标识后面携带TTL,报文总长度,上层协议类型,目的地址,源地址。bitmap2是字节对齐不携带任何数据(rk3568开发板链路层数据发送要求数据长度是偶数字节)。
430e41f4b71Sopenharmony_ci
431e41f4b71Sopenharmony_ci备注:New IP支持变长地址(1字节~8字节),下图中1字节地址仅表示当前报文头中携带的地址是1字节。
432e41f4b71Sopenharmony_ci
433e41f4b71Sopenharmony_ci![image-20221011150018915](figures/zh-cn_image-20221011150018915.png)
434e41f4b71Sopenharmony_ci
435e41f4b71Sopenharmony_ci![image-20221011145430048](figures/zh-cn_image-20221011145430048.png)
436e41f4b71Sopenharmony_ci
437e41f4b71Sopenharmony_ci#### TCP数据包
438e41f4b71Sopenharmony_ci
439e41f4b71Sopenharmony_ciTCP数据格式如下,New IP极简报文头包含2字节的bitmap(0x77,0x00),bitmap1标识后面携带TTL,报文总长度,上层协议类型,目的地址,源地址。bitmap2是字节对齐不携带任何数据(rk3568开发板链路层数据发送要求数据长度是偶数字节)。
440e41f4b71Sopenharmony_ci
441e41f4b71Sopenharmony_ci备注:New IP支持变长地址(1字节~8字节),下图中1字节地址仅表示当前报文头中携带的地址是1字节。
442e41f4b71Sopenharmony_ci
443e41f4b71Sopenharmony_ci![image-20221011150215316](figures/zh-cn_image-20221011150215316.png)
444e41f4b71Sopenharmony_ci
445e41f4b71Sopenharmony_ci![image-20221011145616293](figures/zh-cn_image-20221011145616293.png)
446