[patch net-next v8 08/14] net: sched: add rt netlink message type for block get
From: Jiri Pirko <jiri@resnulli.us>
Date: 2018-01-12 15:47:15
Subsystem:
networking [general], selinux security module, tc subsystem, the rest · Maintainers:
"David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Paul Moore, Stephen Smalley, Jamal Hadi Salim, Jiri Pirko, Linus Torvalds
From: Jiri Pirko <redacted> Add simple block get operation which primary purpose is to check the block existence by block index. Signed-off-by: Jiri Pirko <redacted> --- v6->v7: - new patch --- include/uapi/linux/rtnetlink.h | 6 ++++ net/sched/cls_api.c | 64 ++++++++++++++++++++++++++++++++++++++++++ security/selinux/nlmsgtab.c | 5 +++- 3 files changed, 74 insertions(+), 1 deletion(-)
diff --git a/include/uapi/linux/rtnetlink.h b/include/uapi/linux/rtnetlink.h
index da878f2..4b1f626 100644
--- a/include/uapi/linux/rtnetlink.h
+++ b/include/uapi/linux/rtnetlink.h@@ -150,6 +150,12 @@ enum { RTM_NEWCACHEREPORT = 96, #define RTM_NEWCACHEREPORT RTM_NEWCACHEREPORT + RTM_NEWBLOCK = 100, +#define RTM_NEWBLOCK RTM_NEWBLOCK + RTM_DELBLOCK, +#define RTM_DELBLOCK RTM_DELBLOCK + RTM_GETBLOCK, +#define RTM_GETBLOCK RTM_GETBLOCK __RTM_MAX, #define RTM_MAX (((__RTM_MAX + 3) & ~3) - 1) };
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
index d687e58..14e4f20 100644
--- a/net/sched/cls_api.c
+++ b/net/sched/cls_api.c@@ -1553,6 +1553,69 @@ int tc_setup_cb_call(struct tcf_block *block, struct tcf_exts *exts, } EXPORT_SYMBOL(tc_setup_cb_call); +static int block_notify_fill(struct net *net, struct sk_buff *skb, + struct tcf_block *block, u32 portid, u32 seq, + u16 flags, int event) +{ + struct nlmsghdr *nlh; + struct tcmsg *tcm; + + nlh = nlmsg_put(skb, portid, seq, event, sizeof(*tcm), flags); + if (!nlh) + return -EMSGSIZE; + tcm = nlmsg_data(nlh); + memset(tcm, 0, sizeof(*tcm)); + tcm->tcm_family = AF_UNSPEC; + tcm->tcm_ifindex = TCM_IFINDEX_MAGIC_BLOCK; + tcm->tcm_block_index = block->index; + return 0; +} + +static int block_notify(struct net *net, struct sk_buff *oskb, + struct nlmsghdr *n, struct tcf_block *block, int event) +{ + u32 portid = NETLINK_CB(oskb).portid; + struct sk_buff *skb; + int err; + + skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); + if (!skb) + return -ENOBUFS; + + err = block_notify_fill(net, skb, block, portid, + n->nlmsg_seq, n->nlmsg_flags, event); + if (err) { + kfree_skb(skb); + return err; + } + + return netlink_unicast(net->rtnl, skb, portid, MSG_DONTWAIT); +} + +static int tc_ctl_block(struct sk_buff *skb, struct nlmsghdr *n, + struct netlink_ext_ack *extack) +{ + struct net *net = sock_net(skb->sk); + struct tcf_block *block; + struct tcmsg *tcm; + + if (n->nlmsg_len < nlmsg_msg_size(sizeof(*tcm))) + return -EINVAL; + + tcm = nlmsg_data(n); + + if (tcm->tcm_ifindex != TCM_IFINDEX_MAGIC_BLOCK) + return -EINVAL; + + block = tcf_block_lookup(net, tcm->tcm_block_index); + if (!block) { + NL_SET_ERR_MSG(extack, "Block with the given index does not exist"); + return -EINVAL; + } + + return block_notify(net, skb, n, block, RTM_NEWBLOCK); +} + static __net_init int tcf_net_init(struct net *net) { struct tcf_net *tn = net_generic(net, tcf_net_id);
@@ -1591,6 +1654,7 @@ static int __init tc_filter_init(void) rtnl_register(PF_UNSPEC, RTM_DELTFILTER, tc_ctl_tfilter, NULL, 0); rtnl_register(PF_UNSPEC, RTM_GETTFILTER, tc_ctl_tfilter, tc_dump_tfilter, 0); + rtnl_register(PF_UNSPEC, RTM_GETBLOCK, tc_ctl_block, NULL, 0); return 0; }
diff --git a/security/selinux/nlmsgtab.c b/security/selinux/nlmsgtab.c
index 7b7433a..4e95a46 100644
--- a/security/selinux/nlmsgtab.c
+++ b/security/selinux/nlmsgtab.c@@ -80,6 +80,9 @@ static const struct nlmsg_perm nlmsg_route_perms[] = { RTM_NEWSTATS, NETLINK_ROUTE_SOCKET__NLMSG_READ }, { RTM_GETSTATS, NETLINK_ROUTE_SOCKET__NLMSG_READ }, { RTM_NEWCACHEREPORT, NETLINK_ROUTE_SOCKET__NLMSG_READ }, + { RTM_NEWBLOCK, NETLINK_ROUTE_SOCKET__NLMSG_READ }, + { RTM_DELBLOCK, NETLINK_ROUTE_SOCKET__NLMSG_READ }, + { RTM_GETBLOCK, NETLINK_ROUTE_SOCKET__NLMSG_READ }, }; static const struct nlmsg_perm nlmsg_tcpdiag_perms[] =
@@ -159,7 +162,7 @@ int selinux_nlmsg_lookup(u16 sclass, u16 nlmsg_type, u32 *perm) switch (sclass) { case SECCLASS_NETLINK_ROUTE_SOCKET: /* RTM_MAX always point to RTM_SETxxxx, ie RTM_NEWxxx + 3 */ - BUILD_BUG_ON(RTM_MAX != (RTM_NEWCACHEREPORT + 3)); + BUILD_BUG_ON(RTM_MAX != (RTM_NEWBLOCK + 3)); err = nlmsg_perm(nlmsg_type, perm, nlmsg_route_perms, sizeof(nlmsg_route_perms)); break;
--
2.9.5