[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20180112154704.1694-9-jiri@resnulli.us>
Date: Fri, 12 Jan 2018 16:46:58 +0100
From: Jiri Pirko <jiri@...nulli.us>
To: netdev@...r.kernel.org
Cc: davem@...emloft.net, jhs@...atatu.com, xiyou.wangcong@...il.com,
mlxsw@...lanox.com, andrew@...n.ch,
vivien.didelot@...oirfairelinux.com, f.fainelli@...il.com,
michael.chan@...adcom.com, ganeshgr@...lsio.com,
saeedm@...lanox.com, matanb@...lanox.com, leonro@...lanox.com,
idosch@...lanox.com, jakub.kicinski@...ronome.com,
simon.horman@...ronome.com, pieter.jansenvanvuuren@...ronome.com,
john.hurley@...ronome.com, alexander.h.duyck@...el.com,
ogerlitz@...lanox.com, john.fastabend@...il.com,
daniel@...earbox.net, dsahern@...il.com
Subject: [patch net-next v8 08/14] net: sched: add rt netlink message type for block get
From: Jiri Pirko <jiri@...lanox.com>
Add simple block get operation which primary purpose is to check the
block existence by block index.
Signed-off-by: Jiri Pirko <jiri@...lanox.com>
---
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
Powered by blists - more mailing lists