]> rtime.felk.cvut.cz Git - lisovros/linux_canprio.git/blobdiff - net/sched/cls_can.c
cls_can: Handle generator now uses full 32 bits for its values.
[lisovros/linux_canprio.git] / net / sched / cls_can.c
index cf34eb56b8de7d9da26403824df726d8eb6dcd9a..111668e41e821b687b7ced4ef63eb7df0381977e 100644 (file)
@@ -35,9 +35,6 @@
 #include <linux/rcupdate.h>
 #include <linux/can.h>
 
-#define SFF_BITMAP             1       /* Use bitmap for storing rules
-                                       for SFF frames? */
-
 /* Definition of Netlink message parts */
 enum {
        TCA_CANFLTR_UNSPEC,
@@ -60,11 +57,9 @@ struct canfltr_rules {
                                        message; Used for sending information
                                        to userspace (when 'tc filter show' is
                                        invoked) AND when matching EFF frames*/
-#ifdef SFF_BITMAP
        DECLARE_BITMAP(match_sff, (1 << CAN_SFF_ID_BITS)); /* For each SFF CAN
                                        ID (11 bit) there is one record in this
                                        bitfield */
-#endif
        int rules_count;
        int eff_rules_count;
        int sff_rules_count;
@@ -93,7 +88,6 @@ struct canfltr_state {
 static void canfltr_sff_match_add(struct canfltr_rules *rls,
                                u32 can_id, u32 can_mask)
 {
-#ifdef SFF_BITMAP
        int i;
 
        /* Limit can_mask and can_id to SFF range to
@@ -120,7 +114,6 @@ static void canfltr_sff_match_add(struct canfltr_rules *rls,
                if ((i & can_mask) == can_id)
                        set_bit(i, rls->match_sff);
        }
-#endif
 }
 
 /**
@@ -174,20 +167,9 @@ static int canfltr_classify(struct sk_buff *skb, const struct tcf_proto *tp,
                                        break;
                                }
                        }
-               } else {
+               } else { /* SFF */
                        can_id &= CAN_SFF_MASK;
-#ifdef SFF_BITMAP
                        match = test_bit(can_id, r->match_sff);
-#else
-                       for (i = r->eff_rules_count;
-                       i < r->eff_rules_count + r->sff_rules_count; i++) {
-                               if (!(((r->rules_raw[i].can_id ^ can_id) &
-                               r->rules_raw[i].can_mask) & CAN_SFF_MASK)) {
-                                       match = true;
-                                       break;
-                               }
-                       }
-#endif
                }
 
                if (match) {
@@ -229,23 +211,25 @@ static void canfltr_put(struct tcf_proto *tp, unsigned long f)
 {
 }
 
+/**
+ * canfltr_gen_handle() - Generate handle for newly created filter
+ *
+ * This code is heavily inspired by handle generator in cls_basic.c
+ */
 static unsigned int canfltr_gen_handle(struct tcf_proto *tp)
 {
        struct canfltr_head *head = (struct canfltr_head *)tp->root;
-       int i = 0xFFFF;
+       unsigned int i = 0x80000000;
 
-       while (i-- > 0) {
-               u32 h;
+       do {
+               if (++head->hgenerator == 0x7FFFFFFF)
+                       head->hgenerator = 1;
+       } while (--i > 0 && canfltr_get(tp, head->hgenerator));
 
-               head->hgenerator += 0x10000;
-               if (head->hgenerator == 0)
-                       head->hgenerator = 0x10000;
+       if (i == 0)
+               return 0;
 
-               h = head->hgenerator;
-               if (canfltr_get(tp, h) == 0)
-                       return h;
-       }
-       return 0;
+       return head->hgenerator;
 }
 
 static void canfltr_rules_free_rcu(struct rcu_head *rcu)
@@ -392,6 +376,8 @@ static int canfltr_change(struct tcf_proto *tp, unsigned long base, u32 handle,
                f->handle = handle;
        else {
                f->handle = canfltr_gen_handle(tp);
+               if (f->handle == 0)
+                       goto errout;
        }
 
        /* Configure filter */
@@ -472,7 +458,8 @@ static int canfltr_init(struct tcf_proto *tp)
 {
        struct canfltr_head *head;
 
-       if ((tp->protocol != htons(ETH_P_ALL)) && (tp->protocol != htons(ETH_P_CAN)))
+       if ((tp->protocol != htons(ETH_P_ALL)) &&
+           (tp->protocol != htons(ETH_P_CAN)))
                return -1;
 
        /* Work only on CAN frames */
@@ -568,11 +555,6 @@ static struct tcf_proto_ops cls_canfltr_ops __read_mostly = {
 static int __init init_canfltr(void)
 {
        pr_debug("canfltr: CAN filter loaded\n");
-#ifdef SFF_BITMAP
-       pr_debug("canfltr: SFF rules stored in bitmap\n");
-#else
-       pr_debug("canfltr: SFF rules stored in array\n");
-#endif
        return register_tcf_proto_ops(&cls_canfltr_ops);
 }