]> rtime.felk.cvut.cz Git - socketcan-devel.git/blob - kernel/2.6/net/can/raw.c
Some code cleanup:
[socketcan-devel.git] / kernel / 2.6 / net / can / raw.c
1 /*
2  * raw.c
3  *
4  * Copyright (c) 2002-2005 Volkswagen Group Electronic Research
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, the following disclaimer and
12  *    the referenced file 'COPYING'.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. Neither the name of Volkswagen nor the names of its contributors
17  *    may be used to endorse or promote products derived from this software
18  *    without specific prior written permission.
19  *
20  * Alternatively, provided that this notice is retained in full, this
21  * software may be distributed under the terms of the GNU General
22  * Public License ("GPL") version 2 as distributed in the 'COPYING'
23  * file from the main directory of the linux kernel source.
24  *
25  * The provided data structures and external interfaces from this code
26  * are not restricted to be used by modules with a GPL compatible license.
27  *
28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
39  * DAMAGE.
40  *
41  * Send feedback to <socketcan-users@lists.berlios.de>
42  *
43  */
44
45 #include <linux/autoconf.h>
46 #include <linux/module.h>
47 #include <linux/version.h>
48 #include <linux/init.h>
49 #include <linux/net.h>
50 #include <linux/netdevice.h>
51 #include <linux/uio.h>
52 #include <linux/poll.h>
53 #include <net/sock.h>
54
55 #include <linux/can.h>
56 #include <linux/can/error.h>
57 #include <linux/can/raw.h>
58 #include <linux/can/version.h>
59
60 #include "af_can.h"
61
62
63 RCSID("$Id$");
64
65 #define IDENT "raw"
66 static __initdata const char banner[] = KERN_INFO "CAN: raw socket protocol " VERSION "\n"; 
67
68 MODULE_DESCRIPTION("PF_CAN raw sockets");
69 MODULE_LICENSE("Dual BSD/GPL");
70 MODULE_AUTHOR("Urs Thuermann <urs.thuermann@volkswagen.de>");
71
72 #ifdef CONFIG_CAN_DEBUG_CORE
73 static int debug = 0;
74 module_param(debug, int, S_IRUGO);
75 #define DBG(args...)       (debug & 1 ? \
76                                (printk(KERN_DEBUG "RAW %s: ", __func__), \
77                                 printk(args)) : 0)
78 #define DBG_SKB(skb)       (debug & 4 ? can_debug_skb(skb) : 0)
79 #else
80 #define DBG(args...)
81 #define DBG_SKB(skb)
82 #endif
83
84 static int raw_init(struct sock *sk);
85 static int raw_release(struct socket *sock);
86 static int raw_bind   (struct socket *sock, struct sockaddr *uaddr, int len);
87 static int raw_getname(struct socket *sock, struct sockaddr *uaddr,
88                        int *len, int peer);
89 static unsigned int raw_poll(struct file *file, struct socket *sock,
90                              poll_table *wait);
91 static int raw_setsockopt(struct socket *sock, int level, int optname,
92                           char __user *optval, int optlen);
93 static int raw_getsockopt(struct socket *sock, int level, int optname,
94                           char __user *optval, int __user *optlen);
95 static int raw_sendmsg(struct kiocb *iocb, struct socket *sock,
96                        struct msghdr *msg, size_t size);
97 static int raw_recvmsg(struct kiocb *iocb, struct socket *sock,
98                        struct msghdr *msg, size_t size, int flags);
99 static void raw_rcv(struct sk_buff *skb, void *data);
100 static void raw_notifier(unsigned long msg, void *data);
101
102 static void raw_add_filters(struct net_device *dev, struct sock *sk);
103 static void raw_remove_filters(struct net_device *dev, struct sock *sk);
104
105
106 static struct proto_ops raw_ops = {
107         .family        = PF_CAN,
108         .release       = raw_release,
109         .bind          = raw_bind,
110         .connect       = sock_no_connect,
111         .socketpair    = sock_no_socketpair,
112         .accept        = sock_no_accept,
113         .getname       = raw_getname,
114         .poll          = raw_poll,
115         .ioctl         = NULL,          /* use can_ioctl() from af_can.c */
116         .listen        = sock_no_listen,
117         .shutdown      = sock_no_shutdown,
118         .setsockopt    = raw_setsockopt,
119         .getsockopt    = raw_getsockopt,
120         .sendmsg       = raw_sendmsg,
121         .recvmsg       = raw_recvmsg,
122         .mmap          = sock_no_mmap,
123         .sendpage      = sock_no_sendpage,
124 };
125
126
127 /* A raw socket has a list of can_filters attached to it, each receiving
128    the CAN frames matching that filter.  If the filter list is empty,
129    no CAN frames will be received by the socket.  The default after
130    opening the socket, is to have one filter which receives all frames.
131    The filter list is allocated dynamically with the exception of the
132    list containing only one item.  This common case is optimized by
133    storing the single filter in dfilter, to avoid using dynamic memory.
134 */
135
136 struct raw_opt {
137         int bound;
138         int ifindex;
139         int loopback;
140         int recv_own_msgs;
141         int count;                 /* number of active filters */
142         struct can_filter dfilter; /* default/single filter */
143         struct can_filter *filter; /* pointer to filter(s) */
144         can_err_mask_t err_mask;
145 };
146
147 #ifdef CONFIG_CAN_RAW_USER
148 #define RAW_CAP (-1)
149 #else
150 #define RAW_CAP CAP_NET_RAW
151 #endif
152
153 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13)
154
155 struct raw_sock {
156         struct sock    sk;
157         struct raw_opt opt;
158 };
159
160 #define raw_sk(sk) (&((struct raw_sock *)(sk))->opt)
161
162 static struct proto raw_proto = {
163         .name       = "CAN_RAW",
164         .owner      = THIS_MODULE,
165         .obj_size   = sizeof(struct raw_sock),
166         .init       = raw_init,
167 };
168
169 static struct can_proto raw_can_proto = {
170         .type       = SOCK_RAW,
171         .protocol   = CAN_RAW,
172         .capability = RAW_CAP,
173         .ops        = &raw_ops,
174         .prot       = &raw_proto,
175 };
176
177 #else
178
179 #define raw_sk(sk) ((struct raw_opt *)(sk)->sk_protinfo)
180
181 static struct can_proto raw_can_proto = {
182         .type       = SOCK_RAW,
183         .protocol   = CAN_RAW,
184         .capability = RAW_CAP,
185         .ops        = &raw_ops,
186         .owner      = THIS_MODULE,
187         .obj_size   = sizeof(struct raw_opt),
188         .init       = raw_init,
189 };
190
191 #endif
192
193 #define MASK_ALL 0
194
195 static __init int raw_module_init(void)
196 {
197         printk(banner);
198
199         can_proto_register(&raw_can_proto);
200         return 0;
201 }
202
203 static __exit void raw_module_exit(void)
204 {
205         can_proto_unregister(&raw_can_proto);
206 }
207
208 static int raw_init(struct sock *sk)
209 {
210         struct raw_opt *ro = raw_sk(sk);
211
212         ro->bound            = 0;
213
214         /* set default filter to single entry dfilter */
215         ro->dfilter.can_id   = 0;
216         ro->dfilter.can_mask = MASK_ALL;
217         ro->filter           = &ro->dfilter;
218         ro->count            = 1;
219
220         /* set default loopback behaviour */
221         ro->loopback         = 1;
222         ro->recv_own_msgs    = 0;
223
224         return 0;
225 }
226
227 static int raw_release(struct socket *sock)
228 {
229         struct sock *sk = sock->sk;
230         struct raw_opt *ro = raw_sk(sk);
231         struct net_device *dev = NULL;
232
233         DBG("socket %p, sk %p, refcnt %d\n", sock, sk,
234             atomic_read(&sk->sk_refcnt));
235
236         if (ro->bound && ro->ifindex)
237                 dev = dev_get_by_index(ro->ifindex);
238
239         /* remove current filters & unregister */
240         if (ro->bound)
241                 raw_remove_filters(dev, sk);
242         if (ro->count > 1)
243                 kfree(ro->filter);
244
245         /* remove current error mask */
246         if (ro->err_mask && ro->bound)
247                 can_rx_unregister(dev, 0, ro->err_mask | CAN_ERR_FLAG, raw_rcv, sk);
248
249         if (dev) {
250                 can_dev_unregister(dev, raw_notifier, sk);
251                 dev_put(dev);
252         }
253
254         sock_put(sk);
255
256         return 0;
257 }
258
259 static int raw_bind(struct socket *sock, struct sockaddr *uaddr, int len)
260 {
261         struct sockaddr_can *addr = (struct sockaddr_can *)uaddr;
262         struct sock *sk = sock->sk;
263         struct raw_opt *ro = raw_sk(sk);
264         struct net_device *dev;
265
266         DBG("socket %p to device %d\n", sock, addr->can_ifindex);
267
268         if (len < sizeof(*addr))
269                 return -EINVAL;
270
271         if (ro->bound) {
272 #if 1
273                 return -EINVAL;
274 #else
275                 /* remove current bindings / notifier */
276                 if (ro->ifindex) {
277                         dev = dev_get_by_index(ro->ifindex);
278                         if (!dev) {
279                                 DBG("could not find device %d\n",
280                                     addr->can_ifindex);
281                                 return -ENODEV;
282                         }
283                         if (!(dev->flags & IFF_UP)) {
284                                 sk->sk_err = ENETDOWN;
285                                 if (!sock_flag(sk, SOCK_DEAD))
286                                         sk->sk_error_report(sk);
287                                 goto out;
288                         }
289                         can_dev_unregister(dev, raw_notifier, sk);
290                 } else
291                         dev = NULL;
292
293                 /* unregister current filters for this device */
294                 raw_remove_filters(dev, sk);
295
296                 if (dev)
297                         dev_put(dev);
298
299                 ro->bound = 0;
300 #endif
301         }
302
303         if (addr->can_ifindex) {
304                 dev = dev_get_by_index(addr->can_ifindex);
305                 if (!dev) {
306                         DBG("could not find device %d\n", addr->can_ifindex);
307                         return -ENODEV;
308                 }
309                 if (!(dev->flags & IFF_UP)) {
310                         sk->sk_err = ENETDOWN;
311                         if (!sock_flag(sk, SOCK_DEAD))
312                                 sk->sk_error_report(sk);
313                         goto out;
314                 }
315                 can_dev_register(dev, raw_notifier, sk);
316         } else
317                 dev = NULL;
318
319         ro->ifindex = addr->can_ifindex;
320
321         raw_add_filters(dev, sk); /* filters set by default/setsockopt */
322
323         if (ro->err_mask) /* error frame filter set by setsockopt */
324                 can_rx_register(dev, 0, ro->err_mask | CAN_ERR_FLAG, raw_rcv, sk, IDENT);
325
326         ro->bound = 1;
327
328  out:
329         if (dev)
330                 dev_put(dev);
331
332         return 0;
333 }
334
335 static int raw_getname(struct socket *sock, struct sockaddr *uaddr,
336                        int *len, int peer)
337 {
338         struct sockaddr_can *addr = (struct sockaddr_can *)uaddr;
339         struct sock *sk = sock->sk;
340         struct raw_opt *ro = raw_sk(sk);
341
342         if (peer)
343                 return -EOPNOTSUPP;
344
345         addr->can_family  = AF_CAN;
346         addr->can_ifindex = ro->ifindex;
347         *len = sizeof(*addr);
348
349         return 0;
350 }
351
352 static unsigned int raw_poll(struct file *file, struct socket *sock,
353                              poll_table *wait)
354 {
355         unsigned int mask = 0;
356
357         DBG("socket %p\n", sock);
358
359         mask = datagram_poll(file, sock, wait);
360         return mask;
361 }
362
363 static int raw_setsockopt(struct socket *sock, int level, int optname,
364                           char __user *optval, int optlen)
365 {
366         struct sock *sk = sock->sk;
367         struct raw_opt *ro = raw_sk(sk);
368         struct can_filter *filter = NULL;  /* dyn. alloc'ed filters */
369         struct can_filter sfilter;         /* single filter */
370         struct net_device *dev = NULL;
371         can_err_mask_t err_mask = 0;
372         int count = 0;
373         int err;
374
375         if (level != SOL_CAN_RAW)
376                 return -EINVAL;
377
378         switch (optname) {
379         case CAN_RAW_FILTER:
380                 if (optlen % sizeof(struct can_filter) != 0)
381                         return -EINVAL;
382
383                 count = optlen / sizeof(struct can_filter);
384
385                 if (count > 1) { /* does not fit into dfilter */
386                         if (!(filter = kmalloc(optlen, GFP_KERNEL)))
387                                 return -ENOMEM;
388                         if ((err = copy_from_user(filter, optval, optlen))) {
389                                 kfree(filter);
390                                 return err;
391                         }
392                 } else if (count == 1) {
393                         if ((err = copy_from_user(&sfilter, optval, optlen)))
394                                 return err;
395                 }
396
397                 if (ro->bound && ro->ifindex)
398                         dev = dev_get_by_index(ro->ifindex);
399
400                 /* remove current filters & unregister */
401                 if (ro->bound)
402                         raw_remove_filters(dev, sk);
403                 if (ro->count > 1)
404                         kfree(ro->filter);
405
406                 if (count == 1) { /* copy data for single filter */
407                         ro->dfilter = sfilter;
408                         filter = &ro->dfilter;
409                 }
410
411                 /* add new filters & register */
412                 ro->filter = filter;
413                 ro->count  = count;
414                 if (ro->bound)
415                         raw_add_filters(dev, sk);
416
417                 if (dev)
418                         dev_put(dev);
419
420                 break;
421
422         case CAN_RAW_ERR_FILTER:
423                 if (optlen != sizeof(err_mask))
424                         return -EINVAL;
425                 if ((err = copy_from_user(&err_mask, optval, optlen)))
426                         return err;
427
428                 err_mask &= CAN_ERR_MASK;
429
430                 if (ro->bound && ro->ifindex)
431                         dev = dev_get_by_index(ro->ifindex);
432
433                 /* remove current error mask */
434                 if (ro->err_mask && ro->bound)
435                         can_rx_unregister(dev, 0, ro->err_mask | CAN_ERR_FLAG, raw_rcv, sk);
436
437                 /* add new error mask */
438                 ro->err_mask = err_mask;
439                 if (ro->err_mask && ro->bound)
440                         can_rx_register(dev, 0, ro->err_mask | CAN_ERR_FLAG, raw_rcv, sk, IDENT);
441
442                 if (dev)
443                         dev_put(dev);
444
445                 break;
446
447         case CAN_RAW_LOOPBACK:
448                 if (optlen != sizeof(ro->loopback))
449                         return -EINVAL;
450                 if ((err = copy_from_user(&ro->loopback, optval, optlen)))
451                         return err;
452                 break;
453
454         case CAN_RAW_RECV_OWN_MSGS:
455                 if (optlen != sizeof(ro->recv_own_msgs))
456                         return -EINVAL;
457                 if ((err = copy_from_user(&ro->recv_own_msgs, optval, optlen)))
458                         return err;
459                 break;
460
461         default:
462                 return -ENOPROTOOPT;
463         }
464         return 0;
465 }
466
467 static int raw_getsockopt(struct socket *sock, int level, int optname,
468                           char __user *optval, int __user *optlen)
469 {
470         struct sock *sk = sock->sk;
471         struct raw_opt *ro = raw_sk(sk);
472         struct can_filter *filter = ro->filter;
473         int count = ro->count;
474         int len;
475
476         if (level != SOL_CAN_RAW)
477                 return -EINVAL;
478
479         switch (optname) {
480         case CAN_RAW_FILTER:
481                 if (get_user(len, optlen))
482                         return -EFAULT;
483
484                 if (count && filter) {
485                         int filter_size = count * sizeof(struct can_filter);
486                         if (len < filter_size)
487                                 return -EINVAL;
488                         if (len > filter_size)
489                                 len = filter_size;
490                         if (copy_to_user(optval, filter, len))
491                                 return -EFAULT;
492                 } else
493                         len = 0;
494
495                 if (put_user(len, optlen))
496                         return -EFAULT;
497
498                 break;
499
500         case CAN_RAW_ERR_FILTER:
501                 if (get_user(len, optlen))
502                         return -EFAULT;
503
504                 if (len < sizeof(can_err_mask_t))
505                         return -EINVAL;
506
507                 if (len > sizeof(can_err_mask_t))
508                         len = sizeof(can_err_mask_t);
509
510                 if (copy_to_user(optval, &ro->err_mask, len))
511                         return -EFAULT;
512
513                 if (put_user(len, optlen))
514                         return -EFAULT;
515
516                 break;
517
518         case CAN_RAW_LOOPBACK:
519                 if (get_user(len, optlen))
520                         return -EFAULT;
521
522                 if (len < sizeof(int))
523                         return -EINVAL;
524
525                 if (len > sizeof(int))
526                         len = sizeof(int);
527
528                 if (copy_to_user(optval, &ro->loopback, len))
529                         return -EFAULT;
530
531                 if (put_user(len, optlen))
532                         return -EFAULT;
533
534                 break;
535
536         case CAN_RAW_RECV_OWN_MSGS:
537                 if (get_user(len, optlen))
538                         return -EFAULT;
539
540                 if (len < sizeof(int))
541                         return -EINVAL;
542
543                 if (len > sizeof(int))
544                         len = sizeof(int);
545
546                 if (copy_to_user(optval, &ro->recv_own_msgs, len))
547                         return -EFAULT;
548
549                 if (put_user(len, optlen))
550                         return -EFAULT;
551
552                 break;
553
554         default:
555                 return -ENOPROTOOPT;
556         }
557         return 0;
558 }
559
560 static void raw_add_filters(struct net_device *dev, struct sock *sk)
561 {
562         struct raw_opt *ro = raw_sk(sk);
563         struct can_filter *filter = ro->filter;
564         int i;
565
566         for (i = 0; i < ro->count; i++) {
567                 can_rx_register(dev, filter[i].can_id, filter[i].can_mask,
568                                 raw_rcv, sk, IDENT);
569                 DBG("filter can_id %08X, can_mask %08X%s, sk %p\n",
570                     filter[i].can_id, filter[i].can_mask,
571                     filter[i].can_id & CAN_INV_FILTER ? " (inv)" : "", sk);
572         }
573 }
574
575 static void raw_remove_filters(struct net_device *dev, struct sock *sk)
576 {
577         struct raw_opt *ro = raw_sk(sk);
578         struct can_filter *filter = ro->filter;
579         int i;
580
581         for (i = 0; i < ro->count; i++) {
582                 can_rx_unregister(dev, filter[i].can_id, filter[i].can_mask,
583                                   raw_rcv, sk);
584                 DBG("filter can_id %08X, can_mask %08X%s, sk %p\n",
585                     filter[i].can_id, filter[i].can_mask,
586                     filter[i].can_id & CAN_INV_FILTER ? " (inv)" : "", sk);
587         }
588 }
589
590 static int raw_sendmsg(struct kiocb *iocb, struct socket *sock,
591                        struct msghdr *msg, size_t size)
592 {
593         struct sock *sk = sock->sk;
594         struct raw_opt *ro = raw_sk(sk);
595         struct sk_buff *skb;
596         struct net_device *dev;
597         int ifindex;
598         int err;
599
600         DBG("socket %p, sk %p\n", sock, sk);
601
602         if (msg->msg_name) {
603                 struct sockaddr_can *addr = (struct sockaddr_can *)msg->msg_name;
604                 if (addr->can_family != AF_CAN)
605                         return -EINVAL;
606                 ifindex = addr->can_ifindex;
607         } else
608                 ifindex = ro->ifindex;
609
610         if (!(dev = dev_get_by_index(ifindex))) {
611                 DBG("device %d not found\n", ifindex);
612                 return -ENXIO;
613         }
614
615         if (!(skb = alloc_skb(size, GFP_KERNEL))) {
616                 dev_put(dev);
617                 return -ENOMEM;
618         }
619
620         if ((err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size)) < 0) {
621                 kfree_skb(skb);
622                 dev_put(dev);
623                 return err;
624         }
625         skb->dev = dev;
626         skb->sk  = sk;
627
628         DBG("sending skbuff to interface %d\n", ifindex);
629         DBG_SKB(skb);
630
631         err = can_send(skb, ro->loopback);
632
633         dev_put(dev);
634
635         if (err)
636                 return err;
637
638         return size;
639 }
640
641 static int raw_recvmsg(struct kiocb *iocb, struct socket *sock,
642                        struct msghdr *msg, size_t size, int flags)
643 {
644         struct sock *sk = sock->sk;
645         struct sk_buff *skb;
646         int error = 0;
647         int noblock;
648
649         DBG("socket %p, sk %p\n", sock, sk);
650
651         noblock =  flags & MSG_DONTWAIT;
652         flags   &= ~MSG_DONTWAIT;
653
654         if (!(skb = skb_recv_datagram(sk, flags, noblock, &error)))
655                 return error;
656
657         DBG("delivering skbuff %p\n", skb);
658         DBG_SKB(skb);
659
660         if (size < skb->len)
661                 msg->msg_flags |= MSG_TRUNC;
662         else
663                 size = skb->len;
664
665         if ((error = memcpy_toiovec(msg->msg_iov, skb->data, size)) < 0) {
666                 skb_free_datagram(sk, skb);
667                 return error;
668         }
669
670         sock_recv_timestamp(msg, sk, skb);
671
672         if (msg->msg_name) {
673                 msg->msg_namelen = sizeof(struct sockaddr_can);
674                 memcpy(msg->msg_name, skb->cb, msg->msg_namelen);
675         }
676
677         DBG("freeing sock %p, skbuff %p\n", sk, skb);
678         skb_free_datagram(sk, skb);
679
680         return size;
681 }
682
683 static void raw_rcv(struct sk_buff *skb, void *data)
684 {
685         struct sock *sk = (struct sock*)data;
686         struct raw_opt *ro = raw_sk(sk);
687         struct sockaddr_can *addr;
688         int error;
689
690         DBG("received skbuff %p, sk %p\n", skb, sk);
691         DBG_SKB(skb);
692
693         if (!ro->recv_own_msgs) {
694                 if (*(struct sock **)skb->cb == sk) { /* tx sock reference */
695                         DBG("trashed own tx msg\n");
696                         kfree_skb(skb);
697                         return;
698                 }
699         }
700
701         addr = (struct sockaddr_can *)skb->cb;
702         memset(addr, 0, sizeof(*addr));
703         addr->can_family  = AF_CAN;
704         addr->can_ifindex = skb->dev->ifindex;
705
706         if ((error = sock_queue_rcv_skb(sk, skb)) < 0) {
707                 DBG("sock_queue_rcv_skb failed: %d\n", error);
708                 DBG("freeing skbuff %p\n", skb);
709                 kfree_skb(skb);
710         }
711 }
712
713 static void raw_notifier(unsigned long msg, void *data)
714 {
715         struct sock *sk = (struct sock *)data;
716         struct raw_opt *ro = raw_sk(sk);
717
718         DBG("called for sock %p\n", sk);
719
720         switch (msg) {
721         case NETDEV_UNREGISTER:
722                 ro->ifindex = 0;
723                 ro->bound   = 0;
724                 /* fallthrough */
725         case NETDEV_DOWN:
726                 sk->sk_err = ENETDOWN;
727                 if (!sock_flag(sk, SOCK_DEAD))
728                         sk->sk_error_report(sk);
729                 break;
730         }
731 }
732
733
734 module_init(raw_module_init);
735 module_exit(raw_module_exit);