aboutsummaryrefslogtreecommitdiffstats
path: root/net/dcb/dcbnl.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/dcb/dcbnl.c')
-rw-r--r--net/dcb/dcbnl.c1168
1 files changed, 398 insertions, 770 deletions
diff --git a/net/dcb/dcbnl.c b/net/dcb/dcbnl.c
index 656c7c75b192..81f2bb62dea3 100644
--- a/net/dcb/dcbnl.c
+++ b/net/dcb/dcbnl.c
@@ -28,8 +28,7 @@
28#include <linux/module.h> 28#include <linux/module.h>
29#include <net/sock.h> 29#include <net/sock.h>
30 30
31/** 31/* Data Center Bridging (DCB) is a collection of Ethernet enhancements
32 * Data Center Bridging (DCB) is a collection of Ethernet enhancements
33 * intended to allow network traffic with differing requirements 32 * intended to allow network traffic with differing requirements
34 * (highly reliable, no drops vs. best effort vs. low latency) to operate 33 * (highly reliable, no drops vs. best effort vs. low latency) to operate
35 * and co-exist on Ethernet. Current DCB features are: 34 * and co-exist on Ethernet. Current DCB features are:
@@ -196,92 +195,66 @@ static const struct nla_policy dcbnl_featcfg_nest[DCB_FEATCFG_ATTR_MAX + 1] = {
196static LIST_HEAD(dcb_app_list); 195static LIST_HEAD(dcb_app_list);
197static DEFINE_SPINLOCK(dcb_lock); 196static DEFINE_SPINLOCK(dcb_lock);
198 197
199/* standard netlink reply call */ 198static struct sk_buff *dcbnl_newmsg(int type, u8 cmd, u32 port, u32 seq,
200static int dcbnl_reply(u8 value, u8 event, u8 cmd, u8 attr, u32 pid, 199 u32 flags, struct nlmsghdr **nlhp)
201 u32 seq, u16 flags)
202{ 200{
203 struct sk_buff *dcbnl_skb; 201 struct sk_buff *skb;
204 struct dcbmsg *dcb; 202 struct dcbmsg *dcb;
205 struct nlmsghdr *nlh; 203 struct nlmsghdr *nlh;
206 int ret = -EINVAL;
207 204
208 dcbnl_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 205 skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
209 if (!dcbnl_skb) 206 if (!skb)
210 return ret; 207 return NULL;
211 208
212 nlh = NLMSG_NEW(dcbnl_skb, pid, seq, event, sizeof(*dcb), flags); 209 nlh = nlmsg_put(skb, port, seq, type, sizeof(*dcb), flags);
210 BUG_ON(!nlh);
213 211
214 dcb = NLMSG_DATA(nlh); 212 dcb = nlmsg_data(nlh);
215 dcb->dcb_family = AF_UNSPEC; 213 dcb->dcb_family = AF_UNSPEC;
216 dcb->cmd = cmd; 214 dcb->cmd = cmd;
217 dcb->dcb_pad = 0; 215 dcb->dcb_pad = 0;
218 216
219 ret = nla_put_u8(dcbnl_skb, attr, value); 217 if (nlhp)
220 if (ret) 218 *nlhp = nlh;
221 goto err;
222 219
223 /* end the message, assign the nlmsg_len. */ 220 return skb;
224 nlmsg_end(dcbnl_skb, nlh);
225 ret = rtnl_unicast(dcbnl_skb, &init_net, pid);
226 if (ret)
227 return -EINVAL;
228
229 return 0;
230nlmsg_failure:
231err:
232 kfree_skb(dcbnl_skb);
233 return ret;
234} 221}
235 222
236static int dcbnl_getstate(struct net_device *netdev, struct nlattr **tb, 223static int dcbnl_getstate(struct net_device *netdev, struct nlmsghdr *nlh,
237 u32 pid, u32 seq, u16 flags) 224 u32 seq, struct nlattr **tb, struct sk_buff *skb)
238{ 225{
239 int ret = -EINVAL;
240
241 /* if (!tb[DCB_ATTR_STATE] || !netdev->dcbnl_ops->getstate) */ 226 /* if (!tb[DCB_ATTR_STATE] || !netdev->dcbnl_ops->getstate) */
242 if (!netdev->dcbnl_ops->getstate) 227 if (!netdev->dcbnl_ops->getstate)
243 return ret; 228 return -EOPNOTSUPP;
244
245 ret = dcbnl_reply(netdev->dcbnl_ops->getstate(netdev), RTM_GETDCB,
246 DCB_CMD_GSTATE, DCB_ATTR_STATE, pid, seq, flags);
247 229
248 return ret; 230 return nla_put_u8(skb, DCB_ATTR_STATE,
231 netdev->dcbnl_ops->getstate(netdev));
249} 232}
250 233
251static int dcbnl_getpfccfg(struct net_device *netdev, struct nlattr **tb, 234static int dcbnl_getpfccfg(struct net_device *netdev, struct nlmsghdr *nlh,
252 u32 pid, u32 seq, u16 flags) 235 u32 seq, struct nlattr **tb, struct sk_buff *skb)
253{ 236{
254 struct sk_buff *dcbnl_skb;
255 struct nlmsghdr *nlh;
256 struct dcbmsg *dcb;
257 struct nlattr *data[DCB_PFC_UP_ATTR_MAX + 1], *nest; 237 struct nlattr *data[DCB_PFC_UP_ATTR_MAX + 1], *nest;
258 u8 value; 238 u8 value;
259 int ret = -EINVAL; 239 int ret;
260 int i; 240 int i;
261 int getall = 0; 241 int getall = 0;
262 242
263 if (!tb[DCB_ATTR_PFC_CFG] || !netdev->dcbnl_ops->getpfccfg) 243 if (!tb[DCB_ATTR_PFC_CFG])
264 return ret; 244 return -EINVAL;
245
246 if (!netdev->dcbnl_ops->getpfccfg)
247 return -EOPNOTSUPP;
265 248
266 ret = nla_parse_nested(data, DCB_PFC_UP_ATTR_MAX, 249 ret = nla_parse_nested(data, DCB_PFC_UP_ATTR_MAX,
267 tb[DCB_ATTR_PFC_CFG], 250 tb[DCB_ATTR_PFC_CFG],
268 dcbnl_pfc_up_nest); 251 dcbnl_pfc_up_nest);
269 if (ret) 252 if (ret)
270 goto err_out; 253 return ret;
271
272 dcbnl_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
273 if (!dcbnl_skb)
274 goto err_out;
275
276 nlh = NLMSG_NEW(dcbnl_skb, pid, seq, RTM_GETDCB, sizeof(*dcb), flags);
277
278 dcb = NLMSG_DATA(nlh);
279 dcb->dcb_family = AF_UNSPEC;
280 dcb->cmd = DCB_CMD_PFC_GCFG;
281 254
282 nest = nla_nest_start(dcbnl_skb, DCB_ATTR_PFC_CFG); 255 nest = nla_nest_start(skb, DCB_ATTR_PFC_CFG);
283 if (!nest) 256 if (!nest)
284 goto err; 257 return -EMSGSIZE;
285 258
286 if (data[DCB_PFC_UP_ATTR_ALL]) 259 if (data[DCB_PFC_UP_ATTR_ALL])
287 getall = 1; 260 getall = 1;
@@ -292,103 +265,53 @@ static int dcbnl_getpfccfg(struct net_device *netdev, struct nlattr **tb,
292 265
293 netdev->dcbnl_ops->getpfccfg(netdev, i - DCB_PFC_UP_ATTR_0, 266 netdev->dcbnl_ops->getpfccfg(netdev, i - DCB_PFC_UP_ATTR_0,
294 &value); 267 &value);
295 ret = nla_put_u8(dcbnl_skb, i, value); 268 ret = nla_put_u8(skb, i, value);
296
297 if (ret) { 269 if (ret) {
298 nla_nest_cancel(dcbnl_skb, nest); 270 nla_nest_cancel(skb, nest);
299 goto err; 271 return ret;
300 } 272 }
301 } 273 }
302 nla_nest_end(dcbnl_skb, nest); 274 nla_nest_end(skb, nest);
303
304 nlmsg_end(dcbnl_skb, nlh);
305
306 ret = rtnl_unicast(dcbnl_skb, &init_net, pid);
307 if (ret)
308 goto err_out;
309 275
310 return 0; 276 return 0;
311nlmsg_failure:
312err:
313 kfree_skb(dcbnl_skb);
314err_out:
315 return -EINVAL;
316} 277}
317 278
318static int dcbnl_getperm_hwaddr(struct net_device *netdev, struct nlattr **tb, 279static int dcbnl_getperm_hwaddr(struct net_device *netdev, struct nlmsghdr *nlh,
319 u32 pid, u32 seq, u16 flags) 280 u32 seq, struct nlattr **tb, struct sk_buff *skb)
320{ 281{
321 struct sk_buff *dcbnl_skb;
322 struct nlmsghdr *nlh;
323 struct dcbmsg *dcb;
324 u8 perm_addr[MAX_ADDR_LEN]; 282 u8 perm_addr[MAX_ADDR_LEN];
325 int ret = -EINVAL;
326 283
327 if (!netdev->dcbnl_ops->getpermhwaddr) 284 if (!netdev->dcbnl_ops->getpermhwaddr)
328 return ret; 285 return -EOPNOTSUPP;
329
330 dcbnl_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
331 if (!dcbnl_skb)
332 goto err_out;
333
334 nlh = NLMSG_NEW(dcbnl_skb, pid, seq, RTM_GETDCB, sizeof(*dcb), flags);
335
336 dcb = NLMSG_DATA(nlh);
337 dcb->dcb_family = AF_UNSPEC;
338 dcb->cmd = DCB_CMD_GPERM_HWADDR;
339 286
340 netdev->dcbnl_ops->getpermhwaddr(netdev, perm_addr); 287 netdev->dcbnl_ops->getpermhwaddr(netdev, perm_addr);
341 288
342 ret = nla_put(dcbnl_skb, DCB_ATTR_PERM_HWADDR, sizeof(perm_addr), 289 return nla_put(skb, DCB_ATTR_PERM_HWADDR, sizeof(perm_addr), perm_addr);
343 perm_addr);
344
345 nlmsg_end(dcbnl_skb, nlh);
346
347 ret = rtnl_unicast(dcbnl_skb, &init_net, pid);
348 if (ret)
349 goto err_out;
350
351 return 0;
352
353nlmsg_failure:
354 kfree_skb(dcbnl_skb);
355err_out:
356 return -EINVAL;
357} 290}
358 291
359static int dcbnl_getcap(struct net_device *netdev, struct nlattr **tb, 292static int dcbnl_getcap(struct net_device *netdev, struct nlmsghdr *nlh,
360 u32 pid, u32 seq, u16 flags) 293 u32 seq, struct nlattr **tb, struct sk_buff *skb)
361{ 294{
362 struct sk_buff *dcbnl_skb;
363 struct nlmsghdr *nlh;
364 struct dcbmsg *dcb;
365 struct nlattr *data[DCB_CAP_ATTR_MAX + 1], *nest; 295 struct nlattr *data[DCB_CAP_ATTR_MAX + 1], *nest;
366 u8 value; 296 u8 value;
367 int ret = -EINVAL; 297 int ret;
368 int i; 298 int i;
369 int getall = 0; 299 int getall = 0;
370 300
371 if (!tb[DCB_ATTR_CAP] || !netdev->dcbnl_ops->getcap) 301 if (!tb[DCB_ATTR_CAP])
372 return ret; 302 return -EINVAL;
303
304 if (!netdev->dcbnl_ops->getcap)
305 return -EOPNOTSUPP;
373 306
374 ret = nla_parse_nested(data, DCB_CAP_ATTR_MAX, tb[DCB_ATTR_CAP], 307 ret = nla_parse_nested(data, DCB_CAP_ATTR_MAX, tb[DCB_ATTR_CAP],
375 dcbnl_cap_nest); 308 dcbnl_cap_nest);
376 if (ret) 309 if (ret)
377 goto err_out; 310 return ret;
378
379 dcbnl_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
380 if (!dcbnl_skb)
381 goto err_out;
382
383 nlh = NLMSG_NEW(dcbnl_skb, pid, seq, RTM_GETDCB, sizeof(*dcb), flags);
384
385 dcb = NLMSG_DATA(nlh);
386 dcb->dcb_family = AF_UNSPEC;
387 dcb->cmd = DCB_CMD_GCAP;
388 311
389 nest = nla_nest_start(dcbnl_skb, DCB_ATTR_CAP); 312 nest = nla_nest_start(skb, DCB_ATTR_CAP);
390 if (!nest) 313 if (!nest)
391 goto err; 314 return -EMSGSIZE;
392 315
393 if (data[DCB_CAP_ATTR_ALL]) 316 if (data[DCB_CAP_ATTR_ALL])
394 getall = 1; 317 getall = 1;
@@ -398,69 +321,41 @@ static int dcbnl_getcap(struct net_device *netdev, struct nlattr **tb,
398 continue; 321 continue;
399 322
400 if (!netdev->dcbnl_ops->getcap(netdev, i, &value)) { 323 if (!netdev->dcbnl_ops->getcap(netdev, i, &value)) {
401 ret = nla_put_u8(dcbnl_skb, i, value); 324 ret = nla_put_u8(skb, i, value);
402
403 if (ret) { 325 if (ret) {
404 nla_nest_cancel(dcbnl_skb, nest); 326 nla_nest_cancel(skb, nest);
405 goto err; 327 return ret;
406 } 328 }
407 } 329 }
408 } 330 }
409 nla_nest_end(dcbnl_skb, nest); 331 nla_nest_end(skb, nest);
410
411 nlmsg_end(dcbnl_skb, nlh);
412
413 ret = rtnl_unicast(dcbnl_skb, &init_net, pid);
414 if (ret)
415 goto err_out;
416 332
417 return 0; 333 return 0;
418nlmsg_failure:
419err:
420 kfree_skb(dcbnl_skb);
421err_out:
422 return -EINVAL;
423} 334}
424 335
425static int dcbnl_getnumtcs(struct net_device *netdev, struct nlattr **tb, 336static int dcbnl_getnumtcs(struct net_device *netdev, struct nlmsghdr *nlh,
426 u32 pid, u32 seq, u16 flags) 337 u32 seq, struct nlattr **tb, struct sk_buff *skb)
427{ 338{
428 struct sk_buff *dcbnl_skb;
429 struct nlmsghdr *nlh;
430 struct dcbmsg *dcb;
431 struct nlattr *data[DCB_NUMTCS_ATTR_MAX + 1], *nest; 339 struct nlattr *data[DCB_NUMTCS_ATTR_MAX + 1], *nest;
432 u8 value; 340 u8 value;
433 int ret = -EINVAL; 341 int ret;
434 int i; 342 int i;
435 int getall = 0; 343 int getall = 0;
436 344
437 if (!tb[DCB_ATTR_NUMTCS] || !netdev->dcbnl_ops->getnumtcs) 345 if (!tb[DCB_ATTR_NUMTCS])
438 return ret; 346 return -EINVAL;
347
348 if (!netdev->dcbnl_ops->getnumtcs)
349 return -EOPNOTSUPP;
439 350
440 ret = nla_parse_nested(data, DCB_NUMTCS_ATTR_MAX, tb[DCB_ATTR_NUMTCS], 351 ret = nla_parse_nested(data, DCB_NUMTCS_ATTR_MAX, tb[DCB_ATTR_NUMTCS],
441 dcbnl_numtcs_nest); 352 dcbnl_numtcs_nest);
442 if (ret) { 353 if (ret)
443 ret = -EINVAL; 354 return ret;
444 goto err_out;
445 }
446
447 dcbnl_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
448 if (!dcbnl_skb) {
449 ret = -EINVAL;
450 goto err_out;
451 }
452
453 nlh = NLMSG_NEW(dcbnl_skb, pid, seq, RTM_GETDCB, sizeof(*dcb), flags);
454
455 dcb = NLMSG_DATA(nlh);
456 dcb->dcb_family = AF_UNSPEC;
457 dcb->cmd = DCB_CMD_GNUMTCS;
458 355
459 nest = nla_nest_start(dcbnl_skb, DCB_ATTR_NUMTCS); 356 nest = nla_nest_start(skb, DCB_ATTR_NUMTCS);
460 if (!nest) { 357 if (!nest)
461 ret = -EINVAL; 358 return -EMSGSIZE;
462 goto err;
463 }
464 359
465 if (data[DCB_NUMTCS_ATTR_ALL]) 360 if (data[DCB_NUMTCS_ATTR_ALL])
466 getall = 1; 361 getall = 1;
@@ -471,53 +366,37 @@ static int dcbnl_getnumtcs(struct net_device *netdev, struct nlattr **tb,
471 366
472 ret = netdev->dcbnl_ops->getnumtcs(netdev, i, &value); 367 ret = netdev->dcbnl_ops->getnumtcs(netdev, i, &value);
473 if (!ret) { 368 if (!ret) {
474 ret = nla_put_u8(dcbnl_skb, i, value); 369 ret = nla_put_u8(skb, i, value);
475
476 if (ret) { 370 if (ret) {
477 nla_nest_cancel(dcbnl_skb, nest); 371 nla_nest_cancel(skb, nest);
478 ret = -EINVAL; 372 return ret;
479 goto err;
480 } 373 }
481 } else { 374 } else
482 goto err; 375 return -EINVAL;
483 }
484 }
485 nla_nest_end(dcbnl_skb, nest);
486
487 nlmsg_end(dcbnl_skb, nlh);
488
489 ret = rtnl_unicast(dcbnl_skb, &init_net, pid);
490 if (ret) {
491 ret = -EINVAL;
492 goto err_out;
493 } 376 }
377 nla_nest_end(skb, nest);
494 378
495 return 0; 379 return 0;
496nlmsg_failure:
497err:
498 kfree_skb(dcbnl_skb);
499err_out:
500 return ret;
501} 380}
502 381
503static int dcbnl_setnumtcs(struct net_device *netdev, struct nlattr **tb, 382static int dcbnl_setnumtcs(struct net_device *netdev, struct nlmsghdr *nlh,
504 u32 pid, u32 seq, u16 flags) 383 u32 seq, struct nlattr **tb, struct sk_buff *skb)
505{ 384{
506 struct nlattr *data[DCB_NUMTCS_ATTR_MAX + 1]; 385 struct nlattr *data[DCB_NUMTCS_ATTR_MAX + 1];
507 int ret = -EINVAL; 386 int ret;
508 u8 value; 387 u8 value;
509 int i; 388 int i;
510 389
511 if (!tb[DCB_ATTR_NUMTCS] || !netdev->dcbnl_ops->setnumtcs) 390 if (!tb[DCB_ATTR_NUMTCS])
512 return ret; 391 return -EINVAL;
392
393 if (!netdev->dcbnl_ops->setnumtcs)
394 return -EOPNOTSUPP;
513 395
514 ret = nla_parse_nested(data, DCB_NUMTCS_ATTR_MAX, tb[DCB_ATTR_NUMTCS], 396 ret = nla_parse_nested(data, DCB_NUMTCS_ATTR_MAX, tb[DCB_ATTR_NUMTCS],
515 dcbnl_numtcs_nest); 397 dcbnl_numtcs_nest);
516 398 if (ret)
517 if (ret) { 399 return ret;
518 ret = -EINVAL;
519 goto err;
520 }
521 400
522 for (i = DCB_NUMTCS_ATTR_ALL+1; i <= DCB_NUMTCS_ATTR_MAX; i++) { 401 for (i = DCB_NUMTCS_ATTR_ALL+1; i <= DCB_NUMTCS_ATTR_MAX; i++) {
523 if (data[i] == NULL) 402 if (data[i] == NULL)
@@ -526,84 +405,68 @@ static int dcbnl_setnumtcs(struct net_device *netdev, struct nlattr **tb,
526 value = nla_get_u8(data[i]); 405 value = nla_get_u8(data[i]);
527 406
528 ret = netdev->dcbnl_ops->setnumtcs(netdev, i, value); 407 ret = netdev->dcbnl_ops->setnumtcs(netdev, i, value);
529
530 if (ret) 408 if (ret)
531 goto operr; 409 break;
532 } 410 }
533 411
534operr: 412 return nla_put_u8(skb, DCB_ATTR_NUMTCS, !!ret);
535 ret = dcbnl_reply(!!ret, RTM_SETDCB, DCB_CMD_SNUMTCS,
536 DCB_ATTR_NUMTCS, pid, seq, flags);
537
538err:
539 return ret;
540} 413}
541 414
542static int dcbnl_getpfcstate(struct net_device *netdev, struct nlattr **tb, 415static int dcbnl_getpfcstate(struct net_device *netdev, struct nlmsghdr *nlh,
543 u32 pid, u32 seq, u16 flags) 416 u32 seq, struct nlattr **tb, struct sk_buff *skb)
544{ 417{
545 int ret = -EINVAL;
546
547 if (!netdev->dcbnl_ops->getpfcstate) 418 if (!netdev->dcbnl_ops->getpfcstate)
548 return ret; 419 return -EOPNOTSUPP;
549
550 ret = dcbnl_reply(netdev->dcbnl_ops->getpfcstate(netdev), RTM_GETDCB,
551 DCB_CMD_PFC_GSTATE, DCB_ATTR_PFC_STATE,
552 pid, seq, flags);
553 420
554 return ret; 421 return nla_put_u8(skb, DCB_ATTR_PFC_STATE,
422 netdev->dcbnl_ops->getpfcstate(netdev));
555} 423}
556 424
557static int dcbnl_setpfcstate(struct net_device *netdev, struct nlattr **tb, 425static int dcbnl_setpfcstate(struct net_device *netdev, struct nlmsghdr *nlh,
558 u32 pid, u32 seq, u16 flags) 426 u32 seq, struct nlattr **tb, struct sk_buff *skb)
559{ 427{
560 int ret = -EINVAL;
561 u8 value; 428 u8 value;
562 429
563 if (!tb[DCB_ATTR_PFC_STATE] || !netdev->dcbnl_ops->setpfcstate) 430 if (!tb[DCB_ATTR_PFC_STATE])
564 return ret; 431 return -EINVAL;
432
433 if (!netdev->dcbnl_ops->setpfcstate)
434 return -EOPNOTSUPP;
565 435
566 value = nla_get_u8(tb[DCB_ATTR_PFC_STATE]); 436 value = nla_get_u8(tb[DCB_ATTR_PFC_STATE]);
567 437
568 netdev->dcbnl_ops->setpfcstate(netdev, value); 438 netdev->dcbnl_ops->setpfcstate(netdev, value);
569 439
570 ret = dcbnl_reply(0, RTM_SETDCB, DCB_CMD_PFC_SSTATE, DCB_ATTR_PFC_STATE, 440 return nla_put_u8(skb, DCB_ATTR_PFC_STATE, 0);
571 pid, seq, flags);
572
573 return ret;
574} 441}
575 442
576static int dcbnl_getapp(struct net_device *netdev, struct nlattr **tb, 443static int dcbnl_getapp(struct net_device *netdev, struct nlmsghdr *nlh,
577 u32 pid, u32 seq, u16 flags) 444 u32 seq, struct nlattr **tb, struct sk_buff *skb)
578{ 445{
579 struct sk_buff *dcbnl_skb;
580 struct nlmsghdr *nlh;
581 struct dcbmsg *dcb;
582 struct nlattr *app_nest; 446 struct nlattr *app_nest;
583 struct nlattr *app_tb[DCB_APP_ATTR_MAX + 1]; 447 struct nlattr *app_tb[DCB_APP_ATTR_MAX + 1];
584 u16 id; 448 u16 id;
585 u8 up, idtype; 449 u8 up, idtype;
586 int ret = -EINVAL; 450 int ret;
587 451
588 if (!tb[DCB_ATTR_APP]) 452 if (!tb[DCB_ATTR_APP])
589 goto out; 453 return -EINVAL;
590 454
591 ret = nla_parse_nested(app_tb, DCB_APP_ATTR_MAX, tb[DCB_ATTR_APP], 455 ret = nla_parse_nested(app_tb, DCB_APP_ATTR_MAX, tb[DCB_ATTR_APP],
592 dcbnl_app_nest); 456 dcbnl_app_nest);
593 if (ret) 457 if (ret)
594 goto out; 458 return ret;
595 459
596 ret = -EINVAL;
597 /* all must be non-null */ 460 /* all must be non-null */
598 if ((!app_tb[DCB_APP_ATTR_IDTYPE]) || 461 if ((!app_tb[DCB_APP_ATTR_IDTYPE]) ||
599 (!app_tb[DCB_APP_ATTR_ID])) 462 (!app_tb[DCB_APP_ATTR_ID]))
600 goto out; 463 return -EINVAL;
601 464
602 /* either by eth type or by socket number */ 465 /* either by eth type or by socket number */
603 idtype = nla_get_u8(app_tb[DCB_APP_ATTR_IDTYPE]); 466 idtype = nla_get_u8(app_tb[DCB_APP_ATTR_IDTYPE]);
604 if ((idtype != DCB_APP_IDTYPE_ETHTYPE) && 467 if ((idtype != DCB_APP_IDTYPE_ETHTYPE) &&
605 (idtype != DCB_APP_IDTYPE_PORTNUM)) 468 (idtype != DCB_APP_IDTYPE_PORTNUM))
606 goto out; 469 return -EINVAL;
607 470
608 id = nla_get_u16(app_tb[DCB_APP_ATTR_ID]); 471 id = nla_get_u16(app_tb[DCB_APP_ATTR_ID]);
609 472
@@ -617,138 +480,106 @@ static int dcbnl_getapp(struct net_device *netdev, struct nlattr **tb,
617 up = dcb_getapp(netdev, &app); 480 up = dcb_getapp(netdev, &app);
618 } 481 }
619 482
620 /* send this back */ 483 app_nest = nla_nest_start(skb, DCB_ATTR_APP);
621 dcbnl_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
622 if (!dcbnl_skb)
623 goto out;
624
625 nlh = NLMSG_NEW(dcbnl_skb, pid, seq, RTM_GETDCB, sizeof(*dcb), flags);
626 dcb = NLMSG_DATA(nlh);
627 dcb->dcb_family = AF_UNSPEC;
628 dcb->cmd = DCB_CMD_GAPP;
629
630 app_nest = nla_nest_start(dcbnl_skb, DCB_ATTR_APP);
631 if (!app_nest) 484 if (!app_nest)
632 goto out_cancel; 485 return -EMSGSIZE;
633 486
634 ret = nla_put_u8(dcbnl_skb, DCB_APP_ATTR_IDTYPE, idtype); 487 ret = nla_put_u8(skb, DCB_APP_ATTR_IDTYPE, idtype);
635 if (ret) 488 if (ret)
636 goto out_cancel; 489 goto out_cancel;
637 490
638 ret = nla_put_u16(dcbnl_skb, DCB_APP_ATTR_ID, id); 491 ret = nla_put_u16(skb, DCB_APP_ATTR_ID, id);
639 if (ret) 492 if (ret)
640 goto out_cancel; 493 goto out_cancel;
641 494
642 ret = nla_put_u8(dcbnl_skb, DCB_APP_ATTR_PRIORITY, up); 495 ret = nla_put_u8(skb, DCB_APP_ATTR_PRIORITY, up);
643 if (ret) 496 if (ret)
644 goto out_cancel; 497 goto out_cancel;
645 498
646 nla_nest_end(dcbnl_skb, app_nest); 499 nla_nest_end(skb, app_nest);
647 nlmsg_end(dcbnl_skb, nlh);
648
649 ret = rtnl_unicast(dcbnl_skb, &init_net, pid);
650 if (ret)
651 goto nlmsg_failure;
652 500
653 goto out; 501 return 0;
654 502
655out_cancel: 503out_cancel:
656 nla_nest_cancel(dcbnl_skb, app_nest); 504 nla_nest_cancel(skb, app_nest);
657nlmsg_failure:
658 kfree_skb(dcbnl_skb);
659out:
660 return ret; 505 return ret;
661} 506}
662 507
663static int dcbnl_setapp(struct net_device *netdev, struct nlattr **tb, 508static int dcbnl_setapp(struct net_device *netdev, struct nlmsghdr *nlh,
664 u32 pid, u32 seq, u16 flags) 509 u32 seq, struct nlattr **tb, struct sk_buff *skb)
665{ 510{
666 int err, ret = -EINVAL; 511 int ret;
667 u16 id; 512 u16 id;
668 u8 up, idtype; 513 u8 up, idtype;
669 struct nlattr *app_tb[DCB_APP_ATTR_MAX + 1]; 514 struct nlattr *app_tb[DCB_APP_ATTR_MAX + 1];
670 515
671 if (!tb[DCB_ATTR_APP]) 516 if (!tb[DCB_ATTR_APP])
672 goto out; 517 return -EINVAL;
673 518
674 ret = nla_parse_nested(app_tb, DCB_APP_ATTR_MAX, tb[DCB_ATTR_APP], 519 ret = nla_parse_nested(app_tb, DCB_APP_ATTR_MAX, tb[DCB_ATTR_APP],
675 dcbnl_app_nest); 520 dcbnl_app_nest);
676 if (ret) 521 if (ret)
677 goto out; 522 return ret;
678 523
679 ret = -EINVAL;
680 /* all must be non-null */ 524 /* all must be non-null */
681 if ((!app_tb[DCB_APP_ATTR_IDTYPE]) || 525 if ((!app_tb[DCB_APP_ATTR_IDTYPE]) ||
682 (!app_tb[DCB_APP_ATTR_ID]) || 526 (!app_tb[DCB_APP_ATTR_ID]) ||
683 (!app_tb[DCB_APP_ATTR_PRIORITY])) 527 (!app_tb[DCB_APP_ATTR_PRIORITY]))
684 goto out; 528 return -EINVAL;
685 529
686 /* either by eth type or by socket number */ 530 /* either by eth type or by socket number */
687 idtype = nla_get_u8(app_tb[DCB_APP_ATTR_IDTYPE]); 531 idtype = nla_get_u8(app_tb[DCB_APP_ATTR_IDTYPE]);
688 if ((idtype != DCB_APP_IDTYPE_ETHTYPE) && 532 if ((idtype != DCB_APP_IDTYPE_ETHTYPE) &&
689 (idtype != DCB_APP_IDTYPE_PORTNUM)) 533 (idtype != DCB_APP_IDTYPE_PORTNUM))
690 goto out; 534 return -EINVAL;
691 535
692 id = nla_get_u16(app_tb[DCB_APP_ATTR_ID]); 536 id = nla_get_u16(app_tb[DCB_APP_ATTR_ID]);
693 up = nla_get_u8(app_tb[DCB_APP_ATTR_PRIORITY]); 537 up = nla_get_u8(app_tb[DCB_APP_ATTR_PRIORITY]);
694 538
695 if (netdev->dcbnl_ops->setapp) { 539 if (netdev->dcbnl_ops->setapp) {
696 err = netdev->dcbnl_ops->setapp(netdev, idtype, id, up); 540 ret = netdev->dcbnl_ops->setapp(netdev, idtype, id, up);
697 } else { 541 } else {
698 struct dcb_app app; 542 struct dcb_app app;
699 app.selector = idtype; 543 app.selector = idtype;
700 app.protocol = id; 544 app.protocol = id;
701 app.priority = up; 545 app.priority = up;
702 err = dcb_setapp(netdev, &app); 546 ret = dcb_setapp(netdev, &app);
703 } 547 }
704 548
705 ret = dcbnl_reply(err, RTM_SETDCB, DCB_CMD_SAPP, DCB_ATTR_APP, 549 ret = nla_put_u8(skb, DCB_ATTR_APP, ret);
706 pid, seq, flags);
707 dcbnl_cee_notify(netdev, RTM_SETDCB, DCB_CMD_SAPP, seq, 0); 550 dcbnl_cee_notify(netdev, RTM_SETDCB, DCB_CMD_SAPP, seq, 0);
708out: 551
709 return ret; 552 return ret;
710} 553}
711 554
712static int __dcbnl_pg_getcfg(struct net_device *netdev, struct nlattr **tb, 555static int __dcbnl_pg_getcfg(struct net_device *netdev, struct nlmsghdr *nlh,
713 u32 pid, u32 seq, u16 flags, int dir) 556 struct nlattr **tb, struct sk_buff *skb, int dir)
714{ 557{
715 struct sk_buff *dcbnl_skb;
716 struct nlmsghdr *nlh;
717 struct dcbmsg *dcb;
718 struct nlattr *pg_nest, *param_nest, *data; 558 struct nlattr *pg_nest, *param_nest, *data;
719 struct nlattr *pg_tb[DCB_PG_ATTR_MAX + 1]; 559 struct nlattr *pg_tb[DCB_PG_ATTR_MAX + 1];
720 struct nlattr *param_tb[DCB_TC_ATTR_PARAM_MAX + 1]; 560 struct nlattr *param_tb[DCB_TC_ATTR_PARAM_MAX + 1];
721 u8 prio, pgid, tc_pct, up_map; 561 u8 prio, pgid, tc_pct, up_map;
722 int ret = -EINVAL; 562 int ret;
723 int getall = 0; 563 int getall = 0;
724 int i; 564 int i;
725 565
726 if (!tb[DCB_ATTR_PG_CFG] || 566 if (!tb[DCB_ATTR_PG_CFG])
727 !netdev->dcbnl_ops->getpgtccfgtx || 567 return -EINVAL;
568
569 if (!netdev->dcbnl_ops->getpgtccfgtx ||
728 !netdev->dcbnl_ops->getpgtccfgrx || 570 !netdev->dcbnl_ops->getpgtccfgrx ||
729 !netdev->dcbnl_ops->getpgbwgcfgtx || 571 !netdev->dcbnl_ops->getpgbwgcfgtx ||
730 !netdev->dcbnl_ops->getpgbwgcfgrx) 572 !netdev->dcbnl_ops->getpgbwgcfgrx)
731 return ret; 573 return -EOPNOTSUPP;
732 574
733 ret = nla_parse_nested(pg_tb, DCB_PG_ATTR_MAX, 575 ret = nla_parse_nested(pg_tb, DCB_PG_ATTR_MAX,
734 tb[DCB_ATTR_PG_CFG], dcbnl_pg_nest); 576 tb[DCB_ATTR_PG_CFG], dcbnl_pg_nest);
735
736 if (ret) 577 if (ret)
737 goto err_out; 578 return ret;
738
739 dcbnl_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
740 if (!dcbnl_skb)
741 goto err_out;
742
743 nlh = NLMSG_NEW(dcbnl_skb, pid, seq, RTM_GETDCB, sizeof(*dcb), flags);
744
745 dcb = NLMSG_DATA(nlh);
746 dcb->dcb_family = AF_UNSPEC;
747 dcb->cmd = (dir) ? DCB_CMD_PGRX_GCFG : DCB_CMD_PGTX_GCFG;
748 579
749 pg_nest = nla_nest_start(dcbnl_skb, DCB_ATTR_PG_CFG); 580 pg_nest = nla_nest_start(skb, DCB_ATTR_PG_CFG);
750 if (!pg_nest) 581 if (!pg_nest)
751 goto err; 582 return -EMSGSIZE;
752 583
753 if (pg_tb[DCB_PG_ATTR_TC_ALL]) 584 if (pg_tb[DCB_PG_ATTR_TC_ALL])
754 getall = 1; 585 getall = 1;
@@ -766,7 +597,7 @@ static int __dcbnl_pg_getcfg(struct net_device *netdev, struct nlattr **tb,
766 if (ret) 597 if (ret)
767 goto err_pg; 598 goto err_pg;
768 599
769 param_nest = nla_nest_start(dcbnl_skb, i); 600 param_nest = nla_nest_start(skb, i);
770 if (!param_nest) 601 if (!param_nest)
771 goto err_pg; 602 goto err_pg;
772 603
@@ -789,33 +620,33 @@ static int __dcbnl_pg_getcfg(struct net_device *netdev, struct nlattr **tb,
789 620
790 if (param_tb[DCB_TC_ATTR_PARAM_PGID] || 621 if (param_tb[DCB_TC_ATTR_PARAM_PGID] ||
791 param_tb[DCB_TC_ATTR_PARAM_ALL]) { 622 param_tb[DCB_TC_ATTR_PARAM_ALL]) {
792 ret = nla_put_u8(dcbnl_skb, 623 ret = nla_put_u8(skb,
793 DCB_TC_ATTR_PARAM_PGID, pgid); 624 DCB_TC_ATTR_PARAM_PGID, pgid);
794 if (ret) 625 if (ret)
795 goto err_param; 626 goto err_param;
796 } 627 }
797 if (param_tb[DCB_TC_ATTR_PARAM_UP_MAPPING] || 628 if (param_tb[DCB_TC_ATTR_PARAM_UP_MAPPING] ||
798 param_tb[DCB_TC_ATTR_PARAM_ALL]) { 629 param_tb[DCB_TC_ATTR_PARAM_ALL]) {
799 ret = nla_put_u8(dcbnl_skb, 630 ret = nla_put_u8(skb,
800 DCB_TC_ATTR_PARAM_UP_MAPPING, up_map); 631 DCB_TC_ATTR_PARAM_UP_MAPPING, up_map);
801 if (ret) 632 if (ret)
802 goto err_param; 633 goto err_param;
803 } 634 }
804 if (param_tb[DCB_TC_ATTR_PARAM_STRICT_PRIO] || 635 if (param_tb[DCB_TC_ATTR_PARAM_STRICT_PRIO] ||
805 param_tb[DCB_TC_ATTR_PARAM_ALL]) { 636 param_tb[DCB_TC_ATTR_PARAM_ALL]) {
806 ret = nla_put_u8(dcbnl_skb, 637 ret = nla_put_u8(skb,
807 DCB_TC_ATTR_PARAM_STRICT_PRIO, prio); 638 DCB_TC_ATTR_PARAM_STRICT_PRIO, prio);
808 if (ret) 639 if (ret)
809 goto err_param; 640 goto err_param;
810 } 641 }
811 if (param_tb[DCB_TC_ATTR_PARAM_BW_PCT] || 642 if (param_tb[DCB_TC_ATTR_PARAM_BW_PCT] ||
812 param_tb[DCB_TC_ATTR_PARAM_ALL]) { 643 param_tb[DCB_TC_ATTR_PARAM_ALL]) {
813 ret = nla_put_u8(dcbnl_skb, DCB_TC_ATTR_PARAM_BW_PCT, 644 ret = nla_put_u8(skb, DCB_TC_ATTR_PARAM_BW_PCT,
814 tc_pct); 645 tc_pct);
815 if (ret) 646 if (ret)
816 goto err_param; 647 goto err_param;
817 } 648 }
818 nla_nest_end(dcbnl_skb, param_nest); 649 nla_nest_end(skb, param_nest);
819 } 650 }
820 651
821 if (pg_tb[DCB_PG_ATTR_BW_ID_ALL]) 652 if (pg_tb[DCB_PG_ATTR_BW_ID_ALL])
@@ -838,80 +669,71 @@ static int __dcbnl_pg_getcfg(struct net_device *netdev, struct nlattr **tb,
838 netdev->dcbnl_ops->getpgbwgcfgtx(netdev, 669 netdev->dcbnl_ops->getpgbwgcfgtx(netdev,
839 i - DCB_PG_ATTR_BW_ID_0, &tc_pct); 670 i - DCB_PG_ATTR_BW_ID_0, &tc_pct);
840 } 671 }
841 ret = nla_put_u8(dcbnl_skb, i, tc_pct); 672 ret = nla_put_u8(skb, i, tc_pct);
842
843 if (ret) 673 if (ret)
844 goto err_pg; 674 goto err_pg;
845 } 675 }
846 676
847 nla_nest_end(dcbnl_skb, pg_nest); 677 nla_nest_end(skb, pg_nest);
848
849 nlmsg_end(dcbnl_skb, nlh);
850
851 ret = rtnl_unicast(dcbnl_skb, &init_net, pid);
852 if (ret)
853 goto err_out;
854 678
855 return 0; 679 return 0;
856 680
857err_param: 681err_param:
858 nla_nest_cancel(dcbnl_skb, param_nest); 682 nla_nest_cancel(skb, param_nest);
859err_pg: 683err_pg:
860 nla_nest_cancel(dcbnl_skb, pg_nest); 684 nla_nest_cancel(skb, pg_nest);
861nlmsg_failure: 685
862err: 686 return -EMSGSIZE;
863 kfree_skb(dcbnl_skb);
864err_out:
865 ret = -EINVAL;
866 return ret;
867} 687}
868 688
869static int dcbnl_pgtx_getcfg(struct net_device *netdev, struct nlattr **tb, 689static int dcbnl_pgtx_getcfg(struct net_device *netdev, struct nlmsghdr *nlh,
870 u32 pid, u32 seq, u16 flags) 690 u32 seq, struct nlattr **tb, struct sk_buff *skb)
871{ 691{
872 return __dcbnl_pg_getcfg(netdev, tb, pid, seq, flags, 0); 692 return __dcbnl_pg_getcfg(netdev, nlh, tb, skb, 0);
873} 693}
874 694
875static int dcbnl_pgrx_getcfg(struct net_device *netdev, struct nlattr **tb, 695static int dcbnl_pgrx_getcfg(struct net_device *netdev, struct nlmsghdr *nlh,
876 u32 pid, u32 seq, u16 flags) 696 u32 seq, struct nlattr **tb, struct sk_buff *skb)
877{ 697{
878 return __dcbnl_pg_getcfg(netdev, tb, pid, seq, flags, 1); 698 return __dcbnl_pg_getcfg(netdev, nlh, tb, skb, 1);
879} 699}
880 700
881static int dcbnl_setstate(struct net_device *netdev, struct nlattr **tb, 701static int dcbnl_setstate(struct net_device *netdev, struct nlmsghdr *nlh,
882 u32 pid, u32 seq, u16 flags) 702 u32 seq, struct nlattr **tb, struct sk_buff *skb)
883{ 703{
884 int ret = -EINVAL;
885 u8 value; 704 u8 value;
886 705
887 if (!tb[DCB_ATTR_STATE] || !netdev->dcbnl_ops->setstate) 706 if (!tb[DCB_ATTR_STATE])
888 return ret; 707 return -EINVAL;
889 708
890 value = nla_get_u8(tb[DCB_ATTR_STATE]); 709 if (!netdev->dcbnl_ops->setstate)
710 return -EOPNOTSUPP;
891 711
892 ret = dcbnl_reply(netdev->dcbnl_ops->setstate(netdev, value), 712 value = nla_get_u8(tb[DCB_ATTR_STATE]);
893 RTM_SETDCB, DCB_CMD_SSTATE, DCB_ATTR_STATE,
894 pid, seq, flags);
895 713
896 return ret; 714 return nla_put_u8(skb, DCB_ATTR_STATE,
715 netdev->dcbnl_ops->setstate(netdev, value));
897} 716}
898 717
899static int dcbnl_setpfccfg(struct net_device *netdev, struct nlattr **tb, 718static int dcbnl_setpfccfg(struct net_device *netdev, struct nlmsghdr *nlh,
900 u32 pid, u32 seq, u16 flags) 719 u32 seq, struct nlattr **tb, struct sk_buff *skb)
901{ 720{
902 struct nlattr *data[DCB_PFC_UP_ATTR_MAX + 1]; 721 struct nlattr *data[DCB_PFC_UP_ATTR_MAX + 1];
903 int i; 722 int i;
904 int ret = -EINVAL; 723 int ret;
905 u8 value; 724 u8 value;
906 725
907 if (!tb[DCB_ATTR_PFC_CFG] || !netdev->dcbnl_ops->setpfccfg) 726 if (!tb[DCB_ATTR_PFC_CFG])
908 return ret; 727 return -EINVAL;
728
729 if (!netdev->dcbnl_ops->setpfccfg)
730 return -EOPNOTSUPP;
909 731
910 ret = nla_parse_nested(data, DCB_PFC_UP_ATTR_MAX, 732 ret = nla_parse_nested(data, DCB_PFC_UP_ATTR_MAX,
911 tb[DCB_ATTR_PFC_CFG], 733 tb[DCB_ATTR_PFC_CFG],
912 dcbnl_pfc_up_nest); 734 dcbnl_pfc_up_nest);
913 if (ret) 735 if (ret)
914 goto err; 736 return ret;
915 737
916 for (i = DCB_PFC_UP_ATTR_0; i <= DCB_PFC_UP_ATTR_7; i++) { 738 for (i = DCB_PFC_UP_ATTR_0; i <= DCB_PFC_UP_ATTR_7; i++) {
917 if (data[i] == NULL) 739 if (data[i] == NULL)
@@ -921,50 +743,53 @@ static int dcbnl_setpfccfg(struct net_device *netdev, struct nlattr **tb,
921 data[i]->nla_type - DCB_PFC_UP_ATTR_0, value); 743 data[i]->nla_type - DCB_PFC_UP_ATTR_0, value);
922 } 744 }
923 745
924 ret = dcbnl_reply(0, RTM_SETDCB, DCB_CMD_PFC_SCFG, DCB_ATTR_PFC_CFG, 746 return nla_put_u8(skb, DCB_ATTR_PFC_CFG, 0);
925 pid, seq, flags);
926err:
927 return ret;
928} 747}
929 748
930static int dcbnl_setall(struct net_device *netdev, struct nlattr **tb, 749static int dcbnl_setall(struct net_device *netdev, struct nlmsghdr *nlh,
931 u32 pid, u32 seq, u16 flags) 750 u32 seq, struct nlattr **tb, struct sk_buff *skb)
932{ 751{
933 int ret = -EINVAL; 752 int ret;
934 753
935 if (!tb[DCB_ATTR_SET_ALL] || !netdev->dcbnl_ops->setall) 754 if (!tb[DCB_ATTR_SET_ALL])
936 return ret; 755 return -EINVAL;
756
757 if (!netdev->dcbnl_ops->setall)
758 return -EOPNOTSUPP;
937 759
938 ret = dcbnl_reply(netdev->dcbnl_ops->setall(netdev), RTM_SETDCB, 760 ret = nla_put_u8(skb, DCB_ATTR_SET_ALL,
939 DCB_CMD_SET_ALL, DCB_ATTR_SET_ALL, pid, seq, flags); 761 netdev->dcbnl_ops->setall(netdev));
940 dcbnl_cee_notify(netdev, RTM_SETDCB, DCB_CMD_SET_ALL, seq, 0); 762 dcbnl_cee_notify(netdev, RTM_SETDCB, DCB_CMD_SET_ALL, seq, 0);
941 763
942 return ret; 764 return ret;
943} 765}
944 766
945static int __dcbnl_pg_setcfg(struct net_device *netdev, struct nlattr **tb, 767static int __dcbnl_pg_setcfg(struct net_device *netdev, struct nlmsghdr *nlh,
946 u32 pid, u32 seq, u16 flags, int dir) 768 u32 seq, struct nlattr **tb, struct sk_buff *skb,
769 int dir)
947{ 770{
948 struct nlattr *pg_tb[DCB_PG_ATTR_MAX + 1]; 771 struct nlattr *pg_tb[DCB_PG_ATTR_MAX + 1];
949 struct nlattr *param_tb[DCB_TC_ATTR_PARAM_MAX + 1]; 772 struct nlattr *param_tb[DCB_TC_ATTR_PARAM_MAX + 1];
950 int ret = -EINVAL; 773 int ret;
951 int i; 774 int i;
952 u8 pgid; 775 u8 pgid;
953 u8 up_map; 776 u8 up_map;
954 u8 prio; 777 u8 prio;
955 u8 tc_pct; 778 u8 tc_pct;
956 779
957 if (!tb[DCB_ATTR_PG_CFG] || 780 if (!tb[DCB_ATTR_PG_CFG])
958 !netdev->dcbnl_ops->setpgtccfgtx || 781 return -EINVAL;
782
783 if (!netdev->dcbnl_ops->setpgtccfgtx ||
959 !netdev->dcbnl_ops->setpgtccfgrx || 784 !netdev->dcbnl_ops->setpgtccfgrx ||
960 !netdev->dcbnl_ops->setpgbwgcfgtx || 785 !netdev->dcbnl_ops->setpgbwgcfgtx ||
961 !netdev->dcbnl_ops->setpgbwgcfgrx) 786 !netdev->dcbnl_ops->setpgbwgcfgrx)
962 return ret; 787 return -EOPNOTSUPP;
963 788
964 ret = nla_parse_nested(pg_tb, DCB_PG_ATTR_MAX, 789 ret = nla_parse_nested(pg_tb, DCB_PG_ATTR_MAX,
965 tb[DCB_ATTR_PG_CFG], dcbnl_pg_nest); 790 tb[DCB_ATTR_PG_CFG], dcbnl_pg_nest);
966 if (ret) 791 if (ret)
967 goto err; 792 return ret;
968 793
969 for (i = DCB_PG_ATTR_TC_0; i <= DCB_PG_ATTR_TC_7; i++) { 794 for (i = DCB_PG_ATTR_TC_0; i <= DCB_PG_ATTR_TC_7; i++) {
970 if (!pg_tb[i]) 795 if (!pg_tb[i])
@@ -973,7 +798,7 @@ static int __dcbnl_pg_setcfg(struct net_device *netdev, struct nlattr **tb,
973 ret = nla_parse_nested(param_tb, DCB_TC_ATTR_PARAM_MAX, 798 ret = nla_parse_nested(param_tb, DCB_TC_ATTR_PARAM_MAX,
974 pg_tb[i], dcbnl_tc_param_nest); 799 pg_tb[i], dcbnl_tc_param_nest);
975 if (ret) 800 if (ret)
976 goto err; 801 return ret;
977 802
978 pgid = DCB_ATTR_VALUE_UNDEFINED; 803 pgid = DCB_ATTR_VALUE_UNDEFINED;
979 prio = DCB_ATTR_VALUE_UNDEFINED; 804 prio = DCB_ATTR_VALUE_UNDEFINED;
@@ -1026,63 +851,47 @@ static int __dcbnl_pg_setcfg(struct net_device *netdev, struct nlattr **tb,
1026 } 851 }
1027 } 852 }
1028 853
1029 ret = dcbnl_reply(0, RTM_SETDCB, 854 return nla_put_u8(skb, DCB_ATTR_PG_CFG, 0);
1030 (dir ? DCB_CMD_PGRX_SCFG : DCB_CMD_PGTX_SCFG),
1031 DCB_ATTR_PG_CFG, pid, seq, flags);
1032
1033err:
1034 return ret;
1035} 855}
1036 856
1037static int dcbnl_pgtx_setcfg(struct net_device *netdev, struct nlattr **tb, 857static int dcbnl_pgtx_setcfg(struct net_device *netdev, struct nlmsghdr *nlh,
1038 u32 pid, u32 seq, u16 flags) 858 u32 seq, struct nlattr **tb, struct sk_buff *skb)
1039{ 859{
1040 return __dcbnl_pg_setcfg(netdev, tb, pid, seq, flags, 0); 860 return __dcbnl_pg_setcfg(netdev, nlh, seq, tb, skb, 0);
1041} 861}
1042 862
1043static int dcbnl_pgrx_setcfg(struct net_device *netdev, struct nlattr **tb, 863static int dcbnl_pgrx_setcfg(struct net_device *netdev, struct nlmsghdr *nlh,
1044 u32 pid, u32 seq, u16 flags) 864 u32 seq, struct nlattr **tb, struct sk_buff *skb)
1045{ 865{
1046 return __dcbnl_pg_setcfg(netdev, tb, pid, seq, flags, 1); 866 return __dcbnl_pg_setcfg(netdev, nlh, seq, tb, skb, 1);
1047} 867}
1048 868
1049static int dcbnl_bcn_getcfg(struct net_device *netdev, struct nlattr **tb, 869static int dcbnl_bcn_getcfg(struct net_device *netdev, struct nlmsghdr *nlh,
1050 u32 pid, u32 seq, u16 flags) 870 u32 seq, struct nlattr **tb, struct sk_buff *skb)
1051{ 871{
1052 struct sk_buff *dcbnl_skb;
1053 struct nlmsghdr *nlh;
1054 struct dcbmsg *dcb;
1055 struct nlattr *bcn_nest; 872 struct nlattr *bcn_nest;
1056 struct nlattr *bcn_tb[DCB_BCN_ATTR_MAX + 1]; 873 struct nlattr *bcn_tb[DCB_BCN_ATTR_MAX + 1];
1057 u8 value_byte; 874 u8 value_byte;
1058 u32 value_integer; 875 u32 value_integer;
1059 int ret = -EINVAL; 876 int ret;
1060 bool getall = false; 877 bool getall = false;
1061 int i; 878 int i;
1062 879
1063 if (!tb[DCB_ATTR_BCN] || !netdev->dcbnl_ops->getbcnrp || 880 if (!tb[DCB_ATTR_BCN])
881 return -EINVAL;
882
883 if (!netdev->dcbnl_ops->getbcnrp ||
1064 !netdev->dcbnl_ops->getbcncfg) 884 !netdev->dcbnl_ops->getbcncfg)
1065 return ret; 885 return -EOPNOTSUPP;
1066 886
1067 ret = nla_parse_nested(bcn_tb, DCB_BCN_ATTR_MAX, 887 ret = nla_parse_nested(bcn_tb, DCB_BCN_ATTR_MAX,
1068 tb[DCB_ATTR_BCN], dcbnl_bcn_nest); 888 tb[DCB_ATTR_BCN], dcbnl_bcn_nest);
1069
1070 if (ret) 889 if (ret)
1071 goto err_out; 890 return ret;
1072
1073 dcbnl_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1074 if (!dcbnl_skb)
1075 goto err_out;
1076
1077 nlh = NLMSG_NEW(dcbnl_skb, pid, seq, RTM_GETDCB, sizeof(*dcb), flags);
1078
1079 dcb = NLMSG_DATA(nlh);
1080 dcb->dcb_family = AF_UNSPEC;
1081 dcb->cmd = DCB_CMD_BCN_GCFG;
1082 891
1083 bcn_nest = nla_nest_start(dcbnl_skb, DCB_ATTR_BCN); 892 bcn_nest = nla_nest_start(skb, DCB_ATTR_BCN);
1084 if (!bcn_nest) 893 if (!bcn_nest)
1085 goto err; 894 return -EMSGSIZE;
1086 895
1087 if (bcn_tb[DCB_BCN_ATTR_ALL]) 896 if (bcn_tb[DCB_BCN_ATTR_ALL])
1088 getall = true; 897 getall = true;
@@ -1093,7 +902,7 @@ static int dcbnl_bcn_getcfg(struct net_device *netdev, struct nlattr **tb,
1093 902
1094 netdev->dcbnl_ops->getbcnrp(netdev, i - DCB_BCN_ATTR_RP_0, 903 netdev->dcbnl_ops->getbcnrp(netdev, i - DCB_BCN_ATTR_RP_0,
1095 &value_byte); 904 &value_byte);
1096 ret = nla_put_u8(dcbnl_skb, i, value_byte); 905 ret = nla_put_u8(skb, i, value_byte);
1097 if (ret) 906 if (ret)
1098 goto err_bcn; 907 goto err_bcn;
1099 } 908 }
@@ -1104,49 +913,41 @@ static int dcbnl_bcn_getcfg(struct net_device *netdev, struct nlattr **tb,
1104 913
1105 netdev->dcbnl_ops->getbcncfg(netdev, i, 914 netdev->dcbnl_ops->getbcncfg(netdev, i,
1106 &value_integer); 915 &value_integer);
1107 ret = nla_put_u32(dcbnl_skb, i, value_integer); 916 ret = nla_put_u32(skb, i, value_integer);
1108 if (ret) 917 if (ret)
1109 goto err_bcn; 918 goto err_bcn;
1110 } 919 }
1111 920
1112 nla_nest_end(dcbnl_skb, bcn_nest); 921 nla_nest_end(skb, bcn_nest);
1113
1114 nlmsg_end(dcbnl_skb, nlh);
1115
1116 ret = rtnl_unicast(dcbnl_skb, &init_net, pid);
1117 if (ret)
1118 goto err_out;
1119 922
1120 return 0; 923 return 0;
1121 924
1122err_bcn: 925err_bcn:
1123 nla_nest_cancel(dcbnl_skb, bcn_nest); 926 nla_nest_cancel(skb, bcn_nest);
1124nlmsg_failure:
1125err:
1126 kfree_skb(dcbnl_skb);
1127err_out:
1128 ret = -EINVAL;
1129 return ret; 927 return ret;
1130} 928}
1131 929
1132static int dcbnl_bcn_setcfg(struct net_device *netdev, struct nlattr **tb, 930static int dcbnl_bcn_setcfg(struct net_device *netdev, struct nlmsghdr *nlh,
1133 u32 pid, u32 seq, u16 flags) 931 u32 seq, struct nlattr **tb, struct sk_buff *skb)
1134{ 932{
1135 struct nlattr *data[DCB_BCN_ATTR_MAX + 1]; 933 struct nlattr *data[DCB_BCN_ATTR_MAX + 1];
1136 int i; 934 int i;
1137 int ret = -EINVAL; 935 int ret;
1138 u8 value_byte; 936 u8 value_byte;
1139 u32 value_int; 937 u32 value_int;
1140 938
1141 if (!tb[DCB_ATTR_BCN] || !netdev->dcbnl_ops->setbcncfg || 939 if (!tb[DCB_ATTR_BCN])
940 return -EINVAL;
941
942 if (!netdev->dcbnl_ops->setbcncfg ||
1142 !netdev->dcbnl_ops->setbcnrp) 943 !netdev->dcbnl_ops->setbcnrp)
1143 return ret; 944 return -EOPNOTSUPP;
1144 945
1145 ret = nla_parse_nested(data, DCB_BCN_ATTR_MAX, 946 ret = nla_parse_nested(data, DCB_BCN_ATTR_MAX,
1146 tb[DCB_ATTR_BCN], 947 tb[DCB_ATTR_BCN],
1147 dcbnl_pfc_up_nest); 948 dcbnl_pfc_up_nest);
1148 if (ret) 949 if (ret)
1149 goto err; 950 return ret;
1150 951
1151 for (i = DCB_BCN_ATTR_RP_0; i <= DCB_BCN_ATTR_RP_7; i++) { 952 for (i = DCB_BCN_ATTR_RP_0; i <= DCB_BCN_ATTR_RP_7; i++) {
1152 if (data[i] == NULL) 953 if (data[i] == NULL)
@@ -1164,10 +965,7 @@ static int dcbnl_bcn_setcfg(struct net_device *netdev, struct nlattr **tb,
1164 i, value_int); 965 i, value_int);
1165 } 966 }
1166 967
1167 ret = dcbnl_reply(0, RTM_SETDCB, DCB_CMD_BCN_SCFG, DCB_ATTR_BCN, 968 return nla_put_u8(skb, DCB_ATTR_BCN, 0);
1168 pid, seq, flags);
1169err:
1170 return ret;
1171} 969}
1172 970
1173static int dcbnl_build_peer_app(struct net_device *netdev, struct sk_buff* skb, 971static int dcbnl_build_peer_app(struct net_device *netdev, struct sk_buff* skb,
@@ -1233,20 +1031,21 @@ static int dcbnl_ieee_fill(struct sk_buff *skb, struct net_device *netdev)
1233 struct dcb_app_type *itr; 1031 struct dcb_app_type *itr;
1234 const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops; 1032 const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops;
1235 int dcbx; 1033 int dcbx;
1236 int err = -EMSGSIZE; 1034 int err;
1237 1035
1238 if (nla_put_string(skb, DCB_ATTR_IFNAME, netdev->name)) 1036 if (nla_put_string(skb, DCB_ATTR_IFNAME, netdev->name))
1239 goto nla_put_failure; 1037 return -EMSGSIZE;
1038
1240 ieee = nla_nest_start(skb, DCB_ATTR_IEEE); 1039 ieee = nla_nest_start(skb, DCB_ATTR_IEEE);
1241 if (!ieee) 1040 if (!ieee)
1242 goto nla_put_failure; 1041 return -EMSGSIZE;
1243 1042
1244 if (ops->ieee_getets) { 1043 if (ops->ieee_getets) {
1245 struct ieee_ets ets; 1044 struct ieee_ets ets;
1246 err = ops->ieee_getets(netdev, &ets); 1045 err = ops->ieee_getets(netdev, &ets);
1247 if (!err && 1046 if (!err &&
1248 nla_put(skb, DCB_ATTR_IEEE_ETS, sizeof(ets), &ets)) 1047 nla_put(skb, DCB_ATTR_IEEE_ETS, sizeof(ets), &ets))
1249 goto nla_put_failure; 1048 return -EMSGSIZE;
1250 } 1049 }
1251 1050
1252 if (ops->ieee_getmaxrate) { 1051 if (ops->ieee_getmaxrate) {
@@ -1256,7 +1055,7 @@ static int dcbnl_ieee_fill(struct sk_buff *skb, struct net_device *netdev)
1256 err = nla_put(skb, DCB_ATTR_IEEE_MAXRATE, 1055 err = nla_put(skb, DCB_ATTR_IEEE_MAXRATE,
1257 sizeof(maxrate), &maxrate); 1056 sizeof(maxrate), &maxrate);
1258 if (err) 1057 if (err)
1259 goto nla_put_failure; 1058 return -EMSGSIZE;
1260 } 1059 }
1261 } 1060 }
1262 1061
@@ -1265,12 +1064,12 @@ static int dcbnl_ieee_fill(struct sk_buff *skb, struct net_device *netdev)
1265 err = ops->ieee_getpfc(netdev, &pfc); 1064 err = ops->ieee_getpfc(netdev, &pfc);
1266 if (!err && 1065 if (!err &&
1267 nla_put(skb, DCB_ATTR_IEEE_PFC, sizeof(pfc), &pfc)) 1066 nla_put(skb, DCB_ATTR_IEEE_PFC, sizeof(pfc), &pfc))
1268 goto nla_put_failure; 1067 return -EMSGSIZE;
1269 } 1068 }
1270 1069
1271 app = nla_nest_start(skb, DCB_ATTR_IEEE_APP_TABLE); 1070 app = nla_nest_start(skb, DCB_ATTR_IEEE_APP_TABLE);
1272 if (!app) 1071 if (!app)
1273 goto nla_put_failure; 1072 return -EMSGSIZE;
1274 1073
1275 spin_lock(&dcb_lock); 1074 spin_lock(&dcb_lock);
1276 list_for_each_entry(itr, &dcb_app_list, list) { 1075 list_for_each_entry(itr, &dcb_app_list, list) {
@@ -1279,7 +1078,7 @@ static int dcbnl_ieee_fill(struct sk_buff *skb, struct net_device *netdev)
1279 &itr->app); 1078 &itr->app);
1280 if (err) { 1079 if (err) {
1281 spin_unlock(&dcb_lock); 1080 spin_unlock(&dcb_lock);
1282 goto nla_put_failure; 1081 return -EMSGSIZE;
1283 } 1082 }
1284 } 1083 }
1285 } 1084 }
@@ -1298,7 +1097,7 @@ static int dcbnl_ieee_fill(struct sk_buff *skb, struct net_device *netdev)
1298 err = ops->ieee_peer_getets(netdev, &ets); 1097 err = ops->ieee_peer_getets(netdev, &ets);
1299 if (!err && 1098 if (!err &&
1300 nla_put(skb, DCB_ATTR_IEEE_PEER_ETS, sizeof(ets), &ets)) 1099 nla_put(skb, DCB_ATTR_IEEE_PEER_ETS, sizeof(ets), &ets))
1301 goto nla_put_failure; 1100 return -EMSGSIZE;
1302 } 1101 }
1303 1102
1304 if (ops->ieee_peer_getpfc) { 1103 if (ops->ieee_peer_getpfc) {
@@ -1306,7 +1105,7 @@ static int dcbnl_ieee_fill(struct sk_buff *skb, struct net_device *netdev)
1306 err = ops->ieee_peer_getpfc(netdev, &pfc); 1105 err = ops->ieee_peer_getpfc(netdev, &pfc);
1307 if (!err && 1106 if (!err &&
1308 nla_put(skb, DCB_ATTR_IEEE_PEER_PFC, sizeof(pfc), &pfc)) 1107 nla_put(skb, DCB_ATTR_IEEE_PEER_PFC, sizeof(pfc), &pfc))
1309 goto nla_put_failure; 1108 return -EMSGSIZE;
1310 } 1109 }
1311 1110
1312 if (ops->peer_getappinfo && ops->peer_getapptable) { 1111 if (ops->peer_getappinfo && ops->peer_getapptable) {
@@ -1315,20 +1114,17 @@ static int dcbnl_ieee_fill(struct sk_buff *skb, struct net_device *netdev)
1315 DCB_ATTR_IEEE_APP_UNSPEC, 1114 DCB_ATTR_IEEE_APP_UNSPEC,
1316 DCB_ATTR_IEEE_APP); 1115 DCB_ATTR_IEEE_APP);
1317 if (err) 1116 if (err)
1318 goto nla_put_failure; 1117 return -EMSGSIZE;
1319 } 1118 }
1320 1119
1321 nla_nest_end(skb, ieee); 1120 nla_nest_end(skb, ieee);
1322 if (dcbx >= 0) { 1121 if (dcbx >= 0) {
1323 err = nla_put_u8(skb, DCB_ATTR_DCBX, dcbx); 1122 err = nla_put_u8(skb, DCB_ATTR_DCBX, dcbx);
1324 if (err) 1123 if (err)
1325 goto nla_put_failure; 1124 return -EMSGSIZE;
1326 } 1125 }
1327 1126
1328 return 0; 1127 return 0;
1329
1330nla_put_failure:
1331 return err;
1332} 1128}
1333 1129
1334static int dcbnl_cee_pg_fill(struct sk_buff *skb, struct net_device *dev, 1130static int dcbnl_cee_pg_fill(struct sk_buff *skb, struct net_device *dev,
@@ -1340,13 +1136,13 @@ static int dcbnl_cee_pg_fill(struct sk_buff *skb, struct net_device *dev,
1340 struct nlattr *pg = nla_nest_start(skb, i); 1136 struct nlattr *pg = nla_nest_start(skb, i);
1341 1137
1342 if (!pg) 1138 if (!pg)
1343 goto nla_put_failure; 1139 return -EMSGSIZE;
1344 1140
1345 for (i = DCB_PG_ATTR_TC_0; i <= DCB_PG_ATTR_TC_7; i++) { 1141 for (i = DCB_PG_ATTR_TC_0; i <= DCB_PG_ATTR_TC_7; i++) {
1346 struct nlattr *tc_nest = nla_nest_start(skb, i); 1142 struct nlattr *tc_nest = nla_nest_start(skb, i);
1347 1143
1348 if (!tc_nest) 1144 if (!tc_nest)
1349 goto nla_put_failure; 1145 return -EMSGSIZE;
1350 1146
1351 pgid = DCB_ATTR_VALUE_UNDEFINED; 1147 pgid = DCB_ATTR_VALUE_UNDEFINED;
1352 prio = DCB_ATTR_VALUE_UNDEFINED; 1148 prio = DCB_ATTR_VALUE_UNDEFINED;
@@ -1364,7 +1160,7 @@ static int dcbnl_cee_pg_fill(struct sk_buff *skb, struct net_device *dev,
1364 nla_put_u8(skb, DCB_TC_ATTR_PARAM_UP_MAPPING, up_map) || 1160 nla_put_u8(skb, DCB_TC_ATTR_PARAM_UP_MAPPING, up_map) ||
1365 nla_put_u8(skb, DCB_TC_ATTR_PARAM_STRICT_PRIO, prio) || 1161 nla_put_u8(skb, DCB_TC_ATTR_PARAM_STRICT_PRIO, prio) ||
1366 nla_put_u8(skb, DCB_TC_ATTR_PARAM_BW_PCT, tc_pct)) 1162 nla_put_u8(skb, DCB_TC_ATTR_PARAM_BW_PCT, tc_pct))
1367 goto nla_put_failure; 1163 return -EMSGSIZE;
1368 nla_nest_end(skb, tc_nest); 1164 nla_nest_end(skb, tc_nest);
1369 } 1165 }
1370 1166
@@ -1378,13 +1174,10 @@ static int dcbnl_cee_pg_fill(struct sk_buff *skb, struct net_device *dev,
1378 ops->getpgbwgcfgtx(dev, i - DCB_PG_ATTR_BW_ID_0, 1174 ops->getpgbwgcfgtx(dev, i - DCB_PG_ATTR_BW_ID_0,
1379 &tc_pct); 1175 &tc_pct);
1380 if (nla_put_u8(skb, i, tc_pct)) 1176 if (nla_put_u8(skb, i, tc_pct))
1381 goto nla_put_failure; 1177 return -EMSGSIZE;
1382 } 1178 }
1383 nla_nest_end(skb, pg); 1179 nla_nest_end(skb, pg);
1384 return 0; 1180 return 0;
1385
1386nla_put_failure:
1387 return -EMSGSIZE;
1388} 1181}
1389 1182
1390static int dcbnl_cee_fill(struct sk_buff *skb, struct net_device *netdev) 1183static int dcbnl_cee_fill(struct sk_buff *skb, struct net_device *netdev)
@@ -1531,27 +1324,16 @@ static int dcbnl_notify(struct net_device *dev, int event, int cmd,
1531 struct net *net = dev_net(dev); 1324 struct net *net = dev_net(dev);
1532 struct sk_buff *skb; 1325 struct sk_buff *skb;
1533 struct nlmsghdr *nlh; 1326 struct nlmsghdr *nlh;
1534 struct dcbmsg *dcb;
1535 const struct dcbnl_rtnl_ops *ops = dev->dcbnl_ops; 1327 const struct dcbnl_rtnl_ops *ops = dev->dcbnl_ops;
1536 int err; 1328 int err;
1537 1329
1538 if (!ops) 1330 if (!ops)
1539 return -EOPNOTSUPP; 1331 return -EOPNOTSUPP;
1540 1332
1541 skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 1333 skb = dcbnl_newmsg(event, cmd, pid, seq, 0, &nlh);
1542 if (!skb) 1334 if (!skb)
1543 return -ENOBUFS; 1335 return -ENOBUFS;
1544 1336
1545 nlh = nlmsg_put(skb, pid, 0, event, sizeof(*dcb), 0);
1546 if (nlh == NULL) {
1547 nlmsg_free(skb);
1548 return -EMSGSIZE;
1549 }
1550
1551 dcb = NLMSG_DATA(nlh);
1552 dcb->dcb_family = AF_UNSPEC;
1553 dcb->cmd = cmd;
1554
1555 if (dcbx_ver == DCB_CAP_DCBX_VER_IEEE) 1337 if (dcbx_ver == DCB_CAP_DCBX_VER_IEEE)
1556 err = dcbnl_ieee_fill(skb, dev); 1338 err = dcbnl_ieee_fill(skb, dev);
1557 else 1339 else
@@ -1559,8 +1341,7 @@ static int dcbnl_notify(struct net_device *dev, int event, int cmd,
1559 1341
1560 if (err < 0) { 1342 if (err < 0) {
1561 /* Report error to broadcast listeners */ 1343 /* Report error to broadcast listeners */
1562 nlmsg_cancel(skb, nlh); 1344 nlmsg_free(skb);
1563 kfree_skb(skb);
1564 rtnl_set_sk_err(net, RTNLGRP_DCB, err); 1345 rtnl_set_sk_err(net, RTNLGRP_DCB, err);
1565 } else { 1346 } else {
1566 /* End nlmsg and notify broadcast listeners */ 1347 /* End nlmsg and notify broadcast listeners */
@@ -1590,15 +1371,15 @@ EXPORT_SYMBOL(dcbnl_cee_notify);
1590 * No attempt is made to reconcile the case where only part of the 1371 * No attempt is made to reconcile the case where only part of the
1591 * cmd can be completed. 1372 * cmd can be completed.
1592 */ 1373 */
1593static int dcbnl_ieee_set(struct net_device *netdev, struct nlattr **tb, 1374static int dcbnl_ieee_set(struct net_device *netdev, struct nlmsghdr *nlh,
1594 u32 pid, u32 seq, u16 flags) 1375 u32 seq, struct nlattr **tb, struct sk_buff *skb)
1595{ 1376{
1596 const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops; 1377 const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops;
1597 struct nlattr *ieee[DCB_ATTR_IEEE_MAX + 1]; 1378 struct nlattr *ieee[DCB_ATTR_IEEE_MAX + 1];
1598 int err = -EOPNOTSUPP; 1379 int err;
1599 1380
1600 if (!ops) 1381 if (!ops)
1601 return err; 1382 return -EOPNOTSUPP;
1602 1383
1603 if (!tb[DCB_ATTR_IEEE]) 1384 if (!tb[DCB_ATTR_IEEE])
1604 return -EINVAL; 1385 return -EINVAL;
@@ -1649,58 +1430,28 @@ static int dcbnl_ieee_set(struct net_device *netdev, struct nlattr **tb,
1649 } 1430 }
1650 1431
1651err: 1432err:
1652 dcbnl_reply(err, RTM_SETDCB, DCB_CMD_IEEE_SET, DCB_ATTR_IEEE, 1433 err = nla_put_u8(skb, DCB_ATTR_IEEE, err);
1653 pid, seq, flags);
1654 dcbnl_ieee_notify(netdev, RTM_SETDCB, DCB_CMD_IEEE_SET, seq, 0); 1434 dcbnl_ieee_notify(netdev, RTM_SETDCB, DCB_CMD_IEEE_SET, seq, 0);
1655 return err; 1435 return err;
1656} 1436}
1657 1437
1658static int dcbnl_ieee_get(struct net_device *netdev, struct nlattr **tb, 1438static int dcbnl_ieee_get(struct net_device *netdev, struct nlmsghdr *nlh,
1659 u32 pid, u32 seq, u16 flags) 1439 u32 seq, struct nlattr **tb, struct sk_buff *skb)
1660{ 1440{
1661 struct net *net = dev_net(netdev);
1662 struct sk_buff *skb;
1663 struct nlmsghdr *nlh;
1664 struct dcbmsg *dcb;
1665 const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops; 1441 const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops;
1666 int err;
1667 1442
1668 if (!ops) 1443 if (!ops)
1669 return -EOPNOTSUPP; 1444 return -EOPNOTSUPP;
1670 1445
1671 skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 1446 return dcbnl_ieee_fill(skb, netdev);
1672 if (!skb)
1673 return -ENOBUFS;
1674
1675 nlh = nlmsg_put(skb, pid, seq, RTM_GETDCB, sizeof(*dcb), flags);
1676 if (nlh == NULL) {
1677 nlmsg_free(skb);
1678 return -EMSGSIZE;
1679 }
1680
1681 dcb = NLMSG_DATA(nlh);
1682 dcb->dcb_family = AF_UNSPEC;
1683 dcb->cmd = DCB_CMD_IEEE_GET;
1684
1685 err = dcbnl_ieee_fill(skb, netdev);
1686
1687 if (err < 0) {
1688 nlmsg_cancel(skb, nlh);
1689 kfree_skb(skb);
1690 } else {
1691 nlmsg_end(skb, nlh);
1692 err = rtnl_unicast(skb, net, pid);
1693 }
1694
1695 return err;
1696} 1447}
1697 1448
1698static int dcbnl_ieee_del(struct net_device *netdev, struct nlattr **tb, 1449static int dcbnl_ieee_del(struct net_device *netdev, struct nlmsghdr *nlh,
1699 u32 pid, u32 seq, u16 flags) 1450 u32 seq, struct nlattr **tb, struct sk_buff *skb)
1700{ 1451{
1701 const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops; 1452 const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops;
1702 struct nlattr *ieee[DCB_ATTR_IEEE_MAX + 1]; 1453 struct nlattr *ieee[DCB_ATTR_IEEE_MAX + 1];
1703 int err = -EOPNOTSUPP; 1454 int err;
1704 1455
1705 if (!ops) 1456 if (!ops)
1706 return -EOPNOTSUPP; 1457 return -EOPNOTSUPP;
@@ -1733,32 +1484,26 @@ static int dcbnl_ieee_del(struct net_device *netdev, struct nlattr **tb,
1733 } 1484 }
1734 1485
1735err: 1486err:
1736 dcbnl_reply(err, RTM_SETDCB, DCB_CMD_IEEE_DEL, DCB_ATTR_IEEE, 1487 err = nla_put_u8(skb, DCB_ATTR_IEEE, err);
1737 pid, seq, flags);
1738 dcbnl_ieee_notify(netdev, RTM_SETDCB, DCB_CMD_IEEE_DEL, seq, 0); 1488 dcbnl_ieee_notify(netdev, RTM_SETDCB, DCB_CMD_IEEE_DEL, seq, 0);
1739 return err; 1489 return err;
1740} 1490}
1741 1491
1742 1492
1743/* DCBX configuration */ 1493/* DCBX configuration */
1744static int dcbnl_getdcbx(struct net_device *netdev, struct nlattr **tb, 1494static int dcbnl_getdcbx(struct net_device *netdev, struct nlmsghdr *nlh,
1745 u32 pid, u32 seq, u16 flags) 1495 u32 seq, struct nlattr **tb, struct sk_buff *skb)
1746{ 1496{
1747 int ret;
1748
1749 if (!netdev->dcbnl_ops->getdcbx) 1497 if (!netdev->dcbnl_ops->getdcbx)
1750 return -EOPNOTSUPP; 1498 return -EOPNOTSUPP;
1751 1499
1752 ret = dcbnl_reply(netdev->dcbnl_ops->getdcbx(netdev), RTM_GETDCB, 1500 return nla_put_u8(skb, DCB_ATTR_DCBX,
1753 DCB_CMD_GDCBX, DCB_ATTR_DCBX, pid, seq, flags); 1501 netdev->dcbnl_ops->getdcbx(netdev));
1754
1755 return ret;
1756} 1502}
1757 1503
1758static int dcbnl_setdcbx(struct net_device *netdev, struct nlattr **tb, 1504static int dcbnl_setdcbx(struct net_device *netdev, struct nlmsghdr *nlh,
1759 u32 pid, u32 seq, u16 flags) 1505 u32 seq, struct nlattr **tb, struct sk_buff *skb)
1760{ 1506{
1761 int ret;
1762 u8 value; 1507 u8 value;
1763 1508
1764 if (!netdev->dcbnl_ops->setdcbx) 1509 if (!netdev->dcbnl_ops->setdcbx)
@@ -1769,19 +1514,13 @@ static int dcbnl_setdcbx(struct net_device *netdev, struct nlattr **tb,
1769 1514
1770 value = nla_get_u8(tb[DCB_ATTR_DCBX]); 1515 value = nla_get_u8(tb[DCB_ATTR_DCBX]);
1771 1516
1772 ret = dcbnl_reply(netdev->dcbnl_ops->setdcbx(netdev, value), 1517 return nla_put_u8(skb, DCB_ATTR_DCBX,
1773 RTM_SETDCB, DCB_CMD_SDCBX, DCB_ATTR_DCBX, 1518 netdev->dcbnl_ops->setdcbx(netdev, value));
1774 pid, seq, flags);
1775
1776 return ret;
1777} 1519}
1778 1520
1779static int dcbnl_getfeatcfg(struct net_device *netdev, struct nlattr **tb, 1521static int dcbnl_getfeatcfg(struct net_device *netdev, struct nlmsghdr *nlh,
1780 u32 pid, u32 seq, u16 flags) 1522 u32 seq, struct nlattr **tb, struct sk_buff *skb)
1781{ 1523{
1782 struct sk_buff *dcbnl_skb;
1783 struct nlmsghdr *nlh;
1784 struct dcbmsg *dcb;
1785 struct nlattr *data[DCB_FEATCFG_ATTR_MAX + 1], *nest; 1524 struct nlattr *data[DCB_FEATCFG_ATTR_MAX + 1], *nest;
1786 u8 value; 1525 u8 value;
1787 int ret, i; 1526 int ret, i;
@@ -1796,25 +1535,11 @@ static int dcbnl_getfeatcfg(struct net_device *netdev, struct nlattr **tb,
1796 ret = nla_parse_nested(data, DCB_FEATCFG_ATTR_MAX, tb[DCB_ATTR_FEATCFG], 1535 ret = nla_parse_nested(data, DCB_FEATCFG_ATTR_MAX, tb[DCB_ATTR_FEATCFG],
1797 dcbnl_featcfg_nest); 1536 dcbnl_featcfg_nest);
1798 if (ret) 1537 if (ret)
1799 goto err_out; 1538 return ret;
1800
1801 dcbnl_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1802 if (!dcbnl_skb) {
1803 ret = -ENOBUFS;
1804 goto err_out;
1805 }
1806
1807 nlh = NLMSG_NEW(dcbnl_skb, pid, seq, RTM_GETDCB, sizeof(*dcb), flags);
1808
1809 dcb = NLMSG_DATA(nlh);
1810 dcb->dcb_family = AF_UNSPEC;
1811 dcb->cmd = DCB_CMD_GFEATCFG;
1812 1539
1813 nest = nla_nest_start(dcbnl_skb, DCB_ATTR_FEATCFG); 1540 nest = nla_nest_start(skb, DCB_ATTR_FEATCFG);
1814 if (!nest) { 1541 if (!nest)
1815 ret = -EMSGSIZE; 1542 return -EMSGSIZE;
1816 goto nla_put_failure;
1817 }
1818 1543
1819 if (data[DCB_FEATCFG_ATTR_ALL]) 1544 if (data[DCB_FEATCFG_ATTR_ALL])
1820 getall = 1; 1545 getall = 1;
@@ -1825,28 +1550,21 @@ static int dcbnl_getfeatcfg(struct net_device *netdev, struct nlattr **tb,
1825 1550
1826 ret = netdev->dcbnl_ops->getfeatcfg(netdev, i, &value); 1551 ret = netdev->dcbnl_ops->getfeatcfg(netdev, i, &value);
1827 if (!ret) 1552 if (!ret)
1828 ret = nla_put_u8(dcbnl_skb, i, value); 1553 ret = nla_put_u8(skb, i, value);
1829 1554
1830 if (ret) { 1555 if (ret) {
1831 nla_nest_cancel(dcbnl_skb, nest); 1556 nla_nest_cancel(skb, nest);
1832 goto nla_put_failure; 1557 goto nla_put_failure;
1833 } 1558 }
1834 } 1559 }
1835 nla_nest_end(dcbnl_skb, nest); 1560 nla_nest_end(skb, nest);
1836 1561
1837 nlmsg_end(dcbnl_skb, nlh);
1838
1839 return rtnl_unicast(dcbnl_skb, &init_net, pid);
1840nla_put_failure: 1562nla_put_failure:
1841 nlmsg_cancel(dcbnl_skb, nlh);
1842nlmsg_failure:
1843 kfree_skb(dcbnl_skb);
1844err_out:
1845 return ret; 1563 return ret;
1846} 1564}
1847 1565
1848static int dcbnl_setfeatcfg(struct net_device *netdev, struct nlattr **tb, 1566static int dcbnl_setfeatcfg(struct net_device *netdev, struct nlmsghdr *nlh,
1849 u32 pid, u32 seq, u16 flags) 1567 u32 seq, struct nlattr **tb, struct sk_buff *skb)
1850{ 1568{
1851 struct nlattr *data[DCB_FEATCFG_ATTR_MAX + 1]; 1569 struct nlattr *data[DCB_FEATCFG_ATTR_MAX + 1];
1852 int ret, i; 1570 int ret, i;
@@ -1876,60 +1594,73 @@ static int dcbnl_setfeatcfg(struct net_device *netdev, struct nlattr **tb,
1876 goto err; 1594 goto err;
1877 } 1595 }
1878err: 1596err:
1879 dcbnl_reply(ret, RTM_SETDCB, DCB_CMD_SFEATCFG, DCB_ATTR_FEATCFG, 1597 ret = nla_put_u8(skb, DCB_ATTR_FEATCFG, ret);
1880 pid, seq, flags);
1881 1598
1882 return ret; 1599 return ret;
1883} 1600}
1884 1601
1885/* Handle CEE DCBX GET commands. */ 1602/* Handle CEE DCBX GET commands. */
1886static int dcbnl_cee_get(struct net_device *netdev, struct nlattr **tb, 1603static int dcbnl_cee_get(struct net_device *netdev, struct nlmsghdr *nlh,
1887 u32 pid, u32 seq, u16 flags) 1604 u32 seq, struct nlattr **tb, struct sk_buff *skb)
1888{ 1605{
1889 struct net *net = dev_net(netdev);
1890 struct sk_buff *skb;
1891 struct nlmsghdr *nlh;
1892 struct dcbmsg *dcb;
1893 const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops; 1606 const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops;
1894 int err;
1895 1607
1896 if (!ops) 1608 if (!ops)
1897 return -EOPNOTSUPP; 1609 return -EOPNOTSUPP;
1898 1610
1899 skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 1611 return dcbnl_cee_fill(skb, netdev);
1900 if (!skb) 1612}
1901 return -ENOBUFS;
1902
1903 nlh = nlmsg_put(skb, pid, seq, RTM_GETDCB, sizeof(*dcb), flags);
1904 if (nlh == NULL) {
1905 nlmsg_free(skb);
1906 return -EMSGSIZE;
1907 }
1908 1613
1909 dcb = NLMSG_DATA(nlh); 1614struct reply_func {
1910 dcb->dcb_family = AF_UNSPEC; 1615 /* reply netlink message type */
1911 dcb->cmd = DCB_CMD_CEE_GET; 1616 int type;
1912 1617
1913 err = dcbnl_cee_fill(skb, netdev); 1618 /* function to fill message contents */
1619 int (*cb)(struct net_device *, struct nlmsghdr *, u32,
1620 struct nlattr **, struct sk_buff *);
1621};
1914 1622
1915 if (err < 0) { 1623static const struct reply_func reply_funcs[DCB_CMD_MAX+1] = {
1916 nlmsg_cancel(skb, nlh); 1624 [DCB_CMD_GSTATE] = { RTM_GETDCB, dcbnl_getstate },
1917 nlmsg_free(skb); 1625 [DCB_CMD_SSTATE] = { RTM_SETDCB, dcbnl_setstate },
1918 } else { 1626 [DCB_CMD_PFC_GCFG] = { RTM_GETDCB, dcbnl_getpfccfg },
1919 nlmsg_end(skb, nlh); 1627 [DCB_CMD_PFC_SCFG] = { RTM_SETDCB, dcbnl_setpfccfg },
1920 err = rtnl_unicast(skb, net, pid); 1628 [DCB_CMD_GPERM_HWADDR] = { RTM_GETDCB, dcbnl_getperm_hwaddr },
1921 } 1629 [DCB_CMD_GCAP] = { RTM_GETDCB, dcbnl_getcap },
1922 return err; 1630 [DCB_CMD_GNUMTCS] = { RTM_GETDCB, dcbnl_getnumtcs },
1923} 1631 [DCB_CMD_SNUMTCS] = { RTM_SETDCB, dcbnl_setnumtcs },
1632 [DCB_CMD_PFC_GSTATE] = { RTM_GETDCB, dcbnl_getpfcstate },
1633 [DCB_CMD_PFC_SSTATE] = { RTM_SETDCB, dcbnl_setpfcstate },
1634 [DCB_CMD_GAPP] = { RTM_GETDCB, dcbnl_getapp },
1635 [DCB_CMD_SAPP] = { RTM_SETDCB, dcbnl_setapp },
1636 [DCB_CMD_PGTX_GCFG] = { RTM_GETDCB, dcbnl_pgtx_getcfg },
1637 [DCB_CMD_PGTX_SCFG] = { RTM_SETDCB, dcbnl_pgtx_setcfg },
1638 [DCB_CMD_PGRX_GCFG] = { RTM_GETDCB, dcbnl_pgrx_getcfg },
1639 [DCB_CMD_PGRX_SCFG] = { RTM_SETDCB, dcbnl_pgrx_setcfg },
1640 [DCB_CMD_SET_ALL] = { RTM_SETDCB, dcbnl_setall },
1641 [DCB_CMD_BCN_GCFG] = { RTM_GETDCB, dcbnl_bcn_getcfg },
1642 [DCB_CMD_BCN_SCFG] = { RTM_SETDCB, dcbnl_bcn_setcfg },
1643 [DCB_CMD_IEEE_GET] = { RTM_GETDCB, dcbnl_ieee_get },
1644 [DCB_CMD_IEEE_SET] = { RTM_SETDCB, dcbnl_ieee_set },
1645 [DCB_CMD_IEEE_DEL] = { RTM_SETDCB, dcbnl_ieee_del },
1646 [DCB_CMD_GDCBX] = { RTM_GETDCB, dcbnl_getdcbx },
1647 [DCB_CMD_SDCBX] = { RTM_SETDCB, dcbnl_setdcbx },
1648 [DCB_CMD_GFEATCFG] = { RTM_GETDCB, dcbnl_getfeatcfg },
1649 [DCB_CMD_SFEATCFG] = { RTM_SETDCB, dcbnl_setfeatcfg },
1650 [DCB_CMD_CEE_GET] = { RTM_GETDCB, dcbnl_cee_get },
1651};
1924 1652
1925static int dcb_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) 1653static int dcb_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
1926{ 1654{
1927 struct net *net = sock_net(skb->sk); 1655 struct net *net = sock_net(skb->sk);
1928 struct net_device *netdev; 1656 struct net_device *netdev;
1929 struct dcbmsg *dcb = (struct dcbmsg *)NLMSG_DATA(nlh); 1657 struct dcbmsg *dcb = nlmsg_data(nlh);
1930 struct nlattr *tb[DCB_ATTR_MAX + 1]; 1658 struct nlattr *tb[DCB_ATTR_MAX + 1];
1931 u32 pid = skb ? NETLINK_CB(skb).pid : 0; 1659 u32 pid = skb ? NETLINK_CB(skb).pid : 0;
1932 int ret = -EINVAL; 1660 int ret = -EINVAL;
1661 struct sk_buff *reply_skb;
1662 struct nlmsghdr *reply_nlh = NULL;
1663 const struct reply_func *fn;
1933 1664
1934 if (!net_eq(net, &init_net)) 1665 if (!net_eq(net, &init_net))
1935 return -EINVAL; 1666 return -EINVAL;
@@ -1939,136 +1670,78 @@ static int dcb_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
1939 if (ret < 0) 1670 if (ret < 0)
1940 return ret; 1671 return ret;
1941 1672
1673 if (dcb->cmd > DCB_CMD_MAX)
1674 return -EINVAL;
1675
1676 /* check if a reply function has been defined for the command */
1677 fn = &reply_funcs[dcb->cmd];
1678 if (!fn->cb)
1679 return -EOPNOTSUPP;
1680
1942 if (!tb[DCB_ATTR_IFNAME]) 1681 if (!tb[DCB_ATTR_IFNAME])
1943 return -EINVAL; 1682 return -EINVAL;
1944 1683
1945 netdev = dev_get_by_name(&init_net, nla_data(tb[DCB_ATTR_IFNAME])); 1684 netdev = dev_get_by_name(&init_net, nla_data(tb[DCB_ATTR_IFNAME]));
1946 if (!netdev) 1685 if (!netdev)
1947 return -EINVAL; 1686 return -ENODEV;
1948 1687
1949 if (!netdev->dcbnl_ops) 1688 if (!netdev->dcbnl_ops) {
1950 goto errout; 1689 ret = -EOPNOTSUPP;
1951
1952 switch (dcb->cmd) {
1953 case DCB_CMD_GSTATE:
1954 ret = dcbnl_getstate(netdev, tb, pid, nlh->nlmsg_seq,
1955 nlh->nlmsg_flags);
1956 goto out;
1957 case DCB_CMD_PFC_GCFG:
1958 ret = dcbnl_getpfccfg(netdev, tb, pid, nlh->nlmsg_seq,
1959 nlh->nlmsg_flags);
1960 goto out;
1961 case DCB_CMD_GPERM_HWADDR:
1962 ret = dcbnl_getperm_hwaddr(netdev, tb, pid, nlh->nlmsg_seq,
1963 nlh->nlmsg_flags);
1964 goto out;
1965 case DCB_CMD_PGTX_GCFG:
1966 ret = dcbnl_pgtx_getcfg(netdev, tb, pid, nlh->nlmsg_seq,
1967 nlh->nlmsg_flags);
1968 goto out;
1969 case DCB_CMD_PGRX_GCFG:
1970 ret = dcbnl_pgrx_getcfg(netdev, tb, pid, nlh->nlmsg_seq,
1971 nlh->nlmsg_flags);
1972 goto out;
1973 case DCB_CMD_BCN_GCFG:
1974 ret = dcbnl_bcn_getcfg(netdev, tb, pid, nlh->nlmsg_seq,
1975 nlh->nlmsg_flags);
1976 goto out;
1977 case DCB_CMD_SSTATE:
1978 ret = dcbnl_setstate(netdev, tb, pid, nlh->nlmsg_seq,
1979 nlh->nlmsg_flags);
1980 goto out;
1981 case DCB_CMD_PFC_SCFG:
1982 ret = dcbnl_setpfccfg(netdev, tb, pid, nlh->nlmsg_seq,
1983 nlh->nlmsg_flags);
1984 goto out; 1690 goto out;
1691 }
1985 1692
1986 case DCB_CMD_SET_ALL: 1693 reply_skb = dcbnl_newmsg(fn->type, dcb->cmd, pid, nlh->nlmsg_seq,
1987 ret = dcbnl_setall(netdev, tb, pid, nlh->nlmsg_seq, 1694 nlh->nlmsg_flags, &reply_nlh);
1988 nlh->nlmsg_flags); 1695 if (!reply_skb) {
1989 goto out; 1696 ret = -ENOBUFS;
1990 case DCB_CMD_PGTX_SCFG:
1991 ret = dcbnl_pgtx_setcfg(netdev, tb, pid, nlh->nlmsg_seq,
1992 nlh->nlmsg_flags);
1993 goto out;
1994 case DCB_CMD_PGRX_SCFG:
1995 ret = dcbnl_pgrx_setcfg(netdev, tb, pid, nlh->nlmsg_seq,
1996 nlh->nlmsg_flags);
1997 goto out;
1998 case DCB_CMD_GCAP:
1999 ret = dcbnl_getcap(netdev, tb, pid, nlh->nlmsg_seq,
2000 nlh->nlmsg_flags);
2001 goto out;
2002 case DCB_CMD_GNUMTCS:
2003 ret = dcbnl_getnumtcs(netdev, tb, pid, nlh->nlmsg_seq,
2004 nlh->nlmsg_flags);
2005 goto out;
2006 case DCB_CMD_SNUMTCS:
2007 ret = dcbnl_setnumtcs(netdev, tb, pid, nlh->nlmsg_seq,
2008 nlh->nlmsg_flags);
2009 goto out;
2010 case DCB_CMD_PFC_GSTATE:
2011 ret = dcbnl_getpfcstate(netdev, tb, pid, nlh->nlmsg_seq,
2012 nlh->nlmsg_flags);
2013 goto out;
2014 case DCB_CMD_PFC_SSTATE:
2015 ret = dcbnl_setpfcstate(netdev, tb, pid, nlh->nlmsg_seq,
2016 nlh->nlmsg_flags);
2017 goto out;
2018 case DCB_CMD_BCN_SCFG:
2019 ret = dcbnl_bcn_setcfg(netdev, tb, pid, nlh->nlmsg_seq,
2020 nlh->nlmsg_flags);
2021 goto out;
2022 case DCB_CMD_GAPP:
2023 ret = dcbnl_getapp(netdev, tb, pid, nlh->nlmsg_seq,
2024 nlh->nlmsg_flags);
2025 goto out;
2026 case DCB_CMD_SAPP:
2027 ret = dcbnl_setapp(netdev, tb, pid, nlh->nlmsg_seq,
2028 nlh->nlmsg_flags);
2029 goto out;
2030 case DCB_CMD_IEEE_SET:
2031 ret = dcbnl_ieee_set(netdev, tb, pid, nlh->nlmsg_seq,
2032 nlh->nlmsg_flags);
2033 goto out;
2034 case DCB_CMD_IEEE_GET:
2035 ret = dcbnl_ieee_get(netdev, tb, pid, nlh->nlmsg_seq,
2036 nlh->nlmsg_flags);
2037 goto out;
2038 case DCB_CMD_IEEE_DEL:
2039 ret = dcbnl_ieee_del(netdev, tb, pid, nlh->nlmsg_seq,
2040 nlh->nlmsg_flags);
2041 goto out;
2042 case DCB_CMD_GDCBX:
2043 ret = dcbnl_getdcbx(netdev, tb, pid, nlh->nlmsg_seq,
2044 nlh->nlmsg_flags);
2045 goto out;
2046 case DCB_CMD_SDCBX:
2047 ret = dcbnl_setdcbx(netdev, tb, pid, nlh->nlmsg_seq,
2048 nlh->nlmsg_flags);
2049 goto out;
2050 case DCB_CMD_GFEATCFG:
2051 ret = dcbnl_getfeatcfg(netdev, tb, pid, nlh->nlmsg_seq,
2052 nlh->nlmsg_flags);
2053 goto out;
2054 case DCB_CMD_SFEATCFG:
2055 ret = dcbnl_setfeatcfg(netdev, tb, pid, nlh->nlmsg_seq,
2056 nlh->nlmsg_flags);
2057 goto out; 1697 goto out;
2058 case DCB_CMD_CEE_GET: 1698 }
2059 ret = dcbnl_cee_get(netdev, tb, pid, nlh->nlmsg_seq, 1699
2060 nlh->nlmsg_flags); 1700 ret = fn->cb(netdev, nlh, nlh->nlmsg_seq, tb, reply_skb);
1701 if (ret < 0) {
1702 nlmsg_free(reply_skb);
2061 goto out; 1703 goto out;
2062 default:
2063 goto errout;
2064 } 1704 }
2065errout: 1705
2066 ret = -EINVAL; 1706 nlmsg_end(reply_skb, reply_nlh);
1707
1708 ret = rtnl_unicast(reply_skb, &init_net, pid);
2067out: 1709out:
2068 dev_put(netdev); 1710 dev_put(netdev);
2069 return ret; 1711 return ret;
2070} 1712}
2071 1713
1714static struct dcb_app_type *dcb_app_lookup(const struct dcb_app *app,
1715 int ifindex, int prio)
1716{
1717 struct dcb_app_type *itr;
1718
1719 list_for_each_entry(itr, &dcb_app_list, list) {
1720 if (itr->app.selector == app->selector &&
1721 itr->app.protocol == app->protocol &&
1722 itr->ifindex == ifindex &&
1723 (!prio || itr->app.priority == prio))
1724 return itr;
1725 }
1726
1727 return NULL;
1728}
1729
1730static int dcb_app_add(const struct dcb_app *app, int ifindex)
1731{
1732 struct dcb_app_type *entry;
1733
1734 entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
1735 if (!entry)
1736 return -ENOMEM;
1737
1738 memcpy(&entry->app, app, sizeof(*app));
1739 entry->ifindex = ifindex;
1740 list_add(&entry->list, &dcb_app_list);
1741
1742 return 0;
1743}
1744
2072/** 1745/**
2073 * dcb_getapp - retrieve the DCBX application user priority 1746 * dcb_getapp - retrieve the DCBX application user priority
2074 * 1747 *
@@ -2082,14 +1755,8 @@ u8 dcb_getapp(struct net_device *dev, struct dcb_app *app)
2082 u8 prio = 0; 1755 u8 prio = 0;
2083 1756
2084 spin_lock(&dcb_lock); 1757 spin_lock(&dcb_lock);
2085 list_for_each_entry(itr, &dcb_app_list, list) { 1758 if ((itr = dcb_app_lookup(app, dev->ifindex, 0)))
2086 if (itr->app.selector == app->selector && 1759 prio = itr->app.priority;
2087 itr->app.protocol == app->protocol &&
2088 itr->ifindex == dev->ifindex) {
2089 prio = itr->app.priority;
2090 break;
2091 }
2092 }
2093 spin_unlock(&dcb_lock); 1760 spin_unlock(&dcb_lock);
2094 1761
2095 return prio; 1762 return prio;
@@ -2107,6 +1774,7 @@ int dcb_setapp(struct net_device *dev, struct dcb_app *new)
2107{ 1774{
2108 struct dcb_app_type *itr; 1775 struct dcb_app_type *itr;
2109 struct dcb_app_type event; 1776 struct dcb_app_type event;
1777 int err = 0;
2110 1778
2111 event.ifindex = dev->ifindex; 1779 event.ifindex = dev->ifindex;
2112 memcpy(&event.app, new, sizeof(event.app)); 1780 memcpy(&event.app, new, sizeof(event.app));
@@ -2115,36 +1783,23 @@ int dcb_setapp(struct net_device *dev, struct dcb_app *new)
2115 1783
2116 spin_lock(&dcb_lock); 1784 spin_lock(&dcb_lock);
2117 /* Search for existing match and replace */ 1785 /* Search for existing match and replace */
2118 list_for_each_entry(itr, &dcb_app_list, list) { 1786 if ((itr = dcb_app_lookup(new, dev->ifindex, 0))) {
2119 if (itr->app.selector == new->selector && 1787 if (new->priority)
2120 itr->app.protocol == new->protocol && 1788 itr->app.priority = new->priority;
2121 itr->ifindex == dev->ifindex) { 1789 else {
2122 if (new->priority) 1790 list_del(&itr->list);
2123 itr->app.priority = new->priority; 1791 kfree(itr);
2124 else {
2125 list_del(&itr->list);
2126 kfree(itr);
2127 }
2128 goto out;
2129 } 1792 }
1793 goto out;
2130 } 1794 }
2131 /* App type does not exist add new application type */ 1795 /* App type does not exist add new application type */
2132 if (new->priority) { 1796 if (new->priority)
2133 struct dcb_app_type *entry; 1797 err = dcb_app_add(new, dev->ifindex);
2134 entry = kmalloc(sizeof(struct dcb_app_type), GFP_ATOMIC);
2135 if (!entry) {
2136 spin_unlock(&dcb_lock);
2137 return -ENOMEM;
2138 }
2139
2140 memcpy(&entry->app, new, sizeof(*new));
2141 entry->ifindex = dev->ifindex;
2142 list_add(&entry->list, &dcb_app_list);
2143 }
2144out: 1798out:
2145 spin_unlock(&dcb_lock); 1799 spin_unlock(&dcb_lock);
2146 call_dcbevent_notifiers(DCB_APP_EVENT, &event); 1800 if (!err)
2147 return 0; 1801 call_dcbevent_notifiers(DCB_APP_EVENT, &event);
1802 return err;
2148} 1803}
2149EXPORT_SYMBOL(dcb_setapp); 1804EXPORT_SYMBOL(dcb_setapp);
2150 1805
@@ -2161,13 +1816,8 @@ u8 dcb_ieee_getapp_mask(struct net_device *dev, struct dcb_app *app)
2161 u8 prio = 0; 1816 u8 prio = 0;
2162 1817
2163 spin_lock(&dcb_lock); 1818 spin_lock(&dcb_lock);
2164 list_for_each_entry(itr, &dcb_app_list, list) { 1819 if ((itr = dcb_app_lookup(app, dev->ifindex, 0)))
2165 if (itr->app.selector == app->selector && 1820 prio |= 1 << itr->app.priority;
2166 itr->app.protocol == app->protocol &&
2167 itr->ifindex == dev->ifindex) {
2168 prio |= 1 << itr->app.priority;
2169 }
2170 }
2171 spin_unlock(&dcb_lock); 1821 spin_unlock(&dcb_lock);
2172 1822
2173 return prio; 1823 return prio;
@@ -2183,7 +1833,6 @@ EXPORT_SYMBOL(dcb_ieee_getapp_mask);
2183 */ 1833 */
2184int dcb_ieee_setapp(struct net_device *dev, struct dcb_app *new) 1834int dcb_ieee_setapp(struct net_device *dev, struct dcb_app *new)
2185{ 1835{
2186 struct dcb_app_type *itr, *entry;
2187 struct dcb_app_type event; 1836 struct dcb_app_type event;
2188 int err = 0; 1837 int err = 0;
2189 1838
@@ -2194,26 +1843,12 @@ int dcb_ieee_setapp(struct net_device *dev, struct dcb_app *new)
2194 1843
2195 spin_lock(&dcb_lock); 1844 spin_lock(&dcb_lock);
2196 /* Search for existing match and abort if found */ 1845 /* Search for existing match and abort if found */
2197 list_for_each_entry(itr, &dcb_app_list, list) { 1846 if (dcb_app_lookup(new, dev->ifindex, new->priority)) {
2198 if (itr->app.selector == new->selector && 1847 err = -EEXIST;
2199 itr->app.protocol == new->protocol &&
2200 itr->app.priority == new->priority &&
2201 itr->ifindex == dev->ifindex) {
2202 err = -EEXIST;
2203 goto out;
2204 }
2205 }
2206
2207 /* App entry does not exist add new entry */
2208 entry = kmalloc(sizeof(struct dcb_app_type), GFP_ATOMIC);
2209 if (!entry) {
2210 err = -ENOMEM;
2211 goto out; 1848 goto out;
2212 } 1849 }
2213 1850
2214 memcpy(&entry->app, new, sizeof(*new)); 1851 err = dcb_app_add(new, dev->ifindex);
2215 entry->ifindex = dev->ifindex;
2216 list_add(&entry->list, &dcb_app_list);
2217out: 1852out:
2218 spin_unlock(&dcb_lock); 1853 spin_unlock(&dcb_lock);
2219 if (!err) 1854 if (!err)
@@ -2240,19 +1875,12 @@ int dcb_ieee_delapp(struct net_device *dev, struct dcb_app *del)
2240 1875
2241 spin_lock(&dcb_lock); 1876 spin_lock(&dcb_lock);
2242 /* Search for existing match and remove it. */ 1877 /* Search for existing match and remove it. */
2243 list_for_each_entry(itr, &dcb_app_list, list) { 1878 if ((itr = dcb_app_lookup(del, dev->ifindex, del->priority))) {
2244 if (itr->app.selector == del->selector && 1879 list_del(&itr->list);
2245 itr->app.protocol == del->protocol && 1880 kfree(itr);
2246 itr->app.priority == del->priority && 1881 err = 0;
2247 itr->ifindex == dev->ifindex) {
2248 list_del(&itr->list);
2249 kfree(itr);
2250 err = 0;
2251 goto out;
2252 }
2253 } 1882 }
2254 1883
2255out:
2256 spin_unlock(&dcb_lock); 1884 spin_unlock(&dcb_lock);
2257 if (!err) 1885 if (!err)
2258 call_dcbevent_notifiers(DCB_APP_EVENT, &event); 1886 call_dcbevent_notifiers(DCB_APP_EVENT, &event);