- if (opt == NULL)
- return handle ? -EINVAL : 0;
-
- if (rtattr_parse(tb, TCA_ROUTE4_MAX, RTA_DATA(opt), RTA_PAYLOAD(opt)) < 0)
- return -EINVAL;
-
- if ((f = (struct route4_filter*)*arg) != NULL) {
- /* Node exists: adjust only classid */
-
- if (f->handle != handle && handle)
- return -EINVAL;
- if (tb[TCA_ROUTE4_CLASSID-1]) {
- unsigned long cl;
-
- f->res.classid = *(u32*)RTA_DATA(tb[TCA_ROUTE4_CLASSID-1]);
- cl = cls_set_class(tp, &f->res.class, tp->q->ops->cl_ops->bind_tcf(tp->q, base, f->res.classid));
- if (cl)
- tp->q->ops->cl_ops->unbind_tcf(tp->q, cl);
- }
-#ifdef CONFIG_NET_CLS_POLICE
- if (tb[TCA_ROUTE4_POLICE-1]) {
- struct tcf_police *police = tcf_police_locate(tb[TCA_ROUTE4_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
- return 0;
- }
-
- /* Now more serious part... */
-
- if (head == NULL) {
- head = kmalloc(sizeof(struct route4_head), GFP_KERNEL);
- if (head == NULL)
- return -ENOBUFS;
- memset(head, 0, sizeof(struct route4_head));
-
- tcf_tree_lock(tp);
- tp->root = head;
- tcf_tree_unlock(tp);
- }
-
- f = kmalloc(sizeof(struct route4_filter), GFP_KERNEL);
- if (f == NULL)
- return -ENOBUFS;
-
- memset(f, 0, sizeof(*f));