aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/dcbnl.h4
-rw-r--r--include/net/dcbnl.h9
-rw-r--r--net/dcb/dcbnl.c133
3 files changed, 135 insertions, 11 deletions
diff --git a/include/linux/dcbnl.h b/include/linux/dcbnl.h
index 287b5618e296..775bdb4465bf 100644
--- a/include/linux/dcbnl.h
+++ b/include/linux/dcbnl.h
@@ -82,7 +82,9 @@ struct ieee_pfc {
82 __u64 indications[IEEE_8021QAZ_MAX_TCS]; 82 __u64 indications[IEEE_8021QAZ_MAX_TCS];
83}; 83};
84 84
85/* This structure contains the IEEE 802.1Qaz APP managed object 85/* This structure contains the IEEE 802.1Qaz APP managed object. This
86 * object is also used for the CEE std as well. There is no difference
87 * between the objects.
86 * 88 *
87 * @selector: protocol identifier type 89 * @selector: protocol identifier type
88 * @protocol: protocol of type indicated 90 * @protocol: protocol of type indicated
diff --git a/include/net/dcbnl.h b/include/net/dcbnl.h
index e2d841e963b3..ab7d623a2793 100644
--- a/include/net/dcbnl.h
+++ b/include/net/dcbnl.h
@@ -22,6 +22,15 @@
22 22
23#include <linux/dcbnl.h> 23#include <linux/dcbnl.h>
24 24
25struct dcb_app_type {
26 char name[IFNAMSIZ];
27 struct dcb_app app;
28 struct list_head list;
29};
30
31u8 dcb_setapp(struct net_device *, struct dcb_app *);
32u8 dcb_getapp(struct net_device *, struct dcb_app *);
33
25/* 34/*
26 * Ops struct for the netlink callbacks. Used by DCB-enabled drivers through 35 * Ops struct for the netlink callbacks. Used by DCB-enabled drivers through
27 * the netdevice struct. 36 * the netdevice struct.
diff --git a/net/dcb/dcbnl.c b/net/dcb/dcbnl.c
index 2ff908498924..cfd731faf6c6 100644
--- a/net/dcb/dcbnl.c
+++ b/net/dcb/dcbnl.c
@@ -179,6 +179,9 @@ static const struct nla_policy dcbnl_ieee_app[DCB_ATTR_IEEE_APP_MAX + 1] = {
179 [DCB_ATTR_IEEE_APP] = {.len = sizeof(struct dcb_app)}, 179 [DCB_ATTR_IEEE_APP] = {.len = sizeof(struct dcb_app)},
180}; 180};
181 181
182static LIST_HEAD(dcb_app_list);
183static DEFINE_SPINLOCK(dcb_lock);
184
182/* standard netlink reply call */ 185/* standard netlink reply call */
183static int dcbnl_reply(u8 value, u8 event, u8 cmd, u8 attr, u32 pid, 186static int dcbnl_reply(u8 value, u8 event, u8 cmd, u8 attr, u32 pid,
184 u32 seq, u16 flags) 187 u32 seq, u16 flags)
@@ -634,12 +637,12 @@ out:
634static int dcbnl_setapp(struct net_device *netdev, struct nlattr **tb, 637static int dcbnl_setapp(struct net_device *netdev, struct nlattr **tb,
635 u32 pid, u32 seq, u16 flags) 638 u32 pid, u32 seq, u16 flags)
636{ 639{
637 int ret = -EINVAL; 640 int err, ret = -EINVAL;
638 u16 id; 641 u16 id;
639 u8 up, idtype; 642 u8 up, idtype;
640 struct nlattr *app_tb[DCB_APP_ATTR_MAX + 1]; 643 struct nlattr *app_tb[DCB_APP_ATTR_MAX + 1];
641 644
642 if (!tb[DCB_ATTR_APP] || !netdev->dcbnl_ops->setapp) 645 if (!tb[DCB_ATTR_APP])
643 goto out; 646 goto out;
644 647
645 ret = nla_parse_nested(app_tb, DCB_APP_ATTR_MAX, tb[DCB_ATTR_APP], 648 ret = nla_parse_nested(app_tb, DCB_APP_ATTR_MAX, tb[DCB_ATTR_APP],
@@ -663,9 +666,18 @@ static int dcbnl_setapp(struct net_device *netdev, struct nlattr **tb,
663 id = nla_get_u16(app_tb[DCB_APP_ATTR_ID]); 666 id = nla_get_u16(app_tb[DCB_APP_ATTR_ID]);
664 up = nla_get_u8(app_tb[DCB_APP_ATTR_PRIORITY]); 667 up = nla_get_u8(app_tb[DCB_APP_ATTR_PRIORITY]);
665 668
666 ret = dcbnl_reply(netdev->dcbnl_ops->setapp(netdev, idtype, id, up), 669 if (netdev->dcbnl_ops->setapp) {
667 RTM_SETDCB, DCB_CMD_SAPP, DCB_ATTR_APP, 670 err = netdev->dcbnl_ops->setapp(netdev, idtype, id, up);
668 pid, seq, flags); 671 } else {
672 struct dcb_app app;
673 app.selector = idtype;
674 app.protocol = id;
675 app.priority = up;
676 err = dcb_setapp(netdev, &app);
677 }
678
679 ret = dcbnl_reply(err, RTM_SETDCB, DCB_CMD_SAPP, DCB_ATTR_APP,
680 pid, seq, flags);
669out: 681out:
670 return ret; 682 return ret;
671} 683}
@@ -1164,7 +1176,7 @@ static int dcbnl_ieee_set(struct net_device *netdev, struct nlattr **tb,
1164 goto err; 1176 goto err;
1165 } 1177 }
1166 1178
1167 if (ieee[DCB_ATTR_IEEE_APP_TABLE] && ops->ieee_setapp) { 1179 if (ieee[DCB_ATTR_IEEE_APP_TABLE]) {
1168 struct nlattr *attr; 1180 struct nlattr *attr;
1169 int rem; 1181 int rem;
1170 1182
@@ -1173,7 +1185,10 @@ static int dcbnl_ieee_set(struct net_device *netdev, struct nlattr **tb,
1173 if (nla_type(attr) != DCB_ATTR_IEEE_APP) 1185 if (nla_type(attr) != DCB_ATTR_IEEE_APP)
1174 continue; 1186 continue;
1175 app_data = nla_data(attr); 1187 app_data = nla_data(attr);
1176 err = ops->ieee_setapp(netdev, app_data); 1188 if (ops->ieee_setapp)
1189 err = ops->ieee_setapp(netdev, app_data);
1190 else
1191 err = dcb_setapp(netdev, app_data);
1177 if (err) 1192 if (err)
1178 goto err; 1193 goto err;
1179 } 1194 }
@@ -1193,7 +1208,8 @@ static int dcbnl_ieee_get(struct net_device *netdev, struct nlattr **tb,
1193 struct sk_buff *skb; 1208 struct sk_buff *skb;
1194 struct nlmsghdr *nlh; 1209 struct nlmsghdr *nlh;
1195 struct dcbmsg *dcb; 1210 struct dcbmsg *dcb;
1196 struct nlattr *ieee; 1211 struct nlattr *ieee, *app;
1212 struct dcb_app_type *itr;
1197 const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops; 1213 const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops;
1198 int err; 1214 int err;
1199 1215
@@ -1230,6 +1246,19 @@ static int dcbnl_ieee_get(struct net_device *netdev, struct nlattr **tb,
1230 NLA_PUT(skb, DCB_ATTR_IEEE_PFC, sizeof(pfc), &pfc); 1246 NLA_PUT(skb, DCB_ATTR_IEEE_PFC, sizeof(pfc), &pfc);
1231 } 1247 }
1232 1248
1249 app = nla_nest_start(skb, DCB_ATTR_IEEE_APP_TABLE);
1250 if (!app)
1251 goto nla_put_failure;
1252
1253 spin_lock(&dcb_lock);
1254 list_for_each_entry(itr, &dcb_app_list, list) {
1255 if (strncmp(itr->name, netdev->name, IFNAMSIZ) == 0)
1256 NLA_PUT(skb, DCB_ATTR_IEEE_APP,
1257 sizeof(itr->app), &itr->app);
1258 }
1259 spin_unlock(&dcb_lock);
1260 nla_nest_end(skb, app);
1261
1233 nla_nest_end(skb, ieee); 1262 nla_nest_end(skb, ieee);
1234 nlmsg_end(skb, nlh); 1263 nlmsg_end(skb, nlh);
1235 1264
@@ -1364,8 +1393,93 @@ out:
1364 return ret; 1393 return ret;
1365} 1394}
1366 1395
1396/**
1397 * dcb_getapp - retrieve the DCBX application user priority
1398 *
1399 * On success returns a non-zero 802.1p user priority bitmap
1400 * otherwise returns 0 as the invalid user priority bitmap to
1401 * indicate an error.
1402 */
1403u8 dcb_getapp(struct net_device *dev, struct dcb_app *app)
1404{
1405 struct dcb_app_type *itr;
1406 u8 prio = 0;
1407
1408 spin_lock(&dcb_lock);
1409 list_for_each_entry(itr, &dcb_app_list, list) {
1410 if (itr->app.selector == app->selector &&
1411 itr->app.protocol == app->protocol &&
1412 (strncmp(itr->name, dev->name, IFNAMSIZ) == 0)) {
1413 prio = itr->app.priority;
1414 break;
1415 }
1416 }
1417 spin_unlock(&dcb_lock);
1418
1419 return prio;
1420}
1421EXPORT_SYMBOL(dcb_getapp);
1422
1423/**
1424 * ixgbe_dcbnl_setapp - add dcb application data to app list
1425 *
1426 * Priority 0 is the default priority this removes applications
1427 * from the app list if the priority is set to zero.
1428 */
1429u8 dcb_setapp(struct net_device *dev, struct dcb_app *new)
1430{
1431 struct dcb_app_type *itr;
1432
1433 spin_lock(&dcb_lock);
1434 /* Search for existing match and replace */
1435 list_for_each_entry(itr, &dcb_app_list, list) {
1436 if (itr->app.selector == new->selector &&
1437 itr->app.protocol == new->protocol &&
1438 (strncmp(itr->name, dev->name, IFNAMSIZ) == 0)) {
1439 if (new->priority)
1440 itr->app.priority = new->priority;
1441 else {
1442 list_del(&itr->list);
1443 kfree(itr);
1444 }
1445 goto out;
1446 }
1447 }
1448 /* App type does not exist add new application type */
1449 if (new->priority) {
1450 struct dcb_app_type *entry;
1451 entry = kmalloc(sizeof(struct dcb_app_type), GFP_ATOMIC);
1452 if (!entry) {
1453 spin_unlock(&dcb_lock);
1454 return -ENOMEM;
1455 }
1456
1457 memcpy(&entry->app, new, sizeof(*new));
1458 strncpy(entry->name, dev->name, IFNAMSIZ);
1459 list_add(&entry->list, &dcb_app_list);
1460 }
1461out:
1462 spin_unlock(&dcb_lock);
1463 return 0;
1464}
1465EXPORT_SYMBOL(dcb_setapp);
1466
1467void dcb_flushapp(void)
1468{
1469 struct dcb_app_type *app;
1470
1471 spin_lock(&dcb_lock);
1472 list_for_each_entry(app, &dcb_app_list, list) {
1473 list_del(&app->list);
1474 kfree(app);
1475 }
1476 spin_unlock(&dcb_lock);
1477}
1478
1367static int __init dcbnl_init(void) 1479static int __init dcbnl_init(void)
1368{ 1480{
1481 INIT_LIST_HEAD(&dcb_app_list);
1482
1369 rtnl_register(PF_UNSPEC, RTM_GETDCB, dcb_doit, NULL); 1483 rtnl_register(PF_UNSPEC, RTM_GETDCB, dcb_doit, NULL);
1370 rtnl_register(PF_UNSPEC, RTM_SETDCB, dcb_doit, NULL); 1484 rtnl_register(PF_UNSPEC, RTM_SETDCB, dcb_doit, NULL);
1371 1485
@@ -1377,7 +1491,6 @@ static void __exit dcbnl_exit(void)
1377{ 1491{
1378 rtnl_unregister(PF_UNSPEC, RTM_GETDCB); 1492 rtnl_unregister(PF_UNSPEC, RTM_GETDCB);
1379 rtnl_unregister(PF_UNSPEC, RTM_SETDCB); 1493 rtnl_unregister(PF_UNSPEC, RTM_SETDCB);
1494 dcb_flushapp();
1380} 1495}
1381module_exit(dcbnl_exit); 1496module_exit(dcbnl_exit);
1382
1383