{
}
+/**
+ * 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)
f->handle = handle;
else {
f->handle = canfltr_gen_handle(tp);
+ if (f->handle == 0)
+ goto errout;
}
/* Configure filter */
{
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 */