diff options
Diffstat (limited to 'net/dcb')
-rw-r--r-- | net/dcb/dcbnl.c | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/net/dcb/dcbnl.c b/net/dcb/dcbnl.c index d5074a567289..2e6dcf2967e2 100644 --- a/net/dcb/dcbnl.c +++ b/net/dcb/dcbnl.c | |||
@@ -1224,6 +1224,54 @@ err: | |||
1224 | return err; | 1224 | return err; |
1225 | } | 1225 | } |
1226 | 1226 | ||
1227 | static int dcbnl_build_peer_app(struct net_device *netdev, struct sk_buff* skb) | ||
1228 | { | ||
1229 | struct dcb_peer_app_info info; | ||
1230 | struct dcb_app *table = NULL; | ||
1231 | const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops; | ||
1232 | u16 app_count; | ||
1233 | int err; | ||
1234 | |||
1235 | |||
1236 | /** | ||
1237 | * retrieve the peer app configuration form the driver. If the driver | ||
1238 | * handlers fail exit without doing anything | ||
1239 | */ | ||
1240 | err = ops->peer_getappinfo(netdev, &info, &app_count); | ||
1241 | if (!err && app_count) { | ||
1242 | table = kmalloc(sizeof(struct dcb_app) * app_count, GFP_KERNEL); | ||
1243 | if (!table) | ||
1244 | return -ENOMEM; | ||
1245 | |||
1246 | err = ops->peer_getapptable(netdev, table); | ||
1247 | } | ||
1248 | |||
1249 | if (!err) { | ||
1250 | u16 i; | ||
1251 | struct nlattr *app; | ||
1252 | |||
1253 | /** | ||
1254 | * build the message, from here on the only possible failure | ||
1255 | * is due to the skb size | ||
1256 | */ | ||
1257 | err = -EMSGSIZE; | ||
1258 | |||
1259 | app = nla_nest_start(skb, DCB_ATTR_IEEE_PEER_APP); | ||
1260 | if (!app) | ||
1261 | goto nla_put_failure; | ||
1262 | |||
1263 | for (i = 0; i < app_count; i++) | ||
1264 | NLA_PUT(skb, DCB_ATTR_IEEE_APP, sizeof(struct dcb_app), | ||
1265 | &table[i]); | ||
1266 | |||
1267 | nla_nest_end(skb, app); | ||
1268 | } | ||
1269 | err = 0; | ||
1270 | |||
1271 | nla_put_failure: | ||
1272 | kfree(table); | ||
1273 | return err; | ||
1274 | } | ||
1227 | 1275 | ||
1228 | /* Handle IEEE 802.1Qaz GET commands. */ | 1276 | /* Handle IEEE 802.1Qaz GET commands. */ |
1229 | static int dcbnl_ieee_get(struct net_device *netdev, struct nlattr **tb, | 1277 | static int dcbnl_ieee_get(struct net_device *netdev, struct nlattr **tb, |
@@ -1288,6 +1336,27 @@ static int dcbnl_ieee_get(struct net_device *netdev, struct nlattr **tb, | |||
1288 | spin_unlock(&dcb_lock); | 1336 | spin_unlock(&dcb_lock); |
1289 | nla_nest_end(skb, app); | 1337 | nla_nest_end(skb, app); |
1290 | 1338 | ||
1339 | /* get peer info if available */ | ||
1340 | if (ops->ieee_peer_getets) { | ||
1341 | struct ieee_ets ets; | ||
1342 | err = ops->ieee_peer_getets(netdev, &ets); | ||
1343 | if (!err) | ||
1344 | NLA_PUT(skb, DCB_ATTR_IEEE_PEER_ETS, sizeof(ets), &ets); | ||
1345 | } | ||
1346 | |||
1347 | if (ops->ieee_peer_getpfc) { | ||
1348 | struct ieee_pfc pfc; | ||
1349 | err = ops->ieee_peer_getpfc(netdev, &pfc); | ||
1350 | if (!err) | ||
1351 | NLA_PUT(skb, DCB_ATTR_IEEE_PEER_PFC, sizeof(pfc), &pfc); | ||
1352 | } | ||
1353 | |||
1354 | if (ops->peer_getappinfo && ops->peer_getapptable) { | ||
1355 | err = dcbnl_build_peer_app(netdev, skb); | ||
1356 | if (err) | ||
1357 | goto nla_put_failure; | ||
1358 | } | ||
1359 | |||
1291 | nla_nest_end(skb, ieee); | 1360 | nla_nest_end(skb, ieee); |
1292 | nlmsg_end(skb, nlh); | 1361 | nlmsg_end(skb, nlh); |
1293 | 1362 | ||