1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3 *
4 * Copyright (c) 2005-2011 Daniel Braniss <danny@cs.huji.ac.il>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 *
28 */
29 /*
30 | iSCSI
31 | $Id: isc_subr.c 560 2009-05-07 07:37:49Z danny $
32 */
33
34 #include <sys/cdefs.h>
35 __FBSDID("$FreeBSD$");
36
37 #include "opt_iscsi_initiator.h"
38
39 #include <sys/param.h>
40 #include <sys/kernel.h>
41 #include <sys/conf.h>
42 #include <sys/gsb_crc32.h>
43 #include <sys/systm.h>
44 #include <sys/malloc.h>
45 #include <sys/ctype.h>
46 #include <sys/errno.h>
47 #include <sys/sysctl.h>
48 #include <sys/file.h>
49 #include <sys/uio.h>
50 #include <sys/socketvar.h>
51 #include <sys/socket.h>
52 #include <sys/protosw.h>
53 #include <sys/proc.h>
54 #include <sys/ioccom.h>
55 #include <sys/queue.h>
56 #include <sys/kthread.h>
57 #include <sys/syslog.h>
58 #include <sys/mbuf.h>
59 #include <sys/libkern.h>
60 #include <vm/uma.h>
61
62 #include <dev/iscsi_initiator/iscsi.h>
63 #include <dev/iscsi_initiator/iscsivar.h>
64
65 static MALLOC_DEFINE(M_ISC, "iSC", "iSCSI driver options");
66
67 static char *
68 i_strdupin(char *s, size_t maxlen)
69 {
70 size_t len;
71 char *p, *q;
72
73 p = malloc(maxlen, M_ISC, M_WAITOK);
74 if(copyinstr(s, p, maxlen, &len)) {
75 free(p, M_ISC);
76 return NULL;
77 }
78 q = malloc(len, M_ISC, M_WAITOK);
79 bcopy(p, q, len);
80 free(p, M_ISC);
81
82 return q;
83 }
84 #if __FreeBSD_version < 800000
85 /*****************************************************************/
86 /* */
87 /* CRC LOOKUP TABLE */
88 /* ================ */
89 /* The following CRC lookup table was generated automagically */
90 /* by the Rocksoft^tm Model CRC Algorithm Table Generation */
91 /* Program V1.0 using the following model parameters: */
92 /* */
93 /* Width : 4 bytes. */
94 /* Poly : 0x1EDC6F41L */
95 /* Reverse : TRUE. */
96 /* */
97 /* For more information on the Rocksoft^tm Model CRC Algorithm, */
98 /* see the document titled "A Painless Guide to CRC Error */
99 /* Detection Algorithms" by Ross Williams */
100 /* (ross@guest.adelaide.edu.au.). This document is likely to be */
101 /* in the FTP archive "ftp.adelaide.edu.au/pub/rocksoft". */
102 /* */
103 /*****************************************************************/
104
105 static uint32_t crc32Table[256] = {
106 0x00000000L, 0xF26B8303L, 0xE13B70F7L, 0x1350F3F4L,
107 0xC79A971FL, 0x35F1141CL, 0x26A1E7E8L, 0xD4CA64EBL,
108 0x8AD958CFL, 0x78B2DBCCL, 0x6BE22838L, 0x9989AB3BL,
109 0x4D43CFD0L, 0xBF284CD3L, 0xAC78BF27L, 0x5E133C24L,
110 0x105EC76FL, 0xE235446CL, 0xF165B798L, 0x030E349BL,
111 0xD7C45070L, 0x25AFD373L, 0x36FF2087L, 0xC494A384L,
112 0x9A879FA0L, 0x68EC1CA3L, 0x7BBCEF57L, 0x89D76C54L,
113 0x5D1D08BFL, 0xAF768BBCL, 0xBC267848L, 0x4E4DFB4BL,
114 0x20BD8EDEL, 0xD2D60DDDL, 0xC186FE29L, 0x33ED7D2AL,
115 0xE72719C1L, 0x154C9AC2L, 0x061C6936L, 0xF477EA35L,
116 0xAA64D611L, 0x580F5512L, 0x4B5FA6E6L, 0xB93425E5L,
117 0x6DFE410EL, 0x9F95C20DL, 0x8CC531F9L, 0x7EAEB2FAL,
118 0x30E349B1L, 0xC288CAB2L, 0xD1D83946L, 0x23B3BA45L,
119 0xF779DEAEL, 0x05125DADL, 0x1642AE59L, 0xE4292D5AL,
120 0xBA3A117EL, 0x4851927DL, 0x5B016189L, 0xA96AE28AL,
121 0x7DA08661L, 0x8FCB0562L, 0x9C9BF696L, 0x6EF07595L,
122 0x417B1DBCL, 0xB3109EBFL, 0xA0406D4BL, 0x522BEE48L,
123 0x86E18AA3L, 0x748A09A0L, 0x67DAFA54L, 0x95B17957L,
124 0xCBA24573L, 0x39C9C670L, 0x2A993584L, 0xD8F2B687L,
125 0x0C38D26CL, 0xFE53516FL, 0xED03A29BL, 0x1F682198L,
126 0x5125DAD3L, 0xA34E59D0L, 0xB01EAA24L, 0x42752927L,
127 0x96BF4DCCL, 0x64D4CECFL, 0x77843D3BL, 0x85EFBE38L,
128 0xDBFC821CL, 0x2997011FL, 0x3AC7F2EBL, 0xC8AC71E8L,
129 0x1C661503L, 0xEE0D9600L, 0xFD5D65F4L, 0x0F36E6F7L,
130 0x61C69362L, 0x93AD1061L, 0x80FDE395L, 0x72966096L,
131 0xA65C047DL, 0x5437877EL, 0x4767748AL, 0xB50CF789L,
132 0xEB1FCBADL, 0x197448AEL, 0x0A24BB5AL, 0xF84F3859L,
133 0x2C855CB2L, 0xDEEEDFB1L, 0xCDBE2C45L, 0x3FD5AF46L,
134 0x7198540DL, 0x83F3D70EL, 0x90A324FAL, 0x62C8A7F9L,
135 0xB602C312L, 0x44694011L, 0x5739B3E5L, 0xA55230E6L,
136 0xFB410CC2L, 0x092A8FC1L, 0x1A7A7C35L, 0xE811FF36L,
137 0x3CDB9BDDL, 0xCEB018DEL, 0xDDE0EB2AL, 0x2F8B6829L,
138 0x82F63B78L, 0x709DB87BL, 0x63CD4B8FL, 0x91A6C88CL,
139 0x456CAC67L, 0xB7072F64L, 0xA457DC90L, 0x563C5F93L,
140 0x082F63B7L, 0xFA44E0B4L, 0xE9141340L, 0x1B7F9043L,
141 0xCFB5F4A8L, 0x3DDE77ABL, 0x2E8E845FL, 0xDCE5075CL,
142 0x92A8FC17L, 0x60C37F14L, 0x73938CE0L, 0x81F80FE3L,
143 0x55326B08L, 0xA759E80BL, 0xB4091BFFL, 0x466298FCL,
144 0x1871A4D8L, 0xEA1A27DBL, 0xF94AD42FL, 0x0B21572CL,
145 0xDFEB33C7L, 0x2D80B0C4L, 0x3ED04330L, 0xCCBBC033L,
146 0xA24BB5A6L, 0x502036A5L, 0x4370C551L, 0xB11B4652L,
147 0x65D122B9L, 0x97BAA1BAL, 0x84EA524EL, 0x7681D14DL,
148 0x2892ED69L, 0xDAF96E6AL, 0xC9A99D9EL, 0x3BC21E9DL,
149 0xEF087A76L, 0x1D63F975L, 0x0E330A81L, 0xFC588982L,
150 0xB21572C9L, 0x407EF1CAL, 0x532E023EL, 0xA145813DL,
151 0x758FE5D6L, 0x87E466D5L, 0x94B49521L, 0x66DF1622L,
152 0x38CC2A06L, 0xCAA7A905L, 0xD9F75AF1L, 0x2B9CD9F2L,
153 0xFF56BD19L, 0x0D3D3E1AL, 0x1E6DCDEEL, 0xEC064EEDL,
154 0xC38D26C4L, 0x31E6A5C7L, 0x22B65633L, 0xD0DDD530L,
155 0x0417B1DBL, 0xF67C32D8L, 0xE52CC12CL, 0x1747422FL,
156 0x49547E0BL, 0xBB3FFD08L, 0xA86F0EFCL, 0x5A048DFFL,
157 0x8ECEE914L, 0x7CA56A17L, 0x6FF599E3L, 0x9D9E1AE0L,
158 0xD3D3E1ABL, 0x21B862A8L, 0x32E8915CL, 0xC083125FL,
159 0x144976B4L, 0xE622F5B7L, 0xF5720643L, 0x07198540L,
160 0x590AB964L, 0xAB613A67L, 0xB831C993L, 0x4A5A4A90L,
161 0x9E902E7BL, 0x6CFBAD78L, 0x7FAB5E8CL, 0x8DC0DD8FL,
162 0xE330A81AL, 0x115B2B19L, 0x020BD8EDL, 0xF0605BEEL,
163 0x24AA3F05L, 0xD6C1BC06L, 0xC5914FF2L, 0x37FACCF1L,
164 0x69E9F0D5L, 0x9B8273D6L, 0x88D28022L, 0x7AB90321L,
165 0xAE7367CAL, 0x5C18E4C9L, 0x4F48173DL, 0xBD23943EL,
166 0xF36E6F75L, 0x0105EC76L, 0x12551F82L, 0xE03E9C81L,
167 0x34F4F86AL, 0xC69F7B69L, 0xD5CF889DL, 0x27A40B9EL,
168 0x79B737BAL, 0x8BDCB4B9L, 0x988C474DL, 0x6AE7C44EL,
169 0xBE2DA0A5L, 0x4C4623A6L, 0x5F16D052L, 0xAD7D5351L
170 };
171
172 static __inline int
173 calculate_crc32c(uint32_t crc, const void *buf, size_t size)
174 {
175 const uint8_t *p = buf;
176
177 while (size--)
178 crc = crc32Table[(crc ^ *p++) & 0xff] ^ (crc >> 8);
179 return crc;
180 }
181 #endif
182
183 static uint32_t
184 i_crc32c(const void *buf, size_t size, uint32_t crc)
185 {
186 crc = crc ^ 0xffffffff;
187 crc = calculate_crc32c(crc, buf, size);
188 crc = crc ^ 0xffffffff;
189 return crc;
190 }
191
192 /*
193 | XXX: not finished coding
194 */
195 int
196 i_setopt(isc_session_t *sp, isc_opt_t *opt)
197 {
198 char buf[16];
199 int error;
200
201 if(opt->maxRecvDataSegmentLength > 0) {
202 sp->opt.maxRecvDataSegmentLength = opt->maxRecvDataSegmentLength;
203 sdebug(2, "maxRecvDataSegmentLength=%d", sp->opt.maxRecvDataSegmentLength);
204 }
205 if(opt->maxXmitDataSegmentLength > 0) {
206 // danny's RFC
207 sp->opt.maxXmitDataSegmentLength = opt->maxXmitDataSegmentLength;
208 sdebug(2, "opt.maXmitDataSegmentLength=%d", sp->opt.maxXmitDataSegmentLength);
209 }
210 if(opt->maxBurstLength != 0) {
211 sp->opt.maxBurstLength = opt->maxBurstLength;
212 sdebug(2, "opt.maxBurstLength=%d", sp->opt.maxBurstLength);
213 }
214
215 if(opt->targetAddress != NULL) {
216 if(sp->opt.targetAddress != NULL)
217 free(sp->opt.targetAddress, M_ISC);
218 sp->opt.targetAddress = i_strdupin(opt->targetAddress, 128);
219 sdebug(2, "opt.targetAddress='%s'", sp->opt.targetAddress);
220 }
221 if(opt->targetName != NULL) {
222 if(sp->opt.targetName != NULL)
223 free(sp->opt.targetName, M_ISC);
224 sp->opt.targetName = i_strdupin(opt->targetName, 128);
225 sdebug(2, "opt.targetName='%s'", sp->opt.targetName);
226 }
227 if(opt->initiatorName != NULL) {
228 if(sp->opt.initiatorName != NULL)
229 free(sp->opt.initiatorName, M_ISC);
230 sp->opt.initiatorName = i_strdupin(opt->initiatorName, 128);
231 sdebug(2, "opt.initiatorName='%s'", sp->opt.initiatorName);
232 }
233
234 if(opt->maxluns > 0) {
235 if(opt->maxluns > ISCSI_MAX_LUNS)
236 sp->opt.maxluns = ISCSI_MAX_LUNS; // silently chop it down ...
237 sp->opt.maxluns = opt->maxluns;
238 sdebug(2, "opt.maxluns=%d", sp->opt.maxluns);
239 }
240
241 if(opt->headerDigest != NULL) {
242 error = copyinstr(opt->headerDigest, buf, sizeof(buf), NULL);
243 if (error != 0)
244 return (error);
245 sdebug(2, "opt.headerDigest='%s'", buf);
246 if(strcmp(buf, "CRC32C") == 0) {
247 sp->hdrDigest = (digest_t *)i_crc32c;
248 sdebug(2, "opt.headerDigest set");
249 }
250 }
251 if(opt->dataDigest != NULL) {
252 error = copyinstr(opt->dataDigest, buf, sizeof(buf), NULL);
253 if (error != 0)
254 return (error);
255 sdebug(2, "opt.dataDigest='%s'", opt->dataDigest);
256 if(strcmp(buf, "CRC32C") == 0) {
257 sp->dataDigest = (digest_t *)i_crc32c;
258 sdebug(2, "opt.dataDigest set");
259 }
260 }
261
262 return 0;
263 }
264
265 void
266 i_freeopt(isc_opt_t *opt)
267 {
268 debug_called(8);
269
270 if(opt->targetAddress != NULL) {
271 free(opt->targetAddress, M_ISC);
272 opt->targetAddress = NULL;
273 }
274 if(opt->targetName != NULL) {
275 free(opt->targetName, M_ISC);
276 opt->targetName = NULL;
277 }
278 if(opt->initiatorName != NULL) {
279 free(opt->initiatorName, M_ISC);
280 opt->initiatorName = NULL;
281 }
282 }
Cache object: 4fd1703a8a1cf0ebb08f45d55993f86f
|