#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");
}
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)
//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");
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