aboutsummaryrefslogtreecommitdiffstats
path: root/net/dcb
diff options
context:
space:
mode:
authorJohn Fastabend <john.r.fastabend@intel.com>2010-12-30 04:25:46 -0500
committerDavid S. Miller <davem@davemloft.net>2010-12-31 13:47:45 -0500
commit3e29027af43728c2a91fe3f735ab2822edaf54a8 (patch)
treefb453671722596b9dcb1af4171bdcfa17cd48d61 /net/dcb
parenta7dd6027e55992dd7c409a71a4a2b576fda2f7c2 (diff)
dcbnl: add support for ieee8021Qaz attributes
The IEEE8021Qaz is the IEEE standard version of CEE. The standard has had enough significant changes from the CEE version that many of the CEE attributes have no meaning in the new spec or do not easily map to IEEE standards. Rather then attempt to create a complicated mapping between CEE and IEEE standards this patch adds a nested IEEE attribute to the list of DCB attributes. The policy is, [DCB_ATTR_IFNAME] [DCB_ATTR_STATE] ... [DCB_ATTR_IEEE] [DCB_ATTR_IEEE_ETS] [DCB_ATTR_IEEE_PFC] [DCB_ATTR_IEEE_APP_TABLE] [DCB_ATTR_IEEE_APP] ... The following dcbnl_rtnl_ops routines were added to handle the IEEE standard, int (*ieee_getets) (struct net_device *, struct ieee_ets *); int (*ieee_setets) (struct net_device *, struct ieee_ets *); int (*ieee_getpfc) (struct net_device *, struct ieee_pfc *); int (*ieee_setpfc) (struct net_device *, struct ieee_pfc *); int (*ieee_getapp) (struct net_device *, struct dcb_app *); int (*ieee_setapp) (struct net_device *, struct dcb_app *); Signed-off-by: John Fastabend <john.r.fastabend@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/dcb')
-rw-r--r--net/dcb/dcbnl.c131
1 files changed, 131 insertions, 0 deletions
diff --git a/net/dcb/dcbnl.c b/net/dcb/dcbnl.c
index 19ac2b985485..2ff908498924 100644
--- a/net/dcb/dcbnl.c
+++ b/net/dcb/dcbnl.c
@@ -66,6 +66,7 @@ static const struct nla_policy dcbnl_rtnl_policy[DCB_ATTR_MAX + 1] = {
66 [DCB_ATTR_PFC_STATE] = {.type = NLA_U8}, 66 [DCB_ATTR_PFC_STATE] = {.type = NLA_U8},
67 [DCB_ATTR_BCN] = {.type = NLA_NESTED}, 67 [DCB_ATTR_BCN] = {.type = NLA_NESTED},
68 [DCB_ATTR_APP] = {.type = NLA_NESTED}, 68 [DCB_ATTR_APP] = {.type = NLA_NESTED},
69 [DCB_ATTR_IEEE] = {.type = NLA_NESTED},
69}; 70};
70 71
71/* DCB priority flow control to User Priority nested attributes */ 72/* DCB priority flow control to User Priority nested attributes */
@@ -167,6 +168,17 @@ static const struct nla_policy dcbnl_app_nest[DCB_APP_ATTR_MAX + 1] = {
167 [DCB_APP_ATTR_PRIORITY] = {.type = NLA_U8}, 168 [DCB_APP_ATTR_PRIORITY] = {.type = NLA_U8},
168}; 169};
169 170
171/* IEEE 802.1Qaz nested attributes. */
172static const struct nla_policy dcbnl_ieee_policy[DCB_ATTR_IEEE_MAX + 1] = {
173 [DCB_ATTR_IEEE_ETS] = {.len = sizeof(struct ieee_ets)},
174 [DCB_ATTR_IEEE_PFC] = {.len = sizeof(struct ieee_pfc)},
175 [DCB_ATTR_IEEE_APP_TABLE] = {.type = NLA_NESTED},
176};
177
178static const struct nla_policy dcbnl_ieee_app[DCB_ATTR_IEEE_APP_MAX + 1] = {
179 [DCB_ATTR_IEEE_APP] = {.len = sizeof(struct dcb_app)},
180};
181
170/* standard netlink reply call */ 182/* standard netlink reply call */
171static int dcbnl_reply(u8 value, u8 event, u8 cmd, u8 attr, u32 pid, 183static int dcbnl_reply(u8 value, u8 event, u8 cmd, u8 attr, u32 pid,
172 u32 seq, u16 flags) 184 u32 seq, u16 flags)
@@ -1118,6 +1130,117 @@ err:
1118 return ret; 1130 return ret;
1119} 1131}
1120 1132
1133/* Handle IEEE 802.1Qaz SET commands. If any requested operation can not
1134 * be completed the entire msg is aborted and error value is returned.
1135 * No attempt is made to reconcile the case where only part of the
1136 * cmd can be completed.
1137 */
1138static int dcbnl_ieee_set(struct net_device *netdev, struct nlattr **tb,
1139 u32 pid, u32 seq, u16 flags)
1140{
1141 const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops;
1142 struct nlattr *ieee[DCB_ATTR_IEEE_MAX + 1];
1143 int err = -EOPNOTSUPP;
1144
1145 if (!ops)
1146 goto err;
1147
1148 err = nla_parse_nested(ieee, DCB_ATTR_IEEE_MAX,
1149 tb[DCB_ATTR_IEEE], dcbnl_ieee_policy);
1150 if (err)
1151 goto err;
1152
1153 if (ieee[DCB_ATTR_IEEE_ETS] && ops->ieee_setets) {
1154 struct ieee_ets *ets = nla_data(ieee[DCB_ATTR_IEEE_ETS]);
1155 err = ops->ieee_setets(netdev, ets);
1156 if (err)
1157 goto err;
1158 }
1159
1160 if (ieee[DCB_ATTR_IEEE_PFC] && ops->ieee_setets) {
1161 struct ieee_pfc *pfc = nla_data(ieee[DCB_ATTR_IEEE_PFC]);
1162 err = ops->ieee_setpfc(netdev, pfc);
1163 if (err)
1164 goto err;
1165 }
1166
1167 if (ieee[DCB_ATTR_IEEE_APP_TABLE] && ops->ieee_setapp) {
1168 struct nlattr *attr;
1169 int rem;
1170
1171 nla_for_each_nested(attr, ieee[DCB_ATTR_IEEE_APP_TABLE], rem) {
1172 struct dcb_app *app_data;
1173 if (nla_type(attr) != DCB_ATTR_IEEE_APP)
1174 continue;
1175 app_data = nla_data(attr);
1176 err = ops->ieee_setapp(netdev, app_data);
1177 if (err)
1178 goto err;
1179 }
1180 }
1181
1182err:
1183 dcbnl_reply(err, RTM_SETDCB, DCB_CMD_IEEE_SET, DCB_ATTR_IEEE,
1184 pid, seq, flags);
1185 return err;
1186}
1187
1188
1189/* Handle IEEE 802.1Qaz GET commands. */
1190static int dcbnl_ieee_get(struct net_device *netdev, struct nlattr **tb,
1191 u32 pid, u32 seq, u16 flags)
1192{
1193 struct sk_buff *skb;
1194 struct nlmsghdr *nlh;
1195 struct dcbmsg *dcb;
1196 struct nlattr *ieee;
1197 const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops;
1198 int err;
1199
1200 if (!ops)
1201 return -EOPNOTSUPP;
1202
1203 skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1204 if (!skb)
1205 return -ENOBUFS;
1206
1207 nlh = NLMSG_NEW(skb, pid, seq, RTM_GETDCB, sizeof(*dcb), flags);
1208
1209 dcb = NLMSG_DATA(nlh);
1210 dcb->dcb_family = AF_UNSPEC;
1211 dcb->cmd = DCB_CMD_IEEE_GET;
1212
1213 NLA_PUT_STRING(skb, DCB_ATTR_IFNAME, netdev->name);
1214
1215 ieee = nla_nest_start(skb, DCB_ATTR_IEEE);
1216 if (!ieee)
1217 goto nla_put_failure;
1218
1219 if (ops->ieee_getets) {
1220 struct ieee_ets ets;
1221 err = ops->ieee_getets(netdev, &ets);
1222 if (!err)
1223 NLA_PUT(skb, DCB_ATTR_IEEE_ETS, sizeof(ets), &ets);
1224 }
1225
1226 if (ops->ieee_getpfc) {
1227 struct ieee_pfc pfc;
1228 err = ops->ieee_getpfc(netdev, &pfc);
1229 if (!err)
1230 NLA_PUT(skb, DCB_ATTR_IEEE_PFC, sizeof(pfc), &pfc);
1231 }
1232
1233 nla_nest_end(skb, ieee);
1234 nlmsg_end(skb, nlh);
1235
1236 return rtnl_unicast(skb, &init_net, pid);
1237nla_put_failure:
1238 nlmsg_cancel(skb, nlh);
1239nlmsg_failure:
1240 kfree_skb(skb);
1241 return -1;
1242}
1243
1121static int dcb_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) 1244static int dcb_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
1122{ 1245{
1123 struct net *net = sock_net(skb->sk); 1246 struct net *net = sock_net(skb->sk);
@@ -1223,6 +1346,14 @@ static int dcb_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
1223 ret = dcbnl_setapp(netdev, tb, pid, nlh->nlmsg_seq, 1346 ret = dcbnl_setapp(netdev, tb, pid, nlh->nlmsg_seq,
1224 nlh->nlmsg_flags); 1347 nlh->nlmsg_flags);
1225 goto out; 1348 goto out;
1349 case DCB_CMD_IEEE_SET:
1350 ret = dcbnl_ieee_set(netdev, tb, pid, nlh->nlmsg_seq,
1351 nlh->nlmsg_flags);
1352 goto out;
1353 case DCB_CMD_IEEE_GET:
1354 ret = dcbnl_ieee_get(netdev, tb, pid, nlh->nlmsg_seq,
1355 nlh->nlmsg_flags);
1356 goto out;
1226 default: 1357 default:
1227 goto errout; 1358 goto errout;
1228 } 1359 }