1
2
3
4
5
6
7
8
9
10
11
12#include <linux/module.h>
13#include <linux/init.h>
14#include <linux/slab.h>
15#include <linux/sched.h>
16#include <linux/ip.h>
17#include "internal.h"
18#include "afs_cm.h"
19
20static int afs_deliver_cb_init_call_back_state(struct afs_call *);
21static int afs_deliver_cb_init_call_back_state3(struct afs_call *);
22static int afs_deliver_cb_probe(struct afs_call *);
23static int afs_deliver_cb_callback(struct afs_call *);
24static int afs_deliver_cb_probe_uuid(struct afs_call *);
25static int afs_deliver_cb_tell_me_about_yourself(struct afs_call *);
26static void afs_cm_destructor(struct afs_call *);
27static void SRXAFSCB_CallBack(struct work_struct *);
28static void SRXAFSCB_InitCallBackState(struct work_struct *);
29static void SRXAFSCB_Probe(struct work_struct *);
30static void SRXAFSCB_ProbeUuid(struct work_struct *);
31static void SRXAFSCB_TellMeAboutYourself(struct work_struct *);
32
33#define CM_NAME(name) \
34 const char afs_SRXCB##name##_name[] __tracepoint_string = \
35 "CB." #name
36
37
38
39
40static CM_NAME(CallBack);
41static const struct afs_call_type afs_SRXCBCallBack = {
42 .name = afs_SRXCBCallBack_name,
43 .deliver = afs_deliver_cb_callback,
44 .destructor = afs_cm_destructor,
45 .work = SRXAFSCB_CallBack,
46};
47
48
49
50
51static CM_NAME(InitCallBackState);
52static const struct afs_call_type afs_SRXCBInitCallBackState = {
53 .name = afs_SRXCBInitCallBackState_name,
54 .deliver = afs_deliver_cb_init_call_back_state,
55 .destructor = afs_cm_destructor,
56 .work = SRXAFSCB_InitCallBackState,
57};
58
59
60
61
62static CM_NAME(InitCallBackState3);
63static const struct afs_call_type afs_SRXCBInitCallBackState3 = {
64 .name = afs_SRXCBInitCallBackState3_name,
65 .deliver = afs_deliver_cb_init_call_back_state3,
66 .destructor = afs_cm_destructor,
67 .work = SRXAFSCB_InitCallBackState,
68};
69
70
71
72
73static CM_NAME(Probe);
74static const struct afs_call_type afs_SRXCBProbe = {
75 .name = afs_SRXCBProbe_name,
76 .deliver = afs_deliver_cb_probe,
77 .destructor = afs_cm_destructor,
78 .work = SRXAFSCB_Probe,
79};
80
81
82
83
84static CM_NAME(ProbeUuid);
85static const struct afs_call_type afs_SRXCBProbeUuid = {
86 .name = afs_SRXCBProbeUuid_name,
87 .deliver = afs_deliver_cb_probe_uuid,
88 .destructor = afs_cm_destructor,
89 .work = SRXAFSCB_ProbeUuid,
90};
91
92
93
94
95static CM_NAME(TellMeAboutYourself);
96static const struct afs_call_type afs_SRXCBTellMeAboutYourself = {
97 .name = afs_SRXCBTellMeAboutYourself_name,
98 .deliver = afs_deliver_cb_tell_me_about_yourself,
99 .destructor = afs_cm_destructor,
100 .work = SRXAFSCB_TellMeAboutYourself,
101};
102
103
104
105
106
107bool afs_cm_incoming_call(struct afs_call *call)
108{
109 _enter("{CB.OP %u}", call->operation_ID);
110
111 switch (call->operation_ID) {
112 case CBCallBack:
113 call->type = &afs_SRXCBCallBack;
114 return true;
115 case CBInitCallBackState:
116 call->type = &afs_SRXCBInitCallBackState;
117 return true;
118 case CBInitCallBackState3:
119 call->type = &afs_SRXCBInitCallBackState3;
120 return true;
121 case CBProbe:
122 call->type = &afs_SRXCBProbe;
123 return true;
124 case CBProbeUuid:
125 call->type = &afs_SRXCBProbeUuid;
126 return true;
127 case CBTellMeAboutYourself:
128 call->type = &afs_SRXCBTellMeAboutYourself;
129 return true;
130 default:
131 return false;
132 }
133}
134
135
136
137
138static void afs_cm_destructor(struct afs_call *call)
139{
140 kfree(call->buffer);
141 call->buffer = NULL;
142}
143
144
145
146
147static void SRXAFSCB_CallBack(struct work_struct *work)
148{
149 struct afs_call *call = container_of(work, struct afs_call, work);
150
151 _enter("");
152
153
154
155
156
157 if (call->cm_server)
158 afs_break_callbacks(call->cm_server, call->count, call->request);
159
160 afs_send_empty_reply(call);
161 afs_put_call(call);
162 _leave("");
163}
164
165
166
167
168static int afs_deliver_cb_callback(struct afs_call *call)
169{
170 struct afs_callback_break *cb;
171 struct sockaddr_rxrpc srx;
172 __be32 *bp;
173 int ret, loop;
174
175 _enter("{%u}", call->unmarshall);
176
177 switch (call->unmarshall) {
178 case 0:
179 call->offset = 0;
180 call->unmarshall++;
181
182
183 case 1:
184 _debug("extract FID count");
185 ret = afs_extract_data(call, &call->tmp, 4, true);
186 if (ret < 0)
187 return ret;
188
189 call->count = ntohl(call->tmp);
190 _debug("FID count: %u", call->count);
191 if (call->count > AFSCBMAX)
192 return afs_protocol_error(call, -EBADMSG);
193
194 call->buffer = kmalloc(call->count * 3 * 4, GFP_KERNEL);
195 if (!call->buffer)
196 return -ENOMEM;
197 call->offset = 0;
198 call->unmarshall++;
199
200 case 2:
201 _debug("extract FID array");
202 ret = afs_extract_data(call, call->buffer,
203 call->count * 3 * 4, true);
204 if (ret < 0)
205 return ret;
206
207 _debug("unmarshall FID array");
208 call->request = kcalloc(call->count,
209 sizeof(struct afs_callback_break),
210 GFP_KERNEL);
211 if (!call->request)
212 return -ENOMEM;
213
214 cb = call->request;
215 bp = call->buffer;
216 for (loop = call->count; loop > 0; loop--, cb++) {
217 cb->fid.vid = ntohl(*bp++);
218 cb->fid.vnode = ntohl(*bp++);
219 cb->fid.unique = ntohl(*bp++);
220 cb->cb.type = AFSCM_CB_UNTYPED;
221 }
222
223 call->offset = 0;
224 call->unmarshall++;
225
226
227 case 3:
228 _debug("extract CB count");
229 ret = afs_extract_data(call, &call->tmp, 4, true);
230 if (ret < 0)
231 return ret;
232
233 call->count2 = ntohl(call->tmp);
234 _debug("CB count: %u", call->count2);
235 if (call->count2 != call->count && call->count2 != 0)
236 return afs_protocol_error(call, -EBADMSG);
237 call->offset = 0;
238 call->unmarshall++;
239
240 case 4:
241 _debug("extract CB array");
242 ret = afs_extract_data(call, call->buffer,
243 call->count2 * 3 * 4, false);
244 if (ret < 0)
245 return ret;
246
247 _debug("unmarshall CB array");
248 cb = call->request;
249 bp = call->buffer;
250 for (loop = call->count2; loop > 0; loop--, cb++) {
251 cb->cb.version = ntohl(*bp++);
252 cb->cb.expiry = ntohl(*bp++);
253 cb->cb.type = ntohl(*bp++);
254 }
255
256 call->offset = 0;
257 call->unmarshall++;
258 case 5:
259 break;
260 }
261
262 if (!afs_check_call_state(call, AFS_CALL_SV_REPLYING))
263 return -EIO;
264
265
266
267 rxrpc_kernel_get_peer(call->net->socket, call->rxcall, &srx);
268 call->cm_server = afs_find_server(call->net, &srx);
269 if (!call->cm_server)
270 trace_afs_cm_no_server(call, &srx);
271
272 return afs_queue_call_work(call);
273}
274
275
276
277
278static void SRXAFSCB_InitCallBackState(struct work_struct *work)
279{
280 struct afs_call *call = container_of(work, struct afs_call, work);
281
282 _enter("{%p}", call->cm_server);
283
284 if (call->cm_server)
285 afs_init_callback_state(call->cm_server);
286 afs_send_empty_reply(call);
287 afs_put_call(call);
288 _leave("");
289}
290
291
292
293
294static int afs_deliver_cb_init_call_back_state(struct afs_call *call)
295{
296 struct sockaddr_rxrpc srx;
297 int ret;
298
299 _enter("");
300
301 rxrpc_kernel_get_peer(call->net->socket, call->rxcall, &srx);
302
303 ret = afs_extract_data(call, NULL, 0, false);
304 if (ret < 0)
305 return ret;
306
307
308
309 call->cm_server = afs_find_server(call->net, &srx);
310 if (!call->cm_server)
311 trace_afs_cm_no_server(call, &srx);
312
313 return afs_queue_call_work(call);
314}
315
316
317
318
319static int afs_deliver_cb_init_call_back_state3(struct afs_call *call)
320{
321 struct afs_uuid *r;
322 unsigned loop;
323 __be32 *b;
324 int ret;
325
326 _enter("");
327
328 _enter("{%u}", call->unmarshall);
329
330 switch (call->unmarshall) {
331 case 0:
332 call->offset = 0;
333 call->buffer = kmalloc(11 * sizeof(__be32), GFP_KERNEL);
334 if (!call->buffer)
335 return -ENOMEM;
336 call->unmarshall++;
337
338 case 1:
339 _debug("extract UUID");
340 ret = afs_extract_data(call, call->buffer,
341 11 * sizeof(__be32), false);
342 switch (ret) {
343 case 0: break;
344 case -EAGAIN: return 0;
345 default: return ret;
346 }
347
348 _debug("unmarshall UUID");
349 call->request = kmalloc(sizeof(struct afs_uuid), GFP_KERNEL);
350 if (!call->request)
351 return -ENOMEM;
352
353 b = call->buffer;
354 r = call->request;
355 r->time_low = b[0];
356 r->time_mid = htons(ntohl(b[1]));
357 r->time_hi_and_version = htons(ntohl(b[2]));
358 r->clock_seq_hi_and_reserved = ntohl(b[3]);
359 r->clock_seq_low = ntohl(b[4]);
360
361 for (loop = 0; loop < 6; loop++)
362 r->node[loop] = ntohl(b[loop + 5]);
363
364 call->offset = 0;
365 call->unmarshall++;
366
367 case 2:
368 break;
369 }
370
371 if (!afs_check_call_state(call, AFS_CALL_SV_REPLYING))
372 return -EIO;
373
374
375
376 rcu_read_lock();
377 call->cm_server = afs_find_server_by_uuid(call->net, call->request);
378 rcu_read_unlock();
379 if (!call->cm_server)
380 trace_afs_cm_no_server_u(call, call->request);
381
382 return afs_queue_call_work(call);
383}
384
385
386
387
388static void SRXAFSCB_Probe(struct work_struct *work)
389{
390 struct afs_call *call = container_of(work, struct afs_call, work);
391
392 _enter("");
393 afs_send_empty_reply(call);
394 afs_put_call(call);
395 _leave("");
396}
397
398
399
400
401static int afs_deliver_cb_probe(struct afs_call *call)
402{
403 int ret;
404
405 _enter("");
406
407 ret = afs_extract_data(call, NULL, 0, false);
408 if (ret < 0)
409 return ret;
410
411 if (!afs_check_call_state(call, AFS_CALL_SV_REPLYING))
412 return -EIO;
413
414 return afs_queue_call_work(call);
415}
416
417
418
419
420static void SRXAFSCB_ProbeUuid(struct work_struct *work)
421{
422 struct afs_call *call = container_of(work, struct afs_call, work);
423 struct afs_uuid *r = call->request;
424
425 struct {
426 __be32 match;
427 } reply;
428
429 _enter("");
430
431 if (memcmp(r, &call->net->uuid, sizeof(call->net->uuid)) == 0)
432 reply.match = htonl(0);
433 else
434 reply.match = htonl(1);
435
436 afs_send_simple_reply(call, &reply, sizeof(reply));
437 afs_put_call(call);
438 _leave("");
439}
440
441
442
443
444static int afs_deliver_cb_probe_uuid(struct afs_call *call)
445{
446 struct afs_uuid *r;
447 unsigned loop;
448 __be32 *b;
449 int ret;
450
451 _enter("{%u}", call->unmarshall);
452
453 switch (call->unmarshall) {
454 case 0:
455 call->offset = 0;
456 call->buffer = kmalloc(11 * sizeof(__be32), GFP_KERNEL);
457 if (!call->buffer)
458 return -ENOMEM;
459 call->unmarshall++;
460
461 case 1:
462 _debug("extract UUID");
463 ret = afs_extract_data(call, call->buffer,
464 11 * sizeof(__be32), false);
465 switch (ret) {
466 case 0: break;
467 case -EAGAIN: return 0;
468 default: return ret;
469 }
470
471 _debug("unmarshall UUID");
472 call->request = kmalloc(sizeof(struct afs_uuid), GFP_KERNEL);
473 if (!call->request)
474 return -ENOMEM;
475
476 b = call->buffer;
477 r = call->request;
478 r->time_low = b[0];
479 r->time_mid = htons(ntohl(b[1]));
480 r->time_hi_and_version = htons(ntohl(b[2]));
481 r->clock_seq_hi_and_reserved = ntohl(b[3]);
482 r->clock_seq_low = ntohl(b[4]);
483
484 for (loop = 0; loop < 6; loop++)
485 r->node[loop] = ntohl(b[loop + 5]);
486
487 call->offset = 0;
488 call->unmarshall++;
489
490 case 2:
491 break;
492 }
493
494 if (!afs_check_call_state(call, AFS_CALL_SV_REPLYING))
495 return -EIO;
496
497 return afs_queue_call_work(call);
498}
499
500
501
502
503static void SRXAFSCB_TellMeAboutYourself(struct work_struct *work)
504{
505 struct afs_interface *ifs;
506 struct afs_call *call = container_of(work, struct afs_call, work);
507 int loop, nifs;
508
509 struct {
510 struct {
511 __be32 nifs;
512 __be32 uuid[11];
513 __be32 ifaddr[32];
514 __be32 netmask[32];
515 __be32 mtu[32];
516 } ia;
517 struct {
518 __be32 capcount;
519 __be32 caps[1];
520 } cap;
521 } reply;
522
523 _enter("");
524
525 nifs = 0;
526 ifs = kcalloc(32, sizeof(*ifs), GFP_KERNEL);
527 if (ifs) {
528 nifs = afs_get_ipv4_interfaces(ifs, 32, false);
529 if (nifs < 0) {
530 kfree(ifs);
531 ifs = NULL;
532 nifs = 0;
533 }
534 }
535
536 memset(&reply, 0, sizeof(reply));
537 reply.ia.nifs = htonl(nifs);
538
539 reply.ia.uuid[0] = call->net->uuid.time_low;
540 reply.ia.uuid[1] = htonl(ntohs(call->net->uuid.time_mid));
541 reply.ia.uuid[2] = htonl(ntohs(call->net->uuid.time_hi_and_version));
542 reply.ia.uuid[3] = htonl((s8) call->net->uuid.clock_seq_hi_and_reserved);
543 reply.ia.uuid[4] = htonl((s8) call->net->uuid.clock_seq_low);
544 for (loop = 0; loop < 6; loop++)
545 reply.ia.uuid[loop + 5] = htonl((s8) call->net->uuid.node[loop]);
546
547 if (ifs) {
548 for (loop = 0; loop < nifs; loop++) {
549 reply.ia.ifaddr[loop] = ifs[loop].address.s_addr;
550 reply.ia.netmask[loop] = ifs[loop].netmask.s_addr;
551 reply.ia.mtu[loop] = htonl(ifs[loop].mtu);
552 }
553 kfree(ifs);
554 }
555
556 reply.cap.capcount = htonl(1);
557 reply.cap.caps[0] = htonl(AFS_CAP_ERROR_TRANSLATION);
558 afs_send_simple_reply(call, &reply, sizeof(reply));
559 afs_put_call(call);
560 _leave("");
561}
562
563
564
565
566static int afs_deliver_cb_tell_me_about_yourself(struct afs_call *call)
567{
568 int ret;
569
570 _enter("");
571
572 ret = afs_extract_data(call, NULL, 0, false);
573 if (ret < 0)
574 return ret;
575
576 if (!afs_check_call_state(call, AFS_CALL_SV_REPLYING))
577 return -EIO;
578
579 return afs_queue_call_work(call);
580}
581