Blame view

net/can/raw.c 20.5 KB
d77cd7fef   Masahiro Yamada   can: remove "WITH...
1
  // SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
d6ada83bb   Marc Kleine-Budde   can: raw: convert...
2
  /* raw.c - Raw sockets for protocol family CAN
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
   *
   * Copyright (c) 2002-2007 Volkswagen Group Electronic Research
   * All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in the
   *    documentation and/or other materials provided with the distribution.
   * 3. Neither the name of Volkswagen nor the names of its contributors
   *    may be used to endorse or promote products derived from this software
   *    without specific prior written permission.
   *
   * Alternatively, provided that this notice is retained in full, this
   * software may be distributed under the terms of the GNU General
   * Public License ("GPL") version 2, in which case the provisions of the
   * GPL apply INSTEAD OF those given above.
   *
   * The provided data structures and external interfaces from this code
   * are not restricted to be used by modules with a GPL compatible license.
   *
   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
   * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
   * DAMAGE.
   *
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
40
41
42
43
44
45
   */
  
  #include <linux/module.h>
  #include <linux/init.h>
  #include <linux/uio.h>
  #include <linux/net.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
46
  #include <linux/slab.h>
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
47
48
49
50
51
52
  #include <linux/netdevice.h>
  #include <linux/socket.h>
  #include <linux/if_arp.h>
  #include <linux/skbuff.h>
  #include <linux/can.h>
  #include <linux/can/core.h>
156c2bb9f   Oliver Hartkopp   can: add private ...
53
  #include <linux/can/skb.h>
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
54
55
56
  #include <linux/can/raw.h>
  #include <net/sock.h>
  #include <net/net_namespace.h>
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
57
58
59
  MODULE_DESCRIPTION("PF_CAN raw protocol");
  MODULE_LICENSE("Dual BSD/GPL");
  MODULE_AUTHOR("Urs Thuermann <urs.thuermann@volkswagen.de>");
b13bb2e99   Lothar Waßmann   net/can: add modu...
60
  MODULE_ALIAS("can-proto-1");
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
61
62
  
  #define MASK_ALL 0
d6ada83bb   Marc Kleine-Budde   can: raw: convert...
63
  /* A raw socket has a list of can_filters attached to it, each receiving
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
64
65
66
67
68
69
70
   * the CAN frames matching that filter.  If the filter list is empty,
   * no CAN frames will be received by the socket.  The default after
   * opening the socket, is to have one filter which receives all frames.
   * The filter list is allocated dynamically with the exception of the
   * list containing only one item.  This common case is optimized by
   * storing the single filter in dfilter, to avoid using dynamic memory.
   */
514ac99c6   Oliver Hartkopp   can: fix multiple...
71
  struct uniqframe {
d3b58c47d   Oliver Hartkopp   can: replace time...
72
  	int skbcnt;
514ac99c6   Oliver Hartkopp   can: fix multiple...
73
  	const struct sk_buff *skb;
a5581ef4c   Oliver Hartkopp   can: introduce ne...
74
  	unsigned int join_rx_count;
514ac99c6   Oliver Hartkopp   can: fix multiple...
75
  };
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
76
77
78
79
80
81
82
  struct raw_sock {
  	struct sock sk;
  	int bound;
  	int ifindex;
  	struct notifier_block notifier;
  	int loopback;
  	int recv_own_msgs;
e2d265d3b   Oliver Hartkopp   canfd: add suppor...
83
  	int fd_frames;
a5581ef4c   Oliver Hartkopp   can: introduce ne...
84
  	int join_filters;
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
85
86
87
88
  	int count;                 /* number of active filters */
  	struct can_filter dfilter; /* default/single filter */
  	struct can_filter *filter; /* pointer to filter(s) */
  	can_err_mask_t err_mask;
514ac99c6   Oliver Hartkopp   can: fix multiple...
89
  	struct uniqframe __percpu *uniq;
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
90
  };
d6ada83bb   Marc Kleine-Budde   can: raw: convert...
91
  /* Return pointer to store the extra msg flags for raw_recvmsg().
1e55659ce   Oliver Hartkopp   can-raw: add msg_...
92
93
94
95
96
   * We use the space of one unsigned int beyond the 'struct sockaddr_can'
   * in skb->cb.
   */
  static inline unsigned int *raw_flags(struct sk_buff *skb)
  {
b4772ef87   Eyal Birger   net: use common m...
97
98
  	sock_skb_cb_check_size(sizeof(struct sockaddr_can) +
  			       sizeof(unsigned int));
1e55659ce   Oliver Hartkopp   can-raw: add msg_...
99
100
101
102
  
  	/* return pointer after struct sockaddr_can */
  	return (unsigned int *)(&((struct sockaddr_can *)skb->cb)[1]);
  }
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
103
104
105
106
  static inline struct raw_sock *raw_sk(const struct sock *sk)
  {
  	return (struct raw_sock *)sk;
  }
