1/* SPDX-License-Identifier: GPL-2.0-or-later */
2/*
3 * Copyright (c) 2022 Huawei Device Co., Ltd.
4 *
5 * Description: Constructs and functions are provided
6 * to handle encapsulation and parsing of the NewIP
7 * network layer protocol header.
8 *
9 * Author: Yang Yanjun <yangyanjun@huawei.com>
10 *
11 * Data: 2022-07-18
12 */
13#ifndef _NEWIP_HDR_H
14#define _NEWIP_HDR_H
15
16#include "nip_addr.h"
17
18/* Ethernet head 14B, +2B byte alignment, +66 to avoid
19 * HMAC driver SKB space expansion caused by Coredum problem
20 */
21/* This parameter is used only to apply for the length of the packet buffer,
22 * but not to determine the actual packet header length
23 */
24#define NIP_ETH_HDR_BASE_LEN 14
25#define NIP_ETH_HDR_LEN (NIP_ETH_HDR_BASE_LEN + 2 + 66)
26
27/* bitmap1 + bitmap2 + TTL + total len + nexthd + daddr + saddr
28 * 1B        1B        1B    2B          1B       9B      9B    = 24B
29 * V4  TCP 1448
30 * NIP TCP 1430 + 30 = 1460
31 */
32/* This interface is only used to define the buffer length.
33 * To calculate the packet header length, use the "get_nip_hdr_len" func
34 */
35#define NIP_HDR_MAX 24
36#define NIP_UDP_HDR_LEN 8
37#define NIP_TCP_HDR_LEN 20
38#define NIP_MIN_MTU (NIP_HDR_MAX + NIP_TCP_HDR_LEN)
39#define NIP_BYTE_ALIGNMENT 2
40
41#define NIP_BITMAP_HAVE_MORE_BIT     0x01
42
43/* Bitmap 1st Byte: bit0 - bit7 */
44#define NIP_BITMAP_INVALID_SET       0x80                      /* Bit 0 is set */
45#define NIP_BITMAP_INCLUDE_TTL       0x40                      /* Bit 1 is set */
46#define NIP_BITMAP_INCLUDE_TOTAL_LEN 0x20                      /* Bit 2 is set */
47#define NIP_BITMAP_INCLUDE_NEXT_HDR  0x10                      /* Bit 3 is set */
48#define NIP_BITMAP_INCLUDE_RES1      0x08                      /* Bit 4 is set */
49#define NIP_BITMAP_INCLUDE_DADDR     0x04                      /* Bit 5 is set */
50#define NIP_BITMAP_INCLUDE_SADDR     0x02                      /* Bit 6 is set */
51#define NIP_BITMAP_HAVE_BYTE_2       NIP_BITMAP_HAVE_MORE_BIT  /* Bit 7 is set */
52
53/* Bitmap 2nd Byte: bit0 - bit7 */
54#define NIP_BITMAP_INCLUDE_HDR_LEN   0x80                      /* Bit 0 is set */
55#define NIP_BITMAP_INCLUDE_RES2      0x40                      /* Bit 1 is set */
56#define NIP_BITMAP_INCLUDE_RES3      0x20                      /* Bit 2 is set */
57#define NIP_BITMAP_INCLUDE_RES4      0x10                      /* Bit 3 is set */
58#define NIP_BITMAP_INCLUDE_RES5      0x08                      /* Bit 4 is set */
59#define NIP_BITMAP_INCLUDE_RES6      0x04                      /* Bit 5 is set */
60#define NIP_BITMAP_INCLUDE_RES7      0x02                      /* Bit 6 is set */
61#define NIP_BITMAP_HAVE_BYTE_3       NIP_BITMAP_HAVE_MORE_BIT  /* Bit 7 is set */
62
63/* Bitmap 1st Byte:
64 * | valid | ttl | total_len | next_hdr | res1 | daddr | saddr | have byte2 |
65 * |   0   |  1  |     0     |     1    |  0   |   1   |   1   |     0      |
66 */
67#define NIP_UDP_BITMAP_1          0x56
68#define NIP_UDP_BITMAP_1_INC_2    0x57
69
70/* Bitmap 1st Byte:
71 * | valid | ttl | total_len | next_hdr | res1 | daddr | saddr | have byte2 |
72 * |   0   |  1  |     1     |     1    |  0   |   1   |   1   |     0      |
73 */
74#define NIP_NORMAL_BITMAP_1        0x76
75#define NIP_NORMAL_BITMAP_1_INC_2  0x77
76
77/* Bitmap 2nd Byte:
78 * | hdr_len | res2 | res2 | res2 | res2 | res2 | res2 | have byte3 |
79 * |  0 or 1 |  0   |  0   |  0   |  0   |  0   |  0   |      0     |
80 */
81#define NIP_NODATA_BITMAP_2        0x00
82#define NIP_NORMAL_BITMAP_2        0x80
83
84/* invalid Bitmap 2nd Byte:
85 * | hdr_len | res2 | res2 | res2 | res2 | res2 | res2 | have byte3 |
86 * |  0 or 1 |  1   |  1   |  1   |  1   |  1   |  1   |      1     |
87 */
88#define NIP_INVALID_BITMAP_2       0x7F
89
90#define NIP_DEFAULT_TTL 128
91#define NIP_ARP_DEFAULT_TTL 64
92#define IPPROTO_NIP_ICMP 0xB1
93
94enum NIP_HDR_TYPE {
95	NIP_HDR_UDP = 0,
96	NIP_HDR_COMM = 1,
97
98	NIP_HDR_TYPE_MAX,
99};
100
101enum NIP_HDR_DECAP_ERR {
102	NIP_HDR_BITMAP_INVALID = 1,
103	NIP_HDR_BITMAP_NUM_OUT_RANGE = 2,
104	NIP_HDR_NO_TTL = 3,
105	NIP_HDR_NO_NEXT_HDR = 4,
106	NIP_HDR_NO_DADDR = 5,
107	NIP_HDR_DECAP_DADDR_ERR = 6,
108	NIP_HDR_DADDR_INVALID = 7,
109	NIP_HDR_DECAP_SADDR_ERR = 8,
110	NIP_HDR_SADDR_INVALID = 9,
111	NIP_HDR_RCV_BUF_READ_OUT_RANGE = 10,
112	NIP_HDR_UNKNOWN_AND_NO_HDR_LEN = 11,
113	NIP_HDR_LEN_INVALID = 12,
114	NIP_HDR_LEN_OUT_RANGE = 13,
115
116	NIP_HDR_DECAP_ERRCODE_MAX,
117};
118
119/* The newIP header contains variable-length fields.
120 * The header structure is defined only for function parameter transmission.
121 * The fields are parsed in the original packet and saved
122 */
123struct nip_hdr_decap {
124	struct nip_addr saddr; /* Source address, network order.(big end) */
125	struct nip_addr daddr; /* Destination address, network order.(big end) */
126
127	unsigned char ttl;          /* Hop count limit */
128	unsigned char nexthdr;      /* Upper-layer Protocol Type: IPPROTO_UDP */
129	unsigned char hdr_len;      /* Indicates the length of the packet header */
130	unsigned char hdr_real_len; /* Indicates the actual length of the packet header */
131
132	unsigned short total_len;   /* Packet length (Header + packet), network order.(big end) */
133	unsigned short no_hdr_len : 1;  /* The header does not contain a header length field */
134	unsigned short include_unknown_bit : 1; /* There is no other bitmap field */
135	unsigned short include_saddr : 1;
136	unsigned short include_daddr : 1;
137	unsigned short include_ttl : 1;
138	unsigned short include_nexthdr : 1;
139	unsigned short include_hdr_len : 1;
140	unsigned short include_total_len : 1;
141	unsigned short res : 8;
142
143	unsigned int rcv_buf_len;
144};
145
146/* The newIP packet header function is an incoming or outgoing parameter,
147 * which is not the content encapsulated in the packet
148 */
149#define BITMAP_MAX 8
150#define RES_NUM 2
151struct nip_hdr_encap {
152	struct nip_addr daddr; /* Destination address, network order.(big end) */
153	struct nip_addr saddr; /* Source address, network order.(big end) */
154
155	unsigned char ttl;     /* Hop count limit */
156	unsigned char nexthdr; /* Upper-layer Protocol Type: IPPROTO_UDP */
157	unsigned short total_len; /* Packet header length + packet data length */
158
159	void *usr_data;             /* User data pointer */
160	unsigned int usr_data_len;  /* Length of data sent by the user */
161	unsigned int trans_hdr_len; /* Transport layer header length */
162
163	unsigned short sport;
164	unsigned short dport;
165
166	/* The following are the output parameters */
167	unsigned char bitmap[BITMAP_MAX]; /* Bitmap currently supports a maximum of 8 bytes */
168	unsigned int bitmap_num;          /* Number of valid elements in the bitmap array */
169
170	unsigned char *hdr_buf;        /* Cache the newIP header */
171	unsigned int hdr_buf_pos;      /* Buf Buffer writable address offset */
172	unsigned short *frag_id_pos;   /* Fragment Offset in the original packet */
173	unsigned char *hdr_len_pos;    /* Indicates the actual length of the packet header */
174	unsigned short *total_len_pos; /* Total length position of the packet */
175
176	/* Whether the bitmap of the packet header carries a flag */
177	unsigned char encap_ttl : 1;
178	unsigned char encap_hdr_len : 1;
179	unsigned char encap_daddr : 1;
180	unsigned char encap_saddr : 1;
181	unsigned char encap_total_len : 1;
182	unsigned char encap_res : 3;
183};
184
185/* Packet segment information */
186struct nip_pkt_seg_info {
187	unsigned int mid_pkt_num;      /* Number of intermediate segments */
188	unsigned int last_pkt_num;     /* Number of last segments */
189
190	unsigned int mid_usr_pkt_len;  /* Middle segment data length (8B aligned) */
191	unsigned int last_usr_pkt_len; /* Length of the last data segment */
192
193	unsigned char *usr_data;       /* Holds a pointer to the user's raw data */
194	unsigned int usr_data_len;     /* Length of user data read this time */
195};
196
197void nip_calc_pkt_frag_num(unsigned int mtu,
198			   unsigned int nip_hdr_len,
199			   unsigned int usr_data_len,
200			   struct nip_pkt_seg_info *seg_info);
201
202void nip_hdr_udp_encap(struct nip_hdr_encap *head);
203
204/* need update total len after this func, call nip_update_total_len */
205void nip_hdr_comm_encap(struct nip_hdr_encap *head);
206
207/* input must be network order. */
208void nip_update_total_len(struct nip_hdr_encap *head, unsigned short total_len);
209
210/* Note: a function call requires its own byte order conversion.(niph->total_len) */
211int nip_hdr_parse(unsigned char *rcv_buf, unsigned int buf_len, struct nip_hdr_decap *niph);
212
213/* The length of the packet header is obtained according to the packet type,
214 * source ADDRESS, and destination address.
215 * If the packet does not carry the source address or destination address, fill in the blank
216 */
217int get_nip_hdr_len(enum NIP_HDR_TYPE hdr_type,
218		    const struct nip_addr *saddr,
219		    const struct nip_addr *daddr);
220
221struct udp_hdr {
222	unsigned short	sport;
223	unsigned short	dport;
224	unsigned short	len;
225	unsigned short	checksum;
226};
227
228/* input must be network order. */
229static inline void nip_build_udp_hdr(unsigned short sport, unsigned short dport,
230				     unsigned short len, unsigned char *buf,
231				     unsigned short checksum)
232{
233	struct udp_hdr *uh;
234
235	uh = (struct udp_hdr *)buf;
236	uh->sport = sport;
237	uh->dport = dport;
238	uh->len = len;
239	uh->checksum = checksum;
240}
241
242#endif /* _NEWIP_HDR_H */
243
244