diff -Nru linux-2.6.10-bk4.orig/include/linux/pkt_cls.h linux-2.6.10-bk4/include/linux/pkt_cls.h --- linux-2.6.10-bk4.orig/include/linux/pkt_cls.h 2005-01-02 22:44:16.000000000 +0100 +++ linux-2.6.10-bk4/include/linux/pkt_cls.h 2005-01-02 22:44:31.000000000 +0100 @@ -347,6 +347,7 @@ { TCF_EM_CONTAINER, TCF_EM_U32, + TCF_EM_NBYTE, __TCF_EM_MAX }; @@ -387,4 +388,11 @@ TCF_EM_OPND_LT }; +struct tcf_em_nbyte +{ + __u16 off; + __u16 len:12; + __u8 layer:4; +}; + #endif diff -Nru linux-2.6.10-bk4.orig/net/sched/Kconfig linux-2.6.10-bk4/net/sched/Kconfig --- linux-2.6.10-bk4.orig/net/sched/Kconfig 2005-01-02 22:44:16.000000000 +0100 +++ linux-2.6.10-bk4/net/sched/Kconfig 2005-01-02 22:44:31.000000000 +0100 @@ -387,6 +387,12 @@ ---help--- TODO +config NET_EMATCH_NBYTE + tristate "N-Byte" + depends on NET_EMATCH + ---help--- + TODO + config NET_CLS_ACT bool "Packet ACTION" depends on EXPERIMENTAL && NET_CLS && NET_QOS diff -Nru linux-2.6.10-bk4.orig/net/sched/Makefile linux-2.6.10-bk4/net/sched/Makefile --- linux-2.6.10-bk4.orig/net/sched/Makefile 2005-01-02 22:44:16.000000000 +0100 +++ linux-2.6.10-bk4/net/sched/Makefile 2005-01-02 22:44:31.000000000 +0100 @@ -35,3 +35,4 @@ obj-$(CONFIG_NET_CLS_RSVP6) += cls_rsvp6.o obj-$(CONFIG_NET_EMATCH) += ematch.o obj-$(CONFIG_NET_EMATCH_U32) += em_u32.o +obj-$(CONFIG_NET_EMATCH_NBYTE) += em_nbyte.o diff -Nru linux-2.6.10-bk4.orig/net/sched/em_nbyte.c linux-2.6.10-bk4/net/sched/em_nbyte.c --- linux-2.6.10-bk4.orig/net/sched/em_nbyte.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.10-bk4/net/sched/em_nbyte.c 2005-01-02 22:54:20.000000000 +0100 @@ -0,0 +1,95 @@ +/* + * net/sched/em_nbyte.c N-Byte ematch + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * Authors: Thomas Graf + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct nbyte_data +{ + struct tcf_em_nbyte hdr; + char pattern[0]; +}; + +static int em_nbyte_validate(struct tcf_proto *tp, void *data, int len, + struct tcf_ematch *m) +{ + struct tcf_em_nbyte *n = data; + + if (len < sizeof(*n) || len < (sizeof(*n) + n->len)) + return -EINVAL; + + m->data = (unsigned long) kmalloc(sizeof(*n) + n->len, GFP_KERNEL); + if (!m->data) + return -ENOBUFS; + + memcpy((void *) m->data, data, sizeof(*n) + n->len); + return 0; +} + +static int em_nbyte_match(struct sk_buff *skb, struct tcf_ematch *m) +{ + struct nbyte_data *d = (struct nbyte_data *) m->data; + u8 *ptr = tcf_get_base_ptr(skb, d->hdr.layer); + + if (unlikely(!tcf_valid_offset(skb, ptr, d->hdr.off, d->hdr.len))) + return 0; + + return !memcmp(ptr + d->hdr.off, d->pattern, d->hdr.len); +} + +static int em_nbyte_destroy(struct tcf_proto *tp, struct tcf_ematch *m) +{ + kfree((void *) m->data); + return 0; +} + +static int em_nbyte_dump(struct sk_buff *skb, struct tcf_ematch *m) +{ + struct nbyte_data *d = (struct nbyte_data *) m->data; + RTA_PUT_NOHDR(skb, sizeof(*d) + d->hdr.len, d); + return 0; +rtattr_failure: + return -1; +} + +static struct tcf_ematch_ops em_nbyte_ops = { + .kind = TCF_EM_NBYTE, + .change = em_nbyte_validate, + .match = em_nbyte_match, + .destroy = em_nbyte_destroy, + .dump = em_nbyte_dump, + .owner = THIS_MODULE, + .link = LIST_HEAD_INIT(em_nbyte_ops.link) +}; + +static int __init init_em_nbyte(void) +{ + return tcf_em_register(&em_nbyte_ops); +} + +static void __exit exit_em_nbyte(void) +{ + tcf_em_unregister(&em_nbyte_ops); +} + +MODULE_LICENSE("GPL"); + +module_init(init_em_nbyte); +module_exit(exit_em_nbyte); +