From e4b7e5b5d3751e91c77d69cce6311233ba15889f Mon Sep 17 00:00:00 2001 From: Rostislav Lisovy Date: Thu, 18 Aug 2011 14:32:24 +0200 Subject: [PATCH] Instead of "match" keyword, there is "matchid" (for SFF) and "matcheid" (for EFF). --- tc/f_canprio.c | 72 +++++++++++++++++++++++++++++++++++++++++++----- tc/setcanprio.sh | 17 ++++++++---- 2 files changed, 76 insertions(+), 13 deletions(-) diff --git a/tc/f_canprio.c b/tc/f_canprio.c index e202b55..6bd0e22 100644 --- a/tc/f_canprio.c +++ b/tc/f_canprio.c @@ -11,20 +11,41 @@ #include #include #include - +#include #include "utils.h" #include "tc_util.h" +#ifdef CONFIG_HAVE_LINUX_CAN_H + #include "linux/can.h" + +#elif !defined(CAN_EFF_FLAG) + /* special address description flags for the CAN_ID */ + #define CAN_EFF_FLAG 0x80000000U /* EFF/SFF is set in the MSB */ + #define CAN_RTR_FLAG 0x40000000U /* remote transmission request */ + #define CAN_ERR_FLAG 0x20000000U /* error frame */ + + /* valid bits in CAN ID for frame formats */ + #define CAN_SFF_MASK 0x000007FFU /* standard frame format (SFF) */ + #define CAN_EFF_MASK 0x1FFFFFFFU /* extended frame format (EFF) */ + #define CAN_ERR_MASK 0x1FFFFFFFU /* omit EFF, RTR, ERR flags */ +#endif + + struct canprio_rule { __u32 canid; __u32 canid_mask; }; - struct canprio_rule canprio_rules[32]; static void explain(void) { - fprintf(stderr, "Usage: ... canprio match CANID:MASK flowid FLOWID\n"); + fprintf(stderr, "Usage: ... canprio [ MATCHSPEC ] [ flowid FLOWID ]\n" + "\n" + "Where: MATCHSPEC := { matchid FILTERID | matcheid FILTERID | \n" + " MATCHSPEC ... }\n" + " FILTERID := CANID:MASK \n" + "\n" + "NOTE: CLASSID, CANID, MASK is parsed as hexadecimal input.\n"); } @@ -34,7 +55,8 @@ static int canprio_parse_opt(struct filter_util *qu, char *handle, struct tcmsg *t = NLMSG_DATA(n); // Why? struct rtattr *tail; long h = 0; - __u32 canid, canid_mask; + __u32 canid; + __u32 canid_mask; int rules_count = 0; if (argc == 0) @@ -59,19 +81,55 @@ static int canprio_parse_opt(struct filter_util *qu, char *handle, //printf(" [parsing match ..."); NEXT_ARG(); - //FIXME why it does not work with "%jx"? - if (sscanf(*argv, "%lx:%lx", &canid, &canid_mask) != 2) { + if (sscanf(*argv, "%"SCNx32 ":" "%"SCNx32, &canid, &canid_mask) != 2) { fprintf(stderr, "improperly formed Can ID & mask '%s'\n", *argv); return -1; } //printf("... 0x%x:0x%x]\n", canid, canid_mask); - if (canid > 0) {// FIXME boundary check + if (canid >= 0) {// FIXME boundary check canprio_rules[rules_count].canid = canid; canprio_rules[rules_count].canid_mask = canid_mask; rules_count++; + + } + + } else if (matches(*argv, "matchid") == 0) { + NEXT_ARG(); + + if (sscanf(*argv, "%"SCNx32 ":" "%"SCNx32, &canid, &canid_mask) != 2) { + fprintf(stderr, "improperly formed Can ID & mask '%s'\n", *argv); + return -1; + } + + if (canid & ~CAN_SFF_MASK) { + fprintf(stderr, "Id 0x%lx exceeded standard CAN ID range.", + (unsigned long)canid); + return -1; + } + + canprio_rules[rules_count].canid = canid; + canprio_rules[rules_count].canid_mask = (canid_mask & CAN_SFF_MASK); + rules_count++; + + } else if (matches(*argv, "matcheid") == 0) { + NEXT_ARG(); + + if (sscanf(*argv, "%"SCNx32 ":" "%"SCNx32, &canid, &canid_mask) != 2) { + fprintf(stderr, "improperly formed Can ID & mask '%s'\n", *argv); + return -1; + } + + if (canid & ~CAN_EFF_MASK) { + fprintf(stderr, "Id 0x%lx exceeded extended CAN ID range.", + (unsigned long)canid); + return -1; } + canprio_rules[rules_count].canid = canid | CAN_EFF_FLAG; + canprio_rules[rules_count].canid_mask = (canid_mask & CAN_EFF_MASK); + rules_count++; + } else if (matches(*argv, "classid") == 0 || strcmp(*argv, "flowid") == 0) { //printf(" [parsing flowid]\n"); diff --git a/tc/setcanprio.sh b/tc/setcanprio.sh index e320030..3bd5a0b 100755 --- a/tc/setcanprio.sh +++ b/tc/setcanprio.sh @@ -3,16 +3,21 @@ if [ "$1" == "del" ]; then # delete all qdiscs & filters sudo ./tc qdisc del dev can0 root -elif [ "$1" = "stat" ]; then # show statistics +elif [ "$1" == "stat" ]; then # show statistics ./tc -s class show dev can0 -else # create Prio qdiscs and configure canprio filter +elif [ "$1" == "prio" ]; then # create Prio qdiscs and configure canprio filter + + #For more information about priorities, bands, dequeuing etc. see manpage "tc-prio" + sudo ./tc qdisc add dev can0 root handle 1: prio - sudo ./tc filter add dev can0 parent 1:0 prio 1 canprio match 0x123:0xffff match 0x124:0xffff flowid 1:1 - sudo ./tc filter add dev can0 parent 1:0 prio 2 canprio match 0x223:0xffff flowid 1:2 - sudo ./tc filter add dev can0 parent 1:0 prio 3 canprio match 0x1:0x1 flowid 1:3 + sudo ./tc filter add dev can0 parent 1:0 prio 1 canprio matchid 0x123:0xffff matchid 0x124:0xffff flowid 1:1 + sudo ./tc filter add dev can0 parent 1:0 prio 2 canprio matchid 0x125:0xffff matcheid 0x125:0xffff flowid 1:1 + sudo ./tc filter add dev can0 parent 1:0 prio 3 canprio matchid 0x223:0xffff flowid 1:2 + sudo ./tc filter add dev can0 parent 1:0 prio 4 canprio matchid 0xa:0xf flowid 1:3 sudo ./tc qdisc show dev can0 - +else + echo -e "Usage: $0 [ del | stat | prio ]" fi -- 2.39.2