aboutsummaryrefslogtreecommitdiffstats
path: root/net/dcb
diff options
context:
space:
mode:
authorThomas Graf <tgraf@suug.ch>2012-06-12 22:54:54 -0400
committerDavid S. Miller <davem@davemloft.net>2012-06-13 18:46:34 -0400
commit33a03aadb52fa05d28aba6d8f0c03c7b3b905897 (patch)
tree4e8fdc1321d516c9a297ece6babde6f164475c80 /net/dcb
parent43b03f1f6d6832d744918947d185a7aee89d1e0f (diff)
dcbnl: Prepare framework to shorten handling functions
There is no need to allocate and send the reply message in each handling function separately. Instead, the reply skb can be allocated and sent in dcb_doit() directly. Signed-off-by: Thomas Graf <tgraf@suug.ch> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/dcb')
-rw-r--r--net/dcb/dcbnl.c71
1 files changed, 71 insertions, 0 deletions
diff --git a/net/dcb/dcbnl.c b/net/dcb/dcbnl.c
index 656c7c75b192..5520e431b072 100644
--- a/net/dcb/dcbnl.c
+++ b/net/dcb/dcbnl.c
@@ -196,6 +196,34 @@ static const struct nla_policy dcbnl_featcfg_nest[DCB_FEATCFG_ATTR_MAX + 1] = {
196static LIST_HEAD(dcb_app_list); 196static LIST_HEAD(dcb_app_list);
197static DEFINE_SPINLOCK(dcb_lock); 197static DEFINE_SPINLOCK(dcb_lock);
198 198
199static struct sk_buff *dcbnl_newmsg(int type, u8 cmd, u32 port, u32 seq,
200 u32 flags, struct nlmsghdr **nlhp)
201{
202 struct sk_buff *skb;
203 struct dcbmsg *dcb;
204 struct nlmsghdr *nlh;
205
206 skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
207 if (!skb)
208 return NULL;
209
210 nlh = nlmsg_put(skb, port, seq, type, sizeof(*dcb), flags);
211 if (!nlh) {
212 /* header should always fit, allocation must be buggy */
213 BUG();
214 }
215
216 dcb = nlmsg_data(nlh);
217 dcb->dcb_family = AF_UNSPEC;
218 dcb->cmd = cmd;
219 dcb->dcb_pad = 0;
220
221 if (nlhp)
222 *nlhp = nlh;
223
224 return skb;
225}
226
199/* standard netlink reply call */ 227/* standard netlink reply call */
200static int dcbnl_reply(u8 value, u8 event, u8 cmd, u8 attr, u32 pid, 228static int dcbnl_reply(u8 value, u8 event, u8 cmd, u8 attr, u32 pid,
201 u32 seq, u16 flags) 229 u32 seq, u16 flags)
@@ -1922,6 +1950,19 @@ static int dcbnl_cee_get(struct net_device *netdev, struct nlattr **tb,
1922 return err; 1950 return err;
1923} 1951}
1924 1952
1953struct reply_func {
1954 /* reply netlink message type */
1955 int type;
1956
1957 /* function to fill message contents */
1958 int (*cb)(struct net_device *, struct nlmsghdr *, u32,
1959 struct nlattr **, struct sk_buff *);
1960};
1961
1962static const struct reply_func reply_funcs[DCB_CMD_MAX+1] = {
1963 /* FIXME: add reply defs */
1964};
1965
1925static int dcb_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) 1966static int dcb_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
1926{ 1967{
1927 struct net *net = sock_net(skb->sk); 1968 struct net *net = sock_net(skb->sk);
@@ -1930,6 +1971,9 @@ static int dcb_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
1930 struct nlattr *tb[DCB_ATTR_MAX + 1]; 1971 struct nlattr *tb[DCB_ATTR_MAX + 1];
1931 u32 pid = skb ? NETLINK_CB(skb).pid : 0; 1972 u32 pid = skb ? NETLINK_CB(skb).pid : 0;
1932 int ret = -EINVAL; 1973 int ret = -EINVAL;
1974 struct sk_buff *reply_skb;
1975 struct nlmsghdr *reply_nlh;
1976 const struct reply_func *fn;
1933 1977
1934 if (!net_eq(net, &init_net)) 1978 if (!net_eq(net, &init_net))
1935 return -EINVAL; 1979 return -EINVAL;
@@ -1939,6 +1983,14 @@ static int dcb_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
1939 if (ret < 0) 1983 if (ret < 0)
1940 return ret; 1984 return ret;
1941 1985
1986 if (dcb->cmd > DCB_CMD_MAX)
1987 return -EINVAL;
1988
1989 /* check if a reply function has been defined for the command */
1990 fn = &reply_funcs[dcb->cmd];
1991 if (!fn->cb)
1992 return -EOPNOTSUPP;
1993
1942 if (!tb[DCB_ATTR_IFNAME]) 1994 if (!tb[DCB_ATTR_IFNAME])
1943 return -EINVAL; 1995 return -EINVAL;
1944 1996
@@ -1949,6 +2001,25 @@ static int dcb_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
1949 if (!netdev->dcbnl_ops) 2001 if (!netdev->dcbnl_ops)
1950 goto errout; 2002 goto errout;
1951 2003
2004 reply_skb = dcbnl_newmsg(fn->type, dcb->cmd, pid, nlh->nlmsg_seq,
2005 nlh->nlmsg_flags, &reply_nlh);
2006 if (!reply_skb) {
2007 ret = -ENOBUFS;
2008 goto out;
2009 }
2010
2011 ret = fn->cb(netdev, nlh, nlh->nlmsg_seq, tb, reply_skb);
2012 if (ret < 0) {
2013 nlmsg_free(reply_skb);
2014 goto out;
2015 }
2016
2017 nlmsg_end(reply_skb, reply_nlh);
2018
2019 ret = rtnl_unicast(reply_skb, &init_net, pid);
2020 if (ret)
2021 goto out;
2022
1952 switch (dcb->cmd) { 2023 switch (dcb->cmd) {
1953 case DCB_CMD_GSTATE: 2024 case DCB_CMD_GSTATE:
1954 ret = dcbnl_getstate(netdev, tb, pid, nlh->nlmsg_seq, 2025 ret = dcbnl_getstate(netdev, tb, pid, nlh->nlmsg_seq,