From ad7f44095ac301ae85f1c3e406a868c5ac664abe Mon Sep 17 00:00:00 2001 From: Oliver Hartkopp Date: Wed, 4 Sep 2013 20:30:34 +0200 Subject: [PATCH] cangw: add an option for the per rule limitation of frame hops Usually the received CAN frames can be processed/routed as much as 'max_hops' times (which is given at module load time of the can-gw module). Introduce a new configuration option ( -l ) to reduce the number of possible hops for a specific gateway rule to a value smaller then max_hops. Mainline upstream commit: http://git.kernel.org/cgit/linux/kernel/git/davem/net-next.git/commit/?id=391ac1282dd7ff1cb8245cccc5262e8e4173edc4 Signed-off-by: Oliver Hartkopp --- cangw.c | 19 ++++++++++++++++++- include/socketcan/can/gw.h | 9 ++++++++- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/cangw.c b/cangw.c index 802aa86..b908fe4 100644 --- a/cangw.c +++ b/cangw.c @@ -196,6 +196,7 @@ void print_usage(char *prg) fprintf(stderr, "Options: -t (preserve src_dev rx timestamp)\n"); fprintf(stderr, " -e (echo sent frames - recommended on vcanx)\n"); fprintf(stderr, " -i (allow to route to incoming interface)\n"); + fprintf(stderr, " -l (limit the number of frame hops / routings)\n"); fprintf(stderr, " -f (set CAN filter)\n"); fprintf(stderr, " -m (set frame modifications)\n"); fprintf(stderr, " -x ::: (XOR checksum)\n"); @@ -417,6 +418,7 @@ int parse_rtlist(char *prgname, unsigned char *rxbuf, int len) case CGW_MOD_OR: case CGW_MOD_XOR: case CGW_MOD_SET: + case CGW_LIM_HOPS: case CGW_CS_XOR: case CGW_CS_CRC8: break; @@ -489,6 +491,10 @@ int parse_rtlist(char *prgname, unsigned char *rxbuf, int len) printmod("SET", RTA_DATA(rta)); break; + case CGW_LIM_HOPS: + printf("-l %d ", *(__u8 *)RTA_DATA(rta)); + break; + case CGW_CS_XOR: print_cs_xor((struct cgw_csum_xor *)RTA_DATA(rta)); break; @@ -545,6 +551,7 @@ int main(int argc, char **argv) struct nlmsgerr *rte; unsigned int src_ifindex = 0; unsigned int dst_ifindex = 0; + __u8 limit_hops = 0; __u16 flags = 0; int len; @@ -563,7 +570,7 @@ int main(int argc, char **argv) memset(&cs_xor, 0, sizeof(cs_xor)); memset(&cs_crc8, 0, sizeof(cs_crc8)); - while ((opt = getopt(argc, argv, "ADFLs:d:teif:c:p:x:m:?")) != -1) { + while ((opt = getopt(argc, argv, "ADFLs:d:teil:f:c:p:x:m:?")) != -1) { switch (opt) { case 'A': @@ -606,6 +613,13 @@ int main(int argc, char **argv) flags |= CGW_FLAGS_CAN_IIF_TX_OK; break; + case 'l': + if (sscanf(optarg, "%hhd", &limit_hops) != 1 || !(limit_hops)) { + printf("Bad hop limit definition '%s'.\n", optarg); + exit(1); + } + break; + case 'f': if (sscanf(optarg, "%x:%x", &filter.can_id, &filter.can_mask) == 2) { @@ -743,6 +757,9 @@ int main(int argc, char **argv) if (have_cs_xor) addattr_l(&req.nh, sizeof(req), CGW_CS_XOR, &cs_xor, sizeof(cs_xor)); + if (limit_hops) + addattr_l(&req.nh, sizeof(req), CGW_LIM_HOPS, &limit_hops, sizeof(__u8)); + /* * a better example code * modmsg.modtype = CGW_MOD_ID; diff --git a/include/socketcan/can/gw.h b/include/socketcan/can/gw.h index 9c290dc..56d3246 100644 --- a/include/socketcan/can/gw.h +++ b/include/socketcan/can/gw.h @@ -45,6 +45,7 @@ enum { 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_LIM_HOPS, /* limit the number of hops of this specific rule */ __CGW_MAX }; @@ -116,13 +117,19 @@ enum { * Sets a CAN receive filter for the gateway job specified by the * struct can_filter described in include/linux/can.h * - * CGW_MOD_XXX (length 17 bytes): + * CGW_MOD_(AND|OR|XOR|SET) (length 17 bytes): * Specifies a modification that's done to a received CAN frame before it is * send out to the destination interface. * * data used as operator * affected CAN frame elements * + * CGW_LIM_HOPS (length 1 byte): + * Limit the number of hops of this specific rule. Usually the received CAN + * frame can be processed as much as 'max_hops' times (which is given at module + * load time of the can-gw module). This value is used to reduce the number of + * possible hops for this gateway job to a value smaller then max_hops. + * * CGW_CS_XOR (length 4 bytes): * Set a simple XOR checksum starting with an initial value into * data[result-idx] using data[start-idx] .. data[end-idx] -- 2.39.2