1e55659ce   Oliver Hartkopp   can-raw: add msg_...
107
  static void raw_rcv(struct sk_buff *oskb, void *data)
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
108
109
110
111
  {
  	struct sock *sk = (struct sock *)data;
  	struct raw_sock *ro = raw_sk(sk);
  	struct sockaddr_can *addr;
1e55659ce   Oliver Hartkopp   can-raw: add msg_...
112
113
  	struct sk_buff *skb;
  	unsigned int *pflags;
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
114

1fa17d4ba   Oliver Hartkopp   can: omit unneede...
115
  	/* check the received tx sock reference */
1e55659ce   Oliver Hartkopp   can-raw: add msg_...
116
  	if (!ro->recv_own_msgs && oskb->sk == sk)
1fa17d4ba   Oliver Hartkopp   can: omit unneede...
117
  		return;
821047c40   Oliver Hartkopp   can: remove CAN F...
118
119
120
  	/* do not pass non-CAN2.0 frames to a legacy socket */
  	if (!ro->fd_frames && oskb->len != CAN_MTU)
  		return;
e2d265d3b   Oliver Hartkopp   canfd: add suppor...
121

514ac99c6   Oliver Hartkopp   can: fix multiple...
122
123
  	/* eliminate multiple filter matches for the same skb */
  	if (this_cpu_ptr(ro->uniq)->skb == oskb &&
d3b58c47d   Oliver Hartkopp   can: replace time...
124
  	    this_cpu_ptr(ro->uniq)->skbcnt == can_skb_prv(oskb)->skbcnt) {
a5581ef4c   Oliver Hartkopp   can: introduce ne...
125
126
127
128
129
130
131
132
  		if (ro->join_filters) {
  			this_cpu_inc(ro->uniq->join_rx_count);
  			/* drop frame until all enabled filters matched */
  			if (this_cpu_ptr(ro->uniq)->join_rx_count < ro->count)
  				return;
  		} else {
  			return;
  		}
514ac99c6   Oliver Hartkopp   can: fix multiple...
133
134
  	} else {
  		this_cpu_ptr(ro->uniq)->skb = oskb;
d3b58c47d   Oliver Hartkopp   can: replace time...
135
  		this_cpu_ptr(ro->uniq)->skbcnt = can_skb_prv(oskb)->skbcnt;
a5581ef4c   Oliver Hartkopp   can: introduce ne...
136
137
138
139
  		this_cpu_ptr(ro->uniq)->join_rx_count = 1;
  		/* drop first frame to check all enabled filters? */
  		if (ro->join_filters && ro->count > 1)
  			return;
514ac99c6   Oliver Hartkopp   can: fix multiple...
140
  	}
1fa17d4ba   Oliver Hartkopp   can: omit unneede...
141
  	/* clone the given skb to be able to enqueue it into the rcv queue */
1e55659ce   Oliver Hartkopp   can-raw: add msg_...
142
  	skb = skb_clone(oskb, GFP_ATOMIC);
1fa17d4ba   Oliver Hartkopp   can: omit unneede...
143
144
  	if (!skb)
  		return;
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
145

6a54dde84   Marc Kleine-Budde   can: raw: fix ind...
146
147
148
149
  	/* Put the datagram to the queue so that raw_recvmsg() can get
  	 * it from there. We need to pass the interface index to
  	 * raw_recvmsg(). We pass a whole struct sockaddr_can in
  	 * skb->cb containing the interface index.
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
150
  	 */
b4772ef87   Eyal Birger   net: use common m...
151
  	sock_skb_cb_check_size(sizeof(struct sockaddr_can));
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
152
153
  	addr = (struct sockaddr_can *)skb->cb;
  	memset(addr, 0, sizeof(*addr));
6a54dde84   Marc Kleine-Budde   can: raw: fix ind...
154
  	addr->can_family = AF_CAN;
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
155
  	addr->can_ifindex = skb->dev->ifindex;
1e55659ce   Oliver Hartkopp   can-raw: add msg_...
156
157
158
159
160
161
162
  	/* add CAN specific message flags for raw_recvmsg() */
  	pflags = raw_flags(skb);
  	*pflags = 0;
  	if (oskb->sk)
  		*pflags |= MSG_DONTROUTE;
  	if (oskb->sk == sk)
  		*pflags |= MSG_CONFIRM;
a219994bf   Urs Thuermann   [CAN]: Minor clea...
163
  	if (sock_queue_rcv_skb(sk, skb) < 0)
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
164
165
  		kfree_skb(skb);
  }
8e8cda6d7   Mario Kicherer   can: initial supp...
166
167
168
  static int raw_enable_filters(struct net *net, struct net_device *dev,
  			      struct sock *sk, struct can_filter *filter,
  			      int count)
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
169
170
171
172
173
  {
  	int err = 0;
  	int i;
  
  	for (i = 0; i < count; i++) {
8e8cda6d7   Mario Kicherer   can: initial supp...
174
  		err = can_rx_register(net, dev, filter[i].can_id,
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
175
  				      filter[i].can_mask,
f1712c737   Eric Dumazet   can: Fix kernel p...
176
  				      raw_rcv, sk, "raw", sk);
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
177
178
179
  		if (err) {
  			/* clean up successfully registered filters */
  			while (--i >= 0)
8e8cda6d7   Mario Kicherer   can: initial supp...
180
  				can_rx_unregister(net, dev, filter[i].can_id,
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
181
182
183
184
185
186
187
188
  						  filter[i].can_mask,
  						  raw_rcv, sk);
  			break;
  		}
  	}
  
  	return err;
  }
