From 8ecd949df59ad0ee752a50f86f9eebb507853922 Mon Sep 17 00:00:00 2001 From: Rostislav Lisovy Date: Fri, 22 Jun 2012 16:16:39 +0200 Subject: [PATCH] em_canid: Number of rules passed during configuration is no longer limited. --- net/sched/em_canid.c | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/net/sched/em_canid.c b/net/sched/em_canid.c index 5cc6e5e4b68..1cdd4a175af 100644 --- a/net/sched/em_canid.c +++ b/net/sched/em_canid.c @@ -24,22 +24,22 @@ #include #include -#define EM_CAN_RULES_SIZE 32 +#define EM_CAN_RULES_MAX 500 struct canid_match { - /* - * Raw rules copied from netlink message; Used for sending - * information to userspace (when 'tc filter show' is invoked) - * AND when matching EFF frames - */ - struct can_filter rules_raw[EM_CAN_RULES_SIZE]; - /* For each SFF CAN ID (11 bit) there is one record in this bitfield */ DECLARE_BITMAP(match_sff, (1 << CAN_SFF_ID_BITS)); int rules_count; - int eff_rules_count; int sff_rules_count; + int eff_rules_count; + + /* + * Raw rules copied from netlink message; Used for sending + * information to userspace (when 'tc filter show' is invoked) + * AND when matching EFF frames + */ + struct can_filter rules_raw[]; }; /** @@ -90,7 +90,7 @@ static void em_canid_sff_match_add(struct canid_match *cm, u32 can_id, static inline struct canid_match *em_canid_priv(struct tcf_ematch *m) { - return (struct canid_match *) (m)->data; + return (struct canid_match *) m->data; } static int em_canid_match(struct sk_buff *skb, struct tcf_ematch *m, @@ -131,24 +131,29 @@ static int em_canid_change(struct tcf_proto *tp, void *data, int len, * fixed size EM_CAN_RULES_SIZE */ struct canid_match *cm; + struct canid_match *cm_old = (struct canid_match *) m->data; int err; int i; + int rulescnt; if (len < sizeof(struct can_filter)) return -EINVAL; + rulescnt = len / sizeof(struct can_filter); + err = -ENOBUFS; - cm = kzalloc(sizeof(*cm), GFP_KERNEL); + cm = kzalloc(sizeof(struct canid_match) + sizeof(struct can_filter) * + rulescnt, GFP_KERNEL); if (cm == NULL) goto errout; cm->sff_rules_count = 0; cm->eff_rules_count = 0; - cm->rules_count = len/sizeof(struct can_filter); + cm->rules_count = rulescnt; err = -EINVAL; /* Be sure to fit into the array */ - if (cm->rules_count > EM_CAN_RULES_SIZE) + if (cm->rules_count > EM_CAN_RULES_MAX) goto errout_free; /* @@ -191,6 +196,11 @@ static int em_canid_change(struct tcf_proto *tp, void *data, int len, m->datalen = sizeof(*cm); m->data = (unsigned long) cm; + if (cm_old != NULL) { + printk("canid: Configuring an existing ematch!\n"); + kfree(cm_old); + } + return 0; errout_free: -- 2.39.2