]> rtime.felk.cvut.cz Git - lisovros/iproute2_canprio.git/commitdiff
Instead of "match" keyword, there is "matchid" (for SFF) and "matcheid" (for EFF).
authorRostislav Lisovy <lisovy@gmail.com>
Thu, 18 Aug 2011 12:32:24 +0000 (14:32 +0200)
committerRostislav Lisovy <lisovy@gmail.com>
Wed, 23 May 2012 08:45:12 +0000 (10:45 +0200)
tc/f_canprio.c
tc/setcanprio.sh

index e202b55e67f99fd2c26b7bc5ecf5902d0e30d088..6bd0e22ab25a91c04c4c6de1c9e104d1b42306b3 100644 (file)
 #include <string.h>
 #include <linux/if.h>
 #include <limits.h>
-
+#include <inttypes.h>
 #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");
index e320030085de94775293691a0de7a279325e9d1c..3bd5a0b573afa840cc4024dc4e11370b6f23c630 100755 (executable)
@@ -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