aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOliver Hartkopp <socketcan@hartkopp.net>2013-01-17 18:43:46 +0100
committerMarc Kleine-Budde <mkl@pengutronix.de>2013-01-26 16:59:02 +0100
commite6afa00a1409bc3bceed9ccb33111519463dfe7b (patch)
tree90a039fdf39a111f7f9510ff012808277a0f2a65
parentcan: gw: add a variable limit for CAN frame routings (diff)
downloadlinux-dev-e6afa00a1409bc3bceed9ccb33111519463dfe7b.tar.xz
linux-dev-e6afa00a1409bc3bceed9ccb33111519463dfe7b.zip
can: gw: indicate and count deleted frames due to misconfiguration
Add a statistic counter to detect deleted frames due to misconfiguration with a new read-only CGW_DELETED netlink attribute for the CAN gateway. Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net> Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
-rw-r--r--include/uapi/linux/can/gw.h1
-rw-r--r--net/can/gw.c12
2 files changed, 12 insertions, 1 deletions
diff --git a/include/uapi/linux/can/gw.h b/include/uapi/linux/can/gw.h
index 0505c7f86213..ae07bec74f4b 100644
--- a/include/uapi/linux/can/gw.h
+++ b/include/uapi/linux/can/gw.h
@@ -44,6 +44,7 @@ enum {
CGW_SRC_IF, /* ifindex of source network interface */
CGW_DST_IF, /* ifindex of destination network interface */
CGW_FILTER, /* specify struct can_filter on source CAN device */
+ CGW_DELETED, /* number of deleted CAN frames (see max_hops param) */
__CGW_MAX
};
diff --git a/net/can/gw.c b/net/can/gw.c
index 4216a80618cb..acdd4656cc3b 100644
--- a/net/can/gw.c
+++ b/net/can/gw.c
@@ -131,6 +131,7 @@ struct cgw_job {
struct rcu_head rcu;
u32 handled_frames;
u32 dropped_frames;
+ u32 deleted_frames;
struct cf_mod mod;
union {
/* CAN frame data source */
@@ -367,8 +368,11 @@ static void can_can_gw_rcv(struct sk_buff *skb, void *data)
BUG_ON(skb->ip_summed != CHECKSUM_UNNECESSARY);
- if (cgw_hops(skb) >= max_hops)
+ if (cgw_hops(skb) >= max_hops) {
+ /* indicate deleted frames due to misconfiguration */
+ gwj->deleted_frames++;
return;
+ }
if (!(gwj->dst.dev->flags & IFF_UP)) {
gwj->dropped_frames++;
@@ -500,6 +504,11 @@ static int cgw_put_job(struct sk_buff *skb, struct cgw_job *gwj, int type,
goto cancel;
}
+ if (gwj->deleted_frames) {
+ if (nla_put_u32(skb, CGW_DELETED, gwj->deleted_frames) < 0)
+ goto cancel;
+ }
+
/* check non default settings of attributes */
if (gwj->mod.modtype.and) {
@@ -799,6 +808,7 @@ static int cgw_create_job(struct sk_buff *skb, struct nlmsghdr *nlh,
gwj->handled_frames = 0;
gwj->dropped_frames = 0;
+ gwj->deleted_frames = 0;
gwj->flags = r->flags;
gwj->gwtype = r->gwtype;