8e8cda6d7   Mario Kicherer   can: initial supp...
189
190
  static int raw_enable_errfilter(struct net *net, struct net_device *dev,
  				struct sock *sk, can_err_mask_t err_mask)
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
191
192
193
194
  {
  	int err = 0;
  
  	if (err_mask)
8e8cda6d7   Mario Kicherer   can: initial supp...
195
  		err = can_rx_register(net, dev, 0, err_mask | CAN_ERR_FLAG,
f1712c737   Eric Dumazet   can: Fix kernel p...
196
  				      raw_rcv, sk, "raw", sk);
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
197
198
199
  
  	return err;
  }
8e8cda6d7   Mario Kicherer   can: initial supp...
200
201
202
  static void raw_disable_filters(struct net *net, struct net_device *dev,
  				struct sock *sk, struct can_filter *filter,
  				int count)
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
203
204
205
206
  {
  	int i;
  
  	for (i = 0; i < count; i++)
8e8cda6d7   Mario Kicherer   can: initial supp...
207
208
  		can_rx_unregister(net, dev, filter[i].can_id,
  				  filter[i].can_mask, raw_rcv, sk);
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
209
  }
8e8cda6d7   Mario Kicherer   can: initial supp...
210
211
  static inline void raw_disable_errfilter(struct net *net,
  					 struct net_device *dev,
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
212
213
214
215
216
  					 struct sock *sk,
  					 can_err_mask_t err_mask)
  
  {
  	if (err_mask)
8e8cda6d7   Mario Kicherer   can: initial supp...
217
  		can_rx_unregister(net, dev, 0, err_mask | CAN_ERR_FLAG,
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
218
219
  				  raw_rcv, sk);
  }
8e8cda6d7   Mario Kicherer   can: initial supp...
220
221
  static inline void raw_disable_allfilters(struct net *net,
  					  struct net_device *dev,
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
222
223
224
  					  struct sock *sk)
  {
  	struct raw_sock *ro = raw_sk(sk);
8e8cda6d7   Mario Kicherer   can: initial supp...
225
226
  	raw_disable_filters(net, dev, sk, ro->filter, ro->count);
  	raw_disable_errfilter(net, dev, sk, ro->err_mask);
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
227
  }
