cangw: support new can-gw features for Linux 3.9+
Added new option '-i' for can-gw rules to allow to route CAN frames back to the originating/incoming CAN interface (which is disabled by default). CAN frames that are deleted due to the violation of the max_hops limit are now printed when displaying the configured rules with 'cangw -L'. Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>pull/7/head
parent
221794dbe8
commit
9dad9f7354
22
cangw.c
22
cangw.c
|
|
@ -192,6 +192,7 @@ void print_usage(char *prg)
|
||||||
fprintf(stderr, " -d <dst_dev> (destination netdevice)\n");
|
fprintf(stderr, " -d <dst_dev> (destination netdevice)\n");
|
||||||
fprintf(stderr, "Options: -t (preserve src_dev rx timestamp)\n");
|
fprintf(stderr, "Options: -t (preserve src_dev rx timestamp)\n");
|
||||||
fprintf(stderr, " -e (echo sent frames - recommended on vcanx)\n");
|
fprintf(stderr, " -e (echo sent frames - recommended on vcanx)\n");
|
||||||
|
fprintf(stderr, " -i (allow to route to incoming interface)\n");
|
||||||
fprintf(stderr, " -f <filter> (set CAN filter)\n");
|
fprintf(stderr, " -f <filter> (set CAN filter)\n");
|
||||||
fprintf(stderr, " -m <mod> (set frame modifications)\n");
|
fprintf(stderr, " -m <mod> (set frame modifications)\n");
|
||||||
fprintf(stderr, " -x <from_idx>:<to_idx>:<result_idx>:<init_xor_val> (XOR checksum)\n");
|
fprintf(stderr, " -x <from_idx>:<to_idx>:<result_idx>:<init_xor_val> (XOR checksum)\n");
|
||||||
|
|
@ -353,7 +354,7 @@ int parse_rtlist(char *prgname, unsigned char *rxbuf, int len)
|
||||||
struct nlmsghdr *nlh;
|
struct nlmsghdr *nlh;
|
||||||
unsigned int src_ifindex = 0;
|
unsigned int src_ifindex = 0;
|
||||||
unsigned int dst_ifindex = 0;
|
unsigned int dst_ifindex = 0;
|
||||||
__u32 handled, dropped;
|
__u32 handled, dropped, deleted;
|
||||||
int rtlen;
|
int rtlen;
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -394,6 +395,7 @@ int parse_rtlist(char *prgname, unsigned char *rxbuf, int len)
|
||||||
|
|
||||||
handled = 0;
|
handled = 0;
|
||||||
dropped = 0;
|
dropped = 0;
|
||||||
|
deleted = 0;
|
||||||
src_ifindex = 0;
|
src_ifindex = 0;
|
||||||
dst_ifindex = 0;
|
dst_ifindex = 0;
|
||||||
|
|
||||||
|
|
@ -432,6 +434,10 @@ int parse_rtlist(char *prgname, unsigned char *rxbuf, int len)
|
||||||
dropped = *(__u32 *)RTA_DATA(rta);
|
dropped = *(__u32 *)RTA_DATA(rta);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case CGW_DELETED:
|
||||||
|
deleted = *(__u32 *)RTA_DATA(rta);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
printf("Unknown attribute %d!", rta->rta_type);
|
printf("Unknown attribute %d!", rta->rta_type);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
@ -449,6 +455,9 @@ int parse_rtlist(char *prgname, unsigned char *rxbuf, int len)
|
||||||
if (rtc->flags & CGW_FLAGS_CAN_SRC_TSTAMP)
|
if (rtc->flags & CGW_FLAGS_CAN_SRC_TSTAMP)
|
||||||
printf("-t ");
|
printf("-t ");
|
||||||
|
|
||||||
|
if (rtc->flags & CGW_FLAGS_CAN_IIF_TX_OK)
|
||||||
|
printf("-i ");
|
||||||
|
|
||||||
/* second parse for mod attributes */
|
/* second parse for mod attributes */
|
||||||
rta = (struct rtattr *) RTCAN_RTA(rtc);
|
rta = (struct rtattr *) RTCAN_RTA(rtc);
|
||||||
rtlen = RTCAN_PAYLOAD(nlh);
|
rtlen = RTCAN_PAYLOAD(nlh);
|
||||||
|
|
@ -489,6 +498,7 @@ int parse_rtlist(char *prgname, unsigned char *rxbuf, int len)
|
||||||
case CGW_DST_IF:
|
case CGW_DST_IF:
|
||||||
case CGW_HANDLED:
|
case CGW_HANDLED:
|
||||||
case CGW_DROPPED:
|
case CGW_DROPPED:
|
||||||
|
case CGW_DELETED:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
@ -498,7 +508,9 @@ int parse_rtlist(char *prgname, unsigned char *rxbuf, int len)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("# %d handled %d dropped\n", handled, dropped); /* end of entry */
|
/* end of entry */
|
||||||
|
printf("# %d handled %d dropped %d deleted\n",
|
||||||
|
handled, dropped, deleted);
|
||||||
|
|
||||||
/* jump to next NLMSG in the given buffer */
|
/* jump to next NLMSG in the given buffer */
|
||||||
nlh = NLMSG_NEXT(nlh, len);
|
nlh = NLMSG_NEXT(nlh, len);
|
||||||
|
|
@ -548,7 +560,7 @@ int main(int argc, char **argv)
|
||||||
memset(&cs_xor, 0, sizeof(cs_xor));
|
memset(&cs_xor, 0, sizeof(cs_xor));
|
||||||
memset(&cs_crc8, 0, sizeof(cs_crc8));
|
memset(&cs_crc8, 0, sizeof(cs_crc8));
|
||||||
|
|
||||||
while ((opt = getopt(argc, argv, "ADFLs:d:tef:c:p:x:m:?")) != -1) {
|
while ((opt = getopt(argc, argv, "ADFLs:d:teif:c:p:x:m:?")) != -1) {
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
|
|
||||||
case 'A':
|
case 'A':
|
||||||
|
|
@ -587,6 +599,10 @@ int main(int argc, char **argv)
|
||||||
flags |= CGW_FLAGS_CAN_ECHO;
|
flags |= CGW_FLAGS_CAN_ECHO;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'i':
|
||||||
|
flags |= CGW_FLAGS_CAN_IIF_TX_OK;
|
||||||
|
break;
|
||||||
|
|
||||||
case 'f':
|
case 'f':
|
||||||
if (sscanf(optarg, "%x:%x", &filter.can_id,
|
if (sscanf(optarg, "%x:%x", &filter.can_id,
|
||||||
&filter.can_mask) == 2) {
|
&filter.can_mask) == 2) {
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,7 @@ enum {
|
||||||
CGW_SRC_IF, /* ifindex of source network interface */
|
CGW_SRC_IF, /* ifindex of source network interface */
|
||||||
CGW_DST_IF, /* ifindex of destination network interface */
|
CGW_DST_IF, /* ifindex of destination network interface */
|
||||||
CGW_FILTER, /* specify struct can_filter on source CAN device */
|
CGW_FILTER, /* specify struct can_filter on source CAN device */
|
||||||
|
CGW_DELETED, /* number of deleted CAN frames (see max_hops param) */
|
||||||
__CGW_MAX
|
__CGW_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -51,6 +52,7 @@ enum {
|
||||||
|
|
||||||
#define CGW_FLAGS_CAN_ECHO 0x01
|
#define CGW_FLAGS_CAN_ECHO 0x01
|
||||||
#define CGW_FLAGS_CAN_SRC_TSTAMP 0x02
|
#define CGW_FLAGS_CAN_SRC_TSTAMP 0x02
|
||||||
|
#define CGW_FLAGS_CAN_IIF_TX_OK 0x04
|
||||||
|
|
||||||
#define CGW_MOD_FUNCS 4 /* AND OR XOR SET */
|
#define CGW_MOD_FUNCS 4 /* AND OR XOR SET */
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue