Received: with ECARTIS (v1.0.0; list netdev); Tue, 04 Jan 2005 05:38:01 -0800 (PST) Received: from b.mx.projectdream.org (eth0-0.arisu.projectdream.org [194.158.4.191]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id j04DbYW0015675 for ; Tue, 4 Jan 2005 05:37:54 -0800 Received: from postel.suug.ch (unknown [195.134.158.23]) (using TLSv1 with cipher EDH-RSA-DES-CBC3-SHA (168/168 bits)) (No client certificate requested) by b.mx.projectdream.org (Postfix) with ESMTP id 3ECB582; Tue, 4 Jan 2005 14:45:46 +0100 (CET) Received: by postel.suug.ch (Postfix, from userid 10001) id 62A781C0EA; Tue, 4 Jan 2005 14:46:29 +0100 (CET) Date: Tue, 4 Jan 2005 14:46:29 +0100 From: Thomas Graf To: jamal Cc: netdev@oss.sgi.com Subject: Re: [RFC] ematch API, u32 ematch, nbyte ematch, basic classifier Message-ID: <20050104134629.GK26856@postel.suug.ch> References: <20050103125635.GB26856@postel.suug.ch> <1104812028.1085.50.camel@jzny.localdomain> <20050104120333.GF26856@postel.suug.ch> <1104844753.1085.99.camel@jzny.localdomain> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1104844753.1085.99.camel@jzny.localdomain> X-Virus-Scanned: ClamAV 0.80/645/Mon Dec 27 14:56:20 2004 clamav-milter version 0.80j on 127.0.0.1 X-Virus-Status: Clean X-archive-position: 13377 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: tgraf@suug.ch Precedence: bulk X-list: netdev * jamal <1104844753.1085.99.camel@jzny.localdomain> 2005-01-04 08:19 > On Tue, 2005-01-04 at 07:03, Thomas Graf wrote: > > change() (Optional) > > My thinking is: > It doesnt have to be simple 32 bit data. > If i pass you a struct and tell you what length it is, then you as the > classifier dont know need to know anything about it. You just store > mystruct as data and datalen from the TLV. you then pass the datastruct > to match() - Of course the match() will have to know what that struct > means. That's exactly how it is, basically the logic is: if (ops->change) { err = ops->change(tp, data, datalen, m); if (err < 0) goto errout; } else if (datalen > 0) { if (mh->flags & TCF_EM_SIMPLE) { if (datalen != sizeof(u32)) goto errout; m->data = *(u32 *) data; } else { void *v = kmalloc(datalen, GFP_KERNEL); if (v == NULL) { err = -ENOBUFS; goto errout; } memcpy(v, data, datalen); m->data = (unsigned long) v; } } m->datalen = datalen; > > destroy() (Optional) > > Called if provided, otheriwse m->data is freed in ematch api unless > > TCF_EM_SIMPLE is set. > > Again using the above logic, destroy becomes just kfree(mystruct) Right, that's exactly how it is if (m->ops->destroy) m->ops->destroy(tp, m); else if (!(m->hdr.flags & TCF_EM_SIMPLE) && m->data) kfree((void *) m->data); > > dump() (Optional) > > Called if provided, otherwise m->data is dumped onto the skb with > > m->datalen as L. Special handling again for TCF_EM_SIMPLE. > > and dump becomes a matter of looking at datalen and encapsulating > mystruct in a TLV without thinking about what the content is. Absolutely true, you know about the code before you read it ;-> if (m->ops->dump) { if (m->ops->dump(skb, m) < 0) goto rtattr_failure; } else if (m->hdr.flags & TCF_EM_SIMPLE) { u32 u = m->data; RTA_PUT_NOHDR(skb, sizeof(u32), &u); } else if (m->datalen > 0) RTA_PUT_NOHDR(skb, m->datalen, (void *) m->data);