+/*
+ * Reset filter to default (blank) settings
+ */
+static void canprio_reset(struct canprio_filter *f)
+{
+ struct canprio_eff_item *effi;
+ struct hlist_node *p, *n;
+
+ if (f->rules.rules_raw != NULL)
+ kfree(f->rules.rules_raw);
+
+ bitmap_zero(f->rules.match_sff, CAN_SFF_MASK + 1);
+ f->rules.inv_match_en = 0;
+ f->rules.rules_count = 0; //FIXME not necessary
+
+ rcu_barrier();
+ hlist_for_each_entry_safe(effi, p, n, &f->rules.match_eff, list) {
+ kfree(effi);
+ }
+ INIT_HLIST_HEAD(&f->rules.match_eff);
+}
+
+static int canprio_set_parms(struct tcf_proto *tp, struct canprio_filter *f,
+ unsigned long base, struct nlattr **tb,
+ struct nlattr *est)
+{
+ struct can_filter *canprio_nl_rules;
+ int err;
+ int i;
+ printk("%s() invoked\n", __FUNCTION__);
+
+ //if (tb[TCA_CANPRIO_CLASSID] == NULL) //FIXME is enough?
+ // return -EINVAL;
+
+ if (tb[TCA_CANPRIO_RULES]) {
+ canprio_nl_rules = nla_data(tb[TCA_CANPRIO_RULES]);
+ f->rules.rules_count = (nla_len(tb[TCA_CANPRIO_RULES]) / sizeof(struct can_filter));
+ printk(" rules_count = %u\n", f->rules.rules_count);
+
+ f->rules.rules_raw = kzalloc(sizeof(struct can_filter) * f->rules.rules_count, GFP_KERNEL);
+ if (f->rules.rules_raw == NULL)
+ return -ENOMEM;
+
+ memcpy(f->rules.rules_raw, canprio_nl_rules,
+ sizeof(struct can_filter) * f->rules.rules_count);
+
+ for (i = 0; i < f->rules.rules_count; i++) {
+ if ((canprio_nl_rules[i].can_id & CAN_EFF_FLAG) &&
+ (canprio_nl_rules[i].can_mask & CAN_EFF_FLAG)) {
+
+ err = canprio_eff_match_add(f, canprio_nl_rules[i].can_id,
+ canprio_nl_rules[i].can_mask);
+ if (err < 0)
+ goto errout;
+ } else {
+ canprio_sff_match_add(f, canprio_nl_rules[i].can_id,
+ canprio_nl_rules[i].can_mask);
+ }
+
+ printk(" can ID to match = 0x%x with mask 0x%x\n",
+ canprio_nl_rules[i].can_id, canprio_nl_rules[i].can_mask);
+ }
+ }
+
+ if (tb[TCA_CANPRIO_INV_EN] != NULL)
+ f->rules.inv_match_en = nla_get_u32(tb[TCA_CANPRIO_INV_EN]);
+
+ return 0;
+
+errout:
+ if (f->rules.rules_raw != NULL) //FIXME is ok?
+ kfree(f->rules.rules_raw);
+
+ return err;
+}