]> rtime.felk.cvut.cz Git - lisovros/iproute2_canprio.git/blobdiff - tc/f_canprio.c
Instead of "match" keyword, there is "matchid" (for SFF) and "matcheid" (for EFF).
[lisovros/iproute2_canprio.git] / tc / f_canprio.c
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");