Patrick McHardy wrote:

Chris Wilson wrote:


My proposed solution is a new Netfilter table which packets pass through
on their way out to a device.There would be just a single terminal target,
CLASSIFY, which would enqueue the packet in the specified classifier.
Unclassified packets which drop off the end of the entry chain would pass
on to the old-style tc filtering system, for backwards compatibility.

i think with netfilter table you mean iptables table. iptables can only see ip, so you still
have the need for tc filters as they exist. The classify target can easily be made,
just set skb->priority to the class id and the qdisc will take care of the rest. if your company
wishes to sponsor me for writing one for you, go ahead ;)
sorry if my last mail sounded arrogant, i think you deserve honour for beeing willing to sponsor linux QoS development.
As sign of my appologies, take this CLASSIFY target patch against latest netfiler CVS ;) It is untested, but despite possible
easy-to-fix typos i hope it works. chmod +x userspace/extensions/.CLASSIFY-test after applying the patch.
Usage is:
-j CLASSIFY --set-class MAJOR:MINOR

Bye,
Patrick






diff -urN netfilter-clean/patch-o-matic/extra/CLASSIFY.patch 
netfilter_nfclassify/patch-o-matic/extra/CLASSIFY.patch
--- netfilter-clean/patch-o-matic/extra/CLASSIFY.patch  1970-01-01 01:00:00.000000000 
+0100
+++ netfilter_nfclassify/patch-o-matic/extra/CLASSIFY.patch     2003-01-25 
+02:41:19.000000000 +0100
@@ -0,0 +1,83 @@
+diff -urN linux-2.4.20-clean/include/linux/netfilter_ipv4/ipt_CLASSIFY.h 
+linux-2.4.20_nfclassify/include/linux/netfilter_ipv4/ipt_CLASSIFY.h
+--- linux-2.4.20-clean/include/linux/netfilter_ipv4/ipt_CLASSIFY.h     1970-01-01 
+01:00:00.000000000 +0100
++++ linux-2.4.20_nfclassify/include/linux/netfilter_ipv4/ipt_CLASSIFY.h        
+2003-01-25 02:11:35.000000000 +0100
+@@ -0,0 +1,8 @@
++#ifndef _IPT_CLASSIFY_H
++#define _IPT_CLASSIFY_H
++
++struct ipt_classify_target_info {
++      unsigned int priority;
++};
++
++#endif /*_IPT_CLASSIFY_H */
+diff -urN linux-2.4.20-clean/net/ipv4/netfilter/ipt_CLASSIFY.c 
+linux-2.4.20_nfclassify/net/ipv4/netfilter/ipt_CLASSIFY.c
+--- linux-2.4.20-clean/net/ipv4/netfilter/ipt_CLASSIFY.c       1970-01-01 
+01:00:00.000000000 +0100
++++ linux-2.4.20_nfclassify/net/ipv4/netfilter/ipt_CLASSIFY.c  2003-01-25 
+02:09:36.000000000 +0100
+@@ -0,0 +1,67 @@
++/* This is a module which is used for setting the skb->priority field of an skb for 
+qdisc classification. */
++#include <linux/module.h>
++#include <linux/skbuff.h>
++#include <linux/ip.h>
++#include <net/checksum.h>
++
++#include <linux/netfilter_ipv4/ip_tables.h>
++#include <linux/netfilter_ipv4/ipt_CLASSIFY.h>
++
++static unsigned int
++target(struct sk_buff **pskb,
++       unsigned int hooknum,
++       const struct net_device *in,
++       const struct net_device *out,
++       const void *targinfo,
++       void *userinfo)
++{
++      const struct ipt_classify_target_info *clinfo = targinfo;
++
++      if((*pskb)->priority != clinfo->priority) {
++              (*pskb)->priority = clinfo->priority;
++              (*pskb)->nfcache |= NFC_ALTERED;
++      }
++      return IPT_CONTINUE;
++}
++
++static int
++checkentry(const char *tablename,
++         const struct ipt_entry *e,
++           void *targinfo,
++           unsigned int targinfosize,
++           unsigned int hook_mask)
++{
++      if (targinfosize != IPT_ALIGN(sizeof(struct ipt_classify_target_info))) {
++              printk(KERN_WARNING "MARK: targinfosize %u != %Zu\n",
++                     targinfosize,
++                     IPT_ALIGN(sizeof(struct ipt_classify_target_info)));
++              return 0;
++      }
++
++      if (strcmp(tablename, "mangle") != 0) {
++              printk(KERN_WARNING "CLASSIFY: can only be called from \"mangle\" 
+table, not \"%s\"\n", tablename);
++              return 0;
++      }
++
++      return 1;
++}
++
++static struct ipt_target ipt_classify_reg
++= { { NULL, NULL }, "CLASSIFY", target, checkentry, NULL, THIS_MODULE };
++
++static int __init init(void)
++{
++      if (ipt_register_target(&ipt_classify_reg))
++              return -EINVAL;
++
++      return 0;
++}
++
++static void __exit fini(void)
++{
++      ipt_unregister_target(&ipt_classify_reg);
++}
++
++module_init(init);
++module_exit(fini);
++MODULE_LICENSE("GPL");
diff -urN netfilter-clean/patch-o-matic/extra/CLASSIFY.patch.config.in 
netfilter_nfclassify/patch-o-matic/extra/CLASSIFY.patch.config.in
--- netfilter-clean/patch-o-matic/extra/CLASSIFY.patch.config.in        1970-01-01 
01:00:00.000000000 +0100
+++ netfilter_nfclassify/patch-o-matic/extra/CLASSIFY.patch.config.in   2003-01-25 
+02:45:03.000000000 +0100
@@ -0,0 +1,2 @@
+      dep_tristate '    MIRROR target support (EXPERIMENTAL)' 
+CONFIG_IP_NF_TARGET_MIRROR $CONFIG_IP_NF_FILTER
+      dep_tristate '    CLASSIFY target support (EXPERIMENTAL)' 
+CONFIG_IP_NF_TARGET_CLASSIFY $CONFIG_IP_NF_FILTER
diff -urN netfilter-clean/patch-o-matic/extra/CLASSIFY.patch.help 
netfilter_nfclassify/patch-o-matic/extra/CLASSIFY.patch.help
--- netfilter-clean/patch-o-matic/extra/CLASSIFY.patch.help     1970-01-01 
01:00:00.000000000 +0100
+++ netfilter_nfclassify/patch-o-matic/extra/CLASSIFY.patch.help        2003-01-25 
+02:42:39.000000000 +0100
@@ -0,0 +1,5 @@
+Author: Patrick McHardy <[EMAIL PROTECTED]>
+Status: untested
+
+This patch adds support for the CLASSIFY target which sets skb->priority.
+Some qdiscs can use this value for classifying packets.
diff -urN netfilter-clean/patch-o-matic/extra/CLASSIFY.patch.makefile 
netfilter_nfclassify/patch-o-matic/extra/CLASSIFY.patch.makefile
--- netfilter-clean/patch-o-matic/extra/CLASSIFY.patch.makefile 1970-01-01 
01:00:00.000000000 +0100
+++ netfilter_nfclassify/patch-o-matic/extra/CLASSIFY.patch.makefile    2003-01-25 
+02:44:26.000000000 +0100
@@ -0,0 +1,2 @@
+obj-$(CONFIG_IP_NF_TARGET_MIRROR) += ipt_MIRROR.o
+obj-$(CONFIG_IP_NF_TARGET_CLASSIFY) += ipt_CLASSIFY.o
diff -urN netfilter-clean/userspace/extensions/.CLASSIFY-test 
netfilter_nfclassify/userspace/extensions/.CLASSIFY-test
--- netfilter-clean/userspace/extensions/.CLASSIFY-test 1970-01-01 01:00:00.000000000 
+0100
+++ netfilter_nfclassify/userspace/extensions/.CLASSIFY-test    2003-01-25 
+02:40:41.000000000 +0100
@@ -0,0 +1,3 @@
+#! /bin/sh
+[ -f $KERNEL_DIR/net/ipv4/netfilter/ipt_CLASSIFY.c ] && echo CLASSIFY
+
diff -urN netfilter-clean/userspace/extensions/libipt_CLASSIFY.c 
netfilter_nfclassify/userspace/extensions/libipt_CLASSIFY.c
--- netfilter-clean/userspace/extensions/libipt_CLASSIFY.c      1970-01-01 
01:00:00.000000000 +0100
+++ netfilter_nfclassify/userspace/extensions/libipt_CLASSIFY.c 2003-01-25 
+02:40:00.000000000 +0100
@@ -0,0 +1,125 @@
+/* Shared library add-on to iptables to add CLASSIFY target support. */
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <getopt.h>
+
+#include <iptables.h>
+#include <linux/netfilter_ipv4/ip_tables.h>
+#include <linux/netfilter_ipv4/ipt_CLASSIFY.h>
+#include <linux/pkt_sched.h>
+
+/* Function which prints out usage message. */
+static void
+help(void)
+{
+       printf(
+"CLASSIFY target v%s options:\n"
+"  --set-class [MAJOR:MINOR]    Set skb->priority value\n"
+"\n",
+IPTABLES_VERSION);
+}
+
+static struct option opts[] = {
+       { "set-class", 1, 0, '1' },
+       { 0 }
+};
+
+/* Initialize the target. */
+static void
+init(struct ipt_entry_target *t, unsigned int *nfcache)
+{
+}
+
+unsigned int string_to_priority(const unsigned char *s)
+{
+       char *t;
+
+       if ((t = strstr(s, ":")) == NULL)
+               return atoi(s);
+       *t = '\0';
+       return TC_H_MAKE(atoi(s) << 16, atoi(t+1));
+}
+
+/* Function which parses command options; returns true if it
+   ate an option */
+static int
+parse(int c, char **argv, int invert, unsigned int *flags,
+      const struct ipt_entry *entry,
+      struct ipt_entry_target **target)
+{
+       struct ipt_classify_target_info *clinfo
+               = (struct ipt_classify_target_info *)(*target)->data;
+
+       switch (c) {
+       case '1':
+               clinfo->priority = string_to_priority(optarg);
+               if (*flags)
+                       exit_error(PARAMETER_PROBLEM,
+                                  "CLASSIFY: Can't specify --set-class twice");
+               *flags = 1;
+               break;
+
+       default:
+               return 0;
+       }
+
+       return 1;
+}
+
+static void
+final_check(unsigned int flags)
+{
+       if (!flags)
+               exit_error(PARAMETER_PROBLEM,
+                          "CLASSIFY: Parameter --set-class is required");
+}
+
+static void
+print_class(unsigned int priority, int numeric)
+{
+       printf("%.4x:%.4x ", TC_H_MAJ(priority)>>16, TC_H_MIN(priority));
+}
+
+/* Prints out the targinfo. */
+static void
+print(const struct ipt_ip *ip,
+      const struct ipt_entry_target *target,
+      int numeric)
+{
+       const struct ipt_classify_target_info *clinfo =
+               (const struct ipt_classify_target_info *)target->data;
+       printf("CLASSIFY set ");
+       print_class(clinfo->priority, numeric);
+}
+
+/* Saves the union ipt_targinfo in parsable form to stdout. */
+static void
+save(const struct ipt_ip *ip, const struct ipt_entry_target *target)
+{
+       const struct ipt_classify_target_info *clinfo =
+               (const struct ipt_classify_target_info *)target->data;
+
+       printf("--set-class %.4x:%.4x ", TC_H_MAJ(priority)>>16, TC_H_MIN(priority));
+}
+
+static
+struct iptables_target classify
+= { NULL,
+    "CLASSIFY",
+    IPTABLES_VERSION,
+    IPT_ALIGN(sizeof(struct ipt_classify_target_info)),
+    IPT_ALIGN(sizeof(struct ipt_classify_target_info)),
+    &help,
+    &init,
+    &parse,
+    &final_check,
+    &print,
+    &save,
+    opts
+};
+
+void _init(void)
+{
+       register_target(&classify);
+}

Reply via email to