]> rtime.felk.cvut.cz Git - lisovros/linux_canprio.git/commitdiff
cls_can: Handle generator now uses full 32 bits for its values.
authorRostislav Lisovy <lisovy@gmail.com>
Wed, 23 May 2012 14:22:45 +0000 (16:22 +0200)
committerRostislav Lisovy <lisovy@gmail.com>
Wed, 23 May 2012 14:22:45 +0000 (16:22 +0200)
net/sched/cls_can.c

index 0f64fb00227bc767602bfa3361cecb8d7206491b..111668e41e821b687b7ced4ef63eb7df0381977e 100644 (file)
@@ -211,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)
@@ -374,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 */
@@ -454,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 */