+static int
+fw_change_attrs(struct tcf_proto *tp, struct fw_filter *f,
+ struct rtattr **tb, struct rtattr **tca, unsigned long base)
+{
+ struct tcf_exts e;
+ int err;
+
+ err = tcf_exts_validate(tp, tb, tca[TCA_RATE-1], &e, &fw_ext_map);
+ if (err < 0)
+ return err;
+
+ 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_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 */
+
+ tcf_exts_change(tp, &f->exts, &e);
+
+ return 0;
+errout:
+ tcf_exts_destroy(tp, &e);
+ return err;
+}
+