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