Commit 8d4390f5 authored by Pedro Tammela's avatar Pedro Tammela Committed by Jakub Kicinski

net/sched: act_api: conditional notification of events

As of today tc-action events are unconditionally built and sent to
RTNLGRP_TC. As with the introduction of rtnl_notify_needed we can check
before-hand if they are really needed.
Signed-off-by: default avatarPedro Tammela <pctammela@mojatatu.com>
Reviewed-by: default avatarJiri Pirko <jiri@nvidia.com>
Link: https://lore.kernel.org/r/20231208192847.714940-6-pctammela@mojatatu.comSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent c73724bf
......@@ -1785,30 +1785,45 @@ static int tcf_action_delete(struct net *net, struct tc_action *actions[])
return 0;
}
static int
tcf_reoffload_del_notify(struct net *net, struct tc_action *action)
static struct sk_buff *tcf_reoffload_del_notify_msg(struct net *net,
struct tc_action *action)
{
size_t attr_size = tcf_action_fill_size(action);
struct tc_action *actions[TCA_ACT_MAX_PRIO] = {
[0] = action,
};
const struct tc_action_ops *ops = action->ops;
struct sk_buff *skb;
int ret;
skb = alloc_skb(max(attr_size, NLMSG_GOODSIZE), GFP_KERNEL);
if (!skb)
return -ENOBUFS;
return ERR_PTR(-ENOBUFS);
if (tca_get_fill(skb, actions, 0, 0, 0, RTM_DELACTION, 0, 1, NULL) <= 0) {
kfree_skb(skb);
return -EINVAL;
return ERR_PTR(-EINVAL);
}
return skb;
}
static int tcf_reoffload_del_notify(struct net *net, struct tc_action *action)
{
const struct tc_action_ops *ops = action->ops;
struct sk_buff *skb;
int ret;
if (!rtnl_notify_needed(net, 0, RTNLGRP_TC)) {
skb = NULL;
} else {
skb = tcf_reoffload_del_notify_msg(net, action);
if (IS_ERR(skb))
return PTR_ERR(skb);
}
ret = tcf_idr_release_unsafe(action);
if (ret == ACT_P_DELETED) {
module_put(ops->owner);
ret = rtnetlink_send(skb, net, 0, RTNLGRP_TC, 0);
ret = rtnetlink_maybe_send(skb, net, 0, RTNLGRP_TC, 0);
} else {
kfree_skb(skb);
}
......@@ -1874,22 +1889,41 @@ int tcf_action_reoffload_cb(flow_indr_block_bind_cb_t *cb,
return 0;
}
static int
tcf_del_notify(struct net *net, struct nlmsghdr *n, struct tc_action *actions[],
u32 portid, size_t attr_size, struct netlink_ext_ack *extack)
static struct sk_buff *tcf_del_notify_msg(struct net *net, struct nlmsghdr *n,
struct tc_action *actions[],
u32 portid, size_t attr_size,
struct netlink_ext_ack *extack)
{
int ret;
struct sk_buff *skb;
skb = alloc_skb(max(attr_size, NLMSG_GOODSIZE), GFP_KERNEL);
if (!skb)
return -ENOBUFS;
return ERR_PTR(-ENOBUFS);
if (tca_get_fill(skb, actions, portid, n->nlmsg_seq, 0, RTM_DELACTION,
0, 2, extack) <= 0) {
NL_SET_ERR_MSG(extack, "Failed to fill netlink TC action attributes");
kfree_skb(skb);
return -EINVAL;
return ERR_PTR(-EINVAL);
}
return skb;
}
static int tcf_del_notify(struct net *net, struct nlmsghdr *n,
struct tc_action *actions[], u32 portid,
size_t attr_size, struct netlink_ext_ack *extack)
{
struct sk_buff *skb;
int ret;
if (!rtnl_notify_needed(net, n->nlmsg_flags, RTNLGRP_TC)) {
skb = NULL;
} else {
skb = tcf_del_notify_msg(net, n, actions, portid, attr_size,
extack);
if (IS_ERR(skb))
return PTR_ERR(skb);
}
/* now do the delete */
......@@ -1900,9 +1934,8 @@ tcf_del_notify(struct net *net, struct nlmsghdr *n, struct tc_action *actions[],
return ret;
}
ret = rtnetlink_send(skb, net, portid, RTNLGRP_TC,
n->nlmsg_flags & NLM_F_ECHO);
return ret;
return rtnetlink_maybe_send(skb, net, portid, RTNLGRP_TC,
n->nlmsg_flags & NLM_F_ECHO);
}
static int
......@@ -1953,25 +1986,44 @@ tca_action_gd(struct net *net, struct nlattr *nla, struct nlmsghdr *n,
return ret;
}
static int
tcf_add_notify(struct net *net, struct nlmsghdr *n, struct tc_action *actions[],
u32 portid, size_t attr_size, struct netlink_ext_ack *extack)
static struct sk_buff *tcf_add_notify_msg(struct net *net, struct nlmsghdr *n,
struct tc_action *actions[],
u32 portid, size_t attr_size,
struct netlink_ext_ack *extack)
{
struct sk_buff *skb;
skb = alloc_skb(max(attr_size, NLMSG_GOODSIZE), GFP_KERNEL);
if (!skb)
return -ENOBUFS;
return ERR_PTR(-ENOBUFS);
if (tca_get_fill(skb, actions, portid, n->nlmsg_seq, n->nlmsg_flags,
RTM_NEWACTION, 0, 0, extack) <= 0) {
NL_SET_ERR_MSG(extack, "Failed to fill netlink attributes while adding TC action");
kfree_skb(skb);
return -EINVAL;
return ERR_PTR(-EINVAL);
}
return skb;
}
static int tcf_add_notify(struct net *net, struct nlmsghdr *n,
struct tc_action *actions[], u32 portid,
size_t attr_size, struct netlink_ext_ack *extack)
{
struct sk_buff *skb;
if (!rtnl_notify_needed(net, n->nlmsg_flags, RTNLGRP_TC)) {
skb = NULL;
} else {
skb = tcf_add_notify_msg(net, n, actions, portid, attr_size,
extack);
if (IS_ERR(skb))
return PTR_ERR(skb);
}
return rtnetlink_send(skb, net, portid, RTNLGRP_TC,
n->nlmsg_flags & NLM_F_ECHO);
return rtnetlink_maybe_send(skb, net, portid, RTNLGRP_TC,
n->nlmsg_flags & NLM_F_ECHO);
}
static int tcf_action_add(struct net *net, struct nlattr *nla,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment