blob: 63ffdb0f3a23fa6bea6b9cb65bd7a63ec0953d84 [file] [log] [blame]
Oliver Hartkoppc18ce102007-11-16 15:53:09 -08001/*
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 *
Oliver Hartkoppc18ce102007-11-16 15:53:09 -080040 */
41
42#include <linux/module.h>
43#include <linux/init.h>
44#include <linux/uio.h>
45#include <linux/net.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090046#include <linux/slab.h>
Oliver Hartkoppc18ce102007-11-16 15:53:09 -080047#include <linux/netdevice.h>
48#include <linux/socket.h>
49#include <linux/if_arp.h>
50#include <linux/skbuff.h>
51#include <linux/can.h>
52#include <linux/can/core.h>
Oliver Hartkopp156c2bb2013-01-17 18:43:39 +010053#include <linux/can/skb.h>
Oliver Hartkoppc18ce102007-11-16 15:53:09 -080054#include <linux/can/raw.h>
55#include <net/sock.h>
56#include <net/net_namespace.h>
57
58#define CAN_RAW_VERSION CAN_VERSION
Oliver Hartkoppc18ce102007-11-16 15:53:09 -080059
60MODULE_DESCRIPTION("PF_CAN raw protocol");
61MODULE_LICENSE("Dual BSD/GPL");
62MODULE_AUTHOR("Urs Thuermann <urs.thuermann@volkswagen.de>");
Lothar Waßmannb13bb2e2009-07-14 23:12:25 +000063MODULE_ALIAS("can-proto-1");
Oliver Hartkoppc18ce102007-11-16 15:53:09 -080064
65#define MASK_ALL 0
66
67/*
68 * A raw socket has a list of can_filters attached to it, each receiving
69 * the CAN frames matching that filter. If the filter list is empty,
70 * no CAN frames will be received by the socket. The default after
71 * opening the socket, is to have one filter which receives all frames.
72 * The filter list is allocated dynamically with the exception of the
73 * list containing only one item. This common case is optimized by
74 * storing the single filter in dfilter, to avoid using dynamic memory.
75 */
76
77struct raw_sock {
78 struct sock sk;
79 int bound;
80 int ifindex;
81 struct notifier_block notifier;
82 int loopback;
83 int recv_own_msgs;
Oliver Hartkoppe2d265d2012-06-13 20:41:31 +020084 int fd_frames;
Oliver Hartkoppc18ce102007-11-16 15:53:09 -080085 int count; /* number of active filters */
86 struct can_filter dfilter; /* default/single filter */
87 struct can_filter *filter; /* pointer to filter(s) */
88 can_err_mask_t err_mask;
89};
90
Oliver Hartkopp1e556592010-10-19 09:32:04 +000091/*
92 * Return pointer to store the extra msg flags for raw_recvmsg().
93 * We use the space of one unsigned int beyond the 'struct sockaddr_can'
94 * in skb->cb.
95 */
96static inline unsigned int *raw_flags(struct sk_buff *skb)
97{
Eyal Birgerb4772ef2015-03-01 14:58:29 +020098 sock_skb_cb_check_size(sizeof(struct sockaddr_can) +
99 sizeof(unsigned int));
Oliver Hartkopp1e556592010-10-19 09:32:04 +0000100
101 /* return pointer after struct sockaddr_can */
102 return (unsigned int *)(&((struct sockaddr_can *)skb->cb)[1]);
103}
104
Oliver Hartkoppc18ce102007-11-16 15:53:09 -0800105static inline struct raw_sock *raw_sk(const struct sock *sk)
106{
107 return (struct raw_sock *)sk;
108}
109
Oliver Hartkopp1e556592010-10-19 09:32:04 +0000110static void raw_rcv(struct sk_buff *oskb, void *data)
Oliver Hartkoppc18ce102007-11-16 15:53:09 -0800111{
112 struct sock *sk = (struct sock *)data;
113 struct raw_sock *ro = raw_sk(sk);
114 struct sockaddr_can *addr;
Oliver Hartkopp1e556592010-10-19 09:32:04 +0000115 struct sk_buff *skb;
116 unsigned int *pflags;
Oliver Hartkoppc18ce102007-11-16 15:53:09 -0800117
Oliver Hartkopp1fa17d42009-01-06 11:07:54 -0800118 /* check the received tx sock reference */
Oliver Hartkopp1e556592010-10-19 09:32:04 +0000119 if (!ro->recv_own_msgs && oskb->sk == sk)
Oliver Hartkopp1fa17d42009-01-06 11:07:54 -0800120 return;
121
Oliver Hartkopp821047c2014-03-01 15:31:53 +0100122 /* do not pass non-CAN2.0 frames to a legacy socket */
123 if (!ro->fd_frames && oskb->len != CAN_MTU)
124 return;
Oliver Hartkoppe2d265d2012-06-13 20:41:31 +0200125
Oliver Hartkopp1fa17d42009-01-06 11:07:54 -0800126 /* clone the given skb to be able to enqueue it into the rcv queue */
Oliver Hartkopp1e556592010-10-19 09:32:04 +0000127 skb = skb_clone(oskb, GFP_ATOMIC);
Oliver Hartkopp1fa17d42009-01-06 11:07:54 -0800128 if (!skb)
129 return;
Oliver Hartkoppc18ce102007-11-16 15:53:09 -0800130
131 /*
132 * Put the datagram to the queue so that raw_recvmsg() can
133 * get it from there. We need to pass the interface index to
134 * raw_recvmsg(). We pass a whole struct sockaddr_can in skb->cb
135 * containing the interface index.
136 */
137
Eyal Birgerb4772ef2015-03-01 14:58:29 +0200138 sock_skb_cb_check_size(sizeof(struct sockaddr_can));
Oliver Hartkoppc18ce102007-11-16 15:53:09 -0800139 addr = (struct sockaddr_can *)skb->cb;
140 memset(addr, 0, sizeof(*addr));
141 addr->can_family = AF_CAN;
142 addr->can_ifindex = skb->dev->ifindex;
143
Oliver Hartkopp1e556592010-10-19 09:32:04 +0000144 /* add CAN specific message flags for raw_recvmsg() */
145 pflags = raw_flags(skb);
146 *pflags = 0;
147 if (oskb->sk)
148 *pflags |= MSG_DONTROUTE;
149 if (oskb->sk == sk)
150 *pflags |= MSG_CONFIRM;
151
Urs Thuermanna2199942008-02-07 18:05:04 -0800152 if (sock_queue_rcv_skb(sk, skb) < 0)
Oliver Hartkoppc18ce102007-11-16 15:53:09 -0800153 kfree_skb(skb);
154}
155
156static int raw_enable_filters(struct net_device *dev, struct sock *sk,
Urs Thuermanna2199942008-02-07 18:05:04 -0800157 struct can_filter *filter, int count)
Oliver Hartkoppc18ce102007-11-16 15:53:09 -0800158{
159 int err = 0;
160 int i;
161
162 for (i = 0; i < count; i++) {
163 err = can_rx_register(dev, filter[i].can_id,
164 filter[i].can_mask,
165 raw_rcv, sk, "raw");
166 if (err) {
167 /* clean up successfully registered filters */
168 while (--i >= 0)
169 can_rx_unregister(dev, filter[i].can_id,
170 filter[i].can_mask,
171 raw_rcv, sk);
172 break;
173 }
174 }
175
176 return err;
177}
178
179static int raw_enable_errfilter(struct net_device *dev, struct sock *sk,
180 can_err_mask_t err_mask)
181{
182 int err = 0;
183
184 if (err_mask)
185 err = can_rx_register(dev, 0, err_mask | CAN_ERR_FLAG,
186 raw_rcv, sk, "raw");
187
188 return err;
189}
190
191static void raw_disable_filters(struct net_device *dev, struct sock *sk,
Urs Thuermanna2199942008-02-07 18:05:04 -0800192 struct can_filter *filter, int count)
Oliver Hartkoppc18ce102007-11-16 15:53:09 -0800193{
194 int i;
195
196 for (i = 0; i < count; i++)
197 can_rx_unregister(dev, filter[i].can_id, filter[i].can_mask,
198 raw_rcv, sk);
199}
200
201static inline void raw_disable_errfilter(struct net_device *dev,
202 struct sock *sk,
203 can_err_mask_t err_mask)
204
205{
206 if (err_mask)
207 can_rx_unregister(dev, 0, err_mask | CAN_ERR_FLAG,
208 raw_rcv, sk);
209}
210
211static inline void raw_disable_allfilters(struct net_device *dev,
212 struct sock *sk)
213{
214 struct raw_sock *ro = raw_sk(sk);
215
216 raw_disable_filters(dev, sk, ro->filter, ro->count);
217 raw_disable_errfilter(dev, sk, ro->err_mask);
218}
219
220static int raw_enable_allfilters(struct net_device *dev, struct sock *sk)
221{
222 struct raw_sock *ro = raw_sk(sk);
223 int err;
224
225 err = raw_enable_filters(dev, sk, ro->filter, ro->count);
226 if (!err) {
227 err = raw_enable_errfilter(dev, sk, ro->err_mask);
228 if (err)
229 raw_disable_filters(dev, sk, ro->filter, ro->count);
230 }
231
232 return err;
233}
234
235static int raw_notifier(struct notifier_block *nb,
Jiri Pirko351638e2013-05-28 01:30:21 +0000236 unsigned long msg, void *ptr)
Oliver Hartkoppc18ce102007-11-16 15:53:09 -0800237{
Jiri Pirko351638e2013-05-28 01:30:21 +0000238 struct net_device *dev = netdev_notifier_info_to_dev(ptr);
Oliver Hartkoppc18ce102007-11-16 15:53:09 -0800239 struct raw_sock *ro = container_of(nb, struct raw_sock, notifier);
240 struct sock *sk = &ro->sk;
241
YOSHIFUJI Hideaki721499e2008-07-19 22:34:43 -0700242 if (!net_eq(dev_net(dev), &init_net))
Oliver Hartkoppc18ce102007-11-16 15:53:09 -0800243 return NOTIFY_DONE;
244
245 if (dev->type != ARPHRD_CAN)
246 return NOTIFY_DONE;
247
248 if (ro->ifindex != dev->ifindex)
249 return NOTIFY_DONE;
250
251 switch (msg) {
252
253 case NETDEV_UNREGISTER:
254 lock_sock(sk);
255 /* remove current filters & unregister */
256 if (ro->bound)
257 raw_disable_allfilters(dev, sk);
258
259 if (ro->count > 1)
260 kfree(ro->filter);
261
262 ro->ifindex = 0;
263 ro->bound = 0;
264 ro->count = 0;
265 release_sock(sk);
266
267 sk->sk_err = ENODEV;
268 if (!sock_flag(sk, SOCK_DEAD))
269 sk->sk_error_report(sk);
270 break;
271
272 case NETDEV_DOWN:
273 sk->sk_err = ENETDOWN;
274 if (!sock_flag(sk, SOCK_DEAD))
275 sk->sk_error_report(sk);
276 break;
277 }
278
279 return NOTIFY_DONE;
280}
281
282static int raw_init(struct sock *sk)
283{
284 struct raw_sock *ro = raw_sk(sk);
285
286 ro->bound = 0;
287 ro->ifindex = 0;
288
289 /* set default filter to single entry dfilter */
290 ro->dfilter.can_id = 0;
291 ro->dfilter.can_mask = MASK_ALL;
292 ro->filter = &ro->dfilter;
293 ro->count = 1;
294
295 /* set default loopback behaviour */
296 ro->loopback = 1;
297 ro->recv_own_msgs = 0;
Oliver Hartkoppe2d265d2012-06-13 20:41:31 +0200298 ro->fd_frames = 0;
Oliver Hartkoppc18ce102007-11-16 15:53:09 -0800299
300 /* set notifier */
301 ro->notifier.notifier_call = raw_notifier;
302
303 register_netdevice_notifier(&ro->notifier);
304
305 return 0;
306}
307
308static int raw_release(struct socket *sock)
309{
310 struct sock *sk = sock->sk;
Oliver Hartkopp10022a62011-04-20 01:57:15 +0000311 struct raw_sock *ro;
312
313 if (!sk)
314 return 0;
315
316 ro = raw_sk(sk);
Oliver Hartkoppc18ce102007-11-16 15:53:09 -0800317
318 unregister_netdevice_notifier(&ro->notifier);
319
320 lock_sock(sk);
321
322 /* remove current filters & unregister */
323 if (ro->bound) {
324 if (ro->ifindex) {
325 struct net_device *dev;
326
327 dev = dev_get_by_index(&init_net, ro->ifindex);
328 if (dev) {
329 raw_disable_allfilters(dev, sk);
330 dev_put(dev);
331 }
332 } else
333 raw_disable_allfilters(NULL, sk);
334 }
335
336 if (ro->count > 1)
337 kfree(ro->filter);
338
339 ro->ifindex = 0;
340 ro->bound = 0;
341 ro->count = 0;
342
Lothar Waßmannf7e5cc02009-07-14 23:10:21 +0000343 sock_orphan(sk);
344 sock->sk = NULL;
345
Oliver Hartkoppc18ce102007-11-16 15:53:09 -0800346 release_sock(sk);
347 sock_put(sk);
348
349 return 0;
350}
351
352static int raw_bind(struct socket *sock, struct sockaddr *uaddr, int len)
353{
354 struct sockaddr_can *addr = (struct sockaddr_can *)uaddr;
355 struct sock *sk = sock->sk;
356 struct raw_sock *ro = raw_sk(sk);
357 int ifindex;
358 int err = 0;
359 int notify_enetdown = 0;
360
361 if (len < sizeof(*addr))
362 return -EINVAL;
363
364 lock_sock(sk);
365
366 if (ro->bound && addr->can_ifindex == ro->ifindex)
367 goto out;
368
369 if (addr->can_ifindex) {
370 struct net_device *dev;
371
372 dev = dev_get_by_index(&init_net, addr->can_ifindex);
373 if (!dev) {
374 err = -ENODEV;
375 goto out;
376 }
377 if (dev->type != ARPHRD_CAN) {
378 dev_put(dev);
379 err = -ENODEV;
380 goto out;
381 }
382 if (!(dev->flags & IFF_UP))
383 notify_enetdown = 1;
384
385 ifindex = dev->ifindex;
386
387 /* filters set by default/setsockopt */
388 err = raw_enable_allfilters(dev, sk);
389 dev_put(dev);
Oliver Hartkoppc18ce102007-11-16 15:53:09 -0800390 } else {
391 ifindex = 0;
392
393 /* filters set by default/setsockopt */
394 err = raw_enable_allfilters(NULL, sk);
395 }
396
397 if (!err) {
398 if (ro->bound) {
399 /* unregister old filters */
400 if (ro->ifindex) {
401 struct net_device *dev;
402
403 dev = dev_get_by_index(&init_net, ro->ifindex);
404 if (dev) {
405 raw_disable_allfilters(dev, sk);
406 dev_put(dev);
407 }
408 } else
409 raw_disable_allfilters(NULL, sk);
410 }
411 ro->ifindex = ifindex;
412 ro->bound = 1;
413 }
414
415 out:
416 release_sock(sk);
417
418 if (notify_enetdown) {
419 sk->sk_err = ENETDOWN;
420 if (!sock_flag(sk, SOCK_DEAD))
421 sk->sk_error_report(sk);
422 }
423
424 return err;
425}
426
427static int raw_getname(struct socket *sock, struct sockaddr *uaddr,
428 int *len, int peer)
429{
430 struct sockaddr_can *addr = (struct sockaddr_can *)uaddr;
431 struct sock *sk = sock->sk;
432 struct raw_sock *ro = raw_sk(sk);
433
434 if (peer)
435 return -EOPNOTSUPP;
436
Eric Dumazete84b90a2009-08-06 20:27:04 +0000437 memset(addr, 0, sizeof(*addr));
Oliver Hartkoppc18ce102007-11-16 15:53:09 -0800438 addr->can_family = AF_CAN;
439 addr->can_ifindex = ro->ifindex;
440
441 *len = sizeof(*addr);
442
443 return 0;
444}
445
446static int raw_setsockopt(struct socket *sock, int level, int optname,
David S. Millerb7058842009-09-30 16:12:20 -0700447 char __user *optval, unsigned int optlen)
Oliver Hartkoppc18ce102007-11-16 15:53:09 -0800448{
449 struct sock *sk = sock->sk;
450 struct raw_sock *ro = raw_sk(sk);
451 struct can_filter *filter = NULL; /* dyn. alloc'ed filters */
452 struct can_filter sfilter; /* single filter */
453 struct net_device *dev = NULL;
454 can_err_mask_t err_mask = 0;
455 int count = 0;
456 int err = 0;
457
458 if (level != SOL_CAN_RAW)
459 return -EINVAL;
Oliver Hartkoppc18ce102007-11-16 15:53:09 -0800460
461 switch (optname) {
462
463 case CAN_RAW_FILTER:
464 if (optlen % sizeof(struct can_filter) != 0)
465 return -EINVAL;
466
467 count = optlen / sizeof(struct can_filter);
468
469 if (count > 1) {
470 /* filter does not fit into dfilter => alloc space */
Julia Lawall16dff912010-05-21 22:18:34 +0000471 filter = memdup_user(optval, optlen);
472 if (IS_ERR(filter))
473 return PTR_ERR(filter);
Oliver Hartkoppc18ce102007-11-16 15:53:09 -0800474 } else if (count == 1) {
Eric Dumazet4ffa8702010-04-09 23:47:31 +0000475 if (copy_from_user(&sfilter, optval, sizeof(sfilter)))
Sam Ravnborg3f91bd42008-04-26 22:57:25 -0700476 return -EFAULT;
Oliver Hartkoppc18ce102007-11-16 15:53:09 -0800477 }
478
479 lock_sock(sk);
480
481 if (ro->bound && ro->ifindex)
482 dev = dev_get_by_index(&init_net, ro->ifindex);
483
484 if (ro->bound) {
485 /* (try to) register the new filters */
486 if (count == 1)
487 err = raw_enable_filters(dev, sk, &sfilter, 1);
488 else
489 err = raw_enable_filters(dev, sk, filter,
490 count);
491 if (err) {
492 if (count > 1)
493 kfree(filter);
Oliver Hartkoppc18ce102007-11-16 15:53:09 -0800494 goto out_fil;
495 }
496
497 /* remove old filter registrations */
498 raw_disable_filters(dev, sk, ro->filter, ro->count);
499 }
500
501 /* remove old filter space */
502 if (ro->count > 1)
503 kfree(ro->filter);
504
505 /* link new filters to the socket */
506 if (count == 1) {
507 /* copy filter data for single filter */
508 ro->dfilter = sfilter;
509 filter = &ro->dfilter;
510 }
511 ro->filter = filter;
512 ro->count = count;
513
514 out_fil:
515 if (dev)
516 dev_put(dev);
517
518 release_sock(sk);
519
520 break;
521
522 case CAN_RAW_ERR_FILTER:
523 if (optlen != sizeof(err_mask))
524 return -EINVAL;
525
Sam Ravnborg3f91bd42008-04-26 22:57:25 -0700526 if (copy_from_user(&err_mask, optval, optlen))
527 return -EFAULT;
Oliver Hartkoppc18ce102007-11-16 15:53:09 -0800528
529 err_mask &= CAN_ERR_MASK;
530
531 lock_sock(sk);
532
533 if (ro->bound && ro->ifindex)
534 dev = dev_get_by_index(&init_net, ro->ifindex);
535
536 /* remove current error mask */
537 if (ro->bound) {
538 /* (try to) register the new err_mask */
539 err = raw_enable_errfilter(dev, sk, err_mask);
540
541 if (err)
542 goto out_err;
543
544 /* remove old err_mask registration */
545 raw_disable_errfilter(dev, sk, ro->err_mask);
546 }
547
548 /* link new err_mask to the socket */
549 ro->err_mask = err_mask;
550
551 out_err:
552 if (dev)
553 dev_put(dev);
554
555 release_sock(sk);
556
557 break;
558
559 case CAN_RAW_LOOPBACK:
560 if (optlen != sizeof(ro->loopback))
561 return -EINVAL;
562
Sam Ravnborg3f91bd42008-04-26 22:57:25 -0700563 if (copy_from_user(&ro->loopback, optval, optlen))
564 return -EFAULT;
Oliver Hartkoppc18ce102007-11-16 15:53:09 -0800565
566 break;
567
568 case CAN_RAW_RECV_OWN_MSGS:
569 if (optlen != sizeof(ro->recv_own_msgs))
570 return -EINVAL;
571
Sam Ravnborg3f91bd42008-04-26 22:57:25 -0700572 if (copy_from_user(&ro->recv_own_msgs, optval, optlen))
573 return -EFAULT;
Oliver Hartkoppc18ce102007-11-16 15:53:09 -0800574
575 break;
576
Oliver Hartkoppe2d265d2012-06-13 20:41:31 +0200577 case CAN_RAW_FD_FRAMES:
578 if (optlen != sizeof(ro->fd_frames))
579 return -EINVAL;
580
581 if (copy_from_user(&ro->fd_frames, optval, optlen))
582 return -EFAULT;
583
584 break;
585
Oliver Hartkoppc18ce102007-11-16 15:53:09 -0800586 default:
587 return -ENOPROTOOPT;
588 }
589 return err;
590}
591
592static int raw_getsockopt(struct socket *sock, int level, int optname,
593 char __user *optval, int __user *optlen)
594{
595 struct sock *sk = sock->sk;
596 struct raw_sock *ro = raw_sk(sk);
597 int len;
598 void *val;
599 int err = 0;
600
601 if (level != SOL_CAN_RAW)
602 return -EINVAL;
603 if (get_user(len, optlen))
604 return -EFAULT;
605 if (len < 0)
606 return -EINVAL;
607
608 switch (optname) {
609
610 case CAN_RAW_FILTER:
611 lock_sock(sk);
612 if (ro->count > 0) {
613 int fsize = ro->count * sizeof(struct can_filter);
614 if (len > fsize)
615 len = fsize;
Pavel Emelyanov653252c2008-04-25 01:49:48 -0700616 if (copy_to_user(optval, ro->filter, len))
617 err = -EFAULT;
Oliver Hartkoppc18ce102007-11-16 15:53:09 -0800618 } else
619 len = 0;
620 release_sock(sk);
621
622 if (!err)
623 err = put_user(len, optlen);
624 return err;
625
626 case CAN_RAW_ERR_FILTER:
627 if (len > sizeof(can_err_mask_t))
628 len = sizeof(can_err_mask_t);
629 val = &ro->err_mask;
630 break;
631
632 case CAN_RAW_LOOPBACK:
633 if (len > sizeof(int))
634 len = sizeof(int);
635 val = &ro->loopback;
636 break;
637
638 case CAN_RAW_RECV_OWN_MSGS:
639 if (len > sizeof(int))
640 len = sizeof(int);
641 val = &ro->recv_own_msgs;
642 break;
643
Oliver Hartkoppe2d265d2012-06-13 20:41:31 +0200644 case CAN_RAW_FD_FRAMES:
645 if (len > sizeof(int))
646 len = sizeof(int);
647 val = &ro->fd_frames;
648 break;
649
Oliver Hartkoppc18ce102007-11-16 15:53:09 -0800650 default:
651 return -ENOPROTOOPT;
652 }
653
654 if (put_user(len, optlen))
655 return -EFAULT;
656 if (copy_to_user(optval, val, len))
657 return -EFAULT;
658 return 0;
659}
660
Ying Xue1b784142015-03-02 15:37:48 +0800661static int raw_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
Oliver Hartkoppc18ce102007-11-16 15:53:09 -0800662{
663 struct sock *sk = sock->sk;
664 struct raw_sock *ro = raw_sk(sk);
665 struct sk_buff *skb;
666 struct net_device *dev;
667 int ifindex;
668 int err;
669
670 if (msg->msg_name) {
Steffen Hurrle342dfc32014-01-17 22:53:15 +0100671 DECLARE_SOCKADDR(struct sockaddr_can *, addr, msg->msg_name);
Oliver Hartkoppc18ce102007-11-16 15:53:09 -0800672
Kurt Van Dijck5e5073282011-01-15 20:56:42 -0800673 if (msg->msg_namelen < sizeof(*addr))
674 return -EINVAL;
675
Oliver Hartkoppc18ce102007-11-16 15:53:09 -0800676 if (addr->can_family != AF_CAN)
677 return -EINVAL;
678
679 ifindex = addr->can_ifindex;
680 } else
681 ifindex = ro->ifindex;
682
Oliver Hartkoppe2d265d2012-06-13 20:41:31 +0200683 if (ro->fd_frames) {
684 if (unlikely(size != CANFD_MTU && size != CAN_MTU))
685 return -EINVAL;
686 } else {
687 if (unlikely(size != CAN_MTU))
688 return -EINVAL;
689 }
Oliver Hartkopp7f2d38e2008-07-05 23:38:43 -0700690
Oliver Hartkoppc18ce102007-11-16 15:53:09 -0800691 dev = dev_get_by_index(&init_net, ifindex);
692 if (!dev)
693 return -ENXIO;
694
Oliver Hartkopp156c2bb2013-01-17 18:43:39 +0100695 skb = sock_alloc_send_skb(sk, size + sizeof(struct can_skb_priv),
696 msg->msg_flags & MSG_DONTWAIT, &err);
Ilpo Järvinenebad5c02008-12-14 23:16:58 -0800697 if (!skb)
698 goto put_dev;
Oliver Hartkoppc18ce102007-11-16 15:53:09 -0800699
Oliver Hartkopp2bf34402013-01-28 08:33:33 +0000700 can_skb_reserve(skb);
701 can_skb_prv(skb)->ifindex = dev->ifindex;
Oliver Hartkopp156c2bb2013-01-17 18:43:39 +0100702
Al Viro6ce8e9c2014-04-06 21:25:44 -0400703 err = memcpy_from_msg(skb_put(skb, size), msg, size);
Ilpo Järvinenebad5c02008-12-14 23:16:58 -0800704 if (err < 0)
705 goto free_skb;
Daniel Borkmannbf84a012013-04-14 08:08:13 +0000706
707 sock_tx_timestamp(sk, &skb_shinfo(skb)->tx_flags);
Oliver Hartkoppcff0d6e2010-08-03 00:31:48 -0700708
Oliver Hartkoppc18ce102007-11-16 15:53:09 -0800709 skb->dev = dev;
710 skb->sk = sk;
Rostislav Lisovybb5ecb02014-01-24 13:17:37 +0100711 skb->priority = sk->sk_priority;
Oliver Hartkoppc18ce102007-11-16 15:53:09 -0800712
713 err = can_send(skb, ro->loopback);
714
715 dev_put(dev);
716
717 if (err)
Ilpo Järvinenebad5c02008-12-14 23:16:58 -0800718 goto send_failed;
Oliver Hartkoppc18ce102007-11-16 15:53:09 -0800719
720 return size;
Ilpo Järvinenebad5c02008-12-14 23:16:58 -0800721
722free_skb:
723 kfree_skb(skb);
724put_dev:
725 dev_put(dev);
726send_failed:
727 return err;
Oliver Hartkoppc18ce102007-11-16 15:53:09 -0800728}
729
Ying Xue1b784142015-03-02 15:37:48 +0800730static int raw_recvmsg(struct socket *sock, struct msghdr *msg, size_t size,
731 int flags)
Oliver Hartkoppc18ce102007-11-16 15:53:09 -0800732{
733 struct sock *sk = sock->sk;
734 struct sk_buff *skb;
Urs Thuermanna2199942008-02-07 18:05:04 -0800735 int err = 0;
Oliver Hartkoppc18ce102007-11-16 15:53:09 -0800736 int noblock;
737
738 noblock = flags & MSG_DONTWAIT;
739 flags &= ~MSG_DONTWAIT;
740
Urs Thuermanna2199942008-02-07 18:05:04 -0800741 skb = skb_recv_datagram(sk, flags, noblock, &err);
Oliver Hartkoppc18ce102007-11-16 15:53:09 -0800742 if (!skb)
Urs Thuermanna2199942008-02-07 18:05:04 -0800743 return err;
Oliver Hartkoppc18ce102007-11-16 15:53:09 -0800744
Oliver Hartkopp821047c2014-03-01 15:31:53 +0100745 if (size < skb->len)
Oliver Hartkoppc18ce102007-11-16 15:53:09 -0800746 msg->msg_flags |= MSG_TRUNC;
747 else
Oliver Hartkopp821047c2014-03-01 15:31:53 +0100748 size = skb->len;
Oliver Hartkoppc18ce102007-11-16 15:53:09 -0800749
Al Viro7eab8d92014-04-06 21:51:23 -0400750 err = memcpy_to_msg(msg, skb->data, size);
Urs Thuermanna2199942008-02-07 18:05:04 -0800751 if (err < 0) {
Oliver Hartkoppc18ce102007-11-16 15:53:09 -0800752 skb_free_datagram(sk, skb);
Urs Thuermanna2199942008-02-07 18:05:04 -0800753 return err;
Oliver Hartkoppc18ce102007-11-16 15:53:09 -0800754 }
755
Neil Horman3b885782009-10-12 13:26:31 -0700756 sock_recv_ts_and_drops(msg, sk, skb);
Oliver Hartkoppc18ce102007-11-16 15:53:09 -0800757
758 if (msg->msg_name) {
Steffen Hurrle342dfc32014-01-17 22:53:15 +0100759 __sockaddr_check_size(sizeof(struct sockaddr_can));
Oliver Hartkoppc18ce102007-11-16 15:53:09 -0800760 msg->msg_namelen = sizeof(struct sockaddr_can);
761 memcpy(msg->msg_name, skb->cb, msg->msg_namelen);
762 }
763
Oliver Hartkopp1e556592010-10-19 09:32:04 +0000764 /* assign the flags that have been recorded in raw_rcv() */
765 msg->msg_flags |= *(raw_flags(skb));
766
Oliver Hartkoppc18ce102007-11-16 15:53:09 -0800767 skb_free_datagram(sk, skb);
768
769 return size;
770}
771
Oliver Hartkopp53914b62011-03-22 08:27:25 +0000772static const struct proto_ops raw_ops = {
Oliver Hartkoppc18ce102007-11-16 15:53:09 -0800773 .family = PF_CAN,
774 .release = raw_release,
775 .bind = raw_bind,
776 .connect = sock_no_connect,
777 .socketpair = sock_no_socketpair,
778 .accept = sock_no_accept,
779 .getname = raw_getname,
780 .poll = datagram_poll,
Oliver Hartkopp53914b62011-03-22 08:27:25 +0000781 .ioctl = can_ioctl, /* use can_ioctl() from af_can.c */
Oliver Hartkoppc18ce102007-11-16 15:53:09 -0800782 .listen = sock_no_listen,
783 .shutdown = sock_no_shutdown,
784 .setsockopt = raw_setsockopt,
785 .getsockopt = raw_getsockopt,
786 .sendmsg = raw_sendmsg,
787 .recvmsg = raw_recvmsg,
788 .mmap = sock_no_mmap,
789 .sendpage = sock_no_sendpage,
790};
791
792static struct proto raw_proto __read_mostly = {
793 .name = "CAN_RAW",
794 .owner = THIS_MODULE,
795 .obj_size = sizeof(struct raw_sock),
796 .init = raw_init,
797};
798
Kurt Van Dijck16506292011-05-03 18:40:57 +0000799static const struct can_proto raw_can_proto = {
Oliver Hartkoppc18ce102007-11-16 15:53:09 -0800800 .type = SOCK_RAW,
801 .protocol = CAN_RAW,
Oliver Hartkoppc18ce102007-11-16 15:53:09 -0800802 .ops = &raw_ops,
803 .prot = &raw_proto,
804};
805
806static __init int raw_module_init(void)
807{
808 int err;
809
Jeremiah Mahlerb111b782014-11-21 23:42:35 -0800810 pr_info("can: raw protocol (rev " CAN_RAW_VERSION ")\n");
Oliver Hartkoppc18ce102007-11-16 15:53:09 -0800811
812 err = can_proto_register(&raw_can_proto);
813 if (err < 0)
814 printk(KERN_ERR "can: registration of raw protocol failed\n");
815
816 return err;
817}
818
819static __exit void raw_module_exit(void)
820{
821 can_proto_unregister(&raw_can_proto);
822}
823
824module_init(raw_module_init);
825module_exit(raw_module_exit);