|
@@ -45,7 +45,7 @@ void tcf_hash_destroy(struct tc_action *a)
|
|
|
}
|
|
|
EXPORT_SYMBOL(tcf_hash_destroy);
|
|
|
|
|
|
-int tcf_hash_release(struct tc_action *a, int bind)
|
|
|
+int __tcf_hash_release(struct tc_action *a, bool bind, bool strict)
|
|
|
{
|
|
|
struct tcf_common *p = a->priv;
|
|
|
int ret = 0;
|
|
@@ -53,7 +53,7 @@ int tcf_hash_release(struct tc_action *a, int bind)
|
|
|
if (p) {
|
|
|
if (bind)
|
|
|
p->tcfc_bindcnt--;
|
|
|
- else if (p->tcfc_bindcnt > 0)
|
|
|
+ else if (strict && p->tcfc_bindcnt > 0)
|
|
|
return -EPERM;
|
|
|
|
|
|
p->tcfc_refcnt--;
|
|
@@ -64,9 +64,10 @@ int tcf_hash_release(struct tc_action *a, int bind)
|
|
|
ret = 1;
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
return ret;
|
|
|
}
|
|
|
-EXPORT_SYMBOL(tcf_hash_release);
|
|
|
+EXPORT_SYMBOL(__tcf_hash_release);
|
|
|
|
|
|
static int tcf_dump_walker(struct sk_buff *skb, struct netlink_callback *cb,
|
|
|
struct tc_action *a)
|
|
@@ -136,7 +137,7 @@ static int tcf_del_walker(struct sk_buff *skb, struct tc_action *a)
|
|
|
head = &hinfo->htab[tcf_hash(i, hinfo->hmask)];
|
|
|
hlist_for_each_entry_safe(p, n, head, tcfc_head) {
|
|
|
a->priv = p;
|
|
|
- ret = tcf_hash_release(a, 0);
|
|
|
+ ret = __tcf_hash_release(a, false, true);
|
|
|
if (ret == ACT_P_DELETED) {
|
|
|
module_put(a->ops->owner);
|
|
|
n_i++;
|
|
@@ -408,7 +409,7 @@ int tcf_action_destroy(struct list_head *actions, int bind)
|
|
|
int ret = 0;
|
|
|
|
|
|
list_for_each_entry_safe(a, tmp, actions, list) {
|
|
|
- ret = tcf_hash_release(a, bind);
|
|
|
+ ret = __tcf_hash_release(a, bind, true);
|
|
|
if (ret == ACT_P_DELETED)
|
|
|
module_put(a->ops->owner);
|
|
|
else if (ret < 0)
|