#include <net/netlink.h>
#include <net/act_api.h>
#include <net/pkt_cls.h>
-#include <linux/can.h>
#include <linux/bitmap.h>
#include <linux/spinlock.h>
#include <linux/rcupdate.h>
#include <linux/can.h>
+#define SFF_BITMAP 1
+#undef SFF_BITMAP
/* Definition of Netlink messages */
enum {
Used for sending information to userspace
(when 'tc filter show' is invoked) AND
when matching EFF frames*/
+#ifdef SFF_BITMAP
DECLARE_BITMAP(match_sff, CAN_SFF_MASK + 1); /* For each SFF Can ID (11 bit)
there is one record in this bitfield */
+#endif
int inv_match_en; /* Inverted match flag */
int rules_count;
int eff_rules_count;
* ----------------------------------------------------------------------------
*/
+#ifdef SFF_BITMAP
static void canprio_sff_match_add(struct canprio_rules *rls, u32 can_id, u32 can_mask)
{
int i;
- printk("%s() invoked\n", __FUNCTION__);
+ pr_debug("%s() invoked\n", __FUNCTION__);
can_mask &= CAN_SFF_MASK;
can_id &= can_mask;
set_bit(i, rls->match_sff);
}
}
+#endif
/*
* Extracts Can ID ot ouf the sk_buff structure.
u32 can_id;
int i;
- printk(" canprio_classify() invoked\n");
+ pr_debug(" canprio_classify() invoked\n");
can_id = (u32)canprio_get_id(skb);
rcu_read_lock();
}
}
} else {
+ 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 & r->rules_raw[i].can_mask & CAN_SFF_MASK) ==
+ (can_id & r->rules_raw[i].can_mask & CAN_SFF_MASK)) {
+
+ match = true;
+ break;
+ }
+ }
+#endif
}
//if (r->inv_match_en)
if (match) {
*res = f->res;
- printk( " canprio_classify() match ok: ID 0x%x\n", can_id);
+ pr_debug( " canprio_classify() match ok: ID 0x%x\n", can_id);
rcu_read_unlock();
return TC_POLICE_OK;
}
struct canprio_head *head = (struct canprio_head *)tp->root;
struct canprio_filter *f;
- //printk("canprio_get(%d) invoked\n", handle);
if (head == NULL)
return 0UL;
- //printk("[running for_each_entry]\n");
list_for_each_entry(f, &head->flist, link) {
- //printk("[f->handle = %d]\n", f->handle);
if (f->handle == handle) {
- //printk("found something\n");
return (unsigned long) f;
}
}
while (i-- > 0) {
u32 h;
- unsigned long tmp;
if ((head->hgenerator += 0x10000) == 0)
head->hgenerator = 0x10000;
h = head->hgenerator;
- //if (canprio_get(tp, h) == 0)
- // return h;
- tmp = canprio_get(tp, h);
- //printk("___tried %d result %lu\n", h, tmp);
- if (tmp == 0)
+ if (canprio_get(tp, h) == 0);
return h;
}
return 0;
struct canprio_rules *rules_tmp;
int err;
int i;
- printk("%s() invoked\n", __FUNCTION__);
+ pr_debug("%s() invoked\n", __FUNCTION__);
rules_tmp = kzalloc(sizeof(*rules_tmp), GFP_KERNEL);
if (rules_tmp == NULL)
return -ENOBUFS;
- if (tb[TCA_CANPRIO_CLASSID] == NULL) //FIXME is enough?
- return -EINVAL;
+ err = -EINVAL;
+ if (tb[TCA_CANPRIO_CLASSID] == NULL)
+ goto errout;
if (tb[TCA_CANPRIO_RULES]) {
canprio_nl_rules = nla_data(tb[TCA_CANPRIO_RULES]);
rules_tmp->sff_rules_count = 0;
rules_tmp->eff_rules_count = 0;
rules_tmp->rules_count = (nla_len(tb[TCA_CANPRIO_RULES]) / sizeof(struct can_filter));
- printk(" rules_count = %u\n", rules_tmp->rules_count);
+ pr_debug(" rules_count = %u\n", rules_tmp->rules_count);
rules_tmp->rules_raw = kzalloc(sizeof(struct can_filter) * rules_tmp->rules_count, GFP_KERNEL);
+ err = -ENOMEM;
if (rules_tmp->rules_raw == NULL)
- return -ENOMEM;
+ goto errout;
/* Process EFF frames */
for (i = 0; i < rules_tmp->rules_count; i++) {
&canprio_nl_rules[i], sizeof(struct can_filter));
rules_tmp->eff_rules_count ++;
- printk(" can ID to match = 0x%x with mask 0x%x\n",
+ pr_debug(" can ID to match = 0x%x with mask 0x%x\n",
canprio_nl_rules[i].can_id, canprio_nl_rules[i].can_mask);
} else {
continue;
&canprio_nl_rules[i], sizeof(struct can_filter));
rules_tmp->sff_rules_count ++;
+#ifdef SFF_BITMAP
canprio_sff_match_add(rules_tmp, canprio_nl_rules[i].can_id,
canprio_nl_rules[i].can_mask);
+#endif
- printk(" can ID to match = 0x%x with mask 0x%x\n",
+ pr_debug(" can ID to match = 0x%x with mask 0x%x\n",
canprio_nl_rules[i].can_id, canprio_nl_rules[i].can_mask);
}
}
return 0;
errout:
- if (rules_tmp->rules_raw != NULL) //FIXME is ok?
- kfree(rules_tmp->rules_raw);
-
+ kfree(rules_tmp);
return err;
}
struct nlattr *tb[TCA_CANPRIO_MAX + 1];
int err;
- printk("%s() invoked\n", __FUNCTION__);
+ pr_debug("%s() invoked\n", __FUNCTION__);
if (tca[TCA_OPTIONS] == NULL)
return -EINVAL;
if (handle && f->handle != handle)
return -EINVAL;
- printk("[change existing filter]\n");
+ pr_debug("[change existing filter]\n");
return canprio_set_parms(tp, f, base, tb, tca[TCA_RATE]);
}
if (f == NULL)
goto errout;
-
if (tb[TCA_CANPRIO_CLASSID]) {
f->res.classid = nla_get_u32(tb[TCA_U32_CLASSID]);
tcf_bind_filter(tp, &f->res, base);
}
-
err = -EINVAL;
if (handle) /* handle passed from userspace */
f->handle = handle;
else {
- //u32 handle;
- //handle = canprio_gen_handle(tp);
- //f->handle = handle;
- f->handle = 1;
+ f->handle = canprio_gen_handle(tp);
}
//Configure filter
return 0;
-
errout:
if (*arg == 0UL && f)
kfree(f);
static int canprio_init(struct tcf_proto *tp)
{
struct canprio_head *head;
- printk(" canprio_init invoked\n");
+ pr_debug(" canprio_init invoked\n");
head = kzalloc(sizeof(*head), GFP_KERNEL);
if (head == NULL)
struct canprio_head *head = (struct canprio_head *) tp->root;
struct canprio_filter *f;
- printk("%s() invoked\n", __FUNCTION__);
+ pr_debug("%s() invoked\n", __FUNCTION__);
list_for_each_entry(f, &head->flist, link) {
if (arg->count < arg->skip)
struct canprio_filter *f = (struct canprio_filter *) fh;
struct nlattr *nest;
struct canprio_rules *r;
- printk("%s() invoked\n", __FUNCTION__);
+ pr_debug("%s() invoked\n", __FUNCTION__);
if (f == NULL)
return skb->len;
static int __init init_canprio(void)
{
- printk("Canprio loaded\n");
+ pr_debug("Canprio loaded\n");
+#ifdef SFF_BITMAP
+ pr_debug("SFF frames stored in bitmap\n");
+#else
+ pr_debug("SFF frames stored in array\n");
+#endif
return register_tcf_proto_ops(&cls_canprio_ops);
}
static void __exit exit_canprio(void)
{
- printk("Canprio removed\n");
+ pr_debug("Canprio removed\n");
unregister_tcf_proto_ops(&cls_canprio_ops);
}