patch-2.2.4 linux/net/sched/cls_api.c
Next file: linux/net/sched/cls_fw.c
Previous file: linux/net/sched/Makefile
Back to the patch index
Back to the overall index
- Lines: 143
- Date:
Sun Mar 21 07:22:00 1999
- Orig file:
v2.2.3/linux/net/sched/cls_api.c
- Orig date:
Sat Sep 5 16:46:42 1998
diff -u --recursive --new-file v2.2.3/linux/net/sched/cls_api.c linux/net/sched/cls_api.c
@@ -7,6 +7,10 @@
* 2 of the License, or (at your option) any later version.
*
* Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
+ *
+ * Changes:
+ *
+ * Eduardo J. Blanco <ejbs@netlabs.com.uy> :990222: kmod support
*/
#include <asm/uaccess.h>
@@ -27,6 +31,7 @@
#include <linux/skbuff.h>
#include <linux/rtnetlink.h>
#include <linux/init.h>
+#include <linux/kmod.h>
#include <net/sock.h>
#include <net/pkt_sched.h>
@@ -87,21 +92,13 @@
/* Select new prio value from the range, managed by kernel. */
-static __inline__ u32 tcf_auto_prio(struct tcf_proto *tp, u32 prio)
+static __inline__ u32 tcf_auto_prio(struct tcf_proto *tp)
{
u32 first = TC_H_MAKE(0xC0000000U,0U);
- if (!tp || tp->next == NULL)
- return first;
-
- if (prio == TC_H_MAKE(0xFFFF0000U,0U))
- first = tp->prio+1;
- else
+ if (tp)
first = tp->prio-1;
- if (first == prio)
- first = tp->prio;
-
return first;
}
@@ -129,10 +126,7 @@
/* If no priority is given, user wants we allocated it. */
if (n->nlmsg_type != RTM_NEWTFILTER || !(n->nlmsg_flags&NLM_F_CREATE))
return -ENOENT;
- if (n->nlmsg_flags&NLM_F_APPEND)
- prio = TC_H_MAKE(0xFFFF0000U,0U);
- else
- prio = TC_H_MAKE(0x80000000U,0U);
+ prio = TC_H_MAKE(0x80000000U,0U);
}
/* Find head of filter chain. */
@@ -194,6 +188,18 @@
if ((tp = kmalloc(sizeof(*tp), GFP_KERNEL)) == NULL)
goto errout;
tp_ops = tcf_proto_lookup_ops(tca[TCA_KIND-1]);
+#ifdef CONFIG_KMOD
+ if (tp_ops==NULL && tca[TCA_KIND-1] != NULL) {
+ struct rtattr *kind = tca[TCA_KIND-1];
+ char module_name[4 + IFNAMSIZ + 1];
+
+ if (RTA_PAYLOAD(kind) <= IFNAMSIZ) {
+ sprintf(module_name, "cls_%s", (char*)RTA_DATA(kind));
+ request_module (module_name);
+ tp_ops = tcf_proto_lookup_ops(kind);
+ }
+ }
+#endif
if (tp_ops == NULL) {
err = -EINVAL;
kfree(tp);
@@ -202,7 +208,7 @@
memset(tp, 0, sizeof(*tp));
tp->ops = tp_ops;
tp->protocol = protocol;
- tp->prio = nprio ? : tcf_auto_prio(*back, prio);
+ tp->prio = nprio ? : tcf_auto_prio(*back);
tp->q = q;
tp->classify = tp_ops->classify;
tp->classid = parent;
@@ -220,7 +226,9 @@
if (fh == 0) {
if (n->nlmsg_type == RTM_DELTFILTER && t->tcm_handle == 0) {
+ net_serialize_enter();
*back = tp->next;
+ net_serialize_leave();
tp->ops->destroy(tp);
kfree(tp);
err = 0;
@@ -249,7 +257,7 @@
}
}
- err = tp->ops->change(tp, t->tcm_handle, tca, &fh);
+ err = tp->ops->change(tp, cl, t->tcm_handle, tca, &fh);
if (err == 0)
tfilter_notify(skb, n, tp, fh, RTM_NEWTFILTER);
@@ -336,12 +344,16 @@
return skb->len;
if ((dev = dev_get_by_index(tcm->tcm_ifindex)) == NULL)
return skb->len;
- if ((q = qdisc_lookup(dev, tcm->tcm_parent)) == NULL)
+ if (!tcm->tcm_parent)
+ q = dev->qdisc_sleeping;
+ else
+ q = qdisc_lookup(dev, TC_H_MAJ(tcm->tcm_parent));
+ if (q == NULL)
return skb->len;
- cops = q->ops->cl_ops;
+ if ((cops = q->ops->cl_ops) == NULL)
+ goto errout;
if (TC_H_MIN(tcm->tcm_parent)) {
- if (cops)
- cl = cops->get(q, tcm->tcm_parent);
+ cl = cops->get(q, tcm->tcm_parent);
if (cl == 0)
goto errout;
}
@@ -360,7 +372,7 @@
TC_H_MIN(tcm->tcm_info) != tp->protocol)
continue;
if (t > s_t)
- memset(&cb->args[1], 0, sizeof(cb->args)-sizeof(int));
+ memset(&cb->args[1], 0, sizeof(cb->args)-sizeof(cb->args[0]));
if (cb->args[1] == 0) {
if (tcf_fill_node(skb, tp, 0, NETLINK_CB(cb->skb).pid,
cb->nlh->nlmsg_seq, NLM_F_MULTI, RTM_NEWTFILTER) <= 0) {
@@ -418,8 +430,8 @@
#ifdef CONFIG_NET_CLS_U32
INIT_TC_FILTER(u32);
#endif
-#ifdef CONFIG_NET_CLS_ROUTE
- INIT_TC_FILTER(route);
+#ifdef CONFIG_NET_CLS_ROUTE4
+ INIT_TC_FILTER(route4);
#endif
#ifdef CONFIG_NET_CLS_FW
INIT_TC_FILTER(fw);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)