Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/net/can/raw.c
15109 views
1
/*
2
* raw.c - Raw sockets for protocol family CAN
3
*
4
* Copyright (c) 2002-2007 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 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
* 3. Neither the name of Volkswagen nor the names of its contributors
16
* may be used to endorse or promote products derived from this software
17
* without specific prior written permission.
18
*
19
* Alternatively, provided that this notice is retained in full, this
20
* software may be distributed under the terms of the GNU General
21
* Public License ("GPL") version 2, in which case the provisions of the
22
* GPL apply INSTEAD OF those given above.
23
*
24
* The provided data structures and external interfaces from this code
25
* are not restricted to be used by modules with a GPL compatible license.
26
*
27
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
30
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
31
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
32
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
33
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
34
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
35
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
36
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
37
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
38
* DAMAGE.
39
*
40
* Send feedback to <[email protected]>
41
*
42
*/
43
44
#include <linux/module.h>
45
#include <linux/init.h>
46
#include <linux/uio.h>
47
#include <linux/net.h>
48
#include <linux/slab.h>
49
#include <linux/netdevice.h>
50
#include <linux/socket.h>
51
#include <linux/if_arp.h>
52
#include <linux/skbuff.h>
53
#include <linux/can.h>
54
#include <linux/can/core.h>
55
#include <linux/can/raw.h>
56
#include <net/sock.h>
57
#include <net/net_namespace.h>
58
59
#define CAN_RAW_VERSION CAN_VERSION
60
static __initdata const char banner[] =
61
KERN_INFO "can: raw protocol (rev " CAN_RAW_VERSION ")\n";
62
63
MODULE_DESCRIPTION("PF_CAN raw protocol");
64
MODULE_LICENSE("Dual BSD/GPL");
65
MODULE_AUTHOR("Urs Thuermann <[email protected]>");
66
MODULE_ALIAS("can-proto-1");
67
68
#define MASK_ALL 0
69
70
/*
71
* A raw socket has a list of can_filters attached to it, each receiving
72
* the CAN frames matching that filter. If the filter list is empty,
73
* no CAN frames will be received by the socket. The default after
74
* opening the socket, is to have one filter which receives all frames.
75
* The filter list is allocated dynamically with the exception of the
76
* list containing only one item. This common case is optimized by
77
* storing the single filter in dfilter, to avoid using dynamic memory.
78
*/
79
80
struct raw_sock {
81
struct sock sk;
82
int bound;
83
int ifindex;
84
struct notifier_block notifier;
85
int loopback;
86
int recv_own_msgs;
87
int count; /* number of active filters */
88
struct can_filter dfilter; /* default/single filter */
89
struct can_filter *filter; /* pointer to filter(s) */
90
can_err_mask_t err_mask;
91
};
92
93
/*
94
* Return pointer to store the extra msg flags for raw_recvmsg().
95
* We use the space of one unsigned int beyond the 'struct sockaddr_can'
96
* in skb->cb.
97
*/
98
static inline unsigned int *raw_flags(struct sk_buff *skb)
99
{
100
BUILD_BUG_ON(sizeof(skb->cb) <= (sizeof(struct sockaddr_can) +
101
sizeof(unsigned int)));
102
103
/* return pointer after struct sockaddr_can */
104
return (unsigned int *)(&((struct sockaddr_can *)skb->cb)[1]);
105
}
106
107
static inline struct raw_sock *raw_sk(const struct sock *sk)
108
{
109
return (struct raw_sock *)sk;
110
}
111
112
static void raw_rcv(struct sk_buff *oskb, void *data)
113
{
114
struct sock *sk = (struct sock *)data;
115
struct raw_sock *ro = raw_sk(sk);
116
struct sockaddr_can *addr;
117
struct sk_buff *skb;
118
unsigned int *pflags;
119
120
/* check the received tx sock reference */
121
if (!ro->recv_own_msgs && oskb->sk == sk)
122
return;
123
124
/* clone the given skb to be able to enqueue it into the rcv queue */
125
skb = skb_clone(oskb, GFP_ATOMIC);
126
if (!skb)
127
return;
128
129
/*
130
* Put the datagram to the queue so that raw_recvmsg() can
131
* get it from there. We need to pass the interface index to
132
* raw_recvmsg(). We pass a whole struct sockaddr_can in skb->cb
133
* containing the interface index.
134
*/
135
136
BUILD_BUG_ON(sizeof(skb->cb) < sizeof(struct sockaddr_can));
137
addr = (struct sockaddr_can *)skb->cb;
138
memset(addr, 0, sizeof(*addr));
139
addr->can_family = AF_CAN;
140
addr->can_ifindex = skb->dev->ifindex;
141
142
/* add CAN specific message flags for raw_recvmsg() */
143
pflags = raw_flags(skb);
144
*pflags = 0;
145
if (oskb->sk)
146
*pflags |= MSG_DONTROUTE;
147
if (oskb->sk == sk)
148
*pflags |= MSG_CONFIRM;
149
150
if (sock_queue_rcv_skb(sk, skb) < 0)
151
kfree_skb(skb);
152
}
153
154
static int raw_enable_filters(struct net_device *dev, struct sock *sk,
155
struct can_filter *filter, int count)
156
{
157
int err = 0;
158
int i;
159
160
for (i = 0; i < count; i++) {
161
err = can_rx_register(dev, filter[i].can_id,
162
filter[i].can_mask,
163
raw_rcv, sk, "raw");
164
if (err) {
165
/* clean up successfully registered filters */
166
while (--i >= 0)
167
can_rx_unregister(dev, filter[i].can_id,
168
filter[i].can_mask,
169
raw_rcv, sk);
170
break;
171
}
172
}
173
174
return err;
175
}
176
177
static int raw_enable_errfilter(struct net_device *dev, struct sock *sk,
178
can_err_mask_t err_mask)
179
{
180
int err = 0;
181
182
if (err_mask)
183
err = can_rx_register(dev, 0, err_mask | CAN_ERR_FLAG,
184
raw_rcv, sk, "raw");
185
186
return err;
187
}
188
189
static void raw_disable_filters(struct net_device *dev, struct sock *sk,
190
struct can_filter *filter, int count)
191
{
192
int i;
193
194
for (i = 0; i < count; i++)
195
can_rx_unregister(dev, filter[i].can_id, filter[i].can_mask,
196
raw_rcv, sk);
197
}
198
199
static inline void raw_disable_errfilter(struct net_device *dev,
200
struct sock *sk,
201
can_err_mask_t err_mask)
202
203
{
204
if (err_mask)
205
can_rx_unregister(dev, 0, err_mask | CAN_ERR_FLAG,
206
raw_rcv, sk);
207
}
208
209
static inline void raw_disable_allfilters(struct net_device *dev,
210
struct sock *sk)
211
{
212
struct raw_sock *ro = raw_sk(sk);
213
214
raw_disable_filters(dev, sk, ro->filter, ro->count);
215
raw_disable_errfilter(dev, sk, ro->err_mask);
216
}
217
218
static int raw_enable_allfilters(struct net_device *dev, struct sock *sk)
219
{
220
struct raw_sock *ro = raw_sk(sk);
221
int err;
222
223
err = raw_enable_filters(dev, sk, ro->filter, ro->count);
224
if (!err) {
225
err = raw_enable_errfilter(dev, sk, ro->err_mask);
226
if (err)
227
raw_disable_filters(dev, sk, ro->filter, ro->count);
228
}
229
230
return err;
231
}
232
233
static int raw_notifier(struct notifier_block *nb,
234
unsigned long msg, void *data)
235
{
236
struct net_device *dev = (struct net_device *)data;
237
struct raw_sock *ro = container_of(nb, struct raw_sock, notifier);
238
struct sock *sk = &ro->sk;
239
240
if (!net_eq(dev_net(dev), &init_net))
241
return NOTIFY_DONE;
242
243
if (dev->type != ARPHRD_CAN)
244
return NOTIFY_DONE;
245
246
if (ro->ifindex != dev->ifindex)
247
return NOTIFY_DONE;
248
249
switch (msg) {
250
251
case NETDEV_UNREGISTER:
252
lock_sock(sk);
253
/* remove current filters & unregister */
254
if (ro->bound)
255
raw_disable_allfilters(dev, sk);
256
257
if (ro->count > 1)
258
kfree(ro->filter);
259
260
ro->ifindex = 0;
261
ro->bound = 0;
262
ro->count = 0;
263
release_sock(sk);
264
265
sk->sk_err = ENODEV;
266
if (!sock_flag(sk, SOCK_DEAD))
267
sk->sk_error_report(sk);
268
break;
269
270
case NETDEV_DOWN:
271
sk->sk_err = ENETDOWN;
272
if (!sock_flag(sk, SOCK_DEAD))
273
sk->sk_error_report(sk);
274
break;
275
}
276
277
return NOTIFY_DONE;
278
}
279
280
static int raw_init(struct sock *sk)
281
{
282
struct raw_sock *ro = raw_sk(sk);
283
284
ro->bound = 0;
285
ro->ifindex = 0;
286
287
/* set default filter to single entry dfilter */
288
ro->dfilter.can_id = 0;
289
ro->dfilter.can_mask = MASK_ALL;
290
ro->filter = &ro->dfilter;
291
ro->count = 1;
292
293
/* set default loopback behaviour */
294
ro->loopback = 1;
295
ro->recv_own_msgs = 0;
296
297
/* set notifier */
298
ro->notifier.notifier_call = raw_notifier;
299
300
register_netdevice_notifier(&ro->notifier);
301
302
return 0;
303
}
304
305
static int raw_release(struct socket *sock)
306
{
307
struct sock *sk = sock->sk;
308
struct raw_sock *ro;
309
310
if (!sk)
311
return 0;
312
313
ro = raw_sk(sk);
314
315
unregister_netdevice_notifier(&ro->notifier);
316
317
lock_sock(sk);
318
319
/* remove current filters & unregister */
320
if (ro->bound) {
321
if (ro->ifindex) {
322
struct net_device *dev;
323
324
dev = dev_get_by_index(&init_net, ro->ifindex);
325
if (dev) {
326
raw_disable_allfilters(dev, sk);
327
dev_put(dev);
328
}
329
} else
330
raw_disable_allfilters(NULL, sk);
331
}
332
333
if (ro->count > 1)
334
kfree(ro->filter);
335
336
ro->ifindex = 0;
337
ro->bound = 0;
338
ro->count = 0;
339
340
sock_orphan(sk);
341
sock->sk = NULL;
342
343
release_sock(sk);
344
sock_put(sk);
345
346
return 0;
347
}
348
349
static int raw_bind(struct socket *sock, struct sockaddr *uaddr, int len)
350
{
351
struct sockaddr_can *addr = (struct sockaddr_can *)uaddr;
352
struct sock *sk = sock->sk;
353
struct raw_sock *ro = raw_sk(sk);
354
int ifindex;
355
int err = 0;
356
int notify_enetdown = 0;
357
358
if (len < sizeof(*addr))
359
return -EINVAL;
360
361
lock_sock(sk);
362
363
if (ro->bound && addr->can_ifindex == ro->ifindex)
364
goto out;
365
366
if (addr->can_ifindex) {
367
struct net_device *dev;
368
369
dev = dev_get_by_index(&init_net, addr->can_ifindex);
370
if (!dev) {
371
err = -ENODEV;
372
goto out;
373
}
374
if (dev->type != ARPHRD_CAN) {
375
dev_put(dev);
376
err = -ENODEV;
377
goto out;
378
}
379
if (!(dev->flags & IFF_UP))
380
notify_enetdown = 1;
381
382
ifindex = dev->ifindex;
383
384
/* filters set by default/setsockopt */
385
err = raw_enable_allfilters(dev, sk);
386
dev_put(dev);
387
} else {
388
ifindex = 0;
389
390
/* filters set by default/setsockopt */
391
err = raw_enable_allfilters(NULL, sk);
392
}
393
394
if (!err) {
395
if (ro->bound) {
396
/* unregister old filters */
397
if (ro->ifindex) {
398
struct net_device *dev;
399
400
dev = dev_get_by_index(&init_net, ro->ifindex);
401
if (dev) {
402
raw_disable_allfilters(dev, sk);
403
dev_put(dev);
404
}
405
} else
406
raw_disable_allfilters(NULL, sk);
407
}
408
ro->ifindex = ifindex;
409
ro->bound = 1;
410
}
411
412
out:
413
release_sock(sk);
414
415
if (notify_enetdown) {
416
sk->sk_err = ENETDOWN;
417
if (!sock_flag(sk, SOCK_DEAD))
418
sk->sk_error_report(sk);
419
}
420
421
return err;
422
}
423
424
static int raw_getname(struct socket *sock, struct sockaddr *uaddr,
425
int *len, int peer)
426
{
427
struct sockaddr_can *addr = (struct sockaddr_can *)uaddr;
428
struct sock *sk = sock->sk;
429
struct raw_sock *ro = raw_sk(sk);
430
431
if (peer)
432
return -EOPNOTSUPP;
433
434
memset(addr, 0, sizeof(*addr));
435
addr->can_family = AF_CAN;
436
addr->can_ifindex = ro->ifindex;
437
438
*len = sizeof(*addr);
439
440
return 0;
441
}
442
443
static int raw_setsockopt(struct socket *sock, int level, int optname,
444
char __user *optval, unsigned int optlen)
445
{
446
struct sock *sk = sock->sk;
447
struct raw_sock *ro = raw_sk(sk);
448
struct can_filter *filter = NULL; /* dyn. alloc'ed filters */
449
struct can_filter sfilter; /* single filter */
450
struct net_device *dev = NULL;
451
can_err_mask_t err_mask = 0;
452
int count = 0;
453
int err = 0;
454
455
if (level != SOL_CAN_RAW)
456
return -EINVAL;
457
458
switch (optname) {
459
460
case CAN_RAW_FILTER:
461
if (optlen % sizeof(struct can_filter) != 0)
462
return -EINVAL;
463
464
count = optlen / sizeof(struct can_filter);
465
466
if (count > 1) {
467
/* filter does not fit into dfilter => alloc space */
468
filter = memdup_user(optval, optlen);
469
if (IS_ERR(filter))
470
return PTR_ERR(filter);
471
} else if (count == 1) {
472
if (copy_from_user(&sfilter, optval, sizeof(sfilter)))
473
return -EFAULT;
474
}
475
476
lock_sock(sk);
477
478
if (ro->bound && ro->ifindex)
479
dev = dev_get_by_index(&init_net, ro->ifindex);
480
481
if (ro->bound) {
482
/* (try to) register the new filters */
483
if (count == 1)
484
err = raw_enable_filters(dev, sk, &sfilter, 1);
485
else
486
err = raw_enable_filters(dev, sk, filter,
487
count);
488
if (err) {
489
if (count > 1)
490
kfree(filter);
491
goto out_fil;
492
}
493
494
/* remove old filter registrations */
495
raw_disable_filters(dev, sk, ro->filter, ro->count);
496
}
497
498
/* remove old filter space */
499
if (ro->count > 1)
500
kfree(ro->filter);
501
502
/* link new filters to the socket */
503
if (count == 1) {
504
/* copy filter data for single filter */
505
ro->dfilter = sfilter;
506
filter = &ro->dfilter;
507
}
508
ro->filter = filter;
509
ro->count = count;
510
511
out_fil:
512
if (dev)
513
dev_put(dev);
514
515
release_sock(sk);
516
517
break;
518
519
case CAN_RAW_ERR_FILTER:
520
if (optlen != sizeof(err_mask))
521
return -EINVAL;
522
523
if (copy_from_user(&err_mask, optval, optlen))
524
return -EFAULT;
525
526
err_mask &= CAN_ERR_MASK;
527
528
lock_sock(sk);
529
530
if (ro->bound && ro->ifindex)
531
dev = dev_get_by_index(&init_net, ro->ifindex);
532
533
/* remove current error mask */
534
if (ro->bound) {
535
/* (try to) register the new err_mask */
536
err = raw_enable_errfilter(dev, sk, err_mask);
537
538
if (err)
539
goto out_err;
540
541
/* remove old err_mask registration */
542
raw_disable_errfilter(dev, sk, ro->err_mask);
543
}
544
545
/* link new err_mask to the socket */
546
ro->err_mask = err_mask;
547
548
out_err:
549
if (dev)
550
dev_put(dev);
551
552
release_sock(sk);
553
554
break;
555
556
case CAN_RAW_LOOPBACK:
557
if (optlen != sizeof(ro->loopback))
558
return -EINVAL;
559
560
if (copy_from_user(&ro->loopback, optval, optlen))
561
return -EFAULT;
562
563
break;
564
565
case CAN_RAW_RECV_OWN_MSGS:
566
if (optlen != sizeof(ro->recv_own_msgs))
567
return -EINVAL;
568
569
if (copy_from_user(&ro->recv_own_msgs, optval, optlen))
570
return -EFAULT;
571
572
break;
573
574
default:
575
return -ENOPROTOOPT;
576
}
577
return err;
578
}
579
580
static int raw_getsockopt(struct socket *sock, int level, int optname,
581
char __user *optval, int __user *optlen)
582
{
583
struct sock *sk = sock->sk;
584
struct raw_sock *ro = raw_sk(sk);
585
int len;
586
void *val;
587
int err = 0;
588
589
if (level != SOL_CAN_RAW)
590
return -EINVAL;
591
if (get_user(len, optlen))
592
return -EFAULT;
593
if (len < 0)
594
return -EINVAL;
595
596
switch (optname) {
597
598
case CAN_RAW_FILTER:
599
lock_sock(sk);
600
if (ro->count > 0) {
601
int fsize = ro->count * sizeof(struct can_filter);
602
if (len > fsize)
603
len = fsize;
604
if (copy_to_user(optval, ro->filter, len))
605
err = -EFAULT;
606
} else
607
len = 0;
608
release_sock(sk);
609
610
if (!err)
611
err = put_user(len, optlen);
612
return err;
613
614
case CAN_RAW_ERR_FILTER:
615
if (len > sizeof(can_err_mask_t))
616
len = sizeof(can_err_mask_t);
617
val = &ro->err_mask;
618
break;
619
620
case CAN_RAW_LOOPBACK:
621
if (len > sizeof(int))
622
len = sizeof(int);
623
val = &ro->loopback;
624
break;
625
626
case CAN_RAW_RECV_OWN_MSGS:
627
if (len > sizeof(int))
628
len = sizeof(int);
629
val = &ro->recv_own_msgs;
630
break;
631
632
default:
633
return -ENOPROTOOPT;
634
}
635
636
if (put_user(len, optlen))
637
return -EFAULT;
638
if (copy_to_user(optval, val, len))
639
return -EFAULT;
640
return 0;
641
}
642
643
static int raw_sendmsg(struct kiocb *iocb, struct socket *sock,
644
struct msghdr *msg, size_t size)
645
{
646
struct sock *sk = sock->sk;
647
struct raw_sock *ro = raw_sk(sk);
648
struct sk_buff *skb;
649
struct net_device *dev;
650
int ifindex;
651
int err;
652
653
if (msg->msg_name) {
654
struct sockaddr_can *addr =
655
(struct sockaddr_can *)msg->msg_name;
656
657
if (msg->msg_namelen < sizeof(*addr))
658
return -EINVAL;
659
660
if (addr->can_family != AF_CAN)
661
return -EINVAL;
662
663
ifindex = addr->can_ifindex;
664
} else
665
ifindex = ro->ifindex;
666
667
if (size != sizeof(struct can_frame))
668
return -EINVAL;
669
670
dev = dev_get_by_index(&init_net, ifindex);
671
if (!dev)
672
return -ENXIO;
673
674
skb = sock_alloc_send_skb(sk, size, msg->msg_flags & MSG_DONTWAIT,
675
&err);
676
if (!skb)
677
goto put_dev;
678
679
err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size);
680
if (err < 0)
681
goto free_skb;
682
err = sock_tx_timestamp(sk, &skb_shinfo(skb)->tx_flags);
683
if (err < 0)
684
goto free_skb;
685
686
/* to be able to check the received tx sock reference in raw_rcv() */
687
skb_shinfo(skb)->tx_flags |= SKBTX_DRV_NEEDS_SK_REF;
688
689
skb->dev = dev;
690
skb->sk = sk;
691
692
err = can_send(skb, ro->loopback);
693
694
dev_put(dev);
695
696
if (err)
697
goto send_failed;
698
699
return size;
700
701
free_skb:
702
kfree_skb(skb);
703
put_dev:
704
dev_put(dev);
705
send_failed:
706
return err;
707
}
708
709
static int raw_recvmsg(struct kiocb *iocb, struct socket *sock,
710
struct msghdr *msg, size_t size, int flags)
711
{
712
struct sock *sk = sock->sk;
713
struct sk_buff *skb;
714
int err = 0;
715
int noblock;
716
717
noblock = flags & MSG_DONTWAIT;
718
flags &= ~MSG_DONTWAIT;
719
720
skb = skb_recv_datagram(sk, flags, noblock, &err);
721
if (!skb)
722
return err;
723
724
if (size < skb->len)
725
msg->msg_flags |= MSG_TRUNC;
726
else
727
size = skb->len;
728
729
err = memcpy_toiovec(msg->msg_iov, skb->data, size);
730
if (err < 0) {
731
skb_free_datagram(sk, skb);
732
return err;
733
}
734
735
sock_recv_ts_and_drops(msg, sk, skb);
736
737
if (msg->msg_name) {
738
msg->msg_namelen = sizeof(struct sockaddr_can);
739
memcpy(msg->msg_name, skb->cb, msg->msg_namelen);
740
}
741
742
/* assign the flags that have been recorded in raw_rcv() */
743
msg->msg_flags |= *(raw_flags(skb));
744
745
skb_free_datagram(sk, skb);
746
747
return size;
748
}
749
750
static const struct proto_ops raw_ops = {
751
.family = PF_CAN,
752
.release = raw_release,
753
.bind = raw_bind,
754
.connect = sock_no_connect,
755
.socketpair = sock_no_socketpair,
756
.accept = sock_no_accept,
757
.getname = raw_getname,
758
.poll = datagram_poll,
759
.ioctl = can_ioctl, /* use can_ioctl() from af_can.c */
760
.listen = sock_no_listen,
761
.shutdown = sock_no_shutdown,
762
.setsockopt = raw_setsockopt,
763
.getsockopt = raw_getsockopt,
764
.sendmsg = raw_sendmsg,
765
.recvmsg = raw_recvmsg,
766
.mmap = sock_no_mmap,
767
.sendpage = sock_no_sendpage,
768
};
769
770
static struct proto raw_proto __read_mostly = {
771
.name = "CAN_RAW",
772
.owner = THIS_MODULE,
773
.obj_size = sizeof(struct raw_sock),
774
.init = raw_init,
775
};
776
777
static const struct can_proto raw_can_proto = {
778
.type = SOCK_RAW,
779
.protocol = CAN_RAW,
780
.ops = &raw_ops,
781
.prot = &raw_proto,
782
};
783
784
static __init int raw_module_init(void)
785
{
786
int err;
787
788
printk(banner);
789
790
err = can_proto_register(&raw_can_proto);
791
if (err < 0)
792
printk(KERN_ERR "can: registration of raw protocol failed\n");
793
794
return err;
795
}
796
797
static __exit void raw_module_exit(void)
798
{
799
can_proto_unregister(&raw_can_proto);
800
}
801
802
module_init(raw_module_init);
803
module_exit(raw_module_exit);
804
805