Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 314256
b: refs/heads/master
c: 33a03aa
h: refs/heads/master
v: v3
  • Loading branch information
Thomas Graf authored and David S. Miller committed Jun 13, 2012
1 parent b1f2699 commit ece3de3
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 43b03f1f6d6832d744918947d185a7aee89d1e0f
refs/heads/master: 33a03aadb52fa05d28aba6d8f0c03c7b3b905897
71 changes: 71 additions & 0 deletions trunk/net/dcb/dcbnl.c
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,34 @@ static const struct nla_policy dcbnl_featcfg_nest[DCB_FEATCFG_ATTR_MAX + 1] = {
static LIST_HEAD(dcb_app_list);
static DEFINE_SPINLOCK(dcb_lock);

static struct sk_buff *dcbnl_newmsg(int type, u8 cmd, u32 port, u32 seq,
u32 flags, struct nlmsghdr **nlhp)
{
struct sk_buff *skb;
struct dcbmsg *dcb;
struct nlmsghdr *nlh;

skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
if (!skb)
return NULL;

nlh = nlmsg_put(skb, port, seq, type, sizeof(*dcb), flags);
if (!nlh) {
/* header should always fit, allocation must be buggy */
BUG();
}

dcb = nlmsg_data(nlh);
dcb->dcb_family = AF_UNSPEC;
dcb->cmd = cmd;
dcb->dcb_pad = 0;

if (nlhp)
*nlhp = nlh;

return skb;
}

/* standard netlink reply call */
static int dcbnl_reply(u8 value, u8 event, u8 cmd, u8 attr, u32 pid,
u32 seq, u16 flags)
Expand Down Expand Up @@ -1922,6 +1950,19 @@ static int dcbnl_cee_get(struct net_device *netdev, struct nlattr **tb,
return err;
}

struct reply_func {
/* reply netlink message type */
int type;

/* function to fill message contents */
int (*cb)(struct net_device *, struct nlmsghdr *, u32,
struct nlattr **, struct sk_buff *);
};

static const struct reply_func reply_funcs[DCB_CMD_MAX+1] = {
/* FIXME: add reply defs */
};

static int dcb_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
{
struct net *net = sock_net(skb->sk);
Expand All @@ -1930,6 +1971,9 @@ static int dcb_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
struct nlattr *tb[DCB_ATTR_MAX + 1];
u32 pid = skb ? NETLINK_CB(skb).pid : 0;
int ret = -EINVAL;
struct sk_buff *reply_skb;
struct nlmsghdr *reply_nlh;
const struct reply_func *fn;

if (!net_eq(net, &init_net))
return -EINVAL;
Expand All @@ -1939,6 +1983,14 @@ static int dcb_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
if (ret < 0)
return ret;

if (dcb->cmd > DCB_CMD_MAX)
return -EINVAL;

/* check if a reply function has been defined for the command */
fn = &reply_funcs[dcb->cmd];
if (!fn->cb)
return -EOPNOTSUPP;

if (!tb[DCB_ATTR_IFNAME])
return -EINVAL;

Expand All @@ -1949,6 +2001,25 @@ static int dcb_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
if (!netdev->dcbnl_ops)
goto errout;

reply_skb = dcbnl_newmsg(fn->type, dcb->cmd, pid, nlh->nlmsg_seq,
nlh->nlmsg_flags, &reply_nlh);
if (!reply_skb) {
ret = -ENOBUFS;
goto out;
}

ret = fn->cb(netdev, nlh, nlh->nlmsg_seq, tb, reply_skb);
if (ret < 0) {
nlmsg_free(reply_skb);
goto out;
}

nlmsg_end(reply_skb, reply_nlh);

ret = rtnl_unicast(reply_skb, &init_net, pid);
if (ret)
goto out;

switch (dcb->cmd) {
case DCB_CMD_GSTATE:
ret = dcbnl_getstate(netdev, tb, pid, nlh->nlmsg_seq,
Expand Down

0 comments on commit ece3de3

Please sign in to comment.