xref: /freebsd-src/sys/dev/nvmf/nvmf_tcp.h (revision b769044f300a2e8534d0581f4fa7b4a296f038fa)
1bbd5b6feSJohn Baldwin /*-
2bbd5b6feSJohn Baldwin  * SPDX-License-Identifier: BSD-2-Clause
3bbd5b6feSJohn Baldwin  *
4bbd5b6feSJohn Baldwin  * Copyright (c) 2022-2024 Chelsio Communications, Inc.
5bbd5b6feSJohn Baldwin  * Written by: John Baldwin <jhb@FreeBSD.org>
6bbd5b6feSJohn Baldwin  */
7bbd5b6feSJohn Baldwin 
8bbd5b6feSJohn Baldwin #ifndef __NVMF_TCP_H__
9bbd5b6feSJohn Baldwin #define	__NVMF_TCP_H__
10bbd5b6feSJohn Baldwin 
11bbd5b6feSJohn Baldwin #ifndef _KERNEL
12bbd5b6feSJohn Baldwin #define	MPASS			assert
13bbd5b6feSJohn Baldwin #endif
14bbd5b6feSJohn Baldwin 
15bbd5b6feSJohn Baldwin #define	NVME_SGL_TYPE_ICD						\
16bbd5b6feSJohn Baldwin 	NVME_SGL_TYPE(NVME_SGL_TYPE_DATA_BLOCK, NVME_SGL_SUBTYPE_OFFSET)
17bbd5b6feSJohn Baldwin 
18bbd5b6feSJohn Baldwin #define	NVME_SGL_TYPE_COMMAND_BUFFER					\
19bbd5b6feSJohn Baldwin 	NVME_SGL_TYPE(NVME_SGL_TYPE_TRANSPORT_DATA_BLOCK,		\
20bbd5b6feSJohn Baldwin 	    NVME_SGL_SUBTYPE_TRANSPORT)
21bbd5b6feSJohn Baldwin 
22bbd5b6feSJohn Baldwin /*
23bbd5b6feSJohn Baldwin  * Validate common fields in a received PDU header.  If an error is
24bbd5b6feSJohn Baldwin  * detected that requires an immediate disconnect, ECONNRESET is
25bbd5b6feSJohn Baldwin  * returned.  If an error is detected that should be reported, EBADMSG
26bbd5b6feSJohn Baldwin  * is returned and *fes and *fei are set to the values to be used in a
27bbd5b6feSJohn Baldwin  * termination request PDU.  If no error is detected, 0 is returned
28bbd5b6feSJohn Baldwin  * and *data_lenp is set to the length of any included data.
29bbd5b6feSJohn Baldwin  *
30bbd5b6feSJohn Baldwin  * Section number references refer to NVM Express over Fabrics
31bbd5b6feSJohn Baldwin  * Revision 1.1 dated October 22, 2019.
32bbd5b6feSJohn Baldwin  */
33bbd5b6feSJohn Baldwin static __inline int
34bbd5b6feSJohn Baldwin nvmf_tcp_validate_pdu_header(const struct nvme_tcp_common_pdu_hdr *ch,
35bbd5b6feSJohn Baldwin     bool controller, bool header_digests, bool data_digests, uint8_t rxpda,
36bbd5b6feSJohn Baldwin     uint32_t *data_lenp, uint16_t *fes, uint32_t *fei)
37bbd5b6feSJohn Baldwin {
38bbd5b6feSJohn Baldwin 	uint32_t data_len, plen;
39bbd5b6feSJohn Baldwin 	u_int expected_hlen, full_hlen;
40bbd5b6feSJohn Baldwin 	uint8_t digest_flags, valid_flags;
41bbd5b6feSJohn Baldwin 
42bbd5b6feSJohn Baldwin 	plen = le32toh(ch->plen);
43*43d45f26SJohn Baldwin 	full_hlen = ch->hlen;
44*43d45f26SJohn Baldwin 	if ((ch->flags & NVME_TCP_CH_FLAGS_HDGSTF) != 0)
45*43d45f26SJohn Baldwin 		full_hlen += sizeof(uint32_t);
46*43d45f26SJohn Baldwin 	if (plen == full_hlen)
47*43d45f26SJohn Baldwin 		data_len = 0;
48*43d45f26SJohn Baldwin 	else
49*43d45f26SJohn Baldwin 		data_len = plen - ch->pdo;
50bbd5b6feSJohn Baldwin 
51bbd5b6feSJohn Baldwin 	/*
52bbd5b6feSJohn Baldwin 	 * Errors must be reported for the lowest incorrect field
53bbd5b6feSJohn Baldwin 	 * first, so validate fields in order.
54bbd5b6feSJohn Baldwin 	 */
55bbd5b6feSJohn Baldwin 
56bbd5b6feSJohn Baldwin 	/* Validate pdu_type. */
57bbd5b6feSJohn Baldwin 
58bbd5b6feSJohn Baldwin 	/* Controllers only receive PDUs with a PDU direction of 0. */
59a7db82cfSJohn Baldwin 	if (controller != ((ch->pdu_type & 0x01) == 0)) {
60bbd5b6feSJohn Baldwin 		printf("NVMe/TCP: Invalid PDU type %u\n", ch->pdu_type);
61bbd5b6feSJohn Baldwin 		*fes = NVME_TCP_TERM_REQ_FES_INVALID_HEADER_FIELD;
62bbd5b6feSJohn Baldwin 		*fei = offsetof(struct nvme_tcp_common_pdu_hdr, pdu_type);
63bbd5b6feSJohn Baldwin 		return (EBADMSG);
64bbd5b6feSJohn Baldwin 	}
65bbd5b6feSJohn Baldwin 
66bbd5b6feSJohn Baldwin 	switch (ch->pdu_type) {
67bbd5b6feSJohn Baldwin 	case NVME_TCP_PDU_TYPE_IC_REQ:
68bbd5b6feSJohn Baldwin 	case NVME_TCP_PDU_TYPE_IC_RESP:
69bbd5b6feSJohn Baldwin 		/* Shouldn't get these for an established connection. */
70bbd5b6feSJohn Baldwin 		printf("NVMe/TCP: Received Initialize Connection PDU\n");
71bbd5b6feSJohn Baldwin 		*fes = NVME_TCP_TERM_REQ_FES_INVALID_HEADER_FIELD;
72bbd5b6feSJohn Baldwin 		*fei = offsetof(struct nvme_tcp_common_pdu_hdr, pdu_type);
73bbd5b6feSJohn Baldwin 		return (EBADMSG);
74bbd5b6feSJohn Baldwin 	case NVME_TCP_PDU_TYPE_H2C_TERM_REQ:
75bbd5b6feSJohn Baldwin 	case NVME_TCP_PDU_TYPE_C2H_TERM_REQ:
76bbd5b6feSJohn Baldwin 		/*
77bbd5b6feSJohn Baldwin 		 * 7.4.7 Termination requests with invalid PDU lengths
78bbd5b6feSJohn Baldwin 		 * result in an immediate connection termination
79bbd5b6feSJohn Baldwin 		 * without reporting an error.
80bbd5b6feSJohn Baldwin 		 */
81bbd5b6feSJohn Baldwin 		if (plen < sizeof(struct nvme_tcp_term_req_hdr) ||
82bbd5b6feSJohn Baldwin 		    plen > NVME_TCP_TERM_REQ_PDU_MAX_SIZE) {
83bbd5b6feSJohn Baldwin 			printf("NVMe/TCP: Received invalid termination request\n");
84bbd5b6feSJohn Baldwin 			return (ECONNRESET);
85bbd5b6feSJohn Baldwin 		}
86bbd5b6feSJohn Baldwin 		break;
87bbd5b6feSJohn Baldwin 	case NVME_TCP_PDU_TYPE_CAPSULE_CMD:
88bbd5b6feSJohn Baldwin 	case NVME_TCP_PDU_TYPE_CAPSULE_RESP:
89bbd5b6feSJohn Baldwin 	case NVME_TCP_PDU_TYPE_H2C_DATA:
90bbd5b6feSJohn Baldwin 	case NVME_TCP_PDU_TYPE_C2H_DATA:
91bbd5b6feSJohn Baldwin 	case NVME_TCP_PDU_TYPE_R2T:
92bbd5b6feSJohn Baldwin 		break;
93bbd5b6feSJohn Baldwin 	default:
94bbd5b6feSJohn Baldwin 		printf("NVMe/TCP: Invalid PDU type %u\n", ch->pdu_type);
95bbd5b6feSJohn Baldwin 		*fes = NVME_TCP_TERM_REQ_FES_INVALID_HEADER_FIELD;
96bbd5b6feSJohn Baldwin 		*fei = offsetof(struct nvme_tcp_common_pdu_hdr, pdu_type);
97bbd5b6feSJohn Baldwin 		return (EBADMSG);
98bbd5b6feSJohn Baldwin 	}
99bbd5b6feSJohn Baldwin 
100bbd5b6feSJohn Baldwin 	/* Validate flags. */
101bbd5b6feSJohn Baldwin 	switch (ch->pdu_type) {
102bbd5b6feSJohn Baldwin 	default:
103bbd5b6feSJohn Baldwin 		__assert_unreachable();
104bbd5b6feSJohn Baldwin 		break;
105bbd5b6feSJohn Baldwin 	case NVME_TCP_PDU_TYPE_H2C_TERM_REQ:
106bbd5b6feSJohn Baldwin 	case NVME_TCP_PDU_TYPE_C2H_TERM_REQ:
107bbd5b6feSJohn Baldwin 		valid_flags = 0;
108bbd5b6feSJohn Baldwin 		break;
109bbd5b6feSJohn Baldwin 	case NVME_TCP_PDU_TYPE_CAPSULE_CMD:
110bbd5b6feSJohn Baldwin 		valid_flags = NVME_TCP_CH_FLAGS_HDGSTF |
111bbd5b6feSJohn Baldwin 		    NVME_TCP_CH_FLAGS_DDGSTF;
112bbd5b6feSJohn Baldwin 		break;
113bbd5b6feSJohn Baldwin 	case NVME_TCP_PDU_TYPE_CAPSULE_RESP:
114bbd5b6feSJohn Baldwin 	case NVME_TCP_PDU_TYPE_R2T:
115bbd5b6feSJohn Baldwin 		valid_flags = NVME_TCP_CH_FLAGS_HDGSTF;
116bbd5b6feSJohn Baldwin 		break;
117bbd5b6feSJohn Baldwin 	case NVME_TCP_PDU_TYPE_H2C_DATA:
118bbd5b6feSJohn Baldwin 		valid_flags = NVME_TCP_CH_FLAGS_HDGSTF |
119bbd5b6feSJohn Baldwin 		    NVME_TCP_CH_FLAGS_DDGSTF | NVME_TCP_H2C_DATA_FLAGS_LAST_PDU;
120bbd5b6feSJohn Baldwin 		break;
121bbd5b6feSJohn Baldwin 	case NVME_TCP_PDU_TYPE_C2H_DATA:
122bbd5b6feSJohn Baldwin 		valid_flags = NVME_TCP_CH_FLAGS_HDGSTF |
123bbd5b6feSJohn Baldwin 		    NVME_TCP_CH_FLAGS_DDGSTF | NVME_TCP_C2H_DATA_FLAGS_LAST_PDU |
124bbd5b6feSJohn Baldwin 		    NVME_TCP_C2H_DATA_FLAGS_SUCCESS;
125bbd5b6feSJohn Baldwin 		break;
126bbd5b6feSJohn Baldwin 	}
127bbd5b6feSJohn Baldwin 	if ((ch->flags & ~valid_flags) != 0) {
128bbd5b6feSJohn Baldwin 		printf("NVMe/TCP: Invalid PDU header flags %#x\n", ch->flags);
129bbd5b6feSJohn Baldwin 		*fes = NVME_TCP_TERM_REQ_FES_INVALID_HEADER_FIELD;
130bbd5b6feSJohn Baldwin 		*fei = offsetof(struct nvme_tcp_common_pdu_hdr, flags);
131bbd5b6feSJohn Baldwin 		return (EBADMSG);
132bbd5b6feSJohn Baldwin 	}
133bbd5b6feSJohn Baldwin 
134*43d45f26SJohn Baldwin 	/*
135*43d45f26SJohn Baldwin 	 * Verify that digests are present iff enabled.  Note that the
136*43d45f26SJohn Baldwin 	 * data digest will not be present if there is no data
137*43d45f26SJohn Baldwin 	 * payload.
138*43d45f26SJohn Baldwin 	 */
139bbd5b6feSJohn Baldwin 	digest_flags = 0;
140bbd5b6feSJohn Baldwin 	if (header_digests)
141bbd5b6feSJohn Baldwin 		digest_flags |= NVME_TCP_CH_FLAGS_HDGSTF;
142*43d45f26SJohn Baldwin 	if (data_digests && data_len != 0)
143bbd5b6feSJohn Baldwin 		digest_flags |= NVME_TCP_CH_FLAGS_DDGSTF;
144bbd5b6feSJohn Baldwin 	if ((digest_flags & valid_flags) !=
145bbd5b6feSJohn Baldwin 	    (ch->flags & (NVME_TCP_CH_FLAGS_HDGSTF |
146bbd5b6feSJohn Baldwin 	    NVME_TCP_CH_FLAGS_DDGSTF))) {
147bbd5b6feSJohn Baldwin 		printf("NVMe/TCP: Invalid PDU header flags %#x\n", ch->flags);
148bbd5b6feSJohn Baldwin 		*fes = NVME_TCP_TERM_REQ_FES_INVALID_HEADER_FIELD;
149bbd5b6feSJohn Baldwin 		*fei = offsetof(struct nvme_tcp_common_pdu_hdr, flags);
150bbd5b6feSJohn Baldwin 		return (EBADMSG);
151bbd5b6feSJohn Baldwin 	}
152bbd5b6feSJohn Baldwin 
153bbd5b6feSJohn Baldwin 	/* 7.4.5.2: SUCCESS in C2H requires LAST_PDU */
154bbd5b6feSJohn Baldwin 	if (ch->pdu_type == NVME_TCP_PDU_TYPE_C2H_DATA &&
155bbd5b6feSJohn Baldwin 	    (ch->flags & (NVME_TCP_C2H_DATA_FLAGS_LAST_PDU |
156bbd5b6feSJohn Baldwin 	    NVME_TCP_C2H_DATA_FLAGS_SUCCESS)) ==
157bbd5b6feSJohn Baldwin 	    NVME_TCP_C2H_DATA_FLAGS_SUCCESS) {
158bbd5b6feSJohn Baldwin 		printf("NVMe/TCP: Invalid PDU header flags %#x\n", ch->flags);
159bbd5b6feSJohn Baldwin 		*fes = NVME_TCP_TERM_REQ_FES_INVALID_HEADER_FIELD;
160bbd5b6feSJohn Baldwin 		*fei = offsetof(struct nvme_tcp_common_pdu_hdr, flags);
161bbd5b6feSJohn Baldwin 		return (EBADMSG);
162bbd5b6feSJohn Baldwin 	}
163bbd5b6feSJohn Baldwin 
164bbd5b6feSJohn Baldwin 	/* Validate hlen. */
165bbd5b6feSJohn Baldwin 	switch (ch->pdu_type) {
166bbd5b6feSJohn Baldwin 	default:
167bbd5b6feSJohn Baldwin 		__assert_unreachable();
168bbd5b6feSJohn Baldwin 		break;
169bbd5b6feSJohn Baldwin 	case NVME_TCP_PDU_TYPE_H2C_TERM_REQ:
170bbd5b6feSJohn Baldwin 	case NVME_TCP_PDU_TYPE_C2H_TERM_REQ:
171bbd5b6feSJohn Baldwin 		expected_hlen = sizeof(struct nvme_tcp_term_req_hdr);
172bbd5b6feSJohn Baldwin 		break;
173bbd5b6feSJohn Baldwin 	case NVME_TCP_PDU_TYPE_CAPSULE_CMD:
174bbd5b6feSJohn Baldwin 		expected_hlen = sizeof(struct nvme_tcp_cmd);
175bbd5b6feSJohn Baldwin 		break;
176bbd5b6feSJohn Baldwin 	case NVME_TCP_PDU_TYPE_CAPSULE_RESP:
177bbd5b6feSJohn Baldwin 		expected_hlen = sizeof(struct nvme_tcp_rsp);
178bbd5b6feSJohn Baldwin 		break;
179bbd5b6feSJohn Baldwin 	case NVME_TCP_PDU_TYPE_H2C_DATA:
180bbd5b6feSJohn Baldwin 		expected_hlen = sizeof(struct nvme_tcp_h2c_data_hdr);
181bbd5b6feSJohn Baldwin 		break;
182bbd5b6feSJohn Baldwin 	case NVME_TCP_PDU_TYPE_C2H_DATA:
183bbd5b6feSJohn Baldwin 		expected_hlen = sizeof(struct nvme_tcp_c2h_data_hdr);
184bbd5b6feSJohn Baldwin 		break;
185bbd5b6feSJohn Baldwin 	case NVME_TCP_PDU_TYPE_R2T:
186bbd5b6feSJohn Baldwin 		expected_hlen = sizeof(struct nvme_tcp_r2t_hdr);
187bbd5b6feSJohn Baldwin 		break;
188bbd5b6feSJohn Baldwin 	}
189bbd5b6feSJohn Baldwin 	if (ch->hlen != expected_hlen) {
190bbd5b6feSJohn Baldwin 		printf("NVMe/TCP: Invalid PDU header length %u\n", ch->hlen);
191bbd5b6feSJohn Baldwin 		*fes = NVME_TCP_TERM_REQ_FES_INVALID_HEADER_FIELD;
192bbd5b6feSJohn Baldwin 		*fei = offsetof(struct nvme_tcp_common_pdu_hdr, hlen);
193bbd5b6feSJohn Baldwin 		return (EBADMSG);
194bbd5b6feSJohn Baldwin 	}
195bbd5b6feSJohn Baldwin 
196bbd5b6feSJohn Baldwin 	/* Validate pdo. */
197bbd5b6feSJohn Baldwin 	switch (ch->pdu_type) {
198bbd5b6feSJohn Baldwin 	default:
199bbd5b6feSJohn Baldwin 		__assert_unreachable();
200bbd5b6feSJohn Baldwin 		break;
201bbd5b6feSJohn Baldwin 	case NVME_TCP_PDU_TYPE_H2C_TERM_REQ:
202bbd5b6feSJohn Baldwin 	case NVME_TCP_PDU_TYPE_C2H_TERM_REQ:
203bbd5b6feSJohn Baldwin 	case NVME_TCP_PDU_TYPE_CAPSULE_RESP:
204bbd5b6feSJohn Baldwin 	case NVME_TCP_PDU_TYPE_R2T:
205bbd5b6feSJohn Baldwin 		if (ch->pdo != 0) {
206bbd5b6feSJohn Baldwin 			printf("NVMe/TCP: Invalid PDU data offset %u\n",
207bbd5b6feSJohn Baldwin 			    ch->pdo);
208bbd5b6feSJohn Baldwin 			*fes = NVME_TCP_TERM_REQ_FES_INVALID_HEADER_FIELD;
209bbd5b6feSJohn Baldwin 			*fei = offsetof(struct nvme_tcp_common_pdu_hdr, pdo);
210bbd5b6feSJohn Baldwin 			return (EBADMSG);
211bbd5b6feSJohn Baldwin 		}
212bbd5b6feSJohn Baldwin 		break;
213bbd5b6feSJohn Baldwin 	case NVME_TCP_PDU_TYPE_CAPSULE_CMD:
214bbd5b6feSJohn Baldwin 	case NVME_TCP_PDU_TYPE_H2C_DATA:
215bbd5b6feSJohn Baldwin 	case NVME_TCP_PDU_TYPE_C2H_DATA:
216bbd5b6feSJohn Baldwin 		/* Permit PDO of 0 if there is no data. */
217*43d45f26SJohn Baldwin 		if (data_len == 0 && ch->pdo == 0)
218bbd5b6feSJohn Baldwin 			break;
219bbd5b6feSJohn Baldwin 
220bbd5b6feSJohn Baldwin 		if (ch->pdo < full_hlen || ch->pdo > plen ||
221bbd5b6feSJohn Baldwin 		    ch->pdo % rxpda != 0) {
222bbd5b6feSJohn Baldwin 			printf("NVMe/TCP: Invalid PDU data offset %u\n",
223bbd5b6feSJohn Baldwin 			    ch->pdo);
224bbd5b6feSJohn Baldwin 			*fes = NVME_TCP_TERM_REQ_FES_INVALID_HEADER_FIELD;
225bbd5b6feSJohn Baldwin 			*fei = offsetof(struct nvme_tcp_common_pdu_hdr, pdo);
226bbd5b6feSJohn Baldwin 			return (EBADMSG);
227bbd5b6feSJohn Baldwin 		}
228bbd5b6feSJohn Baldwin 		break;
229bbd5b6feSJohn Baldwin 	}
230bbd5b6feSJohn Baldwin 
231bbd5b6feSJohn Baldwin 	/* Validate plen. */
232bbd5b6feSJohn Baldwin 	if (plen < ch->hlen) {
233bbd5b6feSJohn Baldwin 		printf("NVMe/TCP: Invalid PDU length %u\n", plen);
234bbd5b6feSJohn Baldwin 		*fes = NVME_TCP_TERM_REQ_FES_INVALID_HEADER_FIELD;
235bbd5b6feSJohn Baldwin 		*fei = offsetof(struct nvme_tcp_common_pdu_hdr, plen);
236bbd5b6feSJohn Baldwin 		return (EBADMSG);
237bbd5b6feSJohn Baldwin 	}
238bbd5b6feSJohn Baldwin 
239bbd5b6feSJohn Baldwin 	switch (ch->pdu_type) {
240bbd5b6feSJohn Baldwin 	default:
241bbd5b6feSJohn Baldwin 		__assert_unreachable();
242bbd5b6feSJohn Baldwin 		break;
243bbd5b6feSJohn Baldwin 	case NVME_TCP_PDU_TYPE_H2C_TERM_REQ:
244bbd5b6feSJohn Baldwin 	case NVME_TCP_PDU_TYPE_C2H_TERM_REQ:
245bbd5b6feSJohn Baldwin 		/* Checked above. */
246bbd5b6feSJohn Baldwin 		MPASS(plen <= NVME_TCP_TERM_REQ_PDU_MAX_SIZE);
247bbd5b6feSJohn Baldwin 		break;
248bbd5b6feSJohn Baldwin 	case NVME_TCP_PDU_TYPE_CAPSULE_CMD:
249bbd5b6feSJohn Baldwin 	case NVME_TCP_PDU_TYPE_H2C_DATA:
250bbd5b6feSJohn Baldwin 	case NVME_TCP_PDU_TYPE_C2H_DATA:
251bbd5b6feSJohn Baldwin 		if ((ch->flags & NVME_TCP_CH_FLAGS_DDGSTF) != 0 &&
252bbd5b6feSJohn Baldwin 		    data_len <= sizeof(uint32_t)) {
253bbd5b6feSJohn Baldwin 			printf("NVMe/TCP: PDU %u too short for digest\n",
254bbd5b6feSJohn Baldwin 			    ch->pdu_type);
255bbd5b6feSJohn Baldwin 			*fes = NVME_TCP_TERM_REQ_FES_INVALID_HEADER_FIELD;
256bbd5b6feSJohn Baldwin 			*fei = offsetof(struct nvme_tcp_common_pdu_hdr, plen);
257bbd5b6feSJohn Baldwin 			return (EBADMSG);
258bbd5b6feSJohn Baldwin 		}
259bbd5b6feSJohn Baldwin 		break;
260bbd5b6feSJohn Baldwin 	case NVME_TCP_PDU_TYPE_R2T:
261bbd5b6feSJohn Baldwin 	case NVME_TCP_PDU_TYPE_CAPSULE_RESP:
262bbd5b6feSJohn Baldwin 		if (data_len != 0) {
263bbd5b6feSJohn Baldwin 			printf("NVMe/TCP: PDU %u with data length %u\n",
264bbd5b6feSJohn Baldwin 			    ch->pdu_type, data_len);
265bbd5b6feSJohn Baldwin 			*fes = NVME_TCP_TERM_REQ_FES_INVALID_HEADER_FIELD;
266bbd5b6feSJohn Baldwin 			*fei = offsetof(struct nvme_tcp_common_pdu_hdr, plen);
267bbd5b6feSJohn Baldwin 			return (EBADMSG);
268bbd5b6feSJohn Baldwin 		}
269bbd5b6feSJohn Baldwin 		break;
270bbd5b6feSJohn Baldwin 	}
271bbd5b6feSJohn Baldwin 
272bbd5b6feSJohn Baldwin 	if ((ch->flags & NVME_TCP_CH_FLAGS_DDGSTF) != 0)
273bbd5b6feSJohn Baldwin 		data_len -= sizeof(uint32_t);
274bbd5b6feSJohn Baldwin 
275bbd5b6feSJohn Baldwin 	*data_lenp = data_len;
276bbd5b6feSJohn Baldwin 	return (0);
277bbd5b6feSJohn Baldwin }
278bbd5b6feSJohn Baldwin 
279bbd5b6feSJohn Baldwin #endif /* !__NVMF_TCP_H__ */
280