extern int tcf_register_action(struct tc_action_ops *a);
extern int tcf_unregister_action(struct tc_action_ops *a);
extern void tcf_action_destroy(struct tc_action *a, int bind);
-extern int tcf_action_exec(struct sk_buff *skb, struct tc_action *a);
+extern int tcf_action_exec(struct sk_buff *skb, struct tc_action *a, struct tcf_result *res);
extern int tcf_action_init(struct rtattr *rta, struct rtattr *est, struct tc_action *a,char *n, int ovr, int bind);
extern int tcf_action_init_1(struct rtattr *rta, struct rtattr *est, struct tc_action *a,char *n, int ovr, int bind);
extern int tcf_action_dump(struct sk_buff *skb, struct tc_action *a, int, int);
return a;
}
-int tcf_action_exec(struct sk_buff *skb,struct tc_action *act)
+int tcf_action_exec(struct sk_buff *skb,struct tc_action *act, struct tcf_result *res)
{
struct tc_action *a;
if (skb->tc_verd & TC_NCLS) {
skb->tc_verd = CLR_TC_NCLS(skb->tc_verd);
D2PRINTK("(%p)tcf_action_exec: cleared TC_NCLS in %s out %s\n",skb,skb->input_dev?skb->input_dev->name:"xxx",skb->dev->name);
- return TC_ACT_OK;
+ ret = TC_ACT_OK;
+ goto exec_done;
}
while ((a = act) != NULL) {
repeat:
}
exec_done:
+ if (skb->tc_classid > 0) {
+ res->classid = skb->tc_classid;
+ res->class = 0;
+ skb->tc_classid = 0;
+ }
return ret;
}
}
#endif
if (f->action) {
- int pol_res = tcf_action_exec(skb, f->action);
+ int pol_res = tcf_action_exec(skb, f->action, res);
if (pol_res >= 0)
return pol_res;
} else
#endif
#ifdef CONFIG_NET_CLS_ACT
if (n->action) {
- int pol_res = tcf_action_exec(skb, n->action);
- if (skb->tc_classid > 0) {
- res->classid = skb->tc_classid;
- skb->tc_classid = 0;
- }
-
+ int pol_res = tcf_action_exec(skb, n->action, res);
if (pol_res >= 0)
return pol_res;
} else