Thread (17 messages) flat view 17 messages, 3 authors, 2004-11-02
STALE7973d

[PATCH 3/6] cls_fw: Use generic routines to configure action/policer

From: Thomas Graf <tgraf@suug.ch>
Date: 2004-10-29 00:24:04

Adds a new function fw_change_attr using the new generic routines which
can be used to change attribute but also to initially set them to avoid
duplicated code.

Signed-off-by: Thomas Graf <tgraf@suug.ch>
--- linux-2.6.10-rc1-bk7.orig/net/sched/cls_fw.c	2004-10-29 00:27:10.000000000 +0200
+++ linux-2.6.10-rc1-bk7/net/sched/cls_fw.c	2004-10-29 00:27:19.000000000 +0200
@@ -155,11 +155,8 @@
 
 	for (h=0; h<256; h++) {
 		while ((f=head->ht[h]) != NULL) {
-			unsigned long cl;
 			head->ht[h] = f->next;
-
-			if ((cl = __cls_set_class(&f->res.class, 0)) != 0)
-				tp->q->ops->cl_ops->unbind_tcf(tp->q, cl);
+			tcf_unbind_filter(tp, &f->res);
 #ifdef CONFIG_NET_CLS_ACT
        if (f->action) {
                tcf_action_destroy(f->action,TCA_ACT_UNBIND);
@@ -187,14 +184,10 @@
 
 	for (fp=&head->ht[fw_hash(f->id)]; *fp; fp = &(*fp)->next) {
 		if (*fp == f) {
-			unsigned long cl;
-
 			tcf_tree_lock(tp);
 			*fp = f->next;
 			tcf_tree_unlock(tp);
-
-			if ((cl = cls_set_class(tp, &f->res.class, 0)) != 0)
-				tp->q->ops->cl_ops->unbind_tcf(tp->q, cl);
+			tcf_unbind_filter(tp, &f->res);
 #ifdef CONFIG_NET_CLS_ACT
        if (f->action) {
                tcf_action_destroy(f->action,TCA_ACT_UNBIND);
@@ -212,21 +205,67 @@
 	return -EINVAL;
 }
 
+static int
+fw_change_attrs(struct tcf_proto *tp, struct fw_filter *f,
+	struct rtattr **tb, struct rtattr **tca, unsigned long base)
+{
+	int err = -EINVAL;
+
+	if (tb[TCA_FW_CLASSID-1]) {
+		if (RTA_PAYLOAD(tb[TCA_FW_CLASSID-1]) != sizeof(u32))
+			goto errout;
+		f->res.classid = *(u32*)RTA_DATA(tb[TCA_FW_CLASSID-1]);
+		tcf_bind_filter(tp, &f->res, base);
+	}
+
+#ifdef CONFIG_NET_CLS_ACT
+	if (tb[TCA_FW_POLICE-1]) {
+		err = tcf_change_act_police(tp, &f->action, tb[TCA_FW_POLICE-1],
+			tca[TCA_RATE-1]);
+		if (err < 0)
+			goto errout;
+	}
+
+	if (tb[TCA_FW_ACT-1]) {
+		err = tcf_change_act(tp, &f->action, tb[TCA_FW_ACT-1],
+			tca[TCA_RATE-1]);
+		if (err < 0)
+			goto errout;
+	}
+
+#ifdef CONFIG_NET_CLS_IND
+	if (tb[TCA_FW_INDEV-1]) {
+		err = tcf_change_indev(tp, f->indev, tb[TCA_FW_INDEV-1]);
+		if (err < 0)
+			goto errout;
+	}
+#endif /* CONFIG_NET_CLS_IND */
+#else /* CONFIG_NET_CLS_ACT */
+#ifdef CONFIG_NET_CLS_POLICE
+	if (tb[TCA_FW_POLICE-1]) {
+		err = tcf_change_police(tp, &f->police, tb[TCA_FW_POLICE-1],
+			tca[TCA_RATE-1]);
+		if (err < 0)
+			goto errout;
+	}
+#endif /* CONFIG_NET_CLS_POLICE */
+#endif /* CONFIG_NET_CLS_ACT */
+
+	err = 0;
+errout:
+	return err;
+}
+
 static int fw_change(struct tcf_proto *tp, unsigned long base,
 		     u32 handle,
 		     struct rtattr **tca,
 		     unsigned long *arg)
 {
 	struct fw_head *head = (struct fw_head*)tp->root;
-	struct fw_filter *f;
+	struct fw_filter *f = (struct fw_filter *) *arg;
 	struct rtattr *opt = tca[TCA_OPTIONS-1];
 	struct rtattr *tb[TCA_FW_MAX];
 	int err;
-#ifdef CONFIG_NET_CLS_ACT
-       struct tc_action *act = NULL;
-       int ret;
-#endif
-
 
 	if (!opt)
 		return handle ? -EINVAL : 0;
@@ -234,85 +273,10 @@
 	if (rtattr_parse(tb, TCA_FW_MAX, RTA_DATA(opt), RTA_PAYLOAD(opt)) < 0)
 		return -EINVAL;
 
-	if ((f = (struct fw_filter*)*arg) != NULL) {
-		/* Node exists: adjust only classid */
-
+	if (f != NULL) {
 		if (f->id != handle && handle)
 			return -EINVAL;
-		if (tb[TCA_FW_CLASSID-1]) {
-			unsigned long cl;
-
-			f->res.classid = *(u32*)RTA_DATA(tb[TCA_FW_CLASSID-1]);
-			cl = tp->q->ops->cl_ops->bind_tcf(tp->q, base, f->res.classid);
-			cl = cls_set_class(tp, &f->res.class, cl);
-			if (cl)
-				tp->q->ops->cl_ops->unbind_tcf(tp->q, cl);
-		}
-#ifdef CONFIG_NET_CLS_ACT
-		if (tb[TCA_FW_POLICE-1]) {
-			act = kmalloc(sizeof(*act),GFP_KERNEL);
-			if (NULL == act)
-				return -ENOMEM;
-
-			memset(act,0,sizeof(*act));
-			ret = tcf_action_init_1(tb[TCA_FW_POLICE-1], tca[TCA_RATE-1] ,act,"police",TCA_ACT_NOREPLACE,TCA_ACT_BIND);
-			if (0 > ret){
-				tcf_action_destroy(act,TCA_ACT_UNBIND);
-				return ret;
-			}
-			act->type = TCA_OLD_COMPAT;
-
-			sch_tree_lock(tp->q);
-			act = xchg(&f->action, act);
-			sch_tree_unlock(tp->q);
-
-			tcf_action_destroy(act,TCA_ACT_UNBIND);
-
-		}
-
-		if(tb[TCA_FW_ACT-1]) {
-			act = kmalloc(sizeof(*act),GFP_KERNEL);
-			if (NULL == act)
-				return -ENOMEM;
-			memset(act,0,sizeof(*act));
-			ret = tcf_action_init(tb[TCA_FW_ACT-1], tca[TCA_RATE-1],act,NULL, TCA_ACT_NOREPLACE,TCA_ACT_BIND);
-			if (0 > ret) {
-				tcf_action_destroy(act,TCA_ACT_UNBIND);
-				return ret;
-			}
-
-			sch_tree_lock(tp->q);
-			act = xchg(&f->action, act);
-			sch_tree_unlock(tp->q);
-
-			tcf_action_destroy(act,TCA_ACT_UNBIND);
-		}
-#ifdef CONFIG_NET_CLS_IND
-		if(tb[TCA_FW_INDEV-1]) {
-			struct rtattr *idev = tb[TCA_FW_INDEV-1];
-			if (RTA_PAYLOAD(idev) >= IFNAMSIZ) {
-				printk("cls_fw: bad indev name %s\n",(char*)RTA_DATA(idev));
-				err = -EINVAL;
-				goto errout;
-			}
-			memset(f->indev,0,IFNAMSIZ);
-			sprintf(f->indev, "%s", (char*)RTA_DATA(idev));
-		}
-#endif
-#else /* only POLICE defined */
-#ifdef CONFIG_NET_CLS_POLICE
-		if (tb[TCA_FW_POLICE-1]) {
-			struct tcf_police *police = tcf_police_locate(tb[TCA_FW_POLICE-1], tca[TCA_RATE-1]);
-
-			tcf_tree_lock(tp);
-			police = xchg(&f->police, police);
-			tcf_tree_unlock(tp);
-
-			tcf_police_release(police,TCA_ACT_UNBIND);
-		}
-#endif
-#endif
-		return 0;
+		return fw_change_attrs(tp, f, tb, tca, base);
 	}
 
 	if (!handle)
@@ -336,45 +300,9 @@
 
 	f->id = handle;
 
-	if (tb[TCA_FW_CLASSID-1]) {
-		err = -EINVAL;
-		if (RTA_PAYLOAD(tb[TCA_FW_CLASSID-1]) != 4)
-			goto errout;
-		f->res.classid = *(u32*)RTA_DATA(tb[TCA_FW_CLASSID-1]);
-		cls_set_class(tp, &f->res.class, tp->q->ops->cl_ops->bind_tcf(tp->q, base, f->res.classid));
-	}
-
-#ifdef CONFIG_NET_CLS_ACT
-	if(tb[TCA_FW_ACT-1]) {
-		act = kmalloc(sizeof(*act),GFP_KERNEL);
-		if (NULL == act)
-			return -ENOMEM;
-		memset(act,0,sizeof(*act));
-		ret = tcf_action_init(tb[TCA_FW_ACT-1], tca[TCA_RATE-1],act,NULL,TCA_ACT_NOREPLACE,TCA_ACT_BIND);
-		if (0 > ret) {
-			tcf_action_destroy(act,TCA_ACT_UNBIND);
-			return ret;
-		}
-		f->action= act;
-	}
-#ifdef CONFIG_NET_CLS_IND
-		if(tb[TCA_FW_INDEV-1]) {
-			struct rtattr *idev = tb[TCA_FW_INDEV-1];
-			if (RTA_PAYLOAD(idev) >= IFNAMSIZ) {
-				printk("cls_fw: bad indev name %s\n",(char*)RTA_DATA(idev));
-				err = -EINVAL;
-				goto errout;
-			}
-			memset(f->indev,0,IFNAMSIZ);
-			sprintf(f->indev, "%s", (char*)RTA_DATA(idev));
-		}
-#endif
-#else
-#ifdef CONFIG_NET_CLS_POLICE
-	if (tb[TCA_FW_POLICE-1])
-		f->police = tcf_police_locate(tb[TCA_FW_POLICE-1], tca[TCA_RATE-1]);
-#endif
-#endif
+	err = fw_change_attrs(tp, f, tb, tca, base);
+	if (err < 0)
+		goto errout;
 
 	f->next = head->ht[fw_hash(handle)];
 	tcf_tree_lock(tp);
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help