aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/dcbnl.h106
-rw-r--r--include/net/dcbnl.h11
-rw-r--r--net/dcb/dcbnl.c131
3 files changed, 248 insertions, 0 deletions
diff --git a/include/linux/dcbnl.h b/include/linux/dcbnl.h
index 8723491f7dfd..287b5618e296 100644
--- a/include/linux/dcbnl.h
+++ b/include/linux/dcbnl.h
@@ -22,6 +22,87 @@
22 22
23#include <linux/types.h> 23#include <linux/types.h>
24 24
25/* IEEE 802.1Qaz std supported values */
26#define IEEE_8021QAZ_MAX_TCS 8
27
28/* This structure contains the IEEE 802.1Qaz ETS managed object
29 *
30 * @willing: willing bit in ETS configuratin TLV
31 * @ets_cap: indicates supported capacity of ets feature
32 * @cbs: credit based shaper ets algorithm supported
33 * @tc_tx_bw: tc tx bandwidth indexed by traffic class
34 * @tc_rx_bw: tc rx bandwidth indexed by traffic class
35 * @tc_tsa: TSA Assignment table, indexed by traffic class
36 * @prio_tc: priority assignment table mapping 8021Qp to traffic class
37 * @tc_reco_bw: recommended tc bandwidth indexed by traffic class for TLV
38 * @tc_reco_tsa: recommended tc bandwidth indexed by traffic class for TLV
39 * @reco_prio_tc: recommended tc tx bandwidth indexed by traffic class for TLV
40 *
41 * Recommended values are used to set fields in the ETS recommendation TLV
42 * with hardware offloaded LLDP.
43 *
44 * ----
45 * TSA Assignment 8 bit identifiers
46 * 0 strict priority
47 * 1 credit-based shaper
48 * 2 enhanced transmission selection
49 * 3-254 reserved
50 * 255 vendor specific
51 */
52struct ieee_ets {
53 __u8 willing;
54 __u8 ets_cap;
55 __u8 cbs;
56 __u8 tc_tx_bw[IEEE_8021QAZ_MAX_TCS];
57 __u8 tc_rx_bw[IEEE_8021QAZ_MAX_TCS];
58 __u8 tc_tsa[IEEE_8021QAZ_MAX_TCS];
59 __u8 prio_tc[IEEE_8021QAZ_MAX_TCS];
60 __u8 tc_reco_bw[IEEE_8021QAZ_MAX_TCS];
61 __u8 tc_reco_tsa[IEEE_8021QAZ_MAX_TCS];
62 __u8 reco_prio_tc[IEEE_8021QAZ_MAX_TCS];
63};
64
65/* This structure contains the IEEE 802.1Qaz PFC managed object
66 *
67 * @pfc_cap: Indicates the number of traffic classes on the local device
68 * that may simultaneously have PFC enabled.
69 * @pfc_en: bitmap indicating pfc enabled traffic classes
70 * @mbc: enable macsec bypass capability
71 * @delay: the allowance made for a round-trip propagation delay of the
72 * link in bits.
73 * @requests: count of the sent pfc frames
74 * @indications: count of the received pfc frames
75 */
76struct ieee_pfc {
77 __u8 pfc_cap;
78 __u8 pfc_en;
79 __u8 mbc;
80 __u16 delay;
81 __u64 requests[IEEE_8021QAZ_MAX_TCS];
82 __u64 indications[IEEE_8021QAZ_MAX_TCS];
83};
84
85/* This structure contains the IEEE 802.1Qaz APP managed object
86 *
87 * @selector: protocol identifier type
88 * @protocol: protocol of type indicated
89 * @priority: 3-bit unsigned integer indicating priority
90 *
91 * ----
92 * Selector field values
93 * 0 Reserved
94 * 1 Ethertype
95 * 2 Well known port number over TCP or SCTP
96 * 3 Well known port number over UDP or DCCP
97 * 4 Well known port number over TCP, SCTP, UDP, or DCCP
98 * 5-7 Reserved
99 */
100struct dcb_app {
101 __u8 selector;
102 __u32 protocol;
103 __u8 priority;
104};
105
25struct dcbmsg { 106struct dcbmsg {
26 __u8 dcb_family; 107 __u8 dcb_family;
27 __u8 cmd; 108 __u8 cmd;
@@ -50,6 +131,8 @@ struct dcbmsg {
50 * @DCB_CMD_SBCN: get backward congestion notification configration. 131 * @DCB_CMD_SBCN: get backward congestion notification configration.
51 * @DCB_CMD_GAPP: get application protocol configuration 132 * @DCB_CMD_GAPP: get application protocol configuration
52 * @DCB_CMD_SAPP: set application protocol configuration 133 * @DCB_CMD_SAPP: set application protocol configuration
134 * @DCB_CMD_IEEE_SET: set IEEE 802.1Qaz configuration
135 * @DCB_CMD_IEEE_GET: get IEEE 802.1Qaz configuration
53 */ 136 */
54enum dcbnl_commands { 137enum dcbnl_commands {
55 DCB_CMD_UNDEFINED, 138 DCB_CMD_UNDEFINED,
@@ -83,6 +166,9 @@ enum dcbnl_commands {
83 DCB_CMD_GAPP, 166 DCB_CMD_GAPP,
84 DCB_CMD_SAPP, 167 DCB_CMD_SAPP,
85 168
169 DCB_CMD_IEEE_SET,
170 DCB_CMD_IEEE_GET,
171
86 __DCB_CMD_ENUM_MAX, 172 __DCB_CMD_ENUM_MAX,
87 DCB_CMD_MAX = __DCB_CMD_ENUM_MAX - 1, 173 DCB_CMD_MAX = __DCB_CMD_ENUM_MAX - 1,
88}; 174};
@@ -102,6 +188,7 @@ enum dcbnl_commands {
102 * @DCB_ATTR_CAP: DCB capabilities of the device (NLA_NESTED) 188 * @DCB_ATTR_CAP: DCB capabilities of the device (NLA_NESTED)
103 * @DCB_ATTR_NUMTCS: number of traffic classes supported (NLA_NESTED) 189 * @DCB_ATTR_NUMTCS: number of traffic classes supported (NLA_NESTED)
104 * @DCB_ATTR_BCN: backward congestion notification configuration (NLA_NESTED) 190 * @DCB_ATTR_BCN: backward congestion notification configuration (NLA_NESTED)
191 * @DCB_ATTR_IEEE: IEEE 802.1Qaz supported attributes (NLA_NESTED)
105 */ 192 */
106enum dcbnl_attrs { 193enum dcbnl_attrs {
107 DCB_ATTR_UNDEFINED, 194 DCB_ATTR_UNDEFINED,
@@ -119,10 +206,29 @@ enum dcbnl_attrs {
119 DCB_ATTR_BCN, 206 DCB_ATTR_BCN,
120 DCB_ATTR_APP, 207 DCB_ATTR_APP,
121 208
209 /* IEEE std attributes */
210 DCB_ATTR_IEEE,
211
122 __DCB_ATTR_ENUM_MAX, 212 __DCB_ATTR_ENUM_MAX,
123 DCB_ATTR_MAX = __DCB_ATTR_ENUM_MAX - 1, 213 DCB_ATTR_MAX = __DCB_ATTR_ENUM_MAX - 1,
124}; 214};
125 215
216enum ieee_attrs {
217 DCB_ATTR_IEEE_UNSPEC,
218 DCB_ATTR_IEEE_ETS,
219 DCB_ATTR_IEEE_PFC,
220 DCB_ATTR_IEEE_APP_TABLE,
221 __DCB_ATTR_IEEE_MAX
222};
223#define DCB_ATTR_IEEE_MAX (__DCB_ATTR_IEEE_MAX - 1)
224
225enum ieee_attrs_app {
226 DCB_ATTR_IEEE_APP_UNSPEC,
227 DCB_ATTR_IEEE_APP,
228 __DCB_ATTR_IEEE_APP_MAX
229};
230#define DCB_ATTR_IEEE_APP_MAX (__DCB_ATTR_IEEE_APP_MAX - 1)
231
126/** 232/**
127 * enum dcbnl_pfc_attrs - DCB Priority Flow Control user priority nested attrs 233 * enum dcbnl_pfc_attrs - DCB Priority Flow Control user priority nested attrs
128 * 234 *
diff --git a/include/net/dcbnl.h b/include/net/dcbnl.h
index b36ac7e0914d..e2d841e963b3 100644
--- a/include/net/dcbnl.h
+++ b/include/net/dcbnl.h
@@ -20,11 +20,22 @@
20#ifndef __NET_DCBNL_H__ 20#ifndef __NET_DCBNL_H__
21#define __NET_DCBNL_H__ 21#define __NET_DCBNL_H__
22 22
23#include <linux/dcbnl.h>
24
23/* 25/*
24 * Ops struct for the netlink callbacks. Used by DCB-enabled drivers through 26 * Ops struct for the netlink callbacks. Used by DCB-enabled drivers through
25 * the netdevice struct. 27 * the netdevice struct.
26 */ 28 */
27struct dcbnl_rtnl_ops { 29struct dcbnl_rtnl_ops {
30 /* IEEE 802.1Qaz std */
31 int (*ieee_getets) (struct net_device *, struct ieee_ets *);
32 int (*ieee_setets) (struct net_device *, struct ieee_ets *);
33 int (*ieee_getpfc) (struct net_device *, struct ieee_pfc *);
34 int (*ieee_setpfc) (struct net_device *, struct ieee_pfc *);
35 int (*ieee_getapp) (struct net_device *, struct dcb_app *);
36 int (*ieee_setapp) (struct net_device *, struct dcb_app *);
37
38 /* CEE std */
28 u8 (*getstate)(struct net_device *); 39 u8 (*getstate)(struct net_device *);
29 u8 (*setstate)(struct net_device *, u8); 40 u8 (*setstate)(struct net_device *, u8);
30 void (*getpermhwaddr)(struct net_device *, u8 *); 41 void (*getpermhwaddr)(struct net_device *, u8 *);
diff --git a/net/dcb/dcbnl.c b/net/dcb/dcbnl.c
index 19ac2b985485..2ff908498924 100644
--- a/net/dcb/dcbnl.c
+++ b/net/dcb/dcbnl.c
@@ -66,6 +66,7 @@ static const struct nla_policy dcbnl_rtnl_policy[DCB_ATTR_MAX + 1] = {
66 [DCB_ATTR_PFC_STATE] = {.type = NLA_U8}, 66 [DCB_ATTR_PFC_STATE] = {.type = NLA_U8},
67 [DCB_ATTR_BCN] = {.type = NLA_NESTED}, 67 [DCB_ATTR_BCN] = {.type = NLA_NESTED},
68 [DCB_ATTR_APP] = {.type = NLA_NESTED}, 68 [DCB_ATTR_APP] = {.type = NLA_NESTED},
69 [DCB_ATTR_IEEE] = {.type = NLA_NESTED},
69}; 70};
70 71
71/* DCB priority flow control to User Priority nested attributes */ 72/* DCB priority flow control to User Priority nested attributes */
@@ -167,6 +168,17 @@ static const struct nla_policy dcbnl_app_nest[DCB_APP_ATTR_MAX + 1] = {
167 [DCB_APP_ATTR_PRIORITY] = {.type = NLA_U8}, 168 [DCB_APP_ATTR_PRIORITY] = {.type = NLA_U8},
168}; 169};
169 170
171/* IEEE 802.1Qaz nested attributes. */
172static const struct nla_policy dcbnl_ieee_policy[DCB_ATTR_IEEE_MAX + 1] = {
173 [DCB_ATTR_IEEE_ETS] = {.len = sizeof(struct ieee_ets)},
174 [DCB_ATTR_IEEE_PFC] = {.len = sizeof(struct ieee_pfc)},
175 [DCB_ATTR_IEEE_APP_TABLE] = {.type = NLA_NESTED},
176};
177
178static const struct nla_policy dcbnl_ieee_app[DCB_ATTR_IEEE_APP_MAX + 1] = {
179 [DCB_ATTR_IEEE_APP] = {.len = sizeof(struct dcb_app)},
180};
181
170/* standard netlink reply call */ 182/* standard netlink reply call */
171static int dcbnl_reply(u8 value, u8 event, u8 cmd, u8 attr, u32 pid, 183static int dcbnl_reply(u8 value, u8 event, u8 cmd, u8 attr, u32 pid,
172 u32 seq, u16 flags) 184 u32 seq, u16 flags)
@@ -1118,6 +1130,117 @@ err:
1118 return ret; 1130 return ret;
1119} 1131}
1120 1132
1133/* Handle IEEE 802.1Qaz SET commands. If any requested operation can not
1134 * be completed the entire msg is aborted and error value is returned.
1135 * No attempt is made to reconcile the case where only part of the
1136 * cmd can be completed.
1137 */
1138static int dcbnl_ieee_set(struct net_device *netdev, struct nlattr **tb,
1139 u32 pid, u32 seq, u16 flags)
1140{
1141 const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops;
1142 struct nlattr *ieee[DCB_ATTR_IEEE_MAX + 1];
1143 int err = -EOPNOTSUPP;
1144
1145 if (!ops)
1146 goto err;
1147
1148 err = nla_parse_nested(ieee, DCB_ATTR_IEEE_MAX,
1149 tb[DCB_ATTR_IEEE], dcbnl_ieee_policy);
1150 if (err)
1151 goto err;
1152
1153 if (ieee[DCB_ATTR_IEEE_ETS] && ops->ieee_setets) {
1154 struct ieee_ets *ets = nla_data(ieee[DCB_ATTR_IEEE_ETS]);
1155 err = ops->ieee_setets(netdev, ets);
1156 if (err)
1157 goto err;
1158 }
1159
1160 if (ieee[DCB_ATTR_IEEE_PFC] && ops->ieee_setets) {
1161 struct ieee_pfc *pfc = nla_data(ieee[DCB_ATTR_IEEE_PFC]);
1162 err = ops->ieee_setpfc(netdev, pfc);
1163 if (err)
1164 goto err;
1165 }
1166
1167 if (ieee[DCB_ATTR_IEEE_APP_TABLE] && ops->ieee_setapp) {
1168 struct nlattr *attr;
1169 int rem;
1170
1171 nla_for_each_nested(attr, ieee[DCB_ATTR_IEEE_APP_TABLE], rem) {
1172 struct dcb_app *app_data;
1173 if (nla_type(attr) != DCB_ATTR_IEEE_APP)
1174 continue;
1175 app_data = nla_data(attr);
1176 err = ops->ieee_setapp(netdev, app_data);
1177 if (err)
1178 goto err;
1179 }
1180 }
1181
1182err:
1183 dcbnl_reply(err, RTM_SETDCB, DCB_CMD_IEEE_SET, DCB_ATTR_IEEE,
1184 pid, seq, flags);
1185 return err;
1186}
1187
1188
1189/* Handle IEEE 802.1Qaz GET commands. */
1190static int dcbnl_ieee_get(struct net_device *netdev, struct nlattr **tb,
1191 u32 pid, u32 seq, u16 flags)
1192{
1193 struct sk_buff *skb;
1194 struct nlmsghdr *nlh;
1195 struct dcbmsg *dcb;
1196 struct nlattr *ieee;
1197 const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops;
1198 int err;
1199
1200 if (!ops)
1201 return -EOPNOTSUPP;
1202
1203 skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1204 if (!skb)
1205 return -ENOBUFS;
1206
1207 nlh = NLMSG_NEW(skb, pid, seq, RTM_GETDCB, sizeof(*dcb), flags);
1208
1209 dcb = NLMSG_DATA(nlh);
1210 dcb->dcb_family = AF_UNSPEC;
1211 dcb->cmd = DCB_CMD_IEEE_GET;
1212
1213 NLA_PUT_STRING(skb, DCB_ATTR_IFNAME, netdev->name);
1214
1215 ieee = nla_nest_start(skb, DCB_ATTR_IEEE);
1216 if (!ieee)
1217 goto nla_put_failure;
1218
1219 if (ops->ieee_getets) {
1220 struct ieee_ets ets;
1221 err = ops->ieee_getets(netdev, &ets);
1222 if (!err)
1223 NLA_PUT(skb, DCB_ATTR_IEEE_ETS, sizeof(ets), &ets);
1224 }
1225
1226 if (ops->ieee_getpfc) {
1227 struct ieee_pfc pfc;
1228 err = ops->ieee_getpfc(netdev, &pfc);
1229 if (!err)
1230 NLA_PUT(skb, DCB_ATTR_IEEE_PFC, sizeof(pfc), &pfc);
1231 }
1232
1233 nla_nest_end(skb, ieee);
1234 nlmsg_end(skb, nlh);
1235
1236 return rtnl_unicast(skb, &init_net, pid);
1237nla_put_failure:
1238 nlmsg_cancel(skb, nlh);
1239nlmsg_failure:
1240 kfree_skb(skb);
1241 return -1;
1242}
1243
1121static int dcb_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) 1244static int dcb_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
1122{ 1245{
1123 struct net *net = sock_net(skb->sk); 1246 struct net *net = sock_net(skb->sk);
@@ -1223,6 +1346,14 @@ static int dcb_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
1223 ret = dcbnl_setapp(netdev, tb, pid, nlh->nlmsg_seq, 1346 ret = dcbnl_setapp(netdev, tb, pid, nlh->nlmsg_seq,
1224 nlh->nlmsg_flags); 1347 nlh->nlmsg_flags);
1225 goto out; 1348 goto out;
1349 case DCB_CMD_IEEE_SET:
1350 ret = dcbnl_ieee_set(netdev, tb, pid, nlh->nlmsg_seq,
1351 nlh->nlmsg_flags);
1352 goto out;
1353 case DCB_CMD_IEEE_GET:
1354 ret = dcbnl_ieee_get(netdev, tb, pid, nlh->nlmsg_seq,
1355 nlh->nlmsg_flags);
1356 goto out;
1226 default: 1357 default:
1227 goto errout; 1358 goto errout;
1228 } 1359 }