8e8cda6d7   Mario Kicherer   can: initial supp...
228
229
  static int raw_enable_allfilters(struct net *net, struct net_device *dev,
  				 struct sock *sk)
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
230
231
232
  {
  	struct raw_sock *ro = raw_sk(sk);
  	int err;
8e8cda6d7   Mario Kicherer   can: initial supp...
233
  	err = raw_enable_filters(net, dev, sk, ro->filter, ro->count);
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
234
  	if (!err) {
8e8cda6d7   Mario Kicherer   can: initial supp...
235
  		err = raw_enable_errfilter(net, dev, sk, ro->err_mask);
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
236
  		if (err)
8e8cda6d7   Mario Kicherer   can: initial supp...
237
238
  			raw_disable_filters(net, dev, sk, ro->filter,
  					    ro->count);
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
239
240
241
242
243
244
  	}
  
  	return err;
  }
  
  static int raw_notifier(struct notifier_block *nb,
351638e7d   Jiri Pirko   net: pass info st...
245
  			unsigned long msg, void *ptr)
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
246
  {
351638e7d   Jiri Pirko   net: pass info st...
247
  	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
248
249
  	struct raw_sock *ro = container_of(nb, struct raw_sock, notifier);
  	struct sock *sk = &ro->sk;
8e8cda6d7   Mario Kicherer   can: initial supp...
250
  	if (!net_eq(dev_net(dev), sock_net(sk)))
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
251
252
253
254
255
256
257
258
259
  		return NOTIFY_DONE;
  
  	if (dev->type != ARPHRD_CAN)
  		return NOTIFY_DONE;
  
  	if (ro->ifindex != dev->ifindex)
  		return NOTIFY_DONE;
  
  	switch (msg) {
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
260
261
262
263
  	case NETDEV_UNREGISTER:
  		lock_sock(sk);
  		/* remove current filters & unregister */
  		if (ro->bound)
8e8cda6d7   Mario Kicherer   can: initial supp...
264
  			raw_disable_allfilters(dev_net(dev), dev, sk);
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
265
266
267
268
269
  
  		if (ro->count > 1)
  			kfree(ro->filter);
  
  		ro->ifindex = 0;
6a54dde84   Marc Kleine-Budde   can: raw: fix ind...
270
271
  		ro->bound = 0;
  		ro->count = 0;
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
  		release_sock(sk);
  
  		sk->sk_err = ENODEV;
  		if (!sock_flag(sk, SOCK_DEAD))
  			sk->sk_error_report(sk);
  		break;
  
  	case NETDEV_DOWN:
  		sk->sk_err = ENETDOWN;
  		if (!sock_flag(sk, SOCK_DEAD))
  			sk->sk_error_report(sk);
  		break;
  	}
  
  	return NOTIFY_DONE;
  }
  
  static int raw_init(struct sock *sk)
  {
  	struct raw_sock *ro = raw_sk(sk);
  
  	ro->bound            = 0;
  	ro->ifindex          = 0;
  
  	/* set default filter to single entry dfilter */
  	ro->dfilter.can_id   = 0;
  	ro->dfilter.can_mask = MASK_ALL;
  	ro->filter           = &ro->dfilter;
  	ro->count            = 1;
  
  	/* set default loopback behaviour */
  	ro->loopback         = 1;
  	ro->recv_own_msgs    = 0;
e2d265d3b   Oliver Hartkopp   canfd: add suppor...
305
  	ro->fd_frames        = 0;
a5581ef4c   Oliver Hartkopp   can: introduce ne...
306
  	ro->join_filters     = 0;
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
307

514ac99c6   Oliver Hartkopp   can: fix multiple...
308
309
310
311
  	/* alloc_percpu provides zero'ed memory */
  	ro->uniq = alloc_percpu(struct uniqframe);
  	if (unlikely(!ro->uniq))
  		return -ENOMEM;
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
312
313
314
315
316
317
318
319
320
321
322
  	/* set notifier */
  	ro->notifier.notifier_call = raw_notifier;
  
  	register_netdevice_notifier(&ro->notifier);
  
  	return 0;
  }
  
  static int raw_release(struct socket *sock)
  {
  	struct sock *sk = sock->sk;
10022a6c6   Oliver Hartkopp   can: add missing ...
323
324
325
326
327
328
  	struct raw_sock *ro;
  
  	if (!sk)
  		return 0;
  
  	ro = raw_sk(sk);
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
329
330
331
332
333
334
335
336
337
  
  	unregister_netdevice_notifier(&ro->notifier);
  
  	lock_sock(sk);
  
  	/* remove current filters & unregister */
  	if (ro->bound) {
  		if (ro->ifindex) {
  			struct net_device *dev;
8e8cda6d7   Mario Kicherer   can: initial supp...
338
  			dev = dev_get_by_index(sock_net(sk), ro->ifindex);
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
339
  			if (dev) {
8e8cda6d7   Mario Kicherer   can: initial supp...
340
  				raw_disable_allfilters(dev_net(dev), dev, sk);
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
341
342
  				dev_put(dev);
  			}
bff100406   Marc Kleine-Budde   can: raw: balance...
343
  		} else {
8e8cda6d7   Mario Kicherer   can: initial supp...
344
  			raw_disable_allfilters(sock_net(sk), NULL, sk);
bff100406   Marc Kleine-Budde   can: raw: balance...
345
  		}
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
346
347
348
349
350
351
  	}
  
  	if (ro->count > 1)
  		kfree(ro->filter);
  
  	ro->ifindex = 0;
6a54dde84   Marc Kleine-Budde   can: raw: fix ind...
352
353
  	ro->bound = 0;
  	ro->count = 0;
514ac99c6   Oliver Hartkopp   can: fix multiple...
354
  	free_percpu(ro->uniq);
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
355

f7e5cc0c4   Lothar Waßmann   net/can bugfix: u...
356
357
  	sock_orphan(sk);
  	sock->sk = NULL;
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
358
359
360
361
362
363
364
365
366
367
368
369
370
371
  	release_sock(sk);
  	sock_put(sk);
  
  	return 0;
  }
  
  static int raw_bind(struct socket *sock, struct sockaddr *uaddr, int len)
  {
  	struct sockaddr_can *addr = (struct sockaddr_can *)uaddr;
  	struct sock *sk = sock->sk;
  	struct raw_sock *ro = raw_sk(sk);
  	int ifindex;
  	int err = 0;
  	int notify_enetdown = 0;
9868b5d44   Kurt Van Dijck   can: introduce CA...
372
  	if (len < CAN_REQUIRED_SIZE(*addr, can_ifindex))
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
373
  		return -EINVAL;
adb552c31   Marc Kleine-Budde   can: raw: raw_bin...
374
375
  	if (addr->can_family != AF_CAN)
  		return -EINVAL;
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
376
377
378
379
380
381
382
383
  
  	lock_sock(sk);
  
  	if (ro->bound && addr->can_ifindex == ro->ifindex)
  		goto out;
  
  	if (addr->can_ifindex) {
  		struct net_device *dev;
8e8cda6d7   Mario Kicherer   can: initial supp...
384
  		dev = dev_get_by_index(sock_net(sk), addr->can_ifindex);
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
  		if (!dev) {
  			err = -ENODEV;
  			goto out;
  		}
  		if (dev->type != ARPHRD_CAN) {
  			dev_put(dev);
  			err = -ENODEV;
  			goto out;
  		}
  		if (!(dev->flags & IFF_UP))
  			notify_enetdown = 1;
  
  		ifindex = dev->ifindex;
  
  		/* filters set by default/setsockopt */
8e8cda6d7   Mario Kicherer   can: initial supp...
400
  		err = raw_enable_allfilters(sock_net(sk), dev, sk);
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
401
  		dev_put(dev);
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
402
403
404
405
  	} else {
  		ifindex = 0;
  
  		/* filters set by default/setsockopt */
8e8cda6d7   Mario Kicherer   can: initial supp...
406
  		err = raw_enable_allfilters(sock_net(sk), NULL, sk);
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
407
408
409
410
411
412
413
  	}
  
  	if (!err) {
  		if (ro->bound) {
  			/* unregister old filters */
  			if (ro->ifindex) {
  				struct net_device *dev;
8e8cda6d7   Mario Kicherer   can: initial supp...
414
415
  				dev = dev_get_by_index(sock_net(sk),
  						       ro->ifindex);
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
416
  				if (dev) {
8e8cda6d7   Mario Kicherer   can: initial supp...
417
418
  					raw_disable_allfilters(dev_net(dev),
  							       dev, sk);
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
419
420
  					dev_put(dev);
  				}
bff100406   Marc Kleine-Budde   can: raw: balance...
421
  			} else {
8e8cda6d7   Mario Kicherer   can: initial supp...
422
  				raw_disable_allfilters(sock_net(sk), NULL, sk);
bff100406   Marc Kleine-Budde   can: raw: balance...
423
  			}
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
  		}
  		ro->ifindex = ifindex;
  		ro->bound = 1;
  	}
  
   out:
  	release_sock(sk);
  
  	if (notify_enetdown) {
  		sk->sk_err = ENETDOWN;
  		if (!sock_flag(sk, SOCK_DEAD))
  			sk->sk_error_report(sk);
  	}
  
  	return err;
  }
  
  static int raw_getname(struct socket *sock, struct sockaddr *uaddr,
9b2c45d47   Denys Vlasenko   net: make getname...
442
  		       int peer)
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
443
444
445
446
447
448
449
  {
  	struct sockaddr_can *addr = (struct sockaddr_can *)uaddr;
  	struct sock *sk = sock->sk;
  	struct raw_sock *ro = raw_sk(sk);
  
  	if (peer)
  		return -EOPNOTSUPP;
e84b90ae5   Eric Dumazet   can: Fix raw_getn...
450
  	memset(addr, 0, sizeof(*addr));
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
451
452
  	addr->can_family  = AF_CAN;
  	addr->can_ifindex = ro->ifindex;
9b2c45d47   Denys Vlasenko   net: make getname...
453
  	return sizeof(*addr);
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
454
455
456
  }
  
  static int raw_setsockopt(struct socket *sock, int level, int optname,
a7b75c5a8   Christoph Hellwig   net: pass a sockp...
457
  			  sockptr_t optval, unsigned int optlen)
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
458
459
460
461
462
463
464
465
466
467
468
469
  {
  	struct sock *sk = sock->sk;
  	struct raw_sock *ro = raw_sk(sk);
  	struct can_filter *filter = NULL;  /* dyn. alloc'ed filters */
  	struct can_filter sfilter;         /* single filter */
  	struct net_device *dev = NULL;
  	can_err_mask_t err_mask = 0;
  	int count = 0;
  	int err = 0;
  
  	if (level != SOL_CAN_RAW)
  		return -EINVAL;
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
470
471
  
  	switch (optname) {
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
472
473
474
  	case CAN_RAW_FILTER:
  		if (optlen % sizeof(struct can_filter) != 0)
  			return -EINVAL;
332b05ca7   Marc Kleine-Budde   can: raw: raw_set...
475
476
  		if (optlen > CAN_RAW_FILTER_MAX * sizeof(struct can_filter))
  			return -EINVAL;
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
477
478
479
480
  		count = optlen / sizeof(struct can_filter);
  
  		if (count > 1) {
  			/* filter does not fit into dfilter => alloc space */
a7b75c5a8   Christoph Hellwig   net: pass a sockp...
481
  			filter = memdup_sockptr(optval, optlen);
16dff9180   Julia Lawall   net/can: Use memd...
482
483
  			if (IS_ERR(filter))
  				return PTR_ERR(filter);
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
484
  		} else if (count == 1) {
a7b75c5a8   Christoph Hellwig   net: pass a sockp...
485
  			if (copy_from_sockptr(&sfilter, optval, sizeof(sfilter)))
3f91bd420   Sam Ravnborg   can: Fix copy_fro...
486
  				return -EFAULT;
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
487
488
489
490
491
  		}
  
  		lock_sock(sk);
  
  		if (ro->bound && ro->ifindex)
8e8cda6d7   Mario Kicherer   can: initial supp...
492
  			dev = dev_get_by_index(sock_net(sk), ro->ifindex);
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
493
494
495
496
  
  		if (ro->bound) {
  			/* (try to) register the new filters */
  			if (count == 1)
8e8cda6d7   Mario Kicherer   can: initial supp...
497
498
  				err = raw_enable_filters(sock_net(sk), dev, sk,
  							 &sfilter, 1);
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
499
  			else
8e8cda6d7   Mario Kicherer   can: initial supp...
500
501
  				err = raw_enable_filters(sock_net(sk), dev, sk,
  							 filter, count);
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
502
503
504
  			if (err) {
  				if (count > 1)
  					kfree(filter);
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
505
506
507
508
  				goto out_fil;
  			}
  
  			/* remove old filter registrations */
8e8cda6d7   Mario Kicherer   can: initial supp...
509
510
  			raw_disable_filters(sock_net(sk), dev, sk, ro->filter,
  					    ro->count);
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
  		}
  
  		/* remove old filter space */
  		if (ro->count > 1)
  			kfree(ro->filter);
  
  		/* link new filters to the socket */
  		if (count == 1) {
  			/* copy filter data for single filter */
  			ro->dfilter = sfilter;
  			filter = &ro->dfilter;
  		}
  		ro->filter = filter;
  		ro->count  = count;
  
   out_fil:
  		if (dev)
  			dev_put(dev);
  
  		release_sock(sk);
  
  		break;
  
  	case CAN_RAW_ERR_FILTER:
  		if (optlen != sizeof(err_mask))
  			return -EINVAL;
a7b75c5a8   Christoph Hellwig   net: pass a sockp...
537
  		if (copy_from_sockptr(&err_mask, optval, optlen))
3f91bd420   Sam Ravnborg   can: Fix copy_fro...
538
  			return -EFAULT;
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
539
540
541
542
543
544
  
  		err_mask &= CAN_ERR_MASK;
  
  		lock_sock(sk);
  
  		if (ro->bound && ro->ifindex)
8e8cda6d7   Mario Kicherer   can: initial supp...
545
  			dev = dev_get_by_index(sock_net(sk), ro->ifindex);
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
546
547
548
549
  
  		/* remove current error mask */
  		if (ro->bound) {
  			/* (try to) register the new err_mask */
8e8cda6d7   Mario Kicherer   can: initial supp...
550
551
  			err = raw_enable_errfilter(sock_net(sk), dev, sk,
  						   err_mask);
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
552
553
554
555
556
  
  			if (err)
  				goto out_err;
  
  			/* remove old err_mask registration */
8e8cda6d7   Mario Kicherer   can: initial supp...
557
558
  			raw_disable_errfilter(sock_net(sk), dev, sk,
  					      ro->err_mask);
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
  		}
  
  		/* link new err_mask to the socket */
  		ro->err_mask = err_mask;
  
   out_err:
  		if (dev)
  			dev_put(dev);
  
  		release_sock(sk);
  
  		break;
  
  	case CAN_RAW_LOOPBACK:
  		if (optlen != sizeof(ro->loopback))
  			return -EINVAL;
a7b75c5a8   Christoph Hellwig   net: pass a sockp...
575
  		if (copy_from_sockptr(&ro->loopback, optval, optlen))
3f91bd420   Sam Ravnborg   can: Fix copy_fro...
576
  			return -EFAULT;
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
577
578
579
580
581
582
  
  		break;
  
  	case CAN_RAW_RECV_OWN_MSGS:
  		if (optlen != sizeof(ro->recv_own_msgs))
  			return -EINVAL;
a7b75c5a8   Christoph Hellwig   net: pass a sockp...
583
  		if (copy_from_sockptr(&ro->recv_own_msgs, optval, optlen))
3f91bd420   Sam Ravnborg   can: Fix copy_fro...
584
  			return -EFAULT;
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
585
586
  
  		break;
e2d265d3b   Oliver Hartkopp   canfd: add suppor...
587
588
589
  	case CAN_RAW_FD_FRAMES:
  		if (optlen != sizeof(ro->fd_frames))
  			return -EINVAL;
a7b75c5a8   Christoph Hellwig   net: pass a sockp...
590
  		if (copy_from_sockptr(&ro->fd_frames, optval, optlen))
e2d265d3b   Oliver Hartkopp   canfd: add suppor...
591
592
593
  			return -EFAULT;
  
  		break;
a5581ef4c   Oliver Hartkopp   can: introduce ne...
594
595
596
  	case CAN_RAW_JOIN_FILTERS:
  		if (optlen != sizeof(ro->join_filters))
  			return -EINVAL;
a7b75c5a8   Christoph Hellwig   net: pass a sockp...
597
  		if (copy_from_sockptr(&ro->join_filters, optval, optlen))
a5581ef4c   Oliver Hartkopp   can: introduce ne...
598
599
600
  			return -EFAULT;
  
  		break;
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
  	default:
  		return -ENOPROTOOPT;
  	}
  	return err;
  }
  
  static int raw_getsockopt(struct socket *sock, int level, int optname,
  			  char __user *optval, int __user *optlen)
  {
  	struct sock *sk = sock->sk;
  	struct raw_sock *ro = raw_sk(sk);
  	int len;
  	void *val;
  	int err = 0;
  
  	if (level != SOL_CAN_RAW)
  		return -EINVAL;
  	if (get_user(len, optlen))
  		return -EFAULT;
  	if (len < 0)
  		return -EINVAL;
  
  	switch (optname) {
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
624
625
626
627
  	case CAN_RAW_FILTER:
  		lock_sock(sk);
  		if (ro->count > 0) {
  			int fsize = ro->count * sizeof(struct can_filter);
d5e4ecac8   Marc Kleine-Budde   can: raw: remove ...
628

c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
629
630
  			if (len > fsize)
  				len = fsize;
653252c23   Pavel Emelyanov   net: Fix wrong in...
631
632
  			if (copy_to_user(optval, ro->filter, len))
  				err = -EFAULT;
bff100406   Marc Kleine-Budde   can: raw: balance...
633
  		} else {
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
634
  			len = 0;
bff100406   Marc Kleine-Budde   can: raw: balance...
635
  		}
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
  		release_sock(sk);
  
  		if (!err)
  			err = put_user(len, optlen);
  		return err;
  
  	case CAN_RAW_ERR_FILTER:
  		if (len > sizeof(can_err_mask_t))
  			len = sizeof(can_err_mask_t);
  		val = &ro->err_mask;
  		break;
  
  	case CAN_RAW_LOOPBACK:
  		if (len > sizeof(int))
  			len = sizeof(int);
  		val = &ro->loopback;
  		break;
  
  	case CAN_RAW_RECV_OWN_MSGS:
  		if (len > sizeof(int))
  			len = sizeof(int);
  		val = &ro->recv_own_msgs;
  		break;
e2d265d3b   Oliver Hartkopp   canfd: add suppor...
659
660
661
662
663
  	case CAN_RAW_FD_FRAMES:
  		if (len > sizeof(int))
  			len = sizeof(int);
  		val = &ro->fd_frames;
  		break;
a5581ef4c   Oliver Hartkopp   can: introduce ne...
664
665
666
667
668
  	case CAN_RAW_JOIN_FILTERS:
  		if (len > sizeof(int))
  			len = sizeof(int);
  		val = &ro->join_filters;
  		break;
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
669
670
671
672
673
674
675
676
677
678
  	default:
  		return -ENOPROTOOPT;
  	}
  
  	if (put_user(len, optlen))
  		return -EFAULT;
  	if (copy_to_user(optval, val, len))
  		return -EFAULT;
  	return 0;
  }
1b7841404   Ying Xue   net: Remove iocb ...
679
  static int raw_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
680
681
682
683
684
685
686
687
688
  {
  	struct sock *sk = sock->sk;
  	struct raw_sock *ro = raw_sk(sk);
  	struct sk_buff *skb;
  	struct net_device *dev;
  	int ifindex;
  	int err;
  
  	if (msg->msg_name) {
342dfc306   Steffen Hurrle   net: add build-ti...
689
  		DECLARE_SOCKADDR(struct sockaddr_can *, addr, msg->msg_name);
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
690

9868b5d44   Kurt Van Dijck   can: introduce CA...
691
  		if (msg->msg_namelen < CAN_REQUIRED_SIZE(*addr, can_ifindex))
5e5073280   Kurt Van Dijck   can: test size of...
692
  			return -EINVAL;
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
693
694
695
696
  		if (addr->can_family != AF_CAN)
  			return -EINVAL;
  
  		ifindex = addr->can_ifindex;
bff100406   Marc Kleine-Budde   can: raw: balance...
697
  	} else {
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
698
  		ifindex = ro->ifindex;
bff100406   Marc Kleine-Budde   can: raw: balance...
699
  	}
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
700

a43608fa7   Oliver Hartkopp   can: raw: check f...
701
702
703
704
705
706
  	dev = dev_get_by_index(sock_net(sk), ifindex);
  	if (!dev)
  		return -ENXIO;
  
  	err = -EINVAL;
  	if (ro->fd_frames && dev->mtu == CANFD_MTU) {
e2d265d3b   Oliver Hartkopp   canfd: add suppor...
707
  		if (unlikely(size != CANFD_MTU && size != CAN_MTU))
a43608fa7   Oliver Hartkopp   can: raw: check f...
708
  			goto put_dev;
e2d265d3b   Oliver Hartkopp   canfd: add suppor...
709
710
  	} else {
  		if (unlikely(size != CAN_MTU))
a43608fa7   Oliver Hartkopp   can: raw: check f...
711
  			goto put_dev;
e2d265d3b   Oliver Hartkopp   canfd: add suppor...
712
  	}
7f2d38eb7   Oliver Hartkopp   can: add sanity c...
713

156c2bb9f   Oliver Hartkopp   can: add private ...
714
715
  	skb = sock_alloc_send_skb(sk, size + sizeof(struct can_skb_priv),
  				  msg->msg_flags & MSG_DONTWAIT, &err);
ebad5c098   Ilpo Järvinen   can: merge error ...
716
717
  	if (!skb)
  		goto put_dev;
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
718

2bf3440d7   Oliver Hartkopp   can: rework skb r...
719
720
  	can_skb_reserve(skb);
  	can_skb_prv(skb)->ifindex = dev->ifindex;
d3b58c47d   Oliver Hartkopp   can: replace time...
721
  	can_skb_prv(skb)->skbcnt = 0;
156c2bb9f   Oliver Hartkopp   can: add private ...
722

6ce8e9ce5   Al Viro   new helper: memcp...
723
  	err = memcpy_from_msg(skb_put(skb, size), msg, size);
ebad5c098   Ilpo Järvinen   can: merge error ...
724
725
  	if (err < 0)
  		goto free_skb;
bf84a0106   Daniel Borkmann   net: sock: make s...
726

8f932f762   Willem de Bruijn   net: add missing ...
727
  	skb_setup_tx_timestamp(skb, sk->sk_tsflags);
cff0d6e6e   Oliver Hartkopp   can-raw: Fix skb_...
728

c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
729
  	skb->dev = dev;
6a54dde84   Marc Kleine-Budde   can: raw: fix ind...
730
  	skb->sk = sk;
bb5ecb0c6   Rostislav Lisovy   can: Propagate SO...
731
  	skb->priority = sk->sk_priority;
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
732
733
734
735
736
737
  
  	err = can_send(skb, ro->loopback);
  
  	dev_put(dev);
  
  	if (err)
ebad5c098   Ilpo Järvinen   can: merge error ...
738
  		goto send_failed;
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
739
740
  
  	return size;
ebad5c098   Ilpo Järvinen   can: merge error ...
741
742
743
744
745
746
747
  
  free_skb:
  	kfree_skb(skb);
  put_dev:
  	dev_put(dev);
  send_failed:
  	return err;
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
748
  }
1b7841404   Ying Xue   net: Remove iocb ...
749
750
  static int raw_recvmsg(struct socket *sock, struct msghdr *msg, size_t size,
  		       int flags)
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
751
752
753
  {
  	struct sock *sk = sock->sk;
  	struct sk_buff *skb;
a219994bf   Urs Thuermann   [CAN]: Minor clea...
754
  	int err = 0;
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
755
  	int noblock;
6a54dde84   Marc Kleine-Budde   can: raw: fix ind...
756
757
  	noblock = flags & MSG_DONTWAIT;
  	flags &= ~MSG_DONTWAIT;
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
758

eb88531bd   Vincent Mailhol   can: raw: add mis...
759
760
761
  	if (flags & MSG_ERRQUEUE)
  		return sock_recv_errqueue(sk, msg, size,
  					  SOL_CAN_RAW, SCM_CAN_RAW_ERRQUEUE);
a219994bf   Urs Thuermann   [CAN]: Minor clea...
762
  	skb = skb_recv_datagram(sk, flags, noblock, &err);
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
763
  	if (!skb)
a219994bf   Urs Thuermann   [CAN]: Minor clea...
764
  		return err;
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
765

821047c40   Oliver Hartkopp   can: remove CAN F...
766
  	if (size < skb->len)
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
767
768
  		msg->msg_flags |= MSG_TRUNC;
  	else
821047c40   Oliver Hartkopp   can: remove CAN F...
769
  		size = skb->len;
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
770

7eab8d9e8   Al Viro   new helper: memcp...
771
  	err = memcpy_to_msg(msg, skb->data, size);
a219994bf   Urs Thuermann   [CAN]: Minor clea...
772
  	if (err < 0) {
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
773
  		skb_free_datagram(sk, skb);
a219994bf   Urs Thuermann   [CAN]: Minor clea...
774
  		return err;
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
775
  	}
3b885787e   Neil Horman   net: Generalize s...
776
  	sock_recv_ts_and_drops(msg, sk, skb);
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
777
778
  
  	if (msg->msg_name) {
342dfc306   Steffen Hurrle   net: add build-ti...
779
  		__sockaddr_check_size(sizeof(struct sockaddr_can));
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
780
781
782
  		msg->msg_namelen = sizeof(struct sockaddr_can);
  		memcpy(msg->msg_name, skb->cb, msg->msg_namelen);
  	}
1e55659ce   Oliver Hartkopp   can-raw: add msg_...
783
784
  	/* assign the flags that have been recorded in raw_rcv() */
  	msg->msg_flags |= *(raw_flags(skb));
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
785
786
787
788
  	skb_free_datagram(sk, skb);
  
  	return size;
  }
af0b1470b   Marc Kleine-Budde   can: raw: raw_soc...
789
790
  static int raw_sock_no_ioctlcmd(struct socket *sock, unsigned int cmd,
  				unsigned long arg)
473d924d7   Oliver Hartkopp   can: fix ioctl fu...
791
792
793
794
  {
  	/* no ioctls for socket layer -> hand it down to NIC layer */
  	return -ENOIOCTLCMD;
  }
53914b679   Oliver Hartkopp   can: make struct ...
795
  static const struct proto_ops raw_ops = {
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
796
797
798
799
800
801
802
  	.family        = PF_CAN,
  	.release       = raw_release,
  	.bind          = raw_bind,
  	.connect       = sock_no_connect,
  	.socketpair    = sock_no_socketpair,
  	.accept        = sock_no_accept,
  	.getname       = raw_getname,
a11e1d432   Linus Torvalds   Revert changes to...
803
  	.poll          = datagram_poll,
473d924d7   Oliver Hartkopp   can: fix ioctl fu...
804
  	.ioctl         = raw_sock_no_ioctlcmd,
c7cbdbf29   Arnd Bergmann   net: rework SIOCG...
805
  	.gettstamp     = sock_gettstamp,
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
  	.listen        = sock_no_listen,
  	.shutdown      = sock_no_shutdown,
  	.setsockopt    = raw_setsockopt,
  	.getsockopt    = raw_getsockopt,
  	.sendmsg       = raw_sendmsg,
  	.recvmsg       = raw_recvmsg,
  	.mmap          = sock_no_mmap,
  	.sendpage      = sock_no_sendpage,
  };
  
  static struct proto raw_proto __read_mostly = {
  	.name       = "CAN_RAW",
  	.owner      = THIS_MODULE,
  	.obj_size   = sizeof(struct raw_sock),
  	.init       = raw_init,
  };
1650629d1   Kurt Van Dijck   can: make struct ...
822
  static const struct can_proto raw_can_proto = {
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
823
824
  	.type       = SOCK_RAW,
  	.protocol   = CAN_RAW,
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
825
826
827
828
829
830
831
  	.ops        = &raw_ops,
  	.prot       = &raw_proto,
  };
  
  static __init int raw_module_init(void)
  {
  	int err;
f726f3d37   Oliver Hartkopp   can: remove obsol...
832
833
  	pr_info("can: raw protocol
  ");
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
834
835
836
  
  	err = can_proto_register(&raw_can_proto);
  	if (err < 0)
d956b1a87   Marc Kleine-Budde   can: raw: raw_mod...
837
838
  		pr_err("can: registration of raw protocol failed
  ");
c18ce101f   Oliver Hartkopp   [CAN]: Add raw pr...
839
840
841
842
843
844
845
846
847
848
849
  
  	return err;
  }
  
  static __exit void raw_module_exit(void)
  {
  	can_proto_unregister(&raw_can_proto);
  }
  
  module_init(raw_module_init);
  module_exit(raw_module_exit);