[NET]: Kill direct includes of asm/checksum.h
[linux-2.6.git] / net / rxrpc / transport.c
1 /* transport.c: Rx Transport routines
2  *
3  * Copyright (C) 2002 Red Hat, Inc. All Rights Reserved.
4  * Written by David Howells (dhowells@redhat.com)
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version
9  * 2 of the License, or (at your option) any later version.
10  */
11
12 #include <linux/sched.h>
13 #include <linux/slab.h>
14 #include <linux/module.h>
15 #include <rxrpc/transport.h>
16 #include <rxrpc/peer.h>
17 #include <rxrpc/connection.h>
18 #include <rxrpc/call.h>
19 #include <rxrpc/message.h>
20 #include <rxrpc/krxiod.h>
21 #include <rxrpc/krxsecd.h>
22 #include <linux/udp.h>
23 #include <linux/in.h>
24 #include <linux/in6.h>
25 #include <linux/icmp.h>
26 #include <linux/skbuff.h>
27 #include <net/sock.h>
28 #include <net/ip.h>
29 #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
30 #include <linux/ipv6.h> /* this should _really_ be in errqueue.h.. */
31 #endif
32 #include <linux/errqueue.h>
33 #include <asm/uaccess.h>
34 #include "internal.h"
35
36 struct errormsg {
37         struct cmsghdr                  cmsg;           /* control message header */
38         struct sock_extended_err        ee;             /* extended error information */
39         struct sockaddr_in              icmp_src;       /* ICMP packet source address */
40 };
41
42 static DEFINE_SPINLOCK(rxrpc_transports_lock);
43 static struct list_head rxrpc_transports = LIST_HEAD_INIT(rxrpc_transports);
44
45 __RXACCT_DECL(atomic_t rxrpc_transport_count);
46 LIST_HEAD(rxrpc_proc_transports);
47 DECLARE_RWSEM(rxrpc_proc_transports_sem);
48
49 static void rxrpc_data_ready(struct sock *sk, int count);
50 static void rxrpc_error_report(struct sock *sk);
51 static int rxrpc_trans_receive_new_call(struct rxrpc_transport *trans,
52                                         struct list_head *msgq);
53 static void rxrpc_trans_receive_error_report(struct rxrpc_transport *trans);
54
55 /*****************************************************************************/
56 /*
57  * create a new transport endpoint using the specified UDP port
58  */
59 int rxrpc_create_transport(unsigned short port,
60                            struct rxrpc_transport **_trans)
61 {
62         struct rxrpc_transport *trans;
63         struct sockaddr_in sin;
64         mm_segment_t oldfs;
65         struct sock *sock;
66         int ret, opt;
67
68         _enter("%hu", port);
69
70         trans = kzalloc(sizeof(struct rxrpc_transport), GFP_KERNEL);
71         if (!trans)
72                 return -ENOMEM;
73
74         atomic_set(&trans->usage, 1);
75         INIT_LIST_HEAD(&trans->services);
76         INIT_LIST_HEAD(&trans->link);
77         INIT_LIST_HEAD(&trans->krxiodq_link);
78         spin_lock_init(&trans->lock);
79         INIT_LIST_HEAD(&trans->peer_active);
80         INIT_LIST_HEAD(&trans->peer_graveyard);
81         spin_lock_init(&trans->peer_gylock);
82         init_waitqueue_head(&trans->peer_gy_waitq);
83         rwlock_init(&trans->peer_lock);
84         atomic_set(&trans->peer_count, 0);
85         trans->port = port;
86
87         /* create a UDP socket to be my actual transport endpoint */
88         ret = sock_create_kern(PF_INET, SOCK_DGRAM, IPPROTO_UDP, &trans->socket);
89         if (ret < 0)
90                 goto error;
91
92         /* use the specified port */
93         if (port) {
94                 memset(&sin, 0, sizeof(sin));
95                 sin.sin_family = AF_INET;
96                 sin.sin_port = htons(port);
97                 ret = trans->socket->ops->bind(trans->socket,
98                                                (struct sockaddr *) &sin,
99                                                sizeof(sin));
100                 if (ret < 0)
101                         goto error;
102         }
103
104         opt = 1;
105         oldfs = get_fs();
106         set_fs(KERNEL_DS);
107         ret = trans->socket->ops->setsockopt(trans->socket, SOL_IP, IP_RECVERR,
108                                              (char *) &opt, sizeof(opt));
109         set_fs(oldfs);
110
111         spin_lock(&rxrpc_transports_lock);
112         list_add(&trans->link, &rxrpc_transports);
113         spin_unlock(&rxrpc_transports_lock);
114
115         /* set the socket up */
116         sock = trans->socket->sk;
117         sock->sk_user_data      = trans;
118         sock->sk_data_ready     = rxrpc_data_ready;
119         sock->sk_error_report   = rxrpc_error_report;
120
121         down_write(&rxrpc_proc_transports_sem);
122         list_add_tail(&trans->proc_link, &rxrpc_proc_transports);
123         up_write(&rxrpc_proc_transports_sem);
124
125         __RXACCT(atomic_inc(&rxrpc_transport_count));
126
127         *_trans = trans;
128         _leave(" = 0 (%p)", trans);
129         return 0;
130
131  error:
132         /* finish cleaning up the transport (not really needed here, but...) */
133         if (trans->socket)
134                 trans->socket->ops->shutdown(trans->socket, 2);
135
136         /* close the socket */
137         if (trans->socket) {
138                 trans->socket->sk->sk_user_data = NULL;
139                 sock_release(trans->socket);
140                 trans->socket = NULL;
141         }
142
143         kfree(trans);
144
145
146         _leave(" = %d", ret);
147         return ret;
148 } /* end rxrpc_create_transport() */
149
150 /*****************************************************************************/
151 /*
152  * destroy a transport endpoint
153  */
154 void rxrpc_put_transport(struct rxrpc_transport *trans)
155 {
156         _enter("%p{u=%d p=%hu}",
157                trans, atomic_read(&trans->usage), trans->port);
158
159         BUG_ON(atomic_read(&trans->usage) <= 0);
160
161         /* to prevent a race, the decrement and the dequeue must be
162          * effectively atomic */
163         spin_lock(&rxrpc_transports_lock);
164         if (likely(!atomic_dec_and_test(&trans->usage))) {
165                 spin_unlock(&rxrpc_transports_lock);
166                 _leave("");
167                 return;
168         }
169
170         list_del(&trans->link);
171         spin_unlock(&rxrpc_transports_lock);
172
173         /* finish cleaning up the transport */
174         if (trans->socket)
175                 trans->socket->ops->shutdown(trans->socket, 2);
176
177         rxrpc_krxsecd_clear_transport(trans);
178         rxrpc_krxiod_dequeue_transport(trans);
179
180         /* discard all peer information */
181         rxrpc_peer_clearall(trans);
182
183         down_write(&rxrpc_proc_transports_sem);
184         list_del(&trans->proc_link);
185         up_write(&rxrpc_proc_transports_sem);
186         __RXACCT(atomic_dec(&rxrpc_transport_count));
187
188         /* close the socket */
189         if (trans->socket) {
190                 trans->socket->sk->sk_user_data = NULL;
191                 sock_release(trans->socket);
192                 trans->socket = NULL;
193         }
194
195         kfree(trans);
196
197         _leave("");
198 } /* end rxrpc_put_transport() */
199
200 /*****************************************************************************/
201 /*
202  * add a service to a transport to be listened upon
203  */
204 int rxrpc_add_service(struct rxrpc_transport *trans,
205                       struct rxrpc_service *newsrv)
206 {
207         struct rxrpc_service *srv;
208         struct list_head *_p;
209         int ret = -EEXIST;
210
211         _enter("%p{%hu},%p{%hu}",
212                trans, trans->port, newsrv, newsrv->service_id);
213
214         /* verify that the service ID is not already present */
215         spin_lock(&trans->lock);
216
217         list_for_each(_p, &trans->services) {
218                 srv = list_entry(_p, struct rxrpc_service, link);
219                 if (srv->service_id == newsrv->service_id)
220                         goto out;
221         }
222
223         /* okay - add the transport to the list */
224         list_add_tail(&newsrv->link, &trans->services);
225         rxrpc_get_transport(trans);
226         ret = 0;
227
228  out:
229         spin_unlock(&trans->lock);
230
231         _leave("= %d", ret);
232         return ret;
233 } /* end rxrpc_add_service() */
234
235 /*****************************************************************************/
236 /*
237  * remove a service from a transport
238  */
239 void rxrpc_del_service(struct rxrpc_transport *trans, struct rxrpc_service *srv)
240 {
241         _enter("%p{%hu},%p{%hu}", trans, trans->port, srv, srv->service_id);
242
243         spin_lock(&trans->lock);
244         list_del(&srv->link);
245         spin_unlock(&trans->lock);
246
247         rxrpc_put_transport(trans);
248
249         _leave("");
250 } /* end rxrpc_del_service() */
251
252 /*****************************************************************************/
253 /*
254  * INET callback when data has been received on the socket.
255  */
256 static void rxrpc_data_ready(struct sock *sk, int count)
257 {
258         struct rxrpc_transport *trans;
259
260         _enter("%p{t=%p},%d", sk, sk->sk_user_data, count);
261
262         /* queue the transport for attention by krxiod */
263         trans = (struct rxrpc_transport *) sk->sk_user_data;
264         if (trans)
265                 rxrpc_krxiod_queue_transport(trans);
266
267         /* wake up anyone waiting on the socket */
268         if (sk->sk_sleep && waitqueue_active(sk->sk_sleep))
269                 wake_up_interruptible(sk->sk_sleep);
270
271         _leave("");
272 } /* end rxrpc_data_ready() */
273
274 /*****************************************************************************/
275 /*
276  * INET callback when an ICMP error packet is received
277  * - sk->err is error (EHOSTUNREACH, EPROTO or EMSGSIZE)
278  */
279 static void rxrpc_error_report(struct sock *sk)
280 {
281         struct rxrpc_transport *trans;
282
283         _enter("%p{t=%p}", sk, sk->sk_user_data);
284
285         /* queue the transport for attention by krxiod */
286         trans = (struct rxrpc_transport *) sk->sk_user_data;
287         if (trans) {
288                 trans->error_rcvd = 1;
289                 rxrpc_krxiod_queue_transport(trans);
290         }
291
292         /* wake up anyone waiting on the socket */
293         if (sk->sk_sleep && waitqueue_active(sk->sk_sleep))
294                 wake_up_interruptible(sk->sk_sleep);
295
296         _leave("");
297 } /* end rxrpc_error_report() */
298
299 /*****************************************************************************/
300 /*
301  * split a message up, allocating message records and filling them in
302  * from the contents of a socket buffer
303  */
304 static int rxrpc_incoming_msg(struct rxrpc_transport *trans,
305                               struct sk_buff *pkt,
306                               struct list_head *msgq)
307 {
308         struct rxrpc_message *msg;
309         int ret;
310
311         _enter("");
312
313         msg = kzalloc(sizeof(struct rxrpc_message), GFP_KERNEL);
314         if (!msg) {
315                 _leave(" = -ENOMEM");
316                 return -ENOMEM;
317         }
318
319         atomic_set(&msg->usage, 1);
320         list_add_tail(&msg->link,msgq);
321
322         /* dig out the Rx routing parameters */
323         if (skb_copy_bits(pkt, sizeof(struct udphdr),
324                           &msg->hdr, sizeof(msg->hdr)) < 0) {
325                 ret = -EBADMSG;
326                 goto error;
327         }
328
329         msg->trans = trans;
330         msg->state = RXRPC_MSG_RECEIVED;
331         skb_get_timestamp(pkt, &msg->stamp);
332         if (msg->stamp.tv_sec == 0) {
333                 do_gettimeofday(&msg->stamp); 
334                 if (pkt->sk) 
335                         sock_enable_timestamp(pkt->sk);
336         } 
337         msg->seq = ntohl(msg->hdr.seq);
338
339         /* attach the packet */
340         skb_get(pkt);
341         msg->pkt = pkt;
342
343         msg->offset = sizeof(struct udphdr) + sizeof(struct rxrpc_header);
344         msg->dsize = msg->pkt->len - msg->offset;
345
346         _net("Rx Received packet from %s (%08x;%08x,%1x,%d,%s,%02x,%d,%d)",
347              msg->hdr.flags & RXRPC_CLIENT_INITIATED ? "client" : "server",
348              ntohl(msg->hdr.epoch),
349              (ntohl(msg->hdr.cid) & RXRPC_CIDMASK) >> RXRPC_CIDSHIFT,
350              ntohl(msg->hdr.cid) & RXRPC_CHANNELMASK,
351              ntohl(msg->hdr.callNumber),
352              rxrpc_pkts[msg->hdr.type],
353              msg->hdr.flags,
354              ntohs(msg->hdr.serviceId),
355              msg->hdr.securityIndex);
356
357         __RXACCT(atomic_inc(&rxrpc_message_count));
358
359         /* split off jumbo packets */
360         while (msg->hdr.type == RXRPC_PACKET_TYPE_DATA &&
361                msg->hdr.flags & RXRPC_JUMBO_PACKET
362                ) {
363                 struct rxrpc_jumbo_header jumbo;
364                 struct rxrpc_message *jumbomsg = msg;
365
366                 _debug("split jumbo packet");
367
368                 /* quick sanity check */
369                 ret = -EBADMSG;
370                 if (msg->dsize <
371                     RXRPC_JUMBO_DATALEN + sizeof(struct rxrpc_jumbo_header))
372                         goto error;
373                 if (msg->hdr.flags & RXRPC_LAST_PACKET)
374                         goto error;
375
376                 /* dig out the secondary header */
377                 if (skb_copy_bits(pkt, msg->offset + RXRPC_JUMBO_DATALEN,
378                                   &jumbo, sizeof(jumbo)) < 0)
379                         goto error;
380
381                 /* allocate a new message record */
382                 ret = -ENOMEM;
383                 msg = kmemdup(jumbomsg, sizeof(struct rxrpc_message), GFP_KERNEL);
384                 if (!msg)
385                         goto error;
386
387                 list_add_tail(&msg->link, msgq);
388
389                 /* adjust the jumbo packet */
390                 jumbomsg->dsize = RXRPC_JUMBO_DATALEN;
391
392                 /* attach the packet here too */
393                 skb_get(pkt);
394
395                 /* adjust the parameters */
396                 msg->seq++;
397                 msg->hdr.seq = htonl(msg->seq);
398                 msg->hdr.serial = htonl(ntohl(msg->hdr.serial) + 1);
399                 msg->offset += RXRPC_JUMBO_DATALEN +
400                         sizeof(struct rxrpc_jumbo_header);
401                 msg->dsize -= RXRPC_JUMBO_DATALEN +
402                         sizeof(struct rxrpc_jumbo_header);
403                 msg->hdr.flags = jumbo.flags;
404                 msg->hdr._rsvd = jumbo._rsvd;
405
406                 _net("Rx Split jumbo packet from %s"
407                      " (%08x;%08x,%1x,%d,%s,%02x,%d,%d)",
408                      msg->hdr.flags & RXRPC_CLIENT_INITIATED ? "client" : "server",
409                      ntohl(msg->hdr.epoch),
410                      (ntohl(msg->hdr.cid) & RXRPC_CIDMASK) >> RXRPC_CIDSHIFT,
411                      ntohl(msg->hdr.cid) & RXRPC_CHANNELMASK,
412                      ntohl(msg->hdr.callNumber),
413                      rxrpc_pkts[msg->hdr.type],
414                      msg->hdr.flags,
415                      ntohs(msg->hdr.serviceId),
416                      msg->hdr.securityIndex);
417
418                 __RXACCT(atomic_inc(&rxrpc_message_count));
419         }
420
421         _leave(" = 0 #%d", atomic_read(&rxrpc_message_count));
422         return 0;
423
424  error:
425         while (!list_empty(msgq)) {
426                 msg = list_entry(msgq->next, struct rxrpc_message, link);
427                 list_del_init(&msg->link);
428
429                 rxrpc_put_message(msg);
430         }
431
432         _leave(" = %d", ret);
433         return ret;
434 } /* end rxrpc_incoming_msg() */
435
436 /*****************************************************************************/
437 /*
438  * accept a new call
439  * - called from krxiod in process context
440  */
441 void rxrpc_trans_receive_packet(struct rxrpc_transport *trans)
442 {
443         struct rxrpc_message *msg;
444         struct rxrpc_peer *peer;
445         struct sk_buff *pkt;
446         int ret;
447         __be32 addr;
448         __be16 port;
449
450         LIST_HEAD(msgq);
451
452         _enter("%p{%d}", trans, trans->port);
453
454         for (;;) {
455                 /* deal with outstanting errors first */
456                 if (trans->error_rcvd)
457                         rxrpc_trans_receive_error_report(trans);
458
459                 /* attempt to receive a packet */
460                 pkt = skb_recv_datagram(trans->socket->sk, 0, 1, &ret);
461                 if (!pkt) {
462                         if (ret == -EAGAIN) {
463                                 _leave(" EAGAIN");
464                                 return;
465                         }
466
467                         /* an icmp error may have occurred */
468                         rxrpc_krxiod_queue_transport(trans);
469                         _leave(" error %d\n", ret);
470                         return;
471                 }
472
473                 /* we'll probably need to checksum it (didn't call
474                  * sock_recvmsg) */
475                 if (skb_checksum_complete(pkt)) {
476                         kfree_skb(pkt);
477                         rxrpc_krxiod_queue_transport(trans);
478                         _leave(" CSUM failed");
479                         return;
480                 }
481
482                 addr = pkt->nh.iph->saddr;
483                 port = pkt->h.uh->source;
484
485                 _net("Rx Received UDP packet from %08x:%04hu",
486                      ntohl(addr), ntohs(port));
487
488                 /* unmarshall the Rx parameters and split jumbo packets */
489                 ret = rxrpc_incoming_msg(trans, pkt, &msgq);
490                 if (ret < 0) {
491                         kfree_skb(pkt);
492                         rxrpc_krxiod_queue_transport(trans);
493                         _leave(" bad packet");
494                         return;
495                 }
496
497                 BUG_ON(list_empty(&msgq));
498
499                 msg = list_entry(msgq.next, struct rxrpc_message, link);
500
501                 /* locate the record for the peer from which it
502                  * originated */
503                 ret = rxrpc_peer_lookup(trans, addr, &peer);
504                 if (ret < 0) {
505                         kdebug("Rx No connections from that peer");
506                         rxrpc_trans_immediate_abort(trans, msg, -EINVAL);
507                         goto finished_msg;
508                 }
509
510                 /* try and find a matching connection */
511                 ret = rxrpc_connection_lookup(peer, msg, &msg->conn);
512                 if (ret < 0) {
513                         kdebug("Rx Unknown Connection");
514                         rxrpc_trans_immediate_abort(trans, msg, -EINVAL);
515                         rxrpc_put_peer(peer);
516                         goto finished_msg;
517                 }
518                 rxrpc_put_peer(peer);
519
520                 /* deal with the first packet of a new call */
521                 if (msg->hdr.flags & RXRPC_CLIENT_INITIATED &&
522                     msg->hdr.type == RXRPC_PACKET_TYPE_DATA &&
523                     ntohl(msg->hdr.seq) == 1
524                     ) {
525                         _debug("Rx New server call");
526                         rxrpc_trans_receive_new_call(trans, &msgq);
527                         goto finished_msg;
528                 }
529
530                 /* deal with subsequent packet(s) of call */
531                 _debug("Rx Call packet");
532                 while (!list_empty(&msgq)) {
533                         msg = list_entry(msgq.next, struct rxrpc_message, link);
534                         list_del_init(&msg->link);
535
536                         ret = rxrpc_conn_receive_call_packet(msg->conn, NULL, msg);
537                         if (ret < 0) {
538                                 rxrpc_trans_immediate_abort(trans, msg, ret);
539                                 rxrpc_put_message(msg);
540                                 goto finished_msg;
541                         }
542
543                         rxrpc_put_message(msg);
544                 }
545
546                 goto finished_msg;
547
548                 /* dispose of the packets */
549         finished_msg:
550                 while (!list_empty(&msgq)) {
551                         msg = list_entry(msgq.next, struct rxrpc_message, link);
552                         list_del_init(&msg->link);
553
554                         rxrpc_put_message(msg);
555                 }
556                 kfree_skb(pkt);
557         }
558
559         _leave("");
560
561 } /* end rxrpc_trans_receive_packet() */
562
563 /*****************************************************************************/
564 /*
565  * accept a new call from a client trying to connect to one of my services
566  * - called in process context
567  */
568 static int rxrpc_trans_receive_new_call(struct rxrpc_transport *trans,
569                                         struct list_head *msgq)
570 {
571         struct rxrpc_message *msg;
572
573         _enter("");
574
575         /* only bother with the first packet */
576         msg = list_entry(msgq->next, struct rxrpc_message, link);
577         list_del_init(&msg->link);
578         rxrpc_krxsecd_queue_incoming_call(msg);
579         rxrpc_put_message(msg);
580
581         _leave(" = 0");
582
583         return 0;
584 } /* end rxrpc_trans_receive_new_call() */
585
586 /*****************************************************************************/
587 /*
588  * perform an immediate abort without connection or call structures
589  */
590 int rxrpc_trans_immediate_abort(struct rxrpc_transport *trans,
591                                 struct rxrpc_message *msg,
592                                 int error)
593 {
594         struct rxrpc_header ahdr;
595         struct sockaddr_in sin;
596         struct msghdr msghdr;
597         struct kvec iov[2];
598         __be32 _error;
599         int len, ret;
600
601         _enter("%p,%p,%d", trans, msg, error);
602
603         /* don't abort an abort packet */
604         if (msg->hdr.type == RXRPC_PACKET_TYPE_ABORT) {
605                 _leave(" = 0");
606                 return 0;
607         }
608
609         _error = htonl(-error);
610
611         /* set up the message to be transmitted */
612         memcpy(&ahdr, &msg->hdr, sizeof(ahdr));
613         ahdr.epoch      = msg->hdr.epoch;
614         ahdr.serial     = htonl(1);
615         ahdr.seq        = 0;
616         ahdr.type       = RXRPC_PACKET_TYPE_ABORT;
617         ahdr.flags      = RXRPC_LAST_PACKET;
618         ahdr.flags      |= ~msg->hdr.flags & RXRPC_CLIENT_INITIATED;
619
620         iov[0].iov_len  = sizeof(ahdr);
621         iov[0].iov_base = &ahdr;
622         iov[1].iov_len  = sizeof(_error);
623         iov[1].iov_base = &_error;
624
625         len = sizeof(ahdr) + sizeof(_error);
626
627         memset(&sin,0,sizeof(sin));
628         sin.sin_family          = AF_INET;
629         sin.sin_port            = msg->pkt->h.uh->source;
630         sin.sin_addr.s_addr     = msg->pkt->nh.iph->saddr;
631
632         msghdr.msg_name         = &sin;
633         msghdr.msg_namelen      = sizeof(sin);
634         msghdr.msg_control      = NULL;
635         msghdr.msg_controllen   = 0;
636         msghdr.msg_flags        = MSG_DONTWAIT;
637
638         _net("Sending message type %d of %d bytes to %08x:%d",
639              ahdr.type,
640              len,
641              ntohl(sin.sin_addr.s_addr),
642              ntohs(sin.sin_port));
643
644         /* send the message */
645         ret = kernel_sendmsg(trans->socket, &msghdr, iov, 2, len);
646
647         _leave(" = %d", ret);
648         return ret;
649 } /* end rxrpc_trans_immediate_abort() */
650
651 /*****************************************************************************/
652 /*
653  * receive an ICMP error report and percolate it to all connections
654  * heading to the affected host or port
655  */
656 static void rxrpc_trans_receive_error_report(struct rxrpc_transport *trans)
657 {
658         struct rxrpc_connection *conn;
659         struct sockaddr_in sin;
660         struct rxrpc_peer *peer;
661         struct list_head connq, *_p;
662         struct errormsg emsg;
663         struct msghdr msg;
664         __be16 port;
665         int local, err;
666
667         _enter("%p", trans);
668
669         for (;;) {
670                 trans->error_rcvd = 0;
671
672                 /* try and receive an error message */
673                 msg.msg_name    = &sin;
674                 msg.msg_namelen = sizeof(sin);
675                 msg.msg_control = &emsg;
676                 msg.msg_controllen = sizeof(emsg);
677                 msg.msg_flags   = 0;
678
679                 err = kernel_recvmsg(trans->socket, &msg, NULL, 0, 0,
680                                    MSG_ERRQUEUE | MSG_DONTWAIT | MSG_TRUNC);
681
682                 if (err == -EAGAIN) {
683                         _leave("");
684                         return;
685                 }
686
687                 if (err < 0) {
688                         printk("%s: unable to recv an error report: %d\n",
689                                __FUNCTION__, err);
690                         _leave("");
691                         return;
692                 }
693
694                 msg.msg_controllen = (char *) msg.msg_control - (char *) &emsg;
695
696                 if (msg.msg_controllen < sizeof(emsg.cmsg) ||
697                     msg.msg_namelen < sizeof(sin)) {
698                         printk("%s: short control message"
699                                " (nlen=%u clen=%Zu fl=%x)\n",
700                                __FUNCTION__,
701                                msg.msg_namelen,
702                                msg.msg_controllen,
703                                msg.msg_flags);
704                         continue;
705                 }
706
707                 _net("Rx Received control message"
708                      " { len=%Zu level=%u type=%u }",
709                      emsg.cmsg.cmsg_len,
710                      emsg.cmsg.cmsg_level,
711                      emsg.cmsg.cmsg_type);
712
713                 if (sin.sin_family != AF_INET) {
714                         printk("Rx Ignoring error report with non-INET address"
715                                " (fam=%u)",
716                                sin.sin_family);
717                         continue;
718                 }
719
720                 _net("Rx Received message pertaining to host addr=%x port=%hu",
721                      ntohl(sin.sin_addr.s_addr), ntohs(sin.sin_port));
722
723                 if (emsg.cmsg.cmsg_level != SOL_IP ||
724                     emsg.cmsg.cmsg_type != IP_RECVERR) {
725                         printk("Rx Ignoring unknown error report"
726                                " { level=%u type=%u }",
727                                emsg.cmsg.cmsg_level,
728                                emsg.cmsg.cmsg_type);
729                         continue;
730                 }
731
732                 if (msg.msg_controllen < sizeof(emsg.cmsg) + sizeof(emsg.ee)) {
733                         printk("%s: short error message (%Zu)\n",
734                                __FUNCTION__, msg.msg_controllen);
735                         _leave("");
736                         return;
737                 }
738
739                 port = sin.sin_port;
740
741                 switch (emsg.ee.ee_origin) {
742                 case SO_EE_ORIGIN_ICMP:
743                         local = 0;
744                         switch (emsg.ee.ee_type) {
745                         case ICMP_DEST_UNREACH:
746                                 switch (emsg.ee.ee_code) {
747                                 case ICMP_NET_UNREACH:
748                                         _net("Rx Received ICMP Network Unreachable");
749                                         port = 0;
750                                         err = -ENETUNREACH;
751                                         break;
752                                 case ICMP_HOST_UNREACH:
753                                         _net("Rx Received ICMP Host Unreachable");
754                                         port = 0;
755                                         err = -EHOSTUNREACH;
756                                         break;
757                                 case ICMP_PORT_UNREACH:
758                                         _net("Rx Received ICMP Port Unreachable");
759                                         err = -ECONNREFUSED;
760                                         break;
761                                 case ICMP_NET_UNKNOWN:
762                                         _net("Rx Received ICMP Unknown Network");
763                                         port = 0;
764                                         err = -ENETUNREACH;
765                                         break;
766                                 case ICMP_HOST_UNKNOWN:
767                                         _net("Rx Received ICMP Unknown Host");
768                                         port = 0;
769                                         err = -EHOSTUNREACH;
770                                         break;
771                                 default:
772                                         _net("Rx Received ICMP DestUnreach { code=%u }",
773                                              emsg.ee.ee_code);
774                                         err = emsg.ee.ee_errno;
775                                         break;
776                                 }
777                                 break;
778
779                         case ICMP_TIME_EXCEEDED:
780                                 _net("Rx Received ICMP TTL Exceeded");
781                                 err = emsg.ee.ee_errno;
782                                 break;
783
784                         default:
785                                 _proto("Rx Received ICMP error { type=%u code=%u }",
786                                        emsg.ee.ee_type, emsg.ee.ee_code);
787                                 err = emsg.ee.ee_errno;
788                                 break;
789                         }
790                         break;
791
792                 case SO_EE_ORIGIN_LOCAL:
793                         _proto("Rx Received local error { error=%d }",
794                                emsg.ee.ee_errno);
795                         local = 1;
796                         err = emsg.ee.ee_errno;
797                         break;
798
799                 case SO_EE_ORIGIN_NONE:
800                 case SO_EE_ORIGIN_ICMP6:
801                 default:
802                         _proto("Rx Received error report { orig=%u }",
803                                emsg.ee.ee_origin);
804                         local = 0;
805                         err = emsg.ee.ee_errno;
806                         break;
807                 }
808
809                 /* find all the connections between this transport and the
810                  * affected destination */
811                 INIT_LIST_HEAD(&connq);
812
813                 if (rxrpc_peer_lookup(trans, sin.sin_addr.s_addr,
814                                       &peer) == 0) {
815                         read_lock(&peer->conn_lock);
816                         list_for_each(_p, &peer->conn_active) {
817                                 conn = list_entry(_p, struct rxrpc_connection,
818                                                   link);
819                                 if (port && conn->addr.sin_port != port)
820                                         continue;
821                                 if (!list_empty(&conn->err_link))
822                                         continue;
823
824                                 rxrpc_get_connection(conn);
825                                 list_add_tail(&conn->err_link, &connq);
826                         }
827                         read_unlock(&peer->conn_lock);
828
829                         /* service all those connections */
830                         while (!list_empty(&connq)) {
831                                 conn = list_entry(connq.next,
832                                                   struct rxrpc_connection,
833                                                   err_link);
834                                 list_del(&conn->err_link);
835
836                                 rxrpc_conn_handle_error(conn, local, err);
837
838                                 rxrpc_put_connection(conn);
839                         }
840
841                         rxrpc_put_peer(peer);
842                 }
843         }
844
845         _leave("");
846         return;
847 } /* end rxrpc_trans_receive_error_report() */