aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2013-01-28 00:19:34 -0500
committerDavid S. Miller <davem@davemloft.net>2013-01-28 00:19:34 -0500
commit61550022b9586972082904b80de26a464c558437 (patch)
tree590c21eed5f723162d3821a398b6d3831f75a488 /net
parent0e36cbb344575e481167e090f0926701f83207d6 (diff)
parente6afa00a1409bc3bceed9ccb33111519463dfe7b (diff)
Merge branch 'for-davem' of git://gitorious.org/linux-can/linux-can-next
Marc Kleine-Budde says: ==================== this is a pull-request for net-next/master. There is are 9 patches by Fabio Baltieri and Kurt Van Dijck which add LED infrastructure and support for CAN devices. Bernd Krumboeck adds a driver for the USB CAN adapter from 8 devices. Oliver Hartkopp improves the CAN gateway functionality. There are 4 patches by me, which clean up the CAN's Kconfig. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/can/Kconfig13
-rw-r--r--net/can/bcm.c12
-rw-r--r--net/can/gw.c74
-rw-r--r--net/can/raw.c8
4 files changed, 80 insertions, 27 deletions
diff --git a/net/can/Kconfig b/net/can/Kconfig
index 03200699d274..a15c0e0d1fc7 100644
--- a/net/can/Kconfig
+++ b/net/can/Kconfig
@@ -16,10 +16,11 @@ menuconfig CAN
16 If you want CAN support you should say Y here and also to the 16 If you want CAN support you should say Y here and also to the
17 specific driver for your controller(s) below. 17 specific driver for your controller(s) below.
18 18
19if CAN
20
19config CAN_RAW 21config CAN_RAW
20 tristate "Raw CAN Protocol (raw access with CAN-ID filtering)" 22 tristate "Raw CAN Protocol (raw access with CAN-ID filtering)"
21 depends on CAN 23 default y
22 default N
23 ---help--- 24 ---help---
24 The raw CAN protocol option offers access to the CAN bus via 25 The raw CAN protocol option offers access to the CAN bus via
25 the BSD socket API. You probably want to use the raw socket in 26 the BSD socket API. You probably want to use the raw socket in
@@ -29,8 +30,7 @@ config CAN_RAW
29 30
30config CAN_BCM 31config CAN_BCM
31 tristate "Broadcast Manager CAN Protocol (with content filtering)" 32 tristate "Broadcast Manager CAN Protocol (with content filtering)"
32 depends on CAN 33 default y
33 default N
34 ---help--- 34 ---help---
35 The Broadcast Manager offers content filtering, timeout monitoring, 35 The Broadcast Manager offers content filtering, timeout monitoring,
36 sending of RTR frames, and cyclic CAN messages without permanent user 36 sending of RTR frames, and cyclic CAN messages without permanent user
@@ -42,8 +42,7 @@ config CAN_BCM
42 42
43config CAN_GW 43config CAN_GW
44 tristate "CAN Gateway/Router (with netlink configuration)" 44 tristate "CAN Gateway/Router (with netlink configuration)"
45 depends on CAN 45 default y
46 default N
47 ---help--- 46 ---help---
48 The CAN Gateway/Router is used to route (and modify) CAN frames. 47 The CAN Gateway/Router is used to route (and modify) CAN frames.
49 It is based on the PF_CAN core infrastructure for msg filtering and 48 It is based on the PF_CAN core infrastructure for msg filtering and
@@ -53,3 +52,5 @@ config CAN_GW
53 by the netlink configuration interface known e.g. from iptables. 52 by the netlink configuration interface known e.g. from iptables.
54 53
55source "drivers/net/can/Kconfig" 54source "drivers/net/can/Kconfig"
55
56endif
diff --git a/net/can/bcm.c b/net/can/bcm.c
index 969b7cdff59d..ccc27b9e8384 100644
--- a/net/can/bcm.c
+++ b/net/can/bcm.c
@@ -54,6 +54,7 @@
54#include <linux/skbuff.h> 54#include <linux/skbuff.h>
55#include <linux/can.h> 55#include <linux/can.h>
56#include <linux/can/core.h> 56#include <linux/can/core.h>
57#include <linux/can/skb.h>
57#include <linux/can/bcm.h> 58#include <linux/can/bcm.h>
58#include <linux/slab.h> 59#include <linux/slab.h>
59#include <net/sock.h> 60#include <net/sock.h>
@@ -256,10 +257,13 @@ static void bcm_can_tx(struct bcm_op *op)
256 return; 257 return;
257 } 258 }
258 259
259 skb = alloc_skb(CFSIZ, gfp_any()); 260 skb = alloc_skb(CFSIZ + sizeof(struct can_skb_priv), gfp_any());
260 if (!skb) 261 if (!skb)
261 goto out; 262 goto out;
262 263
264 skb_reserve(skb, sizeof(struct can_skb_priv));
265 ((struct can_skb_priv *)(skb->head))->ifindex = dev->ifindex;
266
263 memcpy(skb_put(skb, CFSIZ), cf, CFSIZ); 267 memcpy(skb_put(skb, CFSIZ), cf, CFSIZ);
264 268
265 /* send with loopback */ 269 /* send with loopback */
@@ -1199,11 +1203,12 @@ static int bcm_tx_send(struct msghdr *msg, int ifindex, struct sock *sk)
1199 if (!ifindex) 1203 if (!ifindex)
1200 return -ENODEV; 1204 return -ENODEV;
1201 1205
1202 skb = alloc_skb(CFSIZ, GFP_KERNEL); 1206 skb = alloc_skb(CFSIZ + sizeof(struct can_skb_priv), GFP_KERNEL);
1203
1204 if (!skb) 1207 if (!skb)
1205 return -ENOMEM; 1208 return -ENOMEM;
1206 1209
1210 skb_reserve(skb, sizeof(struct can_skb_priv));
1211
1207 err = memcpy_fromiovec(skb_put(skb, CFSIZ), msg->msg_iov, CFSIZ); 1212 err = memcpy_fromiovec(skb_put(skb, CFSIZ), msg->msg_iov, CFSIZ);
1208 if (err < 0) { 1213 if (err < 0) {
1209 kfree_skb(skb); 1214 kfree_skb(skb);
@@ -1216,6 +1221,7 @@ static int bcm_tx_send(struct msghdr *msg, int ifindex, struct sock *sk)
1216 return -ENODEV; 1221 return -ENODEV;
1217 } 1222 }
1218 1223
1224 ((struct can_skb_priv *)(skb->head))->ifindex = dev->ifindex;
1219 skb->dev = dev; 1225 skb->dev = dev;
1220 skb->sk = sk; 1226 skb->sk = sk;
1221 err = can_send(skb, 1); /* send with loopback */ 1227 err = can_send(skb, 1); /* send with loopback */
diff --git a/net/can/gw.c b/net/can/gw.c
index 574dda78eb0f..acdd4656cc3b 100644
--- a/net/can/gw.c
+++ b/net/can/gw.c
@@ -42,6 +42,7 @@
42#include <linux/module.h> 42#include <linux/module.h>
43#include <linux/init.h> 43#include <linux/init.h>
44#include <linux/types.h> 44#include <linux/types.h>
45#include <linux/kernel.h>
45#include <linux/list.h> 46#include <linux/list.h>
46#include <linux/spinlock.h> 47#include <linux/spinlock.h>
47#include <linux/rcupdate.h> 48#include <linux/rcupdate.h>
@@ -52,19 +53,31 @@
52#include <linux/skbuff.h> 53#include <linux/skbuff.h>
53#include <linux/can.h> 54#include <linux/can.h>
54#include <linux/can/core.h> 55#include <linux/can/core.h>
56#include <linux/can/skb.h>
55#include <linux/can/gw.h> 57#include <linux/can/gw.h>
56#include <net/rtnetlink.h> 58#include <net/rtnetlink.h>
57#include <net/net_namespace.h> 59#include <net/net_namespace.h>
58#include <net/sock.h> 60#include <net/sock.h>
59 61
60#define CAN_GW_VERSION "20101209" 62#define CAN_GW_VERSION "20130117"
61static __initconst const char banner[] = 63#define CAN_GW_NAME "can-gw"
62 KERN_INFO "can: netlink gateway (rev " CAN_GW_VERSION ")\n";
63 64
64MODULE_DESCRIPTION("PF_CAN netlink gateway"); 65MODULE_DESCRIPTION("PF_CAN netlink gateway");
65MODULE_LICENSE("Dual BSD/GPL"); 66MODULE_LICENSE("Dual BSD/GPL");
66MODULE_AUTHOR("Oliver Hartkopp <oliver.hartkopp@volkswagen.de>"); 67MODULE_AUTHOR("Oliver Hartkopp <oliver.hartkopp@volkswagen.de>");
67MODULE_ALIAS("can-gw"); 68MODULE_ALIAS(CAN_GW_NAME);
69
70#define CGW_MIN_HOPS 1
71#define CGW_MAX_HOPS 6
72#define CGW_DEFAULT_HOPS 1
73
74static unsigned int max_hops __read_mostly = CGW_DEFAULT_HOPS;
75module_param(max_hops, uint, S_IRUGO);
76MODULE_PARM_DESC(max_hops,
77 "maximum " CAN_GW_NAME " routing hops for CAN frames "
78 "(valid values: " __stringify(CGW_MIN_HOPS) "-"
79 __stringify(CGW_MAX_HOPS) " hops, "
80 "default: " __stringify(CGW_DEFAULT_HOPS) ")");
68 81
69static HLIST_HEAD(cgw_list); 82static HLIST_HEAD(cgw_list);
70static struct notifier_block notifier; 83static struct notifier_block notifier;
@@ -118,6 +131,7 @@ struct cgw_job {
118 struct rcu_head rcu; 131 struct rcu_head rcu;
119 u32 handled_frames; 132 u32 handled_frames;
120 u32 dropped_frames; 133 u32 dropped_frames;
134 u32 deleted_frames;
121 struct cf_mod mod; 135 struct cf_mod mod;
122 union { 136 union {
123 /* CAN frame data source */ 137 /* CAN frame data source */
@@ -338,15 +352,40 @@ static void can_can_gw_rcv(struct sk_buff *skb, void *data)
338 struct sk_buff *nskb; 352 struct sk_buff *nskb;
339 int modidx = 0; 353 int modidx = 0;
340 354
341 /* do not handle already routed frames - see comment below */ 355 /*
342 if (skb_mac_header_was_set(skb)) 356 * Do not handle CAN frames routed more than 'max_hops' times.
357 * In general we should never catch this delimiter which is intended
358 * to cover a misconfiguration protection (e.g. circular CAN routes).
359 *
360 * The Controller Area Network controllers only accept CAN frames with
361 * correct CRCs - which are not visible in the controller registers.
362 * According to skbuff.h documentation the csum_start element for IP
363 * checksums is undefined/unsued when ip_summed == CHECKSUM_UNNECESSARY.
364 * Only CAN skbs can be processed here which already have this property.
365 */
366
367#define cgw_hops(skb) ((skb)->csum_start)
368
369 BUG_ON(skb->ip_summed != CHECKSUM_UNNECESSARY);
370
371 if (cgw_hops(skb) >= max_hops) {
372 /* indicate deleted frames due to misconfiguration */
373 gwj->deleted_frames++;
343 return; 374 return;
375 }
344 376
345 if (!(gwj->dst.dev->flags & IFF_UP)) { 377 if (!(gwj->dst.dev->flags & IFF_UP)) {
346 gwj->dropped_frames++; 378 gwj->dropped_frames++;
347 return; 379 return;
348 } 380 }
349 381
382 /* is sending the skb back to the incoming interface not allowed? */
383 if (!(gwj->flags & CGW_FLAGS_CAN_IIF_TX_OK) &&
384 skb_headroom(skb) == sizeof(struct can_skb_priv) &&
385 (((struct can_skb_priv *)(skb->head))->ifindex ==
386 gwj->dst.dev->ifindex))
387 return;
388
350 /* 389 /*
351 * clone the given skb, which has not been done in can_rcv() 390 * clone the given skb, which has not been done in can_rcv()
352 * 391 *
@@ -363,15 +402,8 @@ static void can_can_gw_rcv(struct sk_buff *skb, void *data)
363 return; 402 return;
364 } 403 }
365 404
366 /* 405 /* put the incremented hop counter in the cloned skb */
367 * Mark routed frames by setting some mac header length which is 406 cgw_hops(nskb) = cgw_hops(skb) + 1;
368 * not relevant for the CAN frames located in the skb->data section.
369 *
370 * As dev->header_ops is not set in CAN netdevices no one is ever
371 * accessing the various header offsets in the CAN skbuffs anyway.
372 * E.g. using the packet socket to read CAN frames is still working.
373 */
374 skb_set_mac_header(nskb, 8);
375 nskb->dev = gwj->dst.dev; 407 nskb->dev = gwj->dst.dev;
376 408
377 /* pointer to modifiable CAN frame */ 409 /* pointer to modifiable CAN frame */
@@ -472,6 +504,11 @@ static int cgw_put_job(struct sk_buff *skb, struct cgw_job *gwj, int type,
472 goto cancel; 504 goto cancel;
473 } 505 }
474 506
507 if (gwj->deleted_frames) {
508 if (nla_put_u32(skb, CGW_DELETED, gwj->deleted_frames) < 0)
509 goto cancel;
510 }
511
475 /* check non default settings of attributes */ 512 /* check non default settings of attributes */
476 513
477 if (gwj->mod.modtype.and) { 514 if (gwj->mod.modtype.and) {
@@ -771,6 +808,7 @@ static int cgw_create_job(struct sk_buff *skb, struct nlmsghdr *nlh,
771 808
772 gwj->handled_frames = 0; 809 gwj->handled_frames = 0;
773 gwj->dropped_frames = 0; 810 gwj->dropped_frames = 0;
811 gwj->deleted_frames = 0;
774 gwj->flags = r->flags; 812 gwj->flags = r->flags;
775 gwj->gwtype = r->gwtype; 813 gwj->gwtype = r->gwtype;
776 814
@@ -895,7 +933,11 @@ static int cgw_remove_job(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
895 933
896static __init int cgw_module_init(void) 934static __init int cgw_module_init(void)
897{ 935{
898 printk(banner); 936 /* sanitize given module parameter */
937 max_hops = clamp_t(unsigned int, max_hops, CGW_MIN_HOPS, CGW_MAX_HOPS);
938
939 pr_info("can: netlink gateway (rev " CAN_GW_VERSION ") max_hops=%d\n",
940 max_hops);
899 941
900 cgw_cache = kmem_cache_create("can_gw", sizeof(struct cgw_job), 942 cgw_cache = kmem_cache_create("can_gw", sizeof(struct cgw_job),
901 0, 0, NULL); 943 0, 0, NULL);
diff --git a/net/can/raw.c b/net/can/raw.c
index 5b0e3e330d97..5d860e8dcc52 100644
--- a/net/can/raw.c
+++ b/net/can/raw.c
@@ -50,6 +50,7 @@
50#include <linux/skbuff.h> 50#include <linux/skbuff.h>
51#include <linux/can.h> 51#include <linux/can.h>
52#include <linux/can/core.h> 52#include <linux/can/core.h>
53#include <linux/can/skb.h>
53#include <linux/can/raw.h> 54#include <linux/can/raw.h>
54#include <net/sock.h> 55#include <net/sock.h>
55#include <net/net_namespace.h> 56#include <net/net_namespace.h>
@@ -699,11 +700,14 @@ static int raw_sendmsg(struct kiocb *iocb, struct socket *sock,
699 if (!dev) 700 if (!dev)
700 return -ENXIO; 701 return -ENXIO;
701 702
702 skb = sock_alloc_send_skb(sk, size, msg->msg_flags & MSG_DONTWAIT, 703 skb = sock_alloc_send_skb(sk, size + sizeof(struct can_skb_priv),
703 &err); 704 msg->msg_flags & MSG_DONTWAIT, &err);
704 if (!skb) 705 if (!skb)
705 goto put_dev; 706 goto put_dev;
706 707
708 skb_reserve(skb, sizeof(struct can_skb_priv));
709 ((struct can_skb_priv *)(skb->head))->ifindex = dev->ifindex;
710
707 err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size); 711 err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size);
708 if (err < 0) 712 if (err < 0)
709 goto free_skb; 713 goto free_skb;