diff options
author | WANG Cong <xiyou.wangcong@gmail.com> | 2017-08-05 07:31:42 +0300 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2017-08-08 00:12:17 +0300 |
commit | 54df2cf819a23dba4bb2c4134ed62659a7d324f5 (patch) | |
tree | 989986433ffd65cd0749e82b84e3366771de6cfc /net/sched/cls_api.c | |
parent | 08bd10ffb44d11000c6b2781e8d9066567e50e27 (diff) | |
download | linux-54df2cf819a23dba4bb2c4134ed62659a7d324f5.tar.xz |
net_sched: refactor notification code for RTM_DELTFILTER
It is confusing to use 'unsigned long fh' as both a handle
and a pointer, especially commit 9ee7837449b3
("net sched filters: fix notification of filter delete with proper handle").
This patch introduces tfilter_del_notify() so that we can
pass it as a pointer as before, and we don't need to check
RTM_DELTFILTER in tcf_fill_node() any more.
This prepares for the next patch.
Cc: Jamal Hadi Salim <jhs@mojatatu.com>
Cc: Jiri Pirko <jiri@resnulli.us>
Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sched/cls_api.c')
-rw-r--r-- | net/sched/cls_api.c | 44 |
1 files changed, 39 insertions, 5 deletions
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c index e655221c654e..afd099727aea 100644 --- a/net/sched/cls_api.c +++ b/net/sched/cls_api.c @@ -104,6 +104,10 @@ static int tfilter_notify(struct net *net, struct sk_buff *oskb, struct nlmsghdr *n, struct tcf_proto *tp, unsigned long fh, int event, bool unicast); +static int tfilter_del_notify(struct net *net, struct sk_buff *oskb, + struct nlmsghdr *n, struct tcf_proto *tp, + unsigned long fh, bool unicast, bool *last); + static void tfilter_notify_chain(struct net *net, struct sk_buff *oskb, struct nlmsghdr *n, struct tcf_chain *chain, int event) @@ -595,11 +599,10 @@ replay: } break; case RTM_DELTFILTER: - err = tp->ops->delete(tp, fh, &last); + err = tfilter_del_notify(net, skb, n, tp, fh, false, + &last); if (err) goto errout; - tfilter_notify(net, skb, n, tp, t->tcm_handle, - RTM_DELTFILTER, false); if (last) { tcf_chain_tp_remove(chain, &chain_info, tp); tcf_proto_destroy(tp); @@ -659,9 +662,9 @@ static int tcf_fill_node(struct net *net, struct sk_buff *skb, goto nla_put_failure; if (nla_put_u32(skb, TCA_CHAIN, tp->chain->index)) goto nla_put_failure; - tcm->tcm_handle = fh; - if (RTM_DELTFILTER != event) { + if (!fh) { tcm->tcm_handle = 0; + } else { if (tp->ops->dump && tp->ops->dump(net, tp, fh, skb, tcm) < 0) goto nla_put_failure; } @@ -698,6 +701,37 @@ static int tfilter_notify(struct net *net, struct sk_buff *oskb, n->nlmsg_flags & NLM_F_ECHO); } +static int tfilter_del_notify(struct net *net, struct sk_buff *oskb, + struct nlmsghdr *n, struct tcf_proto *tp, + unsigned long fh, bool unicast, bool *last) +{ + struct sk_buff *skb; + u32 portid = oskb ? NETLINK_CB(oskb).portid : 0; + int err; + + skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); + if (!skb) + return -ENOBUFS; + + if (tcf_fill_node(net, skb, tp, fh, portid, n->nlmsg_seq, + n->nlmsg_flags, RTM_DELTFILTER) <= 0) { + kfree_skb(skb); + return -EINVAL; + } + + err = tp->ops->delete(tp, fh, last); + if (err) { + kfree_skb(skb); + return err; + } + + if (unicast) + return netlink_unicast(net->rtnl, skb, portid, MSG_DONTWAIT); + + return rtnetlink_send(skb, net, portid, RTNLGRP_TC, + n->nlmsg_flags & NLM_F_ECHO); +} + struct tcf_dump_args { struct tcf_walker w; struct sk_buff *skb; |