net: sched: extend proto ops with 'put' callback

Add optional tp->ops->put() API to be implemented for filter reference
counting. This new function is called by cls API to release filter
reference for filters returned by tp->ops->change() or tp->ops->get()
functions. Implement tfilter_put() helper to call tp->ops->put() only for
classifiers that implement it.

Signed-off-by: Vlad Buslov <vladbu@mellanox.com>
Acked-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Vlad Buslov 2019-02-11 10:55:44 +02:00 коммит произвёл David S. Miller
Родитель ec6743a109
Коммит 7d5509fa0d
2 изменённых файлов: 12 добавлений и 1 удалений

Просмотреть файл

@ -277,6 +277,7 @@ struct tcf_proto_ops {
struct netlink_ext_ack *extack); struct netlink_ext_ack *extack);
void* (*get)(struct tcf_proto*, u32 handle); void* (*get)(struct tcf_proto*, u32 handle);
void (*put)(struct tcf_proto *tp, void *f);
int (*change)(struct net *net, struct sk_buff *, int (*change)(struct net *net, struct sk_buff *,
struct tcf_proto*, unsigned long, struct tcf_proto*, unsigned long,
u32 handle, struct nlattr **, u32 handle, struct nlattr **,

Просмотреть файл

@ -1870,6 +1870,12 @@ static void tfilter_notify_chain(struct net *net, struct sk_buff *oskb,
q, parent, NULL, event, false); q, parent, NULL, event, false);
} }
static void tfilter_put(struct tcf_proto *tp, void *fh)
{
if (tp->ops->put && fh)
tp->ops->put(tp, fh);
}
static int tc_new_tfilter(struct sk_buff *skb, struct nlmsghdr *n, static int tc_new_tfilter(struct sk_buff *skb, struct nlmsghdr *n,
struct netlink_ext_ack *extack) struct netlink_ext_ack *extack)
{ {
@ -2012,6 +2018,7 @@ replay:
goto errout; goto errout;
} }
} else if (n->nlmsg_flags & NLM_F_EXCL) { } else if (n->nlmsg_flags & NLM_F_EXCL) {
tfilter_put(tp, fh);
NL_SET_ERR_MSG(extack, "Filter already exists"); NL_SET_ERR_MSG(extack, "Filter already exists");
err = -EEXIST; err = -EEXIST;
goto errout; goto errout;
@ -2026,9 +2033,11 @@ replay:
err = tp->ops->change(net, skb, tp, cl, t->tcm_handle, tca, &fh, err = tp->ops->change(net, skb, tp, cl, t->tcm_handle, tca, &fh,
n->nlmsg_flags & NLM_F_CREATE ? TCA_ACT_NOREPLACE : TCA_ACT_REPLACE, n->nlmsg_flags & NLM_F_CREATE ? TCA_ACT_NOREPLACE : TCA_ACT_REPLACE,
extack); extack);
if (err == 0) if (err == 0) {
tfilter_notify(net, skb, n, tp, block, q, parent, fh, tfilter_notify(net, skb, n, tp, block, q, parent, fh,
RTM_NEWTFILTER, false); RTM_NEWTFILTER, false);
tfilter_put(tp, fh);
}
errout: errout:
if (err && tp_created) if (err && tp_created)
@ -2259,6 +2268,7 @@ static int tc_get_tfilter(struct sk_buff *skb, struct nlmsghdr *n,
NL_SET_ERR_MSG(extack, "Failed to send filter notify message"); NL_SET_ERR_MSG(extack, "Failed to send filter notify message");
} }
tfilter_put(tp, fh);
errout: errout:
if (chain) { if (chain) {
if (tp && !IS_ERR(tp)) if (tp && !IS_ERR(tp))