20 #include <linux/netdevice.h>
21 #include <linux/netlink.h>
22 #include <linux/slab.h>
27 #include <linux/rtnetlink.h>
28 #include <linux/module.h>
209 nlh = nlmsg_put(skb, port, seq, type,
sizeof(*dcb), flags);
212 dcb = nlmsg_data(nlh);
227 if (!netdev->dcbnl_ops->getstate)
231 netdev->dcbnl_ops->getstate(netdev));
246 if (!netdev->dcbnl_ops->getpfccfg)
250 tb[DCB_ATTR_PFC_CFG],
255 nest = nla_nest_start(skb, DCB_ATTR_PFC_CFG);
263 if (!getall && !data[i])
268 ret = nla_put_u8(skb, i, value);
270 nla_nest_cancel(skb, nest);
274 nla_nest_end(skb, nest);
284 if (!netdev->dcbnl_ops->getpermhwaddr)
287 netdev->dcbnl_ops->getpermhwaddr(netdev, perm_addr);
304 if (!netdev->dcbnl_ops->getcap)
312 nest = nla_nest_start(skb, DCB_ATTR_CAP);
320 if (!getall && !data[i])
323 if (!netdev->dcbnl_ops->getcap(netdev, i, &value)) {
324 ret = nla_put_u8(skb, i, value);
326 nla_nest_cancel(skb, nest);
331 nla_nest_end(skb, nest);
348 if (!netdev->dcbnl_ops->getnumtcs)
356 nest = nla_nest_start(skb, DCB_ATTR_NUMTCS);
364 if (!getall && !data[i])
367 ret = netdev->dcbnl_ops->getnumtcs(netdev, i, &value);
369 ret = nla_put_u8(skb, i, value);
371 nla_nest_cancel(skb, nest);
377 nla_nest_end(skb, nest);
390 if (!tb[DCB_ATTR_NUMTCS])
393 if (!netdev->dcbnl_ops->setnumtcs)
405 value = nla_get_u8(data[i]);
407 ret = netdev->dcbnl_ops->setnumtcs(netdev, i, value);
412 return nla_put_u8(skb, DCB_ATTR_NUMTCS, !!ret);
418 if (!netdev->dcbnl_ops->getpfcstate)
422 netdev->dcbnl_ops->getpfcstate(netdev));
433 if (!netdev->dcbnl_ops->setpfcstate)
436 value = nla_get_u8(tb[DCB_ATTR_PFC_STATE]);
438 netdev->dcbnl_ops->setpfcstate(netdev, value);
440 return nla_put_u8(skb, DCB_ATTR_PFC_STATE, 0);
466 idtype = nla_get_u8(app_tb[DCB_APP_ATTR_IDTYPE]);
471 id = nla_get_u16(app_tb[DCB_APP_ATTR_ID]);
473 if (netdev->dcbnl_ops->getapp) {
474 up = netdev->dcbnl_ops->getapp(netdev, idtype,
id);
483 app_nest = nla_nest_start(skb, DCB_ATTR_APP);
487 ret = nla_put_u8(skb, DCB_APP_ATTR_IDTYPE, idtype);
491 ret = nla_put_u16(skb, DCB_APP_ATTR_ID,
id);
499 nla_nest_end(skb, app_nest);
504 nla_nest_cancel(skb, app_nest);
516 if (!tb[DCB_ATTR_APP])
525 if ((!app_tb[DCB_APP_ATTR_IDTYPE]) ||
526 (!app_tb[DCB_APP_ATTR_ID]) ||
531 idtype = nla_get_u8(app_tb[DCB_APP_ATTR_IDTYPE]);
536 id = nla_get_u16(app_tb[DCB_APP_ATTR_ID]);
537 up = nla_get_u8(app_tb[DCB_APP_ATTR_PRIORITY]);
539 if (netdev->dcbnl_ops->setapp) {
540 ret = netdev->dcbnl_ops->setapp(netdev, idtype,
id, up);
549 ret = nla_put_u8(skb, DCB_ATTR_APP, ret);
569 if (!netdev->dcbnl_ops->getpgtccfgtx ||
570 !netdev->dcbnl_ops->getpgtccfgrx ||
571 !netdev->dcbnl_ops->getpgbwgcfgtx ||
572 !netdev->dcbnl_ops->getpgbwgcfgrx)
576 tb[DCB_ATTR_PG_CFG], dcbnl_pg_nest);
580 pg_nest = nla_nest_start(skb, DCB_ATTR_PG_CFG);
588 if (!getall && !pg_tb[i])
591 if (pg_tb[DCB_PG_ATTR_TC_ALL])
596 data, dcbnl_tc_param_nest);
600 param_nest = nla_nest_start(skb, i);
611 netdev->dcbnl_ops->getpgtccfgrx(netdev,
613 &pgid, &tc_pct, &up_map);
616 netdev->dcbnl_ops->getpgtccfgtx(netdev,
618 &pgid, &tc_pct, &up_map);
623 ret = nla_put_u8(skb,
629 param_tb[DCB_TC_ATTR_PARAM_ALL]) {
630 ret = nla_put_u8(skb,
636 param_tb[DCB_TC_ATTR_PARAM_ALL]) {
637 ret = nla_put_u8(skb,
643 param_tb[DCB_TC_ATTR_PARAM_ALL]) {
649 nla_nest_end(skb, param_nest);
658 if (!getall && !pg_tb[i])
665 netdev->dcbnl_ops->getpgbwgcfgrx(netdev,
669 netdev->dcbnl_ops->getpgbwgcfgtx(netdev,
672 ret = nla_put_u8(skb, i, tc_pct);
677 nla_nest_end(skb, pg_nest);
682 nla_nest_cancel(skb, param_nest);
684 nla_nest_cancel(skb, pg_nest);
692 return __dcbnl_pg_getcfg(netdev, nlh, tb, skb, 0);
698 return __dcbnl_pg_getcfg(netdev, nlh, tb, skb, 1);
709 if (!netdev->dcbnl_ops->setstate)
712 value = nla_get_u8(tb[DCB_ATTR_STATE]);
714 return nla_put_u8(skb, DCB_ATTR_STATE,
715 netdev->dcbnl_ops->setstate(netdev, value));
726 if (!tb[DCB_ATTR_PFC_CFG])
729 if (!netdev->dcbnl_ops->setpfccfg)
733 tb[DCB_ATTR_PFC_CFG],
741 value = nla_get_u8(data[i]);
742 netdev->dcbnl_ops->setpfccfg(netdev,
746 return nla_put_u8(skb, DCB_ATTR_PFC_CFG, 0);
757 if (!netdev->dcbnl_ops->setall)
760 ret = nla_put_u8(skb, DCB_ATTR_SET_ALL,
761 netdev->dcbnl_ops->setall(netdev));
780 if (!tb[DCB_ATTR_PG_CFG])
783 if (!netdev->dcbnl_ops->setpgtccfgtx ||
784 !netdev->dcbnl_ops->setpgtccfgrx ||
785 !netdev->dcbnl_ops->setpgbwgcfgtx ||
786 !netdev->dcbnl_ops->setpgbwgcfgrx)
790 tb[DCB_ATTR_PG_CFG], dcbnl_pg_nest);
799 pg_tb[i], dcbnl_tc_param_nest);
810 nla_get_u8(param_tb[DCB_TC_ATTR_PARAM_STRICT_PRIO]);
813 pgid = nla_get_u8(param_tb[DCB_TC_ATTR_PARAM_PGID]);
816 tc_pct = nla_get_u8(param_tb[DCB_TC_ATTR_PARAM_BW_PCT]);
820 nla_get_u8(param_tb[DCB_TC_ATTR_PARAM_UP_MAPPING]);
825 netdev->dcbnl_ops->setpgtccfgrx(netdev,
827 prio, pgid, tc_pct, up_map);
830 netdev->dcbnl_ops->setpgtccfgtx(netdev,
832 prio, pgid, tc_pct, up_map);
840 tc_pct = nla_get_u8(pg_tb[i]);
845 netdev->dcbnl_ops->setpgbwgcfgrx(netdev,
849 netdev->dcbnl_ops->setpgbwgcfgtx(netdev,
854 return nla_put_u8(skb, DCB_ATTR_PG_CFG, 0);
860 return __dcbnl_pg_setcfg(netdev, nlh, seq, tb, skb, 0);
866 return __dcbnl_pg_setcfg(netdev, nlh, seq, tb, skb, 1);
883 if (!netdev->dcbnl_ops->getbcnrp ||
884 !netdev->dcbnl_ops->getbcncfg)
888 tb[DCB_ATTR_BCN], dcbnl_bcn_nest);
892 bcn_nest = nla_nest_start(skb, DCB_ATTR_BCN);
900 if (!getall && !bcn_tb[i])
905 ret = nla_put_u8(skb, i, value_byte);
911 if (!getall && !bcn_tb[i])
914 netdev->dcbnl_ops->getbcncfg(netdev, i,
916 ret = nla_put_u32(skb, i, value_integer);
921 nla_nest_end(skb, bcn_nest);
926 nla_nest_cancel(skb, bcn_nest);
939 if (!tb[DCB_ATTR_BCN])
942 if (!netdev->dcbnl_ops->setbcncfg ||
943 !netdev->dcbnl_ops->setbcnrp)
955 value_byte = nla_get_u8(data[i]);
956 netdev->dcbnl_ops->setbcnrp(netdev,
963 value_int = nla_get_u32(data[i]);
964 netdev->dcbnl_ops->setbcncfg(netdev,
968 return nla_put_u8(skb, DCB_ATTR_BCN, 0);
972 int app_nested_type,
int app_info_type,
987 if (!err && app_count) {
1005 app = nla_nest_start(skb, app_nested_type);
1007 goto nla_put_failure;
1009 if (app_info_type &&
1011 goto nla_put_failure;
1013 for (i = 0; i < app_count; i++) {
1016 goto nla_put_failure;
1018 nla_nest_end(skb, app);
1030 struct nlattr *ieee, *app;
1056 sizeof(maxrate), &maxrate);
1074 spin_lock(&dcb_lock);
1080 spin_unlock(&dcb_lock);
1086 if (netdev->dcbnl_ops->getdcbx)
1087 dcbx = netdev->dcbnl_ops->getdcbx(netdev);
1091 spin_unlock(&dcb_lock);
1092 nla_nest_end(skb, app);
1112 err = dcbnl_build_peer_app(netdev, skb,
1120 nla_nest_end(skb, ieee);
1136 struct nlattr *
pg = nla_nest_start(skb, i);
1142 struct nlattr *tc_nest = nla_nest_start(skb, i);
1154 &prio, &pgid, &tc_pct, &up_map);
1157 &prio, &pgid, &tc_pct, &up_map);
1159 if (nla_put_u8(skb, DCB_TC_ATTR_PARAM_PGID, pgid) ||
1160 nla_put_u8(skb, DCB_TC_ATTR_PARAM_UP_MAPPING, up_map) ||
1161 nla_put_u8(skb, DCB_TC_ATTR_PARAM_STRICT_PRIO, prio) ||
1162 nla_put_u8(skb, DCB_TC_ATTR_PARAM_BW_PCT, tc_pct))
1164 nla_nest_end(skb, tc_nest);
1176 if (nla_put_u8(skb, i, tc_pct))
1179 nla_nest_end(skb, pg);
1185 struct nlattr *cee, *app;
1192 goto nla_put_failure;
1195 goto nla_put_failure;
1199 err = dcbnl_cee_pg_fill(skb, netdev, 1);
1201 goto nla_put_failure;
1205 err = dcbnl_cee_pg_fill(skb, netdev, 0);
1207 goto nla_put_failure;
1215 goto nla_put_failure;
1219 if (nla_put_u8(skb, i, value))
1220 goto nla_put_failure;
1222 nla_nest_end(skb, pfc_nest);
1226 spin_lock(&dcb_lock);
1233 struct nlattr *app_nest = nla_nest_start(skb,
1238 err = nla_put_u8(skb, DCB_APP_ATTR_IDTYPE,
1243 err = nla_put_u16(skb, DCB_APP_ATTR_ID,
1248 err = nla_put_u8(skb, DCB_APP_ATTR_PRIORITY,
1253 nla_nest_end(skb, app_nest);
1256 nla_nest_end(skb, app);
1258 if (netdev->dcbnl_ops->getdcbx)
1259 dcbx = netdev->dcbnl_ops->getdcbx(netdev);
1263 spin_unlock(&dcb_lock);
1269 goto nla_put_failure;
1274 nla_put_u8(skb, i, value))
1275 goto nla_put_failure;
1277 nla_nest_end(skb, feat);
1286 goto nla_put_failure;
1294 goto nla_put_failure;
1298 err = dcbnl_build_peer_app(netdev, skb,
1303 goto nla_put_failure;
1305 nla_nest_end(skb, cee);
1311 goto nla_put_failure;
1316 spin_unlock(&dcb_lock);
1322 u32 seq,
u32 portid,
int dcbx_ver)
1324 struct net *
net = dev_net(dev);
1333 skb = dcbnl_newmsg(event, cmd, portid, seq, 0, &nlh);
1338 err = dcbnl_ieee_fill(skb, dev);
1340 err = dcbnl_cee_fill(skb, dev);
1348 nlmsg_end(skb, nlh);
1388 tb[DCB_ATTR_IEEE], dcbnl_ieee_policy);
1422 app_data = nla_data(attr);
1433 err = nla_put_u8(skb, DCB_ATTR_IEEE, err);
1446 return dcbnl_ieee_fill(skb, netdev);
1459 if (!tb[DCB_ATTR_IEEE])
1463 tb[DCB_ATTR_IEEE], dcbnl_ieee_policy);
1467 if (ieee[DCB_ATTR_IEEE_APP_TABLE]) {
1476 app_data = nla_data(attr);
1487 err = nla_put_u8(skb, DCB_ATTR_IEEE, err);
1497 if (!netdev->dcbnl_ops->getdcbx)
1501 netdev->dcbnl_ops->getdcbx(netdev));
1509 if (!netdev->dcbnl_ops->setdcbx)
1515 value = nla_get_u8(tb[DCB_ATTR_DCBX]);
1517 return nla_put_u8(skb, DCB_ATTR_DCBX,
1518 netdev->dcbnl_ops->setdcbx(netdev, value));
1529 if (!netdev->dcbnl_ops->getfeatcfg)
1536 dcbnl_featcfg_nest);
1540 nest = nla_nest_start(skb, DCB_ATTR_FEATCFG);
1548 if (!getall && !data[i])
1551 ret = netdev->dcbnl_ops->getfeatcfg(netdev, i, &value);
1553 ret = nla_put_u8(skb, i, value);
1556 nla_nest_cancel(skb, nest);
1557 goto nla_put_failure;
1560 nla_nest_end(skb, nest);
1573 if (!netdev->dcbnl_ops->setfeatcfg)
1576 if (!tb[DCB_ATTR_FEATCFG])
1580 dcbnl_featcfg_nest);
1586 if (data[i] ==
NULL)
1589 value = nla_get_u8(data[i]);
1591 ret = netdev->dcbnl_ops->setfeatcfg(netdev, i, value);
1597 ret = nla_put_u8(skb, DCB_ATTR_FEATCFG, ret);
1611 return dcbnl_cee_fill(skb, netdev);
1655 struct net *net = sock_net(skb->
sk);
1657 struct dcbmsg *dcb = nlmsg_data(nlh);
1677 fn = &reply_funcs[dcb->
cmd];
1688 if (!netdev->dcbnl_ops) {
1700 ret = fn->
cb(netdev, nlh, nlh->
nlmsg_seq, tb, reply_skb);
1702 nlmsg_free(reply_skb);
1706 nlmsg_end(reply_skb, reply_nlh);
1723 (!prio || itr->
app.priority == prio))
1730 static int dcb_app_add(
const struct dcb_app *app,
int ifindex)
1740 list_add(&entry->
list, &dcb_app_list);
1757 spin_lock(&dcb_lock);
1758 if ((itr = dcb_app_lookup(app, dev->
ifindex, 0)))
1759 prio = itr->
app.priority;
1760 spin_unlock(&dcb_lock);
1781 if (dev->dcbnl_ops->getdcbx)
1782 event.dcbx = dev->dcbnl_ops->getdcbx(dev);
1784 spin_lock(&dcb_lock);
1786 if ((itr = dcb_app_lookup(
new, dev->
ifindex, 0))) {
1788 itr->
app.priority =
new->priority;
1797 err = dcb_app_add(
new, dev->
ifindex);
1799 spin_unlock(&dcb_lock);
1818 spin_lock(&dcb_lock);
1819 if ((itr = dcb_app_lookup(app, dev->
ifindex, 0)))
1820 prio |= 1 << itr->
app.priority;
1821 spin_unlock(&dcb_lock);
1841 if (dev->dcbnl_ops->getdcbx)
1842 event.dcbx = dev->dcbnl_ops->getdcbx(dev);
1844 spin_lock(&dcb_lock);
1846 if (dcb_app_lookup(
new, dev->
ifindex, new->priority)) {
1851 err = dcb_app_add(
new, dev->
ifindex);
1853 spin_unlock(&dcb_lock);
1873 if (dev->dcbnl_ops->getdcbx)
1874 event.dcbx = dev->dcbnl_ops->getdcbx(dev);
1876 spin_lock(&dcb_lock);
1884 spin_unlock(&dcb_lock);
1891 static void dcb_flushapp(
void)
1896 spin_lock(&dcb_lock);
1901 spin_unlock(&dcb_lock);
1904 static int __init dcbnl_init(
void)
1906 INIT_LIST_HEAD(&dcb_app_list);
1915 static void __exit dcbnl_exit(
void)