Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 255656
b: refs/heads/master
c: 314b477
h: refs/heads/master
v: v3
  • Loading branch information
John Fastabend authored and David S. Miller committed Jun 21, 2011
1 parent 75cfa47 commit eeecea0
Show file tree
Hide file tree
Showing 4 changed files with 151 additions and 84 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: c7797baf9f3900996ca800ab6298f95957bb4606
refs/heads/master: 314b4778ed579f29b6d46ba90dbf31314c13805f
2 changes: 2 additions & 0 deletions trunk/include/linux/rtnetlink.h
Original file line number Diff line number Diff line change
Expand Up @@ -585,6 +585,8 @@ enum rtnetlink_groups {
#define RTNLGRP_PHONET_IFADDR RTNLGRP_PHONET_IFADDR
RTNLGRP_PHONET_ROUTE,
#define RTNLGRP_PHONET_ROUTE RTNLGRP_PHONET_ROUTE
RTNLGRP_DCB,
#define RTNLGRP_DCB RTNLGRP_DCB
__RTNLGRP_MAX
};
#define RTNLGRP_MAX (__RTNLGRP_MAX - 1)
Expand Down
2 changes: 2 additions & 0 deletions trunk/include/net/dcbnl.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ struct dcb_app_type {
u8 dcb_setapp(struct net_device *, struct dcb_app *);
u8 dcb_getapp(struct net_device *, struct dcb_app *);

int dcbnl_notify(struct net_device *dev, int event, int cmd, u32 seq, u32 pid);

/*
* Ops struct for the netlink callbacks. Used by DCB-enabled drivers through
* the netdevice struct.
Expand Down
229 changes: 146 additions & 83 deletions trunk/net/dcb/dcbnl.c
Original file line number Diff line number Diff line change
Expand Up @@ -1166,64 +1166,6 @@ static int dcbnl_bcn_setcfg(struct net_device *netdev, struct nlattr **tb,
return ret;
}

/* Handle IEEE 802.1Qaz SET commands. If any requested operation can not
* be completed the entire msg is aborted and error value is returned.
* No attempt is made to reconcile the case where only part of the
* cmd can be completed.
*/
static int dcbnl_ieee_set(struct net_device *netdev, struct nlattr **tb,
u32 pid, u32 seq, u16 flags)
{
const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops;
struct nlattr *ieee[DCB_ATTR_IEEE_MAX + 1];
int err = -EOPNOTSUPP;

if (!ops)
goto err;

err = nla_parse_nested(ieee, DCB_ATTR_IEEE_MAX,
tb[DCB_ATTR_IEEE], dcbnl_ieee_policy);
if (err)
goto err;

if (ieee[DCB_ATTR_IEEE_ETS] && ops->ieee_setets) {
struct ieee_ets *ets = nla_data(ieee[DCB_ATTR_IEEE_ETS]);
err = ops->ieee_setets(netdev, ets);
if (err)
goto err;
}

if (ieee[DCB_ATTR_IEEE_PFC] && ops->ieee_setpfc) {
struct ieee_pfc *pfc = nla_data(ieee[DCB_ATTR_IEEE_PFC]);
err = ops->ieee_setpfc(netdev, pfc);
if (err)
goto err;
}

if (ieee[DCB_ATTR_IEEE_APP_TABLE]) {
struct nlattr *attr;
int rem;

nla_for_each_nested(attr, ieee[DCB_ATTR_IEEE_APP_TABLE], rem) {
struct dcb_app *app_data;
if (nla_type(attr) != DCB_ATTR_IEEE_APP)
continue;
app_data = nla_data(attr);
if (ops->ieee_setapp)
err = ops->ieee_setapp(netdev, app_data);
else
err = dcb_setapp(netdev, app_data);
if (err)
goto err;
}
}

err:
dcbnl_reply(err, RTM_SETDCB, DCB_CMD_IEEE_SET, DCB_ATTR_IEEE,
pid, seq, flags);
return err;
}

static int dcbnl_build_peer_app(struct net_device *netdev, struct sk_buff* skb,
int app_nested_type, int app_info_type,
int app_entry_type)
Expand Down Expand Up @@ -1279,30 +1221,13 @@ static int dcbnl_build_peer_app(struct net_device *netdev, struct sk_buff* skb,
}

/* Handle IEEE 802.1Qaz GET commands. */
static int dcbnl_ieee_get(struct net_device *netdev, struct nlattr **tb,
u32 pid, u32 seq, u16 flags)
static int dcbnl_ieee_fill(struct sk_buff *skb, struct net_device *netdev)
{
struct sk_buff *skb;
struct nlmsghdr *nlh;
struct dcbmsg *dcb;
struct nlattr *ieee, *app;
struct dcb_app_type *itr;
const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops;
int dcbx;
int err;

if (!ops)
return -EOPNOTSUPP;

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

nlh = NLMSG_NEW(skb, pid, seq, RTM_GETDCB, sizeof(*dcb), flags);

dcb = NLMSG_DATA(nlh);
dcb->dcb_family = AF_UNSPEC;
dcb->cmd = DCB_CMD_IEEE_GET;
int err = -EMSGSIZE;

NLA_PUT_STRING(skb, DCB_ATTR_IFNAME, netdev->name);

Expand Down Expand Up @@ -1378,16 +1303,154 @@ static int dcbnl_ieee_get(struct net_device *netdev, struct nlattr **tb,
if (err)
goto nla_put_failure;
}
nlmsg_end(skb, nlh);

return rtnl_unicast(skb, &init_net, pid);
return 0;

nla_put_failure:
nlmsg_cancel(skb, nlh);
nlmsg_failure:
kfree_skb(skb);
return -1;
return err;
}

int dcbnl_notify(struct net_device *dev, int event, int cmd,
u32 seq, u32 pid)
{
struct net *net = dev_net(dev);
struct sk_buff *skb;
struct nlmsghdr *nlh;
struct dcbmsg *dcb;
const struct dcbnl_rtnl_ops *ops = dev->dcbnl_ops;
int err;

if (!ops)
return -EOPNOTSUPP;

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

nlh = nlmsg_put(skb, pid, 0, event, sizeof(*dcb), 0);
if (nlh == NULL) {
kfree(skb);
return -EMSGSIZE;
}

dcb = NLMSG_DATA(nlh);
dcb->dcb_family = AF_UNSPEC;
dcb->cmd = cmd;

err = dcbnl_ieee_fill(skb, dev);
if (err < 0) {
/* Report error to broadcast listeners */
nlmsg_cancel(skb, nlh);
kfree_skb(skb);
rtnl_set_sk_err(net, RTNLGRP_DCB, err);
} else {
/* End nlmsg and notify broadcast listeners */
nlmsg_end(skb, nlh);
rtnl_notify(skb, net, 0, RTNLGRP_DCB, NULL, GFP_KERNEL);
}

return err;
}
EXPORT_SYMBOL(dcbnl_notify);

/* Handle IEEE 802.1Qaz SET commands. If any requested operation can not
* be completed the entire msg is aborted and error value is returned.
* No attempt is made to reconcile the case where only part of the
* cmd can be completed.
*/
static int dcbnl_ieee_set(struct net_device *netdev, struct nlattr **tb,
u32 pid, u32 seq, u16 flags)
{
const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops;
struct nlattr *ieee[DCB_ATTR_IEEE_MAX + 1];
int err = -EOPNOTSUPP;

if (!ops)
return err;

err = nla_parse_nested(ieee, DCB_ATTR_IEEE_MAX,
tb[DCB_ATTR_IEEE], dcbnl_ieee_policy);
if (err)
return err;

if (ieee[DCB_ATTR_IEEE_ETS] && ops->ieee_setets) {
struct ieee_ets *ets = nla_data(ieee[DCB_ATTR_IEEE_ETS]);
err = ops->ieee_setets(netdev, ets);
if (err)
goto err;
}

if (ieee[DCB_ATTR_IEEE_PFC] && ops->ieee_setpfc) {
struct ieee_pfc *pfc = nla_data(ieee[DCB_ATTR_IEEE_PFC]);
err = ops->ieee_setpfc(netdev, pfc);
if (err)
goto err;
}

if (ieee[DCB_ATTR_IEEE_APP_TABLE]) {
struct nlattr *attr;
int rem;

nla_for_each_nested(attr, ieee[DCB_ATTR_IEEE_APP_TABLE], rem) {
struct dcb_app *app_data;
if (nla_type(attr) != DCB_ATTR_IEEE_APP)
continue;
app_data = nla_data(attr);
if (ops->ieee_setapp)
err = ops->ieee_setapp(netdev, app_data);
else
err = dcb_setapp(netdev, app_data);
if (err)
goto err;
}
}

err:
dcbnl_reply(err, RTM_SETDCB, DCB_CMD_IEEE_SET, DCB_ATTR_IEEE,
pid, seq, flags);
dcbnl_notify(netdev, RTM_SETDCB, DCB_CMD_IEEE_SET, seq, 0);
return err;
}

static int dcbnl_ieee_get(struct net_device *netdev, struct nlattr **tb,
u32 pid, u32 seq, u16 flags)
{
struct net *net = dev_net(netdev);
struct sk_buff *skb;
struct nlmsghdr *nlh;
struct dcbmsg *dcb;
const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops;
int err;

if (!ops)
return -EOPNOTSUPP;

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

nlh = nlmsg_put(skb, pid, seq, RTM_GETDCB, sizeof(*dcb), flags);
if (nlh == NULL) {
kfree(skb);
return -EMSGSIZE;
}

dcb = NLMSG_DATA(nlh);
dcb->dcb_family = AF_UNSPEC;
dcb->cmd = DCB_CMD_IEEE_GET;

err = dcbnl_ieee_fill(skb, netdev);

if (err < 0) {
nlmsg_cancel(skb, nlh);
kfree_skb(skb);
} else {
nlmsg_end(skb, nlh);
err = rtnl_unicast(skb, net, pid);
}

return err;
}
/* DCBX configuration */
static int dcbnl_getdcbx(struct net_device *netdev, struct nlattr **tb,
u32 pid, u32 seq, u16 flags)
Expand Down

0 comments on commit eeecea0

Please sign in to comment.