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