diff options
author | David S. Miller <davem@davemloft.net> | 2013-01-28 00:19:34 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-01-28 00:19:34 -0500 |
commit | 61550022b9586972082904b80de26a464c558437 (patch) | |
tree | 590c21eed5f723162d3821a398b6d3831f75a488 /net | |
parent | 0e36cbb344575e481167e090f0926701f83207d6 (diff) | |
parent | e6afa00a1409bc3bceed9ccb33111519463dfe7b (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/Kconfig | 13 | ||||
-rw-r--r-- | net/can/bcm.c | 12 | ||||
-rw-r--r-- | net/can/gw.c | 74 | ||||
-rw-r--r-- | net/can/raw.c | 8 |
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 | ||
19 | if CAN | ||
20 | |||
19 | config CAN_RAW | 21 | config 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 | ||
30 | config CAN_BCM | 31 | config 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 | ||
43 | config CAN_GW | 43 | config 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 | ||
55 | source "drivers/net/can/Kconfig" | 54 | source "drivers/net/can/Kconfig" |
55 | |||
56 | endif | ||
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" |
61 | static __initconst const char banner[] = | 63 | #define CAN_GW_NAME "can-gw" |
62 | KERN_INFO "can: netlink gateway (rev " CAN_GW_VERSION ")\n"; | ||
63 | 64 | ||
64 | MODULE_DESCRIPTION("PF_CAN netlink gateway"); | 65 | MODULE_DESCRIPTION("PF_CAN netlink gateway"); |
65 | MODULE_LICENSE("Dual BSD/GPL"); | 66 | MODULE_LICENSE("Dual BSD/GPL"); |
66 | MODULE_AUTHOR("Oliver Hartkopp <oliver.hartkopp@volkswagen.de>"); | 67 | MODULE_AUTHOR("Oliver Hartkopp <oliver.hartkopp@volkswagen.de>"); |
67 | MODULE_ALIAS("can-gw"); | 68 | MODULE_ALIAS(CAN_GW_NAME); |
69 | |||
70 | #define CGW_MIN_HOPS 1 | ||
71 | #define CGW_MAX_HOPS 6 | ||
72 | #define CGW_DEFAULT_HOPS 1 | ||
73 | |||
74 | static unsigned int max_hops __read_mostly = CGW_DEFAULT_HOPS; | ||
75 | module_param(max_hops, uint, S_IRUGO); | ||
76 | MODULE_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 | ||
69 | static HLIST_HEAD(cgw_list); | 82 | static HLIST_HEAD(cgw_list); |
70 | static struct notifier_block notifier; | 83 | static 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 | ||
896 | static __init int cgw_module_init(void) | 934 | static __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; |