Blame view
net/dcb/dcbnl.c
49 KB
2f90b8657 ixgbe: this patch... |
1 |
/* |
698e1d23c net: dcbnl: Updat... |
2 |
* Copyright (c) 2008-2011, Intel Corporation. |
2f90b8657 ixgbe: this patch... |
3 4 5 6 7 8 9 10 11 12 13 |
* * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, * version 2, as published by the Free Software Foundation. * * This program is distributed in the hope it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along with |
c057b190b net/*: Fix FSF ad... |
14 |
* this program; if not, see <http://www.gnu.org/licenses/>. |
2f90b8657 ixgbe: this patch... |
15 |
* |
36b9ad808 net/dcb: make dcb... |
16 |
* Description: Data Center Bridging netlink interface |
2f90b8657 ixgbe: this patch... |
17 18 19 20 21 |
* Author: Lucy Liu <lucy.liu@intel.com> */ #include <linux/netdevice.h> #include <linux/netlink.h> |
5a0e3ad6a include cleanup: ... |
22 |
#include <linux/slab.h> |
2f90b8657 ixgbe: this patch... |
23 24 25 |
#include <net/netlink.h> #include <net/rtnetlink.h> #include <linux/dcbnl.h> |
96b99684e net_dcb: add appl... |
26 |
#include <net/dcbevent.h> |
2f90b8657 ixgbe: this patch... |
27 |
#include <linux/rtnetlink.h> |
36b9ad808 net/dcb: make dcb... |
28 |
#include <linux/init.h> |
2f90b8657 ixgbe: this patch... |
29 |
#include <net/sock.h> |
ae86b9e38 net: Fix non-kern... |
30 |
/* Data Center Bridging (DCB) is a collection of Ethernet enhancements |
2f90b8657 ixgbe: this patch... |
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
* intended to allow network traffic with differing requirements * (highly reliable, no drops vs. best effort vs. low latency) to operate * and co-exist on Ethernet. Current DCB features are: * * Enhanced Transmission Selection (aka Priority Grouping [PG]) - provides a * framework for assigning bandwidth guarantees to traffic classes. * * Priority-based Flow Control (PFC) - provides a flow control mechanism which * can work independently for each 802.1p priority. * * Congestion Notification - provides a mechanism for end-to-end congestion * control for protocols which do not have built-in congestion management. * * More information about the emerging standards for these Ethernet features * can be found at: http://www.ieee802.org/1/pages/dcbridges.html * * This file implements an rtnetlink interface to allow configuration of DCB * features for capable devices. */ |
2f90b8657 ixgbe: this patch... |
50 51 52 |
/**************** DCB attribute policies *************************************/ /* DCB netlink attributes policy */ |
b54452b07 const: struct nla... |
53 |
static const struct nla_policy dcbnl_rtnl_policy[DCB_ATTR_MAX + 1] = { |
859ee3c43 DCB: Add support ... |
54 55 56 57 58 |
[DCB_ATTR_IFNAME] = {.type = NLA_NUL_STRING, .len = IFNAMSIZ - 1}, [DCB_ATTR_STATE] = {.type = NLA_U8}, [DCB_ATTR_PFC_CFG] = {.type = NLA_NESTED}, [DCB_ATTR_PG_CFG] = {.type = NLA_NESTED}, [DCB_ATTR_SET_ALL] = {.type = NLA_U8}, |
2f90b8657 ixgbe: this patch... |
59 |
[DCB_ATTR_PERM_HWADDR] = {.type = NLA_FLAG}, |
859ee3c43 DCB: Add support ... |
60 61 62 |
[DCB_ATTR_CAP] = {.type = NLA_NESTED}, [DCB_ATTR_PFC_STATE] = {.type = NLA_U8}, [DCB_ATTR_BCN] = {.type = NLA_NESTED}, |
6fa382af6 dcbnl: Add netlin... |
63 |
[DCB_ATTR_APP] = {.type = NLA_NESTED}, |
3e29027af dcbnl: add suppor... |
64 |
[DCB_ATTR_IEEE] = {.type = NLA_NESTED}, |
6241b6259 dcbnl: adding DCB... |
65 |
[DCB_ATTR_DCBX] = {.type = NLA_U8}, |
ea45fe4e1 dcbnl: adding DCB... |
66 |
[DCB_ATTR_FEATCFG] = {.type = NLA_NESTED}, |
2f90b8657 ixgbe: this patch... |
67 68 69 |
}; /* DCB priority flow control to User Priority nested attributes */ |
b54452b07 const: struct nla... |
70 |
static const struct nla_policy dcbnl_pfc_up_nest[DCB_PFC_UP_ATTR_MAX + 1] = { |
2f90b8657 ixgbe: this patch... |
71 72 73 74 75 76 77 78 79 80 81 82 |
[DCB_PFC_UP_ATTR_0] = {.type = NLA_U8}, [DCB_PFC_UP_ATTR_1] = {.type = NLA_U8}, [DCB_PFC_UP_ATTR_2] = {.type = NLA_U8}, [DCB_PFC_UP_ATTR_3] = {.type = NLA_U8}, [DCB_PFC_UP_ATTR_4] = {.type = NLA_U8}, [DCB_PFC_UP_ATTR_5] = {.type = NLA_U8}, [DCB_PFC_UP_ATTR_6] = {.type = NLA_U8}, [DCB_PFC_UP_ATTR_7] = {.type = NLA_U8}, [DCB_PFC_UP_ATTR_ALL] = {.type = NLA_FLAG}, }; /* DCB priority grouping nested attributes */ |
b54452b07 const: struct nla... |
83 |
static const struct nla_policy dcbnl_pg_nest[DCB_PG_ATTR_MAX + 1] = { |
2f90b8657 ixgbe: this patch... |
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
[DCB_PG_ATTR_TC_0] = {.type = NLA_NESTED}, [DCB_PG_ATTR_TC_1] = {.type = NLA_NESTED}, [DCB_PG_ATTR_TC_2] = {.type = NLA_NESTED}, [DCB_PG_ATTR_TC_3] = {.type = NLA_NESTED}, [DCB_PG_ATTR_TC_4] = {.type = NLA_NESTED}, [DCB_PG_ATTR_TC_5] = {.type = NLA_NESTED}, [DCB_PG_ATTR_TC_6] = {.type = NLA_NESTED}, [DCB_PG_ATTR_TC_7] = {.type = NLA_NESTED}, [DCB_PG_ATTR_TC_ALL] = {.type = NLA_NESTED}, [DCB_PG_ATTR_BW_ID_0] = {.type = NLA_U8}, [DCB_PG_ATTR_BW_ID_1] = {.type = NLA_U8}, [DCB_PG_ATTR_BW_ID_2] = {.type = NLA_U8}, [DCB_PG_ATTR_BW_ID_3] = {.type = NLA_U8}, [DCB_PG_ATTR_BW_ID_4] = {.type = NLA_U8}, [DCB_PG_ATTR_BW_ID_5] = {.type = NLA_U8}, [DCB_PG_ATTR_BW_ID_6] = {.type = NLA_U8}, [DCB_PG_ATTR_BW_ID_7] = {.type = NLA_U8}, [DCB_PG_ATTR_BW_ID_ALL] = {.type = NLA_FLAG}, }; /* DCB traffic class nested attributes. */ |
b54452b07 const: struct nla... |
105 |
static const struct nla_policy dcbnl_tc_param_nest[DCB_TC_ATTR_PARAM_MAX + 1] = { |
2f90b8657 ixgbe: this patch... |
106 107 108 109 110 111 |
[DCB_TC_ATTR_PARAM_PGID] = {.type = NLA_U8}, [DCB_TC_ATTR_PARAM_UP_MAPPING] = {.type = NLA_U8}, [DCB_TC_ATTR_PARAM_STRICT_PRIO] = {.type = NLA_U8}, [DCB_TC_ATTR_PARAM_BW_PCT] = {.type = NLA_U8}, [DCB_TC_ATTR_PARAM_ALL] = {.type = NLA_FLAG}, }; |
46132188b DCB: Add interfac... |
112 |
/* DCB capabilities nested attributes. */ |
b54452b07 const: struct nla... |
113 |
static const struct nla_policy dcbnl_cap_nest[DCB_CAP_ATTR_MAX + 1] = { |
46132188b DCB: Add interfac... |
114 115 116 117 118 119 120 121 |
[DCB_CAP_ATTR_ALL] = {.type = NLA_FLAG}, [DCB_CAP_ATTR_PG] = {.type = NLA_U8}, [DCB_CAP_ATTR_PFC] = {.type = NLA_U8}, [DCB_CAP_ATTR_UP2TC] = {.type = NLA_U8}, [DCB_CAP_ATTR_PG_TCS] = {.type = NLA_U8}, [DCB_CAP_ATTR_PFC_TCS] = {.type = NLA_U8}, [DCB_CAP_ATTR_GSP] = {.type = NLA_U8}, [DCB_CAP_ATTR_BCN] = {.type = NLA_U8}, |
6241b6259 dcbnl: adding DCB... |
122 |
[DCB_CAP_ATTR_DCBX] = {.type = NLA_U8}, |
46132188b DCB: Add interfac... |
123 |
}; |
2f90b8657 ixgbe: this patch... |
124 |
|
33dbabc4a DCB: Add interfac... |
125 |
/* DCB capabilities nested attributes. */ |
b54452b07 const: struct nla... |
126 |
static const struct nla_policy dcbnl_numtcs_nest[DCB_NUMTCS_ATTR_MAX + 1] = { |
33dbabc4a DCB: Add interfac... |
127 128 129 130 |
[DCB_NUMTCS_ATTR_ALL] = {.type = NLA_FLAG}, [DCB_NUMTCS_ATTR_PG] = {.type = NLA_U8}, [DCB_NUMTCS_ATTR_PFC] = {.type = NLA_U8}, }; |
859ee3c43 DCB: Add support ... |
131 |
/* DCB BCN nested attributes. */ |
b54452b07 const: struct nla... |
132 |
static const struct nla_policy dcbnl_bcn_nest[DCB_BCN_ATTR_MAX + 1] = { |
859ee3c43 DCB: Add support ... |
133 134 135 136 137 138 139 140 141 |
[DCB_BCN_ATTR_RP_0] = {.type = NLA_U8}, [DCB_BCN_ATTR_RP_1] = {.type = NLA_U8}, [DCB_BCN_ATTR_RP_2] = {.type = NLA_U8}, [DCB_BCN_ATTR_RP_3] = {.type = NLA_U8}, [DCB_BCN_ATTR_RP_4] = {.type = NLA_U8}, [DCB_BCN_ATTR_RP_5] = {.type = NLA_U8}, [DCB_BCN_ATTR_RP_6] = {.type = NLA_U8}, [DCB_BCN_ATTR_RP_7] = {.type = NLA_U8}, [DCB_BCN_ATTR_RP_ALL] = {.type = NLA_FLAG}, |
f4314e815 net: add DCNA att... |
142 143 |
[DCB_BCN_ATTR_BCNA_0] = {.type = NLA_U32}, [DCB_BCN_ATTR_BCNA_1] = {.type = NLA_U32}, |
859ee3c43 DCB: Add support ... |
144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 |
[DCB_BCN_ATTR_ALPHA] = {.type = NLA_U32}, [DCB_BCN_ATTR_BETA] = {.type = NLA_U32}, [DCB_BCN_ATTR_GD] = {.type = NLA_U32}, [DCB_BCN_ATTR_GI] = {.type = NLA_U32}, [DCB_BCN_ATTR_TMAX] = {.type = NLA_U32}, [DCB_BCN_ATTR_TD] = {.type = NLA_U32}, [DCB_BCN_ATTR_RMIN] = {.type = NLA_U32}, [DCB_BCN_ATTR_W] = {.type = NLA_U32}, [DCB_BCN_ATTR_RD] = {.type = NLA_U32}, [DCB_BCN_ATTR_RU] = {.type = NLA_U32}, [DCB_BCN_ATTR_WRTT] = {.type = NLA_U32}, [DCB_BCN_ATTR_RI] = {.type = NLA_U32}, [DCB_BCN_ATTR_C] = {.type = NLA_U32}, [DCB_BCN_ATTR_ALL] = {.type = NLA_FLAG}, }; |
6fa382af6 dcbnl: Add netlin... |
159 |
/* DCB APP nested attributes. */ |
b54452b07 const: struct nla... |
160 |
static const struct nla_policy dcbnl_app_nest[DCB_APP_ATTR_MAX + 1] = { |
6fa382af6 dcbnl: Add netlin... |
161 162 163 164 |
[DCB_APP_ATTR_IDTYPE] = {.type = NLA_U8}, [DCB_APP_ATTR_ID] = {.type = NLA_U16}, [DCB_APP_ATTR_PRIORITY] = {.type = NLA_U8}, }; |
3e29027af dcbnl: add suppor... |
165 166 167 168 169 |
/* IEEE 802.1Qaz nested attributes. */ static const struct nla_policy dcbnl_ieee_policy[DCB_ATTR_IEEE_MAX + 1] = { [DCB_ATTR_IEEE_ETS] = {.len = sizeof(struct ieee_ets)}, [DCB_ATTR_IEEE_PFC] = {.len = sizeof(struct ieee_pfc)}, [DCB_ATTR_IEEE_APP_TABLE] = {.type = NLA_NESTED}, |
08f10affe net/dcb: Add an o... |
170 |
[DCB_ATTR_IEEE_MAXRATE] = {.len = sizeof(struct ieee_maxrate)}, |
c93682477 net/dcb: Add IEEE... |
171 172 |
[DCB_ATTR_IEEE_QCN] = {.len = sizeof(struct ieee_qcn)}, [DCB_ATTR_IEEE_QCN_STATS] = {.len = sizeof(struct ieee_qcn_stats)}, |
3e29027af dcbnl: add suppor... |
173 174 175 176 177 |
}; static const struct nla_policy dcbnl_ieee_app[DCB_ATTR_IEEE_APP_MAX + 1] = { [DCB_ATTR_IEEE_APP] = {.len = sizeof(struct dcb_app)}, }; |
ea45fe4e1 dcbnl: adding DCB... |
178 179 180 181 182 183 184 |
/* DCB number of traffic classes nested attributes. */ static const struct nla_policy dcbnl_featcfg_nest[DCB_FEATCFG_ATTR_MAX + 1] = { [DCB_FEATCFG_ATTR_ALL] = {.type = NLA_FLAG}, [DCB_FEATCFG_ATTR_PG] = {.type = NLA_U8}, [DCB_FEATCFG_ATTR_PFC] = {.type = NLA_U8}, [DCB_FEATCFG_ATTR_APP] = {.type = NLA_U8}, }; |
9ab933ab2 dcbnl: add applic... |
185 186 |
static LIST_HEAD(dcb_app_list); static DEFINE_SPINLOCK(dcb_lock); |
33a03aadb dcbnl: Prepare fr... |
187 188 189 190 191 192 193 194 195 196 197 198 |
static struct sk_buff *dcbnl_newmsg(int type, u8 cmd, u32 port, u32 seq, u32 flags, struct nlmsghdr **nlhp) { struct sk_buff *skb; struct dcbmsg *dcb; struct nlmsghdr *nlh; skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); if (!skb) return NULL; nlh = nlmsg_put(skb, port, seq, type, sizeof(*dcb), flags); |
b3908e22a dcbnl: Use BUG_ON... |
199 |
BUG_ON(!nlh); |
33a03aadb dcbnl: Prepare fr... |
200 201 202 203 204 205 206 207 208 209 210 |
dcb = nlmsg_data(nlh); dcb->dcb_family = AF_UNSPEC; dcb->cmd = cmd; dcb->dcb_pad = 0; if (nlhp) *nlhp = nlh; return skb; } |
7be994138 dcbnl: Shorten al... |
211 212 |
static int dcbnl_getstate(struct net_device *netdev, struct nlmsghdr *nlh, u32 seq, struct nlattr **tb, struct sk_buff *skb) |
2f90b8657 ixgbe: this patch... |
213 |
{ |
2f90b8657 ixgbe: this patch... |
214 215 |
/* if (!tb[DCB_ATTR_STATE] || !netdev->dcbnl_ops->getstate) */ if (!netdev->dcbnl_ops->getstate) |
3d1f48695 dcbnl: Return con... |
216 |
return -EOPNOTSUPP; |
2f90b8657 ixgbe: this patch... |
217 |
|
7be994138 dcbnl: Shorten al... |
218 219 |
return nla_put_u8(skb, DCB_ATTR_STATE, netdev->dcbnl_ops->getstate(netdev)); |
2f90b8657 ixgbe: this patch... |
220 |
} |
7be994138 dcbnl: Shorten al... |
221 222 |
static int dcbnl_getpfccfg(struct net_device *netdev, struct nlmsghdr *nlh, u32 seq, struct nlattr **tb, struct sk_buff *skb) |
2f90b8657 ixgbe: this patch... |
223 |
{ |
2f90b8657 ixgbe: this patch... |
224 225 |
struct nlattr *data[DCB_PFC_UP_ATTR_MAX + 1], *nest; u8 value; |
3d1f48695 dcbnl: Return con... |
226 |
int ret; |
2f90b8657 ixgbe: this patch... |
227 228 |
int i; int getall = 0; |
3d1f48695 dcbnl: Return con... |
229 230 231 232 233 |
if (!tb[DCB_ATTR_PFC_CFG]) return -EINVAL; if (!netdev->dcbnl_ops->getpfccfg) return -EOPNOTSUPP; |
2f90b8657 ixgbe: this patch... |
234 235 236 237 238 |
ret = nla_parse_nested(data, DCB_PFC_UP_ATTR_MAX, tb[DCB_ATTR_PFC_CFG], dcbnl_pfc_up_nest); if (ret) |
3d1f48695 dcbnl: Return con... |
239 |
return ret; |
2f90b8657 ixgbe: this patch... |
240 |
|
7be994138 dcbnl: Shorten al... |
241 |
nest = nla_nest_start(skb, DCB_ATTR_PFC_CFG); |
2f90b8657 ixgbe: this patch... |
242 |
if (!nest) |
3d1f48695 dcbnl: Return con... |
243 |
return -EMSGSIZE; |
2f90b8657 ixgbe: this patch... |
244 245 246 247 248 249 250 251 252 253 |
if (data[DCB_PFC_UP_ATTR_ALL]) getall = 1; for (i = DCB_PFC_UP_ATTR_0; i <= DCB_PFC_UP_ATTR_7; i++) { if (!getall && !data[i]) continue; netdev->dcbnl_ops->getpfccfg(netdev, i - DCB_PFC_UP_ATTR_0, &value); |
7be994138 dcbnl: Shorten al... |
254 |
ret = nla_put_u8(skb, i, value); |
2f90b8657 ixgbe: this patch... |
255 |
if (ret) { |
7be994138 dcbnl: Shorten al... |
256 |
nla_nest_cancel(skb, nest); |
3d1f48695 dcbnl: Return con... |
257 |
return ret; |
2f90b8657 ixgbe: this patch... |
258 259 |
} } |
7be994138 dcbnl: Shorten al... |
260 |
nla_nest_end(skb, nest); |
2f90b8657 ixgbe: this patch... |
261 262 |
return 0; |
2f90b8657 ixgbe: this patch... |
263 |
} |
7be994138 dcbnl: Shorten al... |
264 265 |
static int dcbnl_getperm_hwaddr(struct net_device *netdev, struct nlmsghdr *nlh, u32 seq, struct nlattr **tb, struct sk_buff *skb) |
2f90b8657 ixgbe: this patch... |
266 |
{ |
2f90b8657 ixgbe: this patch... |
267 |
u8 perm_addr[MAX_ADDR_LEN]; |
2f90b8657 ixgbe: this patch... |
268 269 |
if (!netdev->dcbnl_ops->getpermhwaddr) |
3d1f48695 dcbnl: Return con... |
270 |
return -EOPNOTSUPP; |
2f90b8657 ixgbe: this patch... |
271 |
|
29cd8ae0e dcbnl: fix variou... |
272 |
memset(perm_addr, 0, sizeof(perm_addr)); |
2f90b8657 ixgbe: this patch... |
273 |
netdev->dcbnl_ops->getpermhwaddr(netdev, perm_addr); |
7be994138 dcbnl: Shorten al... |
274 |
return nla_put(skb, DCB_ATTR_PERM_HWADDR, sizeof(perm_addr), perm_addr); |
2f90b8657 ixgbe: this patch... |
275 |
} |
7be994138 dcbnl: Shorten al... |
276 277 |
static int dcbnl_getcap(struct net_device *netdev, struct nlmsghdr *nlh, u32 seq, struct nlattr **tb, struct sk_buff *skb) |
46132188b DCB: Add interfac... |
278 |
{ |
46132188b DCB: Add interfac... |
279 280 |
struct nlattr *data[DCB_CAP_ATTR_MAX + 1], *nest; u8 value; |
3d1f48695 dcbnl: Return con... |
281 |
int ret; |
46132188b DCB: Add interfac... |
282 283 |
int i; int getall = 0; |
3d1f48695 dcbnl: Return con... |
284 285 286 287 288 |
if (!tb[DCB_ATTR_CAP]) return -EINVAL; if (!netdev->dcbnl_ops->getcap) return -EOPNOTSUPP; |
46132188b DCB: Add interfac... |
289 290 291 292 |
ret = nla_parse_nested(data, DCB_CAP_ATTR_MAX, tb[DCB_ATTR_CAP], dcbnl_cap_nest); if (ret) |
3d1f48695 dcbnl: Return con... |
293 |
return ret; |
46132188b DCB: Add interfac... |
294 |
|
7be994138 dcbnl: Shorten al... |
295 |
nest = nla_nest_start(skb, DCB_ATTR_CAP); |
46132188b DCB: Add interfac... |
296 |
if (!nest) |
3d1f48695 dcbnl: Return con... |
297 |
return -EMSGSIZE; |
46132188b DCB: Add interfac... |
298 299 300 301 302 303 304 305 306 |
if (data[DCB_CAP_ATTR_ALL]) getall = 1; for (i = DCB_CAP_ATTR_ALL+1; i <= DCB_CAP_ATTR_MAX; i++) { if (!getall && !data[i]) continue; if (!netdev->dcbnl_ops->getcap(netdev, i, &value)) { |
7be994138 dcbnl: Shorten al... |
307 |
ret = nla_put_u8(skb, i, value); |
46132188b DCB: Add interfac... |
308 |
if (ret) { |
7be994138 dcbnl: Shorten al... |
309 |
nla_nest_cancel(skb, nest); |
3d1f48695 dcbnl: Return con... |
310 |
return ret; |
46132188b DCB: Add interfac... |
311 312 313 |
} } } |
7be994138 dcbnl: Shorten al... |
314 |
nla_nest_end(skb, nest); |
46132188b DCB: Add interfac... |
315 316 |
return 0; |
46132188b DCB: Add interfac... |
317 |
} |
7be994138 dcbnl: Shorten al... |
318 319 |
static int dcbnl_getnumtcs(struct net_device *netdev, struct nlmsghdr *nlh, u32 seq, struct nlattr **tb, struct sk_buff *skb) |
33dbabc4a DCB: Add interfac... |
320 |
{ |
33dbabc4a DCB: Add interfac... |
321 322 |
struct nlattr *data[DCB_NUMTCS_ATTR_MAX + 1], *nest; u8 value; |
3d1f48695 dcbnl: Return con... |
323 |
int ret; |
33dbabc4a DCB: Add interfac... |
324 325 |
int i; int getall = 0; |
3d1f48695 dcbnl: Return con... |
326 327 328 329 330 |
if (!tb[DCB_ATTR_NUMTCS]) return -EINVAL; if (!netdev->dcbnl_ops->getnumtcs) return -EOPNOTSUPP; |
33dbabc4a DCB: Add interfac... |
331 332 333 |
ret = nla_parse_nested(data, DCB_NUMTCS_ATTR_MAX, tb[DCB_ATTR_NUMTCS], dcbnl_numtcs_nest); |
3d1f48695 dcbnl: Return con... |
334 335 |
if (ret) return ret; |
33dbabc4a DCB: Add interfac... |
336 |
|
7be994138 dcbnl: Shorten al... |
337 |
nest = nla_nest_start(skb, DCB_ATTR_NUMTCS); |
3d1f48695 dcbnl: Return con... |
338 339 |
if (!nest) return -EMSGSIZE; |
33dbabc4a DCB: Add interfac... |
340 341 342 343 344 345 346 347 348 349 |
if (data[DCB_NUMTCS_ATTR_ALL]) getall = 1; for (i = DCB_NUMTCS_ATTR_ALL+1; i <= DCB_NUMTCS_ATTR_MAX; i++) { if (!getall && !data[i]) continue; ret = netdev->dcbnl_ops->getnumtcs(netdev, i, &value); if (!ret) { |
7be994138 dcbnl: Shorten al... |
350 |
ret = nla_put_u8(skb, i, value); |
33dbabc4a DCB: Add interfac... |
351 |
if (ret) { |
7be994138 dcbnl: Shorten al... |
352 |
nla_nest_cancel(skb, nest); |
3d1f48695 dcbnl: Return con... |
353 |
return ret; |
33dbabc4a DCB: Add interfac... |
354 |
} |
3d1f48695 dcbnl: Return con... |
355 356 |
} else return -EINVAL; |
33dbabc4a DCB: Add interfac... |
357 |
} |
7be994138 dcbnl: Shorten al... |
358 |
nla_nest_end(skb, nest); |
33dbabc4a DCB: Add interfac... |
359 360 |
return 0; |
33dbabc4a DCB: Add interfac... |
361 |
} |
7be994138 dcbnl: Shorten al... |
362 363 |
static int dcbnl_setnumtcs(struct net_device *netdev, struct nlmsghdr *nlh, u32 seq, struct nlattr **tb, struct sk_buff *skb) |
33dbabc4a DCB: Add interfac... |
364 365 |
{ struct nlattr *data[DCB_NUMTCS_ATTR_MAX + 1]; |
3d1f48695 dcbnl: Return con... |
366 |
int ret; |
33dbabc4a DCB: Add interfac... |
367 368 |
u8 value; int i; |
3d1f48695 dcbnl: Return con... |
369 370 371 372 373 |
if (!tb[DCB_ATTR_NUMTCS]) return -EINVAL; if (!netdev->dcbnl_ops->setnumtcs) return -EOPNOTSUPP; |
33dbabc4a DCB: Add interfac... |
374 375 376 |
ret = nla_parse_nested(data, DCB_NUMTCS_ATTR_MAX, tb[DCB_ATTR_NUMTCS], dcbnl_numtcs_nest); |
7be994138 dcbnl: Shorten al... |
377 |
if (ret) |
3d1f48695 dcbnl: Return con... |
378 |
return ret; |
33dbabc4a DCB: Add interfac... |
379 380 381 382 383 384 385 386 |
for (i = DCB_NUMTCS_ATTR_ALL+1; i <= DCB_NUMTCS_ATTR_MAX; i++) { if (data[i] == NULL) continue; value = nla_get_u8(data[i]); ret = netdev->dcbnl_ops->setnumtcs(netdev, i, value); |
33dbabc4a DCB: Add interfac... |
387 |
if (ret) |
7be994138 dcbnl: Shorten al... |
388 |
break; |
33dbabc4a DCB: Add interfac... |
389 |
} |
7be994138 dcbnl: Shorten al... |
390 |
return nla_put_u8(skb, DCB_ATTR_NUMTCS, !!ret); |
33dbabc4a DCB: Add interfac... |
391 |
} |
7be994138 dcbnl: Shorten al... |
392 393 |
static int dcbnl_getpfcstate(struct net_device *netdev, struct nlmsghdr *nlh, u32 seq, struct nlattr **tb, struct sk_buff *skb) |
0eb3aa9ba DCB: Add interfac... |
394 |
{ |
0eb3aa9ba DCB: Add interfac... |
395 |
if (!netdev->dcbnl_ops->getpfcstate) |
3d1f48695 dcbnl: Return con... |
396 |
return -EOPNOTSUPP; |
0eb3aa9ba DCB: Add interfac... |
397 |
|
7be994138 dcbnl: Shorten al... |
398 399 |
return nla_put_u8(skb, DCB_ATTR_PFC_STATE, netdev->dcbnl_ops->getpfcstate(netdev)); |
0eb3aa9ba DCB: Add interfac... |
400 |
} |
7be994138 dcbnl: Shorten al... |
401 402 |
static int dcbnl_setpfcstate(struct net_device *netdev, struct nlmsghdr *nlh, u32 seq, struct nlattr **tb, struct sk_buff *skb) |
0eb3aa9ba DCB: Add interfac... |
403 |
{ |
0eb3aa9ba DCB: Add interfac... |
404 |
u8 value; |
3d1f48695 dcbnl: Return con... |
405 |
if (!tb[DCB_ATTR_PFC_STATE]) |
7be994138 dcbnl: Shorten al... |
406 |
return -EINVAL; |
0eb3aa9ba DCB: Add interfac... |
407 |
|
3d1f48695 dcbnl: Return con... |
408 409 |
if (!netdev->dcbnl_ops->setpfcstate) return -EOPNOTSUPP; |
0eb3aa9ba DCB: Add interfac... |
410 411 412 |
value = nla_get_u8(tb[DCB_ATTR_PFC_STATE]); netdev->dcbnl_ops->setpfcstate(netdev, value); |
7be994138 dcbnl: Shorten al... |
413 |
return nla_put_u8(skb, DCB_ATTR_PFC_STATE, 0); |
0eb3aa9ba DCB: Add interfac... |
414 |
} |
7be994138 dcbnl: Shorten al... |
415 416 |
static int dcbnl_getapp(struct net_device *netdev, struct nlmsghdr *nlh, u32 seq, struct nlattr **tb, struct sk_buff *skb) |
579496865 dcbnl: Add implem... |
417 |
{ |
579496865 dcbnl: Add implem... |
418 419 420 421 |
struct nlattr *app_nest; struct nlattr *app_tb[DCB_APP_ATTR_MAX + 1]; u16 id; u8 up, idtype; |
3d1f48695 dcbnl: Return con... |
422 |
int ret; |
579496865 dcbnl: Add implem... |
423 |
|
3dce38a02 dcbnl: make get_a... |
424 |
if (!tb[DCB_ATTR_APP]) |
3d1f48695 dcbnl: Return con... |
425 |
return -EINVAL; |
579496865 dcbnl: Add implem... |
426 427 428 429 |
ret = nla_parse_nested(app_tb, DCB_APP_ATTR_MAX, tb[DCB_ATTR_APP], dcbnl_app_nest); if (ret) |
3d1f48695 dcbnl: Return con... |
430 |
return ret; |
579496865 dcbnl: Add implem... |
431 |
|
579496865 dcbnl: Add implem... |
432 433 434 |
/* all must be non-null */ if ((!app_tb[DCB_APP_ATTR_IDTYPE]) || (!app_tb[DCB_APP_ATTR_ID])) |
3d1f48695 dcbnl: Return con... |
435 |
return -EINVAL; |
579496865 dcbnl: Add implem... |
436 437 438 439 440 |
/* either by eth type or by socket number */ idtype = nla_get_u8(app_tb[DCB_APP_ATTR_IDTYPE]); if ((idtype != DCB_APP_IDTYPE_ETHTYPE) && (idtype != DCB_APP_IDTYPE_PORTNUM)) |
3d1f48695 dcbnl: Return con... |
441 |
return -EINVAL; |
579496865 dcbnl: Add implem... |
442 443 |
id = nla_get_u16(app_tb[DCB_APP_ATTR_ID]); |
3dce38a02 dcbnl: make get_a... |
444 445 |
if (netdev->dcbnl_ops->getapp) { |
c2659479f Update setapp/get... |
446 447 448 449 450 |
ret = netdev->dcbnl_ops->getapp(netdev, idtype, id); if (ret < 0) return ret; else up = ret; |
3dce38a02 dcbnl: make get_a... |
451 452 453 454 455 456 457 |
} else { struct dcb_app app = { .selector = idtype, .protocol = id, }; up = dcb_getapp(netdev, &app); } |
579496865 dcbnl: Add implem... |
458 |
|
7be994138 dcbnl: Shorten al... |
459 |
app_nest = nla_nest_start(skb, DCB_ATTR_APP); |
d3337de52 Don't potentially... |
460 |
if (!app_nest) |
3d1f48695 dcbnl: Return con... |
461 |
return -EMSGSIZE; |
d3337de52 Don't potentially... |
462 |
|
7be994138 dcbnl: Shorten al... |
463 |
ret = nla_put_u8(skb, DCB_APP_ATTR_IDTYPE, idtype); |
579496865 dcbnl: Add implem... |
464 465 |
if (ret) goto out_cancel; |
7be994138 dcbnl: Shorten al... |
466 |
ret = nla_put_u16(skb, DCB_APP_ATTR_ID, id); |
579496865 dcbnl: Add implem... |
467 468 |
if (ret) goto out_cancel; |
7be994138 dcbnl: Shorten al... |
469 |
ret = nla_put_u8(skb, DCB_APP_ATTR_PRIORITY, up); |
579496865 dcbnl: Add implem... |
470 471 |
if (ret) goto out_cancel; |
7be994138 dcbnl: Shorten al... |
472 |
nla_nest_end(skb, app_nest); |
579496865 dcbnl: Add implem... |
473 |
|
3d1f48695 dcbnl: Return con... |
474 |
return 0; |
579496865 dcbnl: Add implem... |
475 476 |
out_cancel: |
7be994138 dcbnl: Shorten al... |
477 |
nla_nest_cancel(skb, app_nest); |
579496865 dcbnl: Add implem... |
478 479 |
return ret; } |
7be994138 dcbnl: Shorten al... |
480 481 |
static int dcbnl_setapp(struct net_device *netdev, struct nlmsghdr *nlh, u32 seq, struct nlattr **tb, struct sk_buff *skb) |
579496865 dcbnl: Add implem... |
482 |
{ |
3d1f48695 dcbnl: Return con... |
483 |
int ret; |
579496865 dcbnl: Add implem... |
484 485 486 |
u16 id; u8 up, idtype; struct nlattr *app_tb[DCB_APP_ATTR_MAX + 1]; |
9ab933ab2 dcbnl: add applic... |
487 |
if (!tb[DCB_ATTR_APP]) |
3d1f48695 dcbnl: Return con... |
488 |
return -EINVAL; |
579496865 dcbnl: Add implem... |
489 490 491 492 |
ret = nla_parse_nested(app_tb, DCB_APP_ATTR_MAX, tb[DCB_ATTR_APP], dcbnl_app_nest); if (ret) |
3d1f48695 dcbnl: Return con... |
493 |
return ret; |
579496865 dcbnl: Add implem... |
494 |
|
579496865 dcbnl: Add implem... |
495 496 497 498 |
/* all must be non-null */ if ((!app_tb[DCB_APP_ATTR_IDTYPE]) || (!app_tb[DCB_APP_ATTR_ID]) || (!app_tb[DCB_APP_ATTR_PRIORITY])) |
3d1f48695 dcbnl: Return con... |
499 |
return -EINVAL; |
579496865 dcbnl: Add implem... |
500 501 502 503 504 |
/* either by eth type or by socket number */ idtype = nla_get_u8(app_tb[DCB_APP_ATTR_IDTYPE]); if ((idtype != DCB_APP_IDTYPE_ETHTYPE) && (idtype != DCB_APP_IDTYPE_PORTNUM)) |
3d1f48695 dcbnl: Return con... |
505 |
return -EINVAL; |
579496865 dcbnl: Add implem... |
506 507 508 |
id = nla_get_u16(app_tb[DCB_APP_ATTR_ID]); up = nla_get_u8(app_tb[DCB_APP_ATTR_PRIORITY]); |
9ab933ab2 dcbnl: add applic... |
509 |
if (netdev->dcbnl_ops->setapp) { |
3d1f48695 dcbnl: Return con... |
510 |
ret = netdev->dcbnl_ops->setapp(netdev, idtype, id, up); |
c2659479f Update setapp/get... |
511 512 |
if (ret < 0) return ret; |
9ab933ab2 dcbnl: add applic... |
513 514 515 516 517 |
} else { struct dcb_app app; app.selector = idtype; app.protocol = id; app.priority = up; |
3d1f48695 dcbnl: Return con... |
518 |
ret = dcb_setapp(netdev, &app); |
9ab933ab2 dcbnl: add applic... |
519 |
} |
7be994138 dcbnl: Shorten al... |
520 |
ret = nla_put_u8(skb, DCB_ATTR_APP, ret); |
081579840 net: dcb: add CEE... |
521 |
dcbnl_cee_notify(netdev, RTM_SETDCB, DCB_CMD_SAPP, seq, 0); |
3d1f48695 dcbnl: Return con... |
522 |
|
579496865 dcbnl: Add implem... |
523 524 |
return ret; } |
7be994138 dcbnl: Shorten al... |
525 526 |
static int __dcbnl_pg_getcfg(struct net_device *netdev, struct nlmsghdr *nlh, struct nlattr **tb, struct sk_buff *skb, int dir) |
2f90b8657 ixgbe: this patch... |
527 |
{ |
2f90b8657 ixgbe: this patch... |
528 529 530 531 |
struct nlattr *pg_nest, *param_nest, *data; struct nlattr *pg_tb[DCB_PG_ATTR_MAX + 1]; struct nlattr *param_tb[DCB_TC_ATTR_PARAM_MAX + 1]; u8 prio, pgid, tc_pct, up_map; |
3d1f48695 dcbnl: Return con... |
532 |
int ret; |
2f90b8657 ixgbe: this patch... |
533 534 |
int getall = 0; int i; |
3d1f48695 dcbnl: Return con... |
535 536 537 538 |
if (!tb[DCB_ATTR_PG_CFG]) return -EINVAL; if (!netdev->dcbnl_ops->getpgtccfgtx || |
2f90b8657 ixgbe: this patch... |
539 540 541 |
!netdev->dcbnl_ops->getpgtccfgrx || !netdev->dcbnl_ops->getpgbwgcfgtx || !netdev->dcbnl_ops->getpgbwgcfgrx) |
3d1f48695 dcbnl: Return con... |
542 |
return -EOPNOTSUPP; |
2f90b8657 ixgbe: this patch... |
543 544 545 |
ret = nla_parse_nested(pg_tb, DCB_PG_ATTR_MAX, tb[DCB_ATTR_PG_CFG], dcbnl_pg_nest); |
2f90b8657 ixgbe: this patch... |
546 |
if (ret) |
3d1f48695 dcbnl: Return con... |
547 |
return ret; |
2f90b8657 ixgbe: this patch... |
548 |
|
7be994138 dcbnl: Shorten al... |
549 |
pg_nest = nla_nest_start(skb, DCB_ATTR_PG_CFG); |
2f90b8657 ixgbe: this patch... |
550 |
if (!pg_nest) |
3d1f48695 dcbnl: Return con... |
551 |
return -EMSGSIZE; |
2f90b8657 ixgbe: this patch... |
552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 |
if (pg_tb[DCB_PG_ATTR_TC_ALL]) getall = 1; for (i = DCB_PG_ATTR_TC_0; i <= DCB_PG_ATTR_TC_7; i++) { if (!getall && !pg_tb[i]) continue; if (pg_tb[DCB_PG_ATTR_TC_ALL]) data = pg_tb[DCB_PG_ATTR_TC_ALL]; else data = pg_tb[i]; ret = nla_parse_nested(param_tb, DCB_TC_ATTR_PARAM_MAX, data, dcbnl_tc_param_nest); if (ret) goto err_pg; |
7be994138 dcbnl: Shorten al... |
568 |
param_nest = nla_nest_start(skb, i); |
2f90b8657 ixgbe: this patch... |
569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 |
if (!param_nest) goto err_pg; pgid = DCB_ATTR_VALUE_UNDEFINED; prio = DCB_ATTR_VALUE_UNDEFINED; tc_pct = DCB_ATTR_VALUE_UNDEFINED; up_map = DCB_ATTR_VALUE_UNDEFINED; if (dir) { /* Rx */ netdev->dcbnl_ops->getpgtccfgrx(netdev, i - DCB_PG_ATTR_TC_0, &prio, &pgid, &tc_pct, &up_map); } else { /* Tx */ netdev->dcbnl_ops->getpgtccfgtx(netdev, i - DCB_PG_ATTR_TC_0, &prio, &pgid, &tc_pct, &up_map); } if (param_tb[DCB_TC_ATTR_PARAM_PGID] || param_tb[DCB_TC_ATTR_PARAM_ALL]) { |
7be994138 dcbnl: Shorten al... |
591 |
ret = nla_put_u8(skb, |
2f90b8657 ixgbe: this patch... |
592 593 594 595 596 597 |
DCB_TC_ATTR_PARAM_PGID, pgid); if (ret) goto err_param; } if (param_tb[DCB_TC_ATTR_PARAM_UP_MAPPING] || param_tb[DCB_TC_ATTR_PARAM_ALL]) { |
7be994138 dcbnl: Shorten al... |
598 |
ret = nla_put_u8(skb, |
2f90b8657 ixgbe: this patch... |
599 600 601 602 603 604 |
DCB_TC_ATTR_PARAM_UP_MAPPING, up_map); if (ret) goto err_param; } if (param_tb[DCB_TC_ATTR_PARAM_STRICT_PRIO] || param_tb[DCB_TC_ATTR_PARAM_ALL]) { |
7be994138 dcbnl: Shorten al... |
605 |
ret = nla_put_u8(skb, |
2f90b8657 ixgbe: this patch... |
606 607 608 609 610 611 |
DCB_TC_ATTR_PARAM_STRICT_PRIO, prio); if (ret) goto err_param; } if (param_tb[DCB_TC_ATTR_PARAM_BW_PCT] || param_tb[DCB_TC_ATTR_PARAM_ALL]) { |
7be994138 dcbnl: Shorten al... |
612 |
ret = nla_put_u8(skb, DCB_TC_ATTR_PARAM_BW_PCT, |
2f90b8657 ixgbe: this patch... |
613 614 615 616 |
tc_pct); if (ret) goto err_param; } |
7be994138 dcbnl: Shorten al... |
617 |
nla_nest_end(skb, param_nest); |
2f90b8657 ixgbe: this patch... |
618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 |
} if (pg_tb[DCB_PG_ATTR_BW_ID_ALL]) getall = 1; else getall = 0; for (i = DCB_PG_ATTR_BW_ID_0; i <= DCB_PG_ATTR_BW_ID_7; i++) { if (!getall && !pg_tb[i]) continue; tc_pct = DCB_ATTR_VALUE_UNDEFINED; if (dir) { /* Rx */ netdev->dcbnl_ops->getpgbwgcfgrx(netdev, i - DCB_PG_ATTR_BW_ID_0, &tc_pct); } else { /* Tx */ netdev->dcbnl_ops->getpgbwgcfgtx(netdev, i - DCB_PG_ATTR_BW_ID_0, &tc_pct); } |
7be994138 dcbnl: Shorten al... |
640 |
ret = nla_put_u8(skb, i, tc_pct); |
2f90b8657 ixgbe: this patch... |
641 642 643 |
if (ret) goto err_pg; } |
7be994138 dcbnl: Shorten al... |
644 |
nla_nest_end(skb, pg_nest); |
2f90b8657 ixgbe: this patch... |
645 646 647 648 |
return 0; err_param: |
7be994138 dcbnl: Shorten al... |
649 |
nla_nest_cancel(skb, param_nest); |
2f90b8657 ixgbe: this patch... |
650 |
err_pg: |
7be994138 dcbnl: Shorten al... |
651 |
nla_nest_cancel(skb, pg_nest); |
3d1f48695 dcbnl: Return con... |
652 653 |
return -EMSGSIZE; |
2f90b8657 ixgbe: this patch... |
654 |
} |
7be994138 dcbnl: Shorten al... |
655 656 |
static int dcbnl_pgtx_getcfg(struct net_device *netdev, struct nlmsghdr *nlh, u32 seq, struct nlattr **tb, struct sk_buff *skb) |
2f90b8657 ixgbe: this patch... |
657 |
{ |
7be994138 dcbnl: Shorten al... |
658 |
return __dcbnl_pg_getcfg(netdev, nlh, tb, skb, 0); |
2f90b8657 ixgbe: this patch... |
659 |
} |
7be994138 dcbnl: Shorten al... |
660 661 |
static int dcbnl_pgrx_getcfg(struct net_device *netdev, struct nlmsghdr *nlh, u32 seq, struct nlattr **tb, struct sk_buff *skb) |
2f90b8657 ixgbe: this patch... |
662 |
{ |
7be994138 dcbnl: Shorten al... |
663 |
return __dcbnl_pg_getcfg(netdev, nlh, tb, skb, 1); |
2f90b8657 ixgbe: this patch... |
664 |
} |
7be994138 dcbnl: Shorten al... |
665 666 |
static int dcbnl_setstate(struct net_device *netdev, struct nlmsghdr *nlh, u32 seq, struct nlattr **tb, struct sk_buff *skb) |
2f90b8657 ixgbe: this patch... |
667 |
{ |
2f90b8657 ixgbe: this patch... |
668 |
u8 value; |
3d1f48695 dcbnl: Return con... |
669 |
if (!tb[DCB_ATTR_STATE]) |
7be994138 dcbnl: Shorten al... |
670 |
return -EINVAL; |
2f90b8657 ixgbe: this patch... |
671 |
|
3d1f48695 dcbnl: Return con... |
672 673 |
if (!netdev->dcbnl_ops->setstate) return -EOPNOTSUPP; |
2f90b8657 ixgbe: this patch... |
674 |
value = nla_get_u8(tb[DCB_ATTR_STATE]); |
7be994138 dcbnl: Shorten al... |
675 676 |
return nla_put_u8(skb, DCB_ATTR_STATE, netdev->dcbnl_ops->setstate(netdev, value)); |
2f90b8657 ixgbe: this patch... |
677 |
} |
7be994138 dcbnl: Shorten al... |
678 679 |
static int dcbnl_setpfccfg(struct net_device *netdev, struct nlmsghdr *nlh, u32 seq, struct nlattr **tb, struct sk_buff *skb) |
2f90b8657 ixgbe: this patch... |
680 681 682 |
{ struct nlattr *data[DCB_PFC_UP_ATTR_MAX + 1]; int i; |
3d1f48695 dcbnl: Return con... |
683 |
int ret; |
2f90b8657 ixgbe: this patch... |
684 |
u8 value; |
3d1f48695 dcbnl: Return con... |
685 686 687 688 689 |
if (!tb[DCB_ATTR_PFC_CFG]) return -EINVAL; if (!netdev->dcbnl_ops->setpfccfg) return -EOPNOTSUPP; |
2f90b8657 ixgbe: this patch... |
690 691 692 693 694 |
ret = nla_parse_nested(data, DCB_PFC_UP_ATTR_MAX, tb[DCB_ATTR_PFC_CFG], dcbnl_pfc_up_nest); if (ret) |
3d1f48695 dcbnl: Return con... |
695 |
return ret; |
2f90b8657 ixgbe: this patch... |
696 697 698 699 700 701 702 703 |
for (i = DCB_PFC_UP_ATTR_0; i <= DCB_PFC_UP_ATTR_7; i++) { if (data[i] == NULL) continue; value = nla_get_u8(data[i]); netdev->dcbnl_ops->setpfccfg(netdev, data[i]->nla_type - DCB_PFC_UP_ATTR_0, value); } |
7be994138 dcbnl: Shorten al... |
704 |
return nla_put_u8(skb, DCB_ATTR_PFC_CFG, 0); |
2f90b8657 ixgbe: this patch... |
705 |
} |
7be994138 dcbnl: Shorten al... |
706 707 |
static int dcbnl_setall(struct net_device *netdev, struct nlmsghdr *nlh, u32 seq, struct nlattr **tb, struct sk_buff *skb) |
2f90b8657 ixgbe: this patch... |
708 |
{ |
3d1f48695 dcbnl: Return con... |
709 |
int ret; |
2f90b8657 ixgbe: this patch... |
710 |
|
3d1f48695 dcbnl: Return con... |
711 712 713 714 715 |
if (!tb[DCB_ATTR_SET_ALL]) return -EINVAL; if (!netdev->dcbnl_ops->setall) return -EOPNOTSUPP; |
2f90b8657 ixgbe: this patch... |
716 |
|
7be994138 dcbnl: Shorten al... |
717 718 |
ret = nla_put_u8(skb, DCB_ATTR_SET_ALL, netdev->dcbnl_ops->setall(netdev)); |
081579840 net: dcb: add CEE... |
719 |
dcbnl_cee_notify(netdev, RTM_SETDCB, DCB_CMD_SET_ALL, seq, 0); |
2f90b8657 ixgbe: this patch... |
720 721 722 |
return ret; } |
7be994138 dcbnl: Shorten al... |
723 724 725 |
static int __dcbnl_pg_setcfg(struct net_device *netdev, struct nlmsghdr *nlh, u32 seq, struct nlattr **tb, struct sk_buff *skb, int dir) |
2f90b8657 ixgbe: this patch... |
726 727 728 |
{ struct nlattr *pg_tb[DCB_PG_ATTR_MAX + 1]; struct nlattr *param_tb[DCB_TC_ATTR_PARAM_MAX + 1]; |
3d1f48695 dcbnl: Return con... |
729 |
int ret; |
2f90b8657 ixgbe: this patch... |
730 731 732 733 734 |
int i; u8 pgid; u8 up_map; u8 prio; u8 tc_pct; |
3d1f48695 dcbnl: Return con... |
735 736 737 738 |
if (!tb[DCB_ATTR_PG_CFG]) return -EINVAL; if (!netdev->dcbnl_ops->setpgtccfgtx || |
2f90b8657 ixgbe: this patch... |
739 740 741 |
!netdev->dcbnl_ops->setpgtccfgrx || !netdev->dcbnl_ops->setpgbwgcfgtx || !netdev->dcbnl_ops->setpgbwgcfgrx) |
3d1f48695 dcbnl: Return con... |
742 |
return -EOPNOTSUPP; |
2f90b8657 ixgbe: this patch... |
743 744 745 746 |
ret = nla_parse_nested(pg_tb, DCB_PG_ATTR_MAX, tb[DCB_ATTR_PG_CFG], dcbnl_pg_nest); if (ret) |
3d1f48695 dcbnl: Return con... |
747 |
return ret; |
2f90b8657 ixgbe: this patch... |
748 749 750 751 752 753 754 755 |
for (i = DCB_PG_ATTR_TC_0; i <= DCB_PG_ATTR_TC_7; i++) { if (!pg_tb[i]) continue; ret = nla_parse_nested(param_tb, DCB_TC_ATTR_PARAM_MAX, pg_tb[i], dcbnl_tc_param_nest); if (ret) |
3d1f48695 dcbnl: Return con... |
756 |
return ret; |
2f90b8657 ixgbe: this patch... |
757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 |
pgid = DCB_ATTR_VALUE_UNDEFINED; prio = DCB_ATTR_VALUE_UNDEFINED; tc_pct = DCB_ATTR_VALUE_UNDEFINED; up_map = DCB_ATTR_VALUE_UNDEFINED; if (param_tb[DCB_TC_ATTR_PARAM_STRICT_PRIO]) prio = nla_get_u8(param_tb[DCB_TC_ATTR_PARAM_STRICT_PRIO]); if (param_tb[DCB_TC_ATTR_PARAM_PGID]) pgid = nla_get_u8(param_tb[DCB_TC_ATTR_PARAM_PGID]); if (param_tb[DCB_TC_ATTR_PARAM_BW_PCT]) tc_pct = nla_get_u8(param_tb[DCB_TC_ATTR_PARAM_BW_PCT]); if (param_tb[DCB_TC_ATTR_PARAM_UP_MAPPING]) up_map = nla_get_u8(param_tb[DCB_TC_ATTR_PARAM_UP_MAPPING]); /* dir: Tx = 0, Rx = 1 */ if (dir) { /* Rx */ netdev->dcbnl_ops->setpgtccfgrx(netdev, i - DCB_PG_ATTR_TC_0, prio, pgid, tc_pct, up_map); } else { /* Tx */ netdev->dcbnl_ops->setpgtccfgtx(netdev, i - DCB_PG_ATTR_TC_0, prio, pgid, tc_pct, up_map); } } for (i = DCB_PG_ATTR_BW_ID_0; i <= DCB_PG_ATTR_BW_ID_7; i++) { if (!pg_tb[i]) continue; tc_pct = nla_get_u8(pg_tb[i]); /* dir: Tx = 0, Rx = 1 */ if (dir) { /* Rx */ netdev->dcbnl_ops->setpgbwgcfgrx(netdev, i - DCB_PG_ATTR_BW_ID_0, tc_pct); } else { /* Tx */ netdev->dcbnl_ops->setpgbwgcfgtx(netdev, i - DCB_PG_ATTR_BW_ID_0, tc_pct); } } |
bb1dfefdc net: dcb: fix sma... |
808 |
return nla_put_u8(skb, DCB_ATTR_PG_CFG, 0); |
2f90b8657 ixgbe: this patch... |
809 |
} |
7be994138 dcbnl: Shorten al... |
810 811 |
static int dcbnl_pgtx_setcfg(struct net_device *netdev, struct nlmsghdr *nlh, u32 seq, struct nlattr **tb, struct sk_buff *skb) |
2f90b8657 ixgbe: this patch... |
812 |
{ |
7be994138 dcbnl: Shorten al... |
813 |
return __dcbnl_pg_setcfg(netdev, nlh, seq, tb, skb, 0); |
2f90b8657 ixgbe: this patch... |
814 |
} |
7be994138 dcbnl: Shorten al... |
815 816 |
static int dcbnl_pgrx_setcfg(struct net_device *netdev, struct nlmsghdr *nlh, u32 seq, struct nlattr **tb, struct sk_buff *skb) |
2f90b8657 ixgbe: this patch... |
817 |
{ |
7be994138 dcbnl: Shorten al... |
818 |
return __dcbnl_pg_setcfg(netdev, nlh, seq, tb, skb, 1); |
2f90b8657 ixgbe: this patch... |
819 |
} |
7be994138 dcbnl: Shorten al... |
820 821 |
static int dcbnl_bcn_getcfg(struct net_device *netdev, struct nlmsghdr *nlh, u32 seq, struct nlattr **tb, struct sk_buff *skb) |
859ee3c43 DCB: Add support ... |
822 |
{ |
859ee3c43 DCB: Add support ... |
823 824 825 826 |
struct nlattr *bcn_nest; struct nlattr *bcn_tb[DCB_BCN_ATTR_MAX + 1]; u8 value_byte; u32 value_integer; |
3d1f48695 dcbnl: Return con... |
827 |
int ret; |
859ee3c43 DCB: Add support ... |
828 829 |
bool getall = false; int i; |
3d1f48695 dcbnl: Return con... |
830 831 832 833 |
if (!tb[DCB_ATTR_BCN]) return -EINVAL; if (!netdev->dcbnl_ops->getbcnrp || |
859ee3c43 DCB: Add support ... |
834 |
!netdev->dcbnl_ops->getbcncfg) |
3d1f48695 dcbnl: Return con... |
835 |
return -EOPNOTSUPP; |
859ee3c43 DCB: Add support ... |
836 837 838 |
ret = nla_parse_nested(bcn_tb, DCB_BCN_ATTR_MAX, tb[DCB_ATTR_BCN], dcbnl_bcn_nest); |
859ee3c43 DCB: Add support ... |
839 |
if (ret) |
3d1f48695 dcbnl: Return con... |
840 |
return ret; |
859ee3c43 DCB: Add support ... |
841 |
|
7be994138 dcbnl: Shorten al... |
842 |
bcn_nest = nla_nest_start(skb, DCB_ATTR_BCN); |
859ee3c43 DCB: Add support ... |
843 |
if (!bcn_nest) |
3d1f48695 dcbnl: Return con... |
844 |
return -EMSGSIZE; |
859ee3c43 DCB: Add support ... |
845 846 847 848 849 850 851 852 853 854 |
if (bcn_tb[DCB_BCN_ATTR_ALL]) getall = true; for (i = DCB_BCN_ATTR_RP_0; i <= DCB_BCN_ATTR_RP_7; i++) { if (!getall && !bcn_tb[i]) continue; netdev->dcbnl_ops->getbcnrp(netdev, i - DCB_BCN_ATTR_RP_0, &value_byte); |
7be994138 dcbnl: Shorten al... |
855 |
ret = nla_put_u8(skb, i, value_byte); |
859ee3c43 DCB: Add support ... |
856 857 858 |
if (ret) goto err_bcn; } |
f4314e815 net: add DCNA att... |
859 |
for (i = DCB_BCN_ATTR_BCNA_0; i <= DCB_BCN_ATTR_RI; i++) { |
859ee3c43 DCB: Add support ... |
860 861 862 863 864 |
if (!getall && !bcn_tb[i]) continue; netdev->dcbnl_ops->getbcncfg(netdev, i, &value_integer); |
7be994138 dcbnl: Shorten al... |
865 |
ret = nla_put_u32(skb, i, value_integer); |
859ee3c43 DCB: Add support ... |
866 867 868 |
if (ret) goto err_bcn; } |
7be994138 dcbnl: Shorten al... |
869 |
nla_nest_end(skb, bcn_nest); |
859ee3c43 DCB: Add support ... |
870 871 872 873 |
return 0; err_bcn: |
7be994138 dcbnl: Shorten al... |
874 |
nla_nest_cancel(skb, bcn_nest); |
859ee3c43 DCB: Add support ... |
875 876 |
return ret; } |
7be994138 dcbnl: Shorten al... |
877 878 |
static int dcbnl_bcn_setcfg(struct net_device *netdev, struct nlmsghdr *nlh, u32 seq, struct nlattr **tb, struct sk_buff *skb) |
859ee3c43 DCB: Add support ... |
879 880 881 |
{ struct nlattr *data[DCB_BCN_ATTR_MAX + 1]; int i; |
3d1f48695 dcbnl: Return con... |
882 |
int ret; |
859ee3c43 DCB: Add support ... |
883 884 |
u8 value_byte; u32 value_int; |
3d1f48695 dcbnl: Return con... |
885 886 887 888 |
if (!tb[DCB_ATTR_BCN]) return -EINVAL; if (!netdev->dcbnl_ops->setbcncfg || |
f64f9e719 net: Move && and ... |
889 |
!netdev->dcbnl_ops->setbcnrp) |
3d1f48695 dcbnl: Return con... |
890 |
return -EOPNOTSUPP; |
859ee3c43 DCB: Add support ... |
891 892 893 894 895 |
ret = nla_parse_nested(data, DCB_BCN_ATTR_MAX, tb[DCB_ATTR_BCN], dcbnl_pfc_up_nest); if (ret) |
3d1f48695 dcbnl: Return con... |
896 |
return ret; |
859ee3c43 DCB: Add support ... |
897 898 899 900 901 902 903 904 |
for (i = DCB_BCN_ATTR_RP_0; i <= DCB_BCN_ATTR_RP_7; i++) { if (data[i] == NULL) continue; value_byte = nla_get_u8(data[i]); netdev->dcbnl_ops->setbcnrp(netdev, data[i]->nla_type - DCB_BCN_ATTR_RP_0, value_byte); } |
f4314e815 net: add DCNA att... |
905 |
for (i = DCB_BCN_ATTR_BCNA_0; i <= DCB_BCN_ATTR_RI; i++) { |
859ee3c43 DCB: Add support ... |
906 907 908 909 910 911 |
if (data[i] == NULL) continue; value_int = nla_get_u32(data[i]); netdev->dcbnl_ops->setbcncfg(netdev, i, value_int); } |
3d1f48695 dcbnl: Return con... |
912 |
return nla_put_u8(skb, DCB_ATTR_BCN, 0); |
859ee3c43 DCB: Add support ... |
913 |
} |
dc6ed1df5 dcbnl: add suppor... |
914 915 916 |
static int dcbnl_build_peer_app(struct net_device *netdev, struct sk_buff* skb, int app_nested_type, int app_info_type, int app_entry_type) |
eed84713b dcbnl: add suppor... |
917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 |
{ struct dcb_peer_app_info info; struct dcb_app *table = NULL; const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops; u16 app_count; int err; /** * retrieve the peer app configuration form the driver. If the driver * handlers fail exit without doing anything */ err = ops->peer_getappinfo(netdev, &info, &app_count); if (!err && app_count) { table = kmalloc(sizeof(struct dcb_app) * app_count, GFP_KERNEL); if (!table) return -ENOMEM; err = ops->peer_getapptable(netdev, table); } if (!err) { u16 i; struct nlattr *app; /** * build the message, from here on the only possible failure * is due to the skb size */ err = -EMSGSIZE; |
dc6ed1df5 dcbnl: add suppor... |
947 |
app = nla_nest_start(skb, app_nested_type); |
eed84713b dcbnl: add suppor... |
948 949 |
if (!app) goto nla_put_failure; |
1eb4c9777 dcbnl: Stop using... |
950 951 952 |
if (app_info_type && nla_put(skb, app_info_type, sizeof(info), &info)) goto nla_put_failure; |
eed84713b dcbnl: add suppor... |
953 |
|
1eb4c9777 dcbnl: Stop using... |
954 955 956 957 958 |
for (i = 0; i < app_count; i++) { if (nla_put(skb, app_entry_type, sizeof(struct dcb_app), &table[i])) goto nla_put_failure; } |
eed84713b dcbnl: add suppor... |
959 960 961 962 963 964 965 966 |
nla_nest_end(skb, app); } err = 0; nla_put_failure: kfree(table); return err; } |
3e29027af dcbnl: add suppor... |
967 |
|
c93682477 net/dcb: Add IEEE... |
968 |
/* Handle IEEE 802.1Qaz/802.1Qau/802.1Qbb GET commands. */ |
314b4778e net: dcbnl, add m... |
969 |
static int dcbnl_ieee_fill(struct sk_buff *skb, struct net_device *netdev) |
3e29027af dcbnl: add suppor... |
970 |
{ |
9ab933ab2 dcbnl: add applic... |
971 972 |
struct nlattr *ieee, *app; struct dcb_app_type *itr; |
3e29027af dcbnl: add suppor... |
973 |
const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops; |
c7797baf9 dcb: Add DCBX cap... |
974 |
int dcbx; |
3d1f48695 dcbnl: Return con... |
975 |
int err; |
3e29027af dcbnl: add suppor... |
976 |
|
1eb4c9777 dcbnl: Stop using... |
977 |
if (nla_put_string(skb, DCB_ATTR_IFNAME, netdev->name)) |
3d1f48695 dcbnl: Return con... |
978 |
return -EMSGSIZE; |
3e29027af dcbnl: add suppor... |
979 980 |
ieee = nla_nest_start(skb, DCB_ATTR_IEEE); if (!ieee) |
3d1f48695 dcbnl: Return con... |
981 |
return -EMSGSIZE; |
3e29027af dcbnl: add suppor... |
982 983 984 |
if (ops->ieee_getets) { struct ieee_ets ets; |
29cd8ae0e dcbnl: fix variou... |
985 |
memset(&ets, 0, sizeof(ets)); |
3e29027af dcbnl: add suppor... |
986 |
err = ops->ieee_getets(netdev, &ets); |
1eb4c9777 dcbnl: Stop using... |
987 988 |
if (!err && nla_put(skb, DCB_ATTR_IEEE_ETS, sizeof(ets), &ets)) |
3d1f48695 dcbnl: Return con... |
989 |
return -EMSGSIZE; |
3e29027af dcbnl: add suppor... |
990 |
} |
08f10affe net/dcb: Add an o... |
991 992 |
if (ops->ieee_getmaxrate) { struct ieee_maxrate maxrate; |
29cd8ae0e dcbnl: fix variou... |
993 |
memset(&maxrate, 0, sizeof(maxrate)); |
08f10affe net/dcb: Add an o... |
994 995 996 997 998 |
err = ops->ieee_getmaxrate(netdev, &maxrate); if (!err) { err = nla_put(skb, DCB_ATTR_IEEE_MAXRATE, sizeof(maxrate), &maxrate); if (err) |
3d1f48695 dcbnl: Return con... |
999 |
return -EMSGSIZE; |
08f10affe net/dcb: Add an o... |
1000 1001 |
} } |
c93682477 net/dcb: Add IEEE... |
1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 |
if (ops->ieee_getqcn) { struct ieee_qcn qcn; memset(&qcn, 0, sizeof(qcn)); err = ops->ieee_getqcn(netdev, &qcn); if (!err) { err = nla_put(skb, DCB_ATTR_IEEE_QCN, sizeof(qcn), &qcn); if (err) return -EMSGSIZE; } } if (ops->ieee_getqcnstats) { struct ieee_qcn_stats qcn_stats; memset(&qcn_stats, 0, sizeof(qcn_stats)); err = ops->ieee_getqcnstats(netdev, &qcn_stats); if (!err) { err = nla_put(skb, DCB_ATTR_IEEE_QCN_STATS, sizeof(qcn_stats), &qcn_stats); if (err) return -EMSGSIZE; } } |
3e29027af dcbnl: add suppor... |
1027 1028 |
if (ops->ieee_getpfc) { struct ieee_pfc pfc; |
29cd8ae0e dcbnl: fix variou... |
1029 |
memset(&pfc, 0, sizeof(pfc)); |
3e29027af dcbnl: add suppor... |
1030 |
err = ops->ieee_getpfc(netdev, &pfc); |
1eb4c9777 dcbnl: Stop using... |
1031 1032 |
if (!err && nla_put(skb, DCB_ATTR_IEEE_PFC, sizeof(pfc), &pfc)) |
3d1f48695 dcbnl: Return con... |
1033 |
return -EMSGSIZE; |
3e29027af dcbnl: add suppor... |
1034 |
} |
9ab933ab2 dcbnl: add applic... |
1035 1036 |
app = nla_nest_start(skb, DCB_ATTR_IEEE_APP_TABLE); if (!app) |
3d1f48695 dcbnl: Return con... |
1037 |
return -EMSGSIZE; |
9ab933ab2 dcbnl: add applic... |
1038 |
|
52cff74ee dcbnl : Disable s... |
1039 |
spin_lock_bh(&dcb_lock); |
9ab933ab2 dcbnl: add applic... |
1040 |
list_for_each_entry(itr, &dcb_app_list, list) { |
e290ed813 dcb: Use ifindex ... |
1041 |
if (itr->ifindex == netdev->ifindex) { |
70bfa2d2e dcb: unlock on er... |
1042 1043 1044 |
err = nla_put(skb, DCB_ATTR_IEEE_APP, sizeof(itr->app), &itr->app); if (err) { |
52cff74ee dcbnl : Disable s... |
1045 |
spin_unlock_bh(&dcb_lock); |
3d1f48695 dcbnl: Return con... |
1046 |
return -EMSGSIZE; |
70bfa2d2e dcb: unlock on er... |
1047 1048 |
} } |
9ab933ab2 dcbnl: add applic... |
1049 |
} |
c7797baf9 dcb: Add DCBX cap... |
1050 1051 1052 1053 1054 |
if (netdev->dcbnl_ops->getdcbx) dcbx = netdev->dcbnl_ops->getdcbx(netdev); else dcbx = -EOPNOTSUPP; |
52cff74ee dcbnl : Disable s... |
1055 |
spin_unlock_bh(&dcb_lock); |
9ab933ab2 dcbnl: add applic... |
1056 |
nla_nest_end(skb, app); |
eed84713b dcbnl: add suppor... |
1057 1058 1059 |
/* get peer info if available */ if (ops->ieee_peer_getets) { struct ieee_ets ets; |
29cd8ae0e dcbnl: fix variou... |
1060 |
memset(&ets, 0, sizeof(ets)); |
eed84713b dcbnl: add suppor... |
1061 |
err = ops->ieee_peer_getets(netdev, &ets); |
1eb4c9777 dcbnl: Stop using... |
1062 1063 |
if (!err && nla_put(skb, DCB_ATTR_IEEE_PEER_ETS, sizeof(ets), &ets)) |
3d1f48695 dcbnl: Return con... |
1064 |
return -EMSGSIZE; |
eed84713b dcbnl: add suppor... |
1065 1066 1067 1068 |
} if (ops->ieee_peer_getpfc) { struct ieee_pfc pfc; |
29cd8ae0e dcbnl: fix variou... |
1069 |
memset(&pfc, 0, sizeof(pfc)); |
eed84713b dcbnl: add suppor... |
1070 |
err = ops->ieee_peer_getpfc(netdev, &pfc); |
1eb4c9777 dcbnl: Stop using... |
1071 1072 |
if (!err && nla_put(skb, DCB_ATTR_IEEE_PEER_PFC, sizeof(pfc), &pfc)) |
3d1f48695 dcbnl: Return con... |
1073 |
return -EMSGSIZE; |
eed84713b dcbnl: add suppor... |
1074 1075 1076 |
} if (ops->peer_getappinfo && ops->peer_getapptable) { |
dc6ed1df5 dcbnl: add suppor... |
1077 1078 1079 1080 |
err = dcbnl_build_peer_app(netdev, skb, DCB_ATTR_IEEE_PEER_APP, DCB_ATTR_IEEE_APP_UNSPEC, DCB_ATTR_IEEE_APP); |
eed84713b dcbnl: add suppor... |
1081 |
if (err) |
3d1f48695 dcbnl: Return con... |
1082 |
return -EMSGSIZE; |
eed84713b dcbnl: add suppor... |
1083 |
} |
3e29027af dcbnl: add suppor... |
1084 |
nla_nest_end(skb, ieee); |
c7797baf9 dcb: Add DCBX cap... |
1085 1086 1087 |
if (dcbx >= 0) { err = nla_put_u8(skb, DCB_ATTR_DCBX, dcbx); if (err) |
3d1f48695 dcbnl: Return con... |
1088 |
return -EMSGSIZE; |
c7797baf9 dcb: Add DCBX cap... |
1089 |
} |
3e29027af dcbnl: add suppor... |
1090 |
|
314b4778e net: dcbnl, add m... |
1091 |
return 0; |
3e29027af dcbnl: add suppor... |
1092 |
} |
5b7f76267 dcbnl: Add CEE no... |
1093 1094 1095 1096 1097 1098 1099 1100 1101 |
static int dcbnl_cee_pg_fill(struct sk_buff *skb, struct net_device *dev, int dir) { u8 pgid, up_map, prio, tc_pct; const struct dcbnl_rtnl_ops *ops = dev->dcbnl_ops; int i = dir ? DCB_ATTR_CEE_TX_PG : DCB_ATTR_CEE_RX_PG; struct nlattr *pg = nla_nest_start(skb, i); if (!pg) |
3d1f48695 dcbnl: Return con... |
1102 |
return -EMSGSIZE; |
5b7f76267 dcbnl: Add CEE no... |
1103 1104 1105 1106 1107 |
for (i = DCB_PG_ATTR_TC_0; i <= DCB_PG_ATTR_TC_7; i++) { struct nlattr *tc_nest = nla_nest_start(skb, i); if (!tc_nest) |
3d1f48695 dcbnl: Return con... |
1108 |
return -EMSGSIZE; |
5b7f76267 dcbnl: Add CEE no... |
1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 |
pgid = DCB_ATTR_VALUE_UNDEFINED; prio = DCB_ATTR_VALUE_UNDEFINED; tc_pct = DCB_ATTR_VALUE_UNDEFINED; up_map = DCB_ATTR_VALUE_UNDEFINED; if (!dir) ops->getpgtccfgrx(dev, i - DCB_PG_ATTR_TC_0, &prio, &pgid, &tc_pct, &up_map); else ops->getpgtccfgtx(dev, i - DCB_PG_ATTR_TC_0, &prio, &pgid, &tc_pct, &up_map); |
1eb4c9777 dcbnl: Stop using... |
1121 1122 1123 1124 |
if (nla_put_u8(skb, DCB_TC_ATTR_PARAM_PGID, pgid) || nla_put_u8(skb, DCB_TC_ATTR_PARAM_UP_MAPPING, up_map) || nla_put_u8(skb, DCB_TC_ATTR_PARAM_STRICT_PRIO, prio) || nla_put_u8(skb, DCB_TC_ATTR_PARAM_BW_PCT, tc_pct)) |
3d1f48695 dcbnl: Return con... |
1125 |
return -EMSGSIZE; |
5b7f76267 dcbnl: Add CEE no... |
1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 |
nla_nest_end(skb, tc_nest); } for (i = DCB_PG_ATTR_BW_ID_0; i <= DCB_PG_ATTR_BW_ID_7; i++) { tc_pct = DCB_ATTR_VALUE_UNDEFINED; if (!dir) ops->getpgbwgcfgrx(dev, i - DCB_PG_ATTR_BW_ID_0, &tc_pct); else ops->getpgbwgcfgtx(dev, i - DCB_PG_ATTR_BW_ID_0, &tc_pct); |
1eb4c9777 dcbnl: Stop using... |
1138 |
if (nla_put_u8(skb, i, tc_pct)) |
3d1f48695 dcbnl: Return con... |
1139 |
return -EMSGSIZE; |
5b7f76267 dcbnl: Add CEE no... |
1140 1141 1142 |
} nla_nest_end(skb, pg); return 0; |
5b7f76267 dcbnl: Add CEE no... |
1143 1144 1145 1146 1147 1148 1149 1150 1151 |
} static int dcbnl_cee_fill(struct sk_buff *skb, struct net_device *netdev) { struct nlattr *cee, *app; struct dcb_app_type *itr; const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops; int dcbx, i, err = -EMSGSIZE; u8 value; |
1eb4c9777 dcbnl: Stop using... |
1152 1153 |
if (nla_put_string(skb, DCB_ATTR_IFNAME, netdev->name)) goto nla_put_failure; |
5b7f76267 dcbnl: Add CEE no... |
1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 |
cee = nla_nest_start(skb, DCB_ATTR_CEE); if (!cee) goto nla_put_failure; /* local pg */ if (ops->getpgtccfgtx && ops->getpgbwgcfgtx) { err = dcbnl_cee_pg_fill(skb, netdev, 1); if (err) goto nla_put_failure; } if (ops->getpgtccfgrx && ops->getpgbwgcfgrx) { err = dcbnl_cee_pg_fill(skb, netdev, 0); if (err) goto nla_put_failure; } /* local pfc */ if (ops->getpfccfg) { struct nlattr *pfc_nest = nla_nest_start(skb, DCB_ATTR_CEE_PFC); if (!pfc_nest) goto nla_put_failure; for (i = DCB_PFC_UP_ATTR_0; i <= DCB_PFC_UP_ATTR_7; i++) { ops->getpfccfg(netdev, i - DCB_PFC_UP_ATTR_0, &value); |
1eb4c9777 dcbnl: Stop using... |
1180 1181 |
if (nla_put_u8(skb, i, value)) goto nla_put_failure; |
5b7f76267 dcbnl: Add CEE no... |
1182 1183 1184 1185 1186 |
} nla_nest_end(skb, pfc_nest); } /* local app */ |
52cff74ee dcbnl : Disable s... |
1187 |
spin_lock_bh(&dcb_lock); |
5b7f76267 dcbnl: Add CEE no... |
1188 1189 |
app = nla_nest_start(skb, DCB_ATTR_CEE_APP_TABLE); if (!app) |
40f5d72a4 dcbnl: unlock on ... |
1190 |
goto dcb_unlock; |
5b7f76267 dcbnl: Add CEE no... |
1191 1192 |
list_for_each_entry(itr, &dcb_app_list, list) { |
e290ed813 dcb: Use ifindex ... |
1193 |
if (itr->ifindex == netdev->ifindex) { |
5b7f76267 dcbnl: Add CEE no... |
1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 |
struct nlattr *app_nest = nla_nest_start(skb, DCB_ATTR_APP); if (!app_nest) goto dcb_unlock; err = nla_put_u8(skb, DCB_APP_ATTR_IDTYPE, itr->app.selector); if (err) goto dcb_unlock; err = nla_put_u16(skb, DCB_APP_ATTR_ID, itr->app.protocol); if (err) goto dcb_unlock; err = nla_put_u8(skb, DCB_APP_ATTR_PRIORITY, itr->app.priority); if (err) goto dcb_unlock; nla_nest_end(skb, app_nest); } } nla_nest_end(skb, app); if (netdev->dcbnl_ops->getdcbx) dcbx = netdev->dcbnl_ops->getdcbx(netdev); else dcbx = -EOPNOTSUPP; |
52cff74ee dcbnl : Disable s... |
1223 |
spin_unlock_bh(&dcb_lock); |
5b7f76267 dcbnl: Add CEE no... |
1224 1225 1226 1227 1228 1229 1230 1231 1232 |
/* features flags */ if (ops->getfeatcfg) { struct nlattr *feat = nla_nest_start(skb, DCB_ATTR_CEE_FEAT); if (!feat) goto nla_put_failure; for (i = DCB_FEATCFG_ATTR_ALL + 1; i <= DCB_FEATCFG_ATTR_MAX; i++) |
1eb4c9777 dcbnl: Stop using... |
1233 1234 1235 |
if (!ops->getfeatcfg(netdev, i, &value) && nla_put_u8(skb, i, value)) goto nla_put_failure; |
5b7f76267 dcbnl: Add CEE no... |
1236 1237 1238 1239 1240 1241 1242 |
nla_nest_end(skb, feat); } /* peer info if available */ if (ops->cee_peer_getpg) { struct cee_pg pg; |
29cd8ae0e dcbnl: fix variou... |
1243 |
memset(&pg, 0, sizeof(pg)); |
5b7f76267 dcbnl: Add CEE no... |
1244 |
err = ops->cee_peer_getpg(netdev, &pg); |
1eb4c9777 dcbnl: Stop using... |
1245 1246 1247 |
if (!err && nla_put(skb, DCB_ATTR_CEE_PEER_PG, sizeof(pg), &pg)) goto nla_put_failure; |
5b7f76267 dcbnl: Add CEE no... |
1248 1249 1250 1251 |
} if (ops->cee_peer_getpfc) { struct cee_pfc pfc; |
29cd8ae0e dcbnl: fix variou... |
1252 |
memset(&pfc, 0, sizeof(pfc)); |
5b7f76267 dcbnl: Add CEE no... |
1253 |
err = ops->cee_peer_getpfc(netdev, &pfc); |
1eb4c9777 dcbnl: Stop using... |
1254 1255 1256 |
if (!err && nla_put(skb, DCB_ATTR_CEE_PEER_PFC, sizeof(pfc), &pfc)) goto nla_put_failure; |
5b7f76267 dcbnl: Add CEE no... |
1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 |
} if (ops->peer_getappinfo && ops->peer_getapptable) { err = dcbnl_build_peer_app(netdev, skb, DCB_ATTR_CEE_PEER_APP_TABLE, DCB_ATTR_CEE_PEER_APP_INFO, DCB_ATTR_CEE_PEER_APP); if (err) goto nla_put_failure; } nla_nest_end(skb, cee); /* DCBX state */ if (dcbx >= 0) { err = nla_put_u8(skb, DCB_ATTR_DCBX, dcbx); if (err) goto nla_put_failure; } return 0; dcb_unlock: |
52cff74ee dcbnl : Disable s... |
1278 |
spin_unlock_bh(&dcb_lock); |
5b7f76267 dcbnl: Add CEE no... |
1279 |
nla_put_failure: |
c66ebf2db net: dcb: set err... |
1280 |
err = -EMSGSIZE; |
5b7f76267 dcbnl: Add CEE no... |
1281 1282 1283 1284 |
return err; } static int dcbnl_notify(struct net_device *dev, int event, int cmd, |
15e473046 netlink: Rename p... |
1285 |
u32 seq, u32 portid, int dcbx_ver) |
314b4778e net: dcbnl, add m... |
1286 1287 1288 1289 |
{ struct net *net = dev_net(dev); struct sk_buff *skb; struct nlmsghdr *nlh; |
314b4778e net: dcbnl, add m... |
1290 1291 1292 1293 1294 |
const struct dcbnl_rtnl_ops *ops = dev->dcbnl_ops; int err; if (!ops) return -EOPNOTSUPP; |
15e473046 netlink: Rename p... |
1295 |
skb = dcbnl_newmsg(event, cmd, portid, seq, 0, &nlh); |
314b4778e net: dcbnl, add m... |
1296 1297 |
if (!skb) return -ENOBUFS; |
5b7f76267 dcbnl: Add CEE no... |
1298 1299 1300 1301 |
if (dcbx_ver == DCB_CAP_DCBX_VER_IEEE) err = dcbnl_ieee_fill(skb, dev); else err = dcbnl_cee_fill(skb, dev); |
314b4778e net: dcbnl, add m... |
1302 1303 |
if (err < 0) { /* Report error to broadcast listeners */ |
ab6d47073 dcbnl: Use dcbnl_... |
1304 |
nlmsg_free(skb); |
314b4778e net: dcbnl, add m... |
1305 1306 1307 1308 1309 1310 1311 1312 1313 |
rtnl_set_sk_err(net, RTNLGRP_DCB, err); } else { /* End nlmsg and notify broadcast listeners */ nlmsg_end(skb, nlh); rtnl_notify(skb, net, 0, RTNLGRP_DCB, NULL, GFP_KERNEL); } return err; } |
5b7f76267 dcbnl: Add CEE no... |
1314 1315 |
int dcbnl_ieee_notify(struct net_device *dev, int event, int cmd, |
15e473046 netlink: Rename p... |
1316 |
u32 seq, u32 portid) |
5b7f76267 dcbnl: Add CEE no... |
1317 |
{ |
15e473046 netlink: Rename p... |
1318 |
return dcbnl_notify(dev, event, cmd, seq, portid, DCB_CAP_DCBX_VER_IEEE); |
5b7f76267 dcbnl: Add CEE no... |
1319 1320 1321 1322 |
} EXPORT_SYMBOL(dcbnl_ieee_notify); int dcbnl_cee_notify(struct net_device *dev, int event, int cmd, |
15e473046 netlink: Rename p... |
1323 |
u32 seq, u32 portid) |
5b7f76267 dcbnl: Add CEE no... |
1324 |
{ |
15e473046 netlink: Rename p... |
1325 |
return dcbnl_notify(dev, event, cmd, seq, portid, DCB_CAP_DCBX_VER_CEE); |
5b7f76267 dcbnl: Add CEE no... |
1326 1327 |
} EXPORT_SYMBOL(dcbnl_cee_notify); |
314b4778e net: dcbnl, add m... |
1328 |
|
c93682477 net/dcb: Add IEEE... |
1329 1330 1331 |
/* Handle IEEE 802.1Qaz/802.1Qau/802.1Qbb SET commands. * If any requested operation can not be completed * the entire msg is aborted and error value is returned. |
314b4778e net: dcbnl, add m... |
1332 1333 1334 |
* No attempt is made to reconcile the case where only part of the * cmd can be completed. */ |
7be994138 dcbnl: Shorten al... |
1335 1336 |
static int dcbnl_ieee_set(struct net_device *netdev, struct nlmsghdr *nlh, u32 seq, struct nlattr **tb, struct sk_buff *skb) |
314b4778e net: dcbnl, add m... |
1337 1338 1339 |
{ const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops; struct nlattr *ieee[DCB_ATTR_IEEE_MAX + 1]; |
3d1f48695 dcbnl: Return con... |
1340 |
int err; |
314b4778e net: dcbnl, add m... |
1341 1342 |
if (!ops) |
3d1f48695 dcbnl: Return con... |
1343 |
return -EOPNOTSUPP; |
314b4778e net: dcbnl, add m... |
1344 |
|
4003b6587 dcb: Add missing ... |
1345 1346 |
if (!tb[DCB_ATTR_IEEE]) return -EINVAL; |
314b4778e net: dcbnl, add m... |
1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 |
err = nla_parse_nested(ieee, DCB_ATTR_IEEE_MAX, tb[DCB_ATTR_IEEE], dcbnl_ieee_policy); if (err) return err; if (ieee[DCB_ATTR_IEEE_ETS] && ops->ieee_setets) { struct ieee_ets *ets = nla_data(ieee[DCB_ATTR_IEEE_ETS]); err = ops->ieee_setets(netdev, ets); if (err) goto err; } |
08f10affe net/dcb: Add an o... |
1358 1359 1360 1361 1362 1363 1364 |
if (ieee[DCB_ATTR_IEEE_MAXRATE] && ops->ieee_setmaxrate) { struct ieee_maxrate *maxrate = nla_data(ieee[DCB_ATTR_IEEE_MAXRATE]); err = ops->ieee_setmaxrate(netdev, maxrate); if (err) goto err; } |
c93682477 net/dcb: Add IEEE... |
1365 1366 1367 1368 1369 1370 1371 1372 |
if (ieee[DCB_ATTR_IEEE_QCN] && ops->ieee_setqcn) { struct ieee_qcn *qcn = nla_data(ieee[DCB_ATTR_IEEE_QCN]); err = ops->ieee_setqcn(netdev, qcn); if (err) goto err; } |
314b4778e net: dcbnl, add m... |
1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 |
if (ieee[DCB_ATTR_IEEE_PFC] && ops->ieee_setpfc) { struct ieee_pfc *pfc = nla_data(ieee[DCB_ATTR_IEEE_PFC]); err = ops->ieee_setpfc(netdev, pfc); if (err) goto err; } if (ieee[DCB_ATTR_IEEE_APP_TABLE]) { struct nlattr *attr; int rem; nla_for_each_nested(attr, ieee[DCB_ATTR_IEEE_APP_TABLE], rem) { struct dcb_app *app_data; if (nla_type(attr) != DCB_ATTR_IEEE_APP) continue; app_data = nla_data(attr); if (ops->ieee_setapp) err = ops->ieee_setapp(netdev, app_data); else |
b6db2174c dcb: Add ieee_dcb... |
1392 |
err = dcb_ieee_setapp(netdev, app_data); |
314b4778e net: dcbnl, add m... |
1393 1394 1395 1396 1397 1398 |
if (err) goto err; } } err: |
7be994138 dcbnl: Shorten al... |
1399 |
err = nla_put_u8(skb, DCB_ATTR_IEEE, err); |
5b7f76267 dcbnl: Add CEE no... |
1400 |
dcbnl_ieee_notify(netdev, RTM_SETDCB, DCB_CMD_IEEE_SET, seq, 0); |
314b4778e net: dcbnl, add m... |
1401 1402 |
return err; } |
7be994138 dcbnl: Shorten al... |
1403 1404 |
static int dcbnl_ieee_get(struct net_device *netdev, struct nlmsghdr *nlh, u32 seq, struct nlattr **tb, struct sk_buff *skb) |
314b4778e net: dcbnl, add m... |
1405 |
{ |
314b4778e net: dcbnl, add m... |
1406 |
const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops; |
314b4778e net: dcbnl, add m... |
1407 1408 1409 |
if (!ops) return -EOPNOTSUPP; |
7be994138 dcbnl: Shorten al... |
1410 |
return dcbnl_ieee_fill(skb, netdev); |
314b4778e net: dcbnl, add m... |
1411 |
} |
f9ae7e4b5 dcb: Add ieee_dcb... |
1412 |
|
7be994138 dcbnl: Shorten al... |
1413 1414 |
static int dcbnl_ieee_del(struct net_device *netdev, struct nlmsghdr *nlh, u32 seq, struct nlattr **tb, struct sk_buff *skb) |
f9ae7e4b5 dcb: Add ieee_dcb... |
1415 1416 1417 |
{ const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops; struct nlattr *ieee[DCB_ATTR_IEEE_MAX + 1]; |
3d1f48695 dcbnl: Return con... |
1418 |
int err; |
f9ae7e4b5 dcb: Add ieee_dcb... |
1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 |
if (!ops) return -EOPNOTSUPP; if (!tb[DCB_ATTR_IEEE]) return -EINVAL; err = nla_parse_nested(ieee, DCB_ATTR_IEEE_MAX, tb[DCB_ATTR_IEEE], dcbnl_ieee_policy); if (err) return err; if (ieee[DCB_ATTR_IEEE_APP_TABLE]) { struct nlattr *attr; int rem; nla_for_each_nested(attr, ieee[DCB_ATTR_IEEE_APP_TABLE], rem) { struct dcb_app *app_data; if (nla_type(attr) != DCB_ATTR_IEEE_APP) continue; app_data = nla_data(attr); if (ops->ieee_delapp) err = ops->ieee_delapp(netdev, app_data); else err = dcb_ieee_delapp(netdev, app_data); if (err) goto err; } } err: |
7be994138 dcbnl: Shorten al... |
1451 |
err = nla_put_u8(skb, DCB_ATTR_IEEE, err); |
5b7f76267 dcbnl: Add CEE no... |
1452 |
dcbnl_ieee_notify(netdev, RTM_SETDCB, DCB_CMD_IEEE_DEL, seq, 0); |
f9ae7e4b5 dcb: Add ieee_dcb... |
1453 1454 |
return err; } |
6241b6259 dcbnl: adding DCB... |
1455 |
/* DCBX configuration */ |
7be994138 dcbnl: Shorten al... |
1456 1457 |
static int dcbnl_getdcbx(struct net_device *netdev, struct nlmsghdr *nlh, u32 seq, struct nlattr **tb, struct sk_buff *skb) |
6241b6259 dcbnl: adding DCB... |
1458 |
{ |
6241b6259 dcbnl: adding DCB... |
1459 |
if (!netdev->dcbnl_ops->getdcbx) |
7f891cf1f dcbnl: more infor... |
1460 |
return -EOPNOTSUPP; |
6241b6259 dcbnl: adding DCB... |
1461 |
|
7be994138 dcbnl: Shorten al... |
1462 1463 |
return nla_put_u8(skb, DCB_ATTR_DCBX, netdev->dcbnl_ops->getdcbx(netdev)); |
6241b6259 dcbnl: adding DCB... |
1464 |
} |
7be994138 dcbnl: Shorten al... |
1465 1466 |
static int dcbnl_setdcbx(struct net_device *netdev, struct nlmsghdr *nlh, u32 seq, struct nlattr **tb, struct sk_buff *skb) |
6241b6259 dcbnl: adding DCB... |
1467 |
{ |
6241b6259 dcbnl: adding DCB... |
1468 |
u8 value; |
7f891cf1f dcbnl: more infor... |
1469 1470 1471 1472 1473 |
if (!netdev->dcbnl_ops->setdcbx) return -EOPNOTSUPP; if (!tb[DCB_ATTR_DCBX]) return -EINVAL; |
6241b6259 dcbnl: adding DCB... |
1474 1475 |
value = nla_get_u8(tb[DCB_ATTR_DCBX]); |
7be994138 dcbnl: Shorten al... |
1476 1477 |
return nla_put_u8(skb, DCB_ATTR_DCBX, netdev->dcbnl_ops->setdcbx(netdev, value)); |
6241b6259 dcbnl: adding DCB... |
1478 |
} |
7be994138 dcbnl: Shorten al... |
1479 1480 |
static int dcbnl_getfeatcfg(struct net_device *netdev, struct nlmsghdr *nlh, u32 seq, struct nlattr **tb, struct sk_buff *skb) |
ea45fe4e1 dcbnl: adding DCB... |
1481 |
{ |
ea45fe4e1 dcbnl: adding DCB... |
1482 1483 |
struct nlattr *data[DCB_FEATCFG_ATTR_MAX + 1], *nest; u8 value; |
7f891cf1f dcbnl: more infor... |
1484 |
int ret, i; |
ea45fe4e1 dcbnl: adding DCB... |
1485 |
int getall = 0; |
7f891cf1f dcbnl: more infor... |
1486 1487 1488 1489 1490 |
if (!netdev->dcbnl_ops->getfeatcfg) return -EOPNOTSUPP; if (!tb[DCB_ATTR_FEATCFG]) return -EINVAL; |
ea45fe4e1 dcbnl: adding DCB... |
1491 1492 1493 |
ret = nla_parse_nested(data, DCB_FEATCFG_ATTR_MAX, tb[DCB_ATTR_FEATCFG], dcbnl_featcfg_nest); |
7f891cf1f dcbnl: more infor... |
1494 |
if (ret) |
7be994138 dcbnl: Shorten al... |
1495 |
return ret; |
ea45fe4e1 dcbnl: adding DCB... |
1496 |
|
7be994138 dcbnl: Shorten al... |
1497 1498 1499 |
nest = nla_nest_start(skb, DCB_ATTR_FEATCFG); if (!nest) return -EMSGSIZE; |
ea45fe4e1 dcbnl: adding DCB... |
1500 1501 1502 1503 1504 1505 1506 1507 1508 |
if (data[DCB_FEATCFG_ATTR_ALL]) getall = 1; for (i = DCB_FEATCFG_ATTR_ALL+1; i <= DCB_FEATCFG_ATTR_MAX; i++) { if (!getall && !data[i]) continue; ret = netdev->dcbnl_ops->getfeatcfg(netdev, i, &value); |
7f891cf1f dcbnl: more infor... |
1509 |
if (!ret) |
7be994138 dcbnl: Shorten al... |
1510 |
ret = nla_put_u8(skb, i, value); |
ea45fe4e1 dcbnl: adding DCB... |
1511 |
|
7f891cf1f dcbnl: more infor... |
1512 |
if (ret) { |
7be994138 dcbnl: Shorten al... |
1513 |
nla_nest_cancel(skb, nest); |
7f891cf1f dcbnl: more infor... |
1514 1515 |
goto nla_put_failure; } |
ea45fe4e1 dcbnl: adding DCB... |
1516 |
} |
7be994138 dcbnl: Shorten al... |
1517 |
nla_nest_end(skb, nest); |
ea45fe4e1 dcbnl: adding DCB... |
1518 |
|
7f891cf1f dcbnl: more infor... |
1519 |
nla_put_failure: |
ea45fe4e1 dcbnl: adding DCB... |
1520 1521 |
return ret; } |
7be994138 dcbnl: Shorten al... |
1522 1523 |
static int dcbnl_setfeatcfg(struct net_device *netdev, struct nlmsghdr *nlh, u32 seq, struct nlattr **tb, struct sk_buff *skb) |
ea45fe4e1 dcbnl: adding DCB... |
1524 1525 |
{ struct nlattr *data[DCB_FEATCFG_ATTR_MAX + 1]; |
7f891cf1f dcbnl: more infor... |
1526 |
int ret, i; |
ea45fe4e1 dcbnl: adding DCB... |
1527 |
u8 value; |
ea45fe4e1 dcbnl: adding DCB... |
1528 |
|
7f891cf1f dcbnl: more infor... |
1529 1530 1531 1532 1533 |
if (!netdev->dcbnl_ops->setfeatcfg) return -ENOTSUPP; if (!tb[DCB_ATTR_FEATCFG]) return -EINVAL; |
ea45fe4e1 dcbnl: adding DCB... |
1534 1535 1536 |
ret = nla_parse_nested(data, DCB_FEATCFG_ATTR_MAX, tb[DCB_ATTR_FEATCFG], dcbnl_featcfg_nest); |
7f891cf1f dcbnl: more infor... |
1537 |
if (ret) |
ea45fe4e1 dcbnl: adding DCB... |
1538 |
goto err; |
ea45fe4e1 dcbnl: adding DCB... |
1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 |
for (i = DCB_FEATCFG_ATTR_ALL+1; i <= DCB_FEATCFG_ATTR_MAX; i++) { if (data[i] == NULL) continue; value = nla_get_u8(data[i]); ret = netdev->dcbnl_ops->setfeatcfg(netdev, i, value); if (ret) |
7f891cf1f dcbnl: more infor... |
1549 |
goto err; |
ea45fe4e1 dcbnl: adding DCB... |
1550 |
} |
ea45fe4e1 dcbnl: adding DCB... |
1551 |
err: |
7be994138 dcbnl: Shorten al... |
1552 |
ret = nla_put_u8(skb, DCB_ATTR_FEATCFG, ret); |
7f891cf1f dcbnl: more infor... |
1553 |
|
ea45fe4e1 dcbnl: adding DCB... |
1554 1555 |
return ret; } |
dc6ed1df5 dcbnl: add suppor... |
1556 |
/* Handle CEE DCBX GET commands. */ |
7be994138 dcbnl: Shorten al... |
1557 1558 |
static int dcbnl_cee_get(struct net_device *netdev, struct nlmsghdr *nlh, u32 seq, struct nlattr **tb, struct sk_buff *skb) |
dc6ed1df5 dcbnl: add suppor... |
1559 |
{ |
dc6ed1df5 dcbnl: add suppor... |
1560 |
const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops; |
dc6ed1df5 dcbnl: add suppor... |
1561 1562 1563 |
if (!ops) return -EOPNOTSUPP; |
7be994138 dcbnl: Shorten al... |
1564 |
return dcbnl_cee_fill(skb, netdev); |
dc6ed1df5 dcbnl: add suppor... |
1565 |
} |
33a03aadb dcbnl: Prepare fr... |
1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 |
struct reply_func { /* reply netlink message type */ int type; /* function to fill message contents */ int (*cb)(struct net_device *, struct nlmsghdr *, u32, struct nlattr **, struct sk_buff *); }; static const struct reply_func reply_funcs[DCB_CMD_MAX+1] = { |
7be994138 dcbnl: Shorten al... |
1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 |
[DCB_CMD_GSTATE] = { RTM_GETDCB, dcbnl_getstate }, [DCB_CMD_SSTATE] = { RTM_SETDCB, dcbnl_setstate }, [DCB_CMD_PFC_GCFG] = { RTM_GETDCB, dcbnl_getpfccfg }, [DCB_CMD_PFC_SCFG] = { RTM_SETDCB, dcbnl_setpfccfg }, [DCB_CMD_GPERM_HWADDR] = { RTM_GETDCB, dcbnl_getperm_hwaddr }, [DCB_CMD_GCAP] = { RTM_GETDCB, dcbnl_getcap }, [DCB_CMD_GNUMTCS] = { RTM_GETDCB, dcbnl_getnumtcs }, [DCB_CMD_SNUMTCS] = { RTM_SETDCB, dcbnl_setnumtcs }, [DCB_CMD_PFC_GSTATE] = { RTM_GETDCB, dcbnl_getpfcstate }, [DCB_CMD_PFC_SSTATE] = { RTM_SETDCB, dcbnl_setpfcstate }, [DCB_CMD_GAPP] = { RTM_GETDCB, dcbnl_getapp }, [DCB_CMD_SAPP] = { RTM_SETDCB, dcbnl_setapp }, [DCB_CMD_PGTX_GCFG] = { RTM_GETDCB, dcbnl_pgtx_getcfg }, [DCB_CMD_PGTX_SCFG] = { RTM_SETDCB, dcbnl_pgtx_setcfg }, [DCB_CMD_PGRX_GCFG] = { RTM_GETDCB, dcbnl_pgrx_getcfg }, [DCB_CMD_PGRX_SCFG] = { RTM_SETDCB, dcbnl_pgrx_setcfg }, [DCB_CMD_SET_ALL] = { RTM_SETDCB, dcbnl_setall }, [DCB_CMD_BCN_GCFG] = { RTM_GETDCB, dcbnl_bcn_getcfg }, [DCB_CMD_BCN_SCFG] = { RTM_SETDCB, dcbnl_bcn_setcfg }, [DCB_CMD_IEEE_GET] = { RTM_GETDCB, dcbnl_ieee_get }, [DCB_CMD_IEEE_SET] = { RTM_SETDCB, dcbnl_ieee_set }, [DCB_CMD_IEEE_DEL] = { RTM_SETDCB, dcbnl_ieee_del }, [DCB_CMD_GDCBX] = { RTM_GETDCB, dcbnl_getdcbx }, [DCB_CMD_SDCBX] = { RTM_SETDCB, dcbnl_setdcbx }, [DCB_CMD_GFEATCFG] = { RTM_GETDCB, dcbnl_getfeatcfg }, [DCB_CMD_SFEATCFG] = { RTM_SETDCB, dcbnl_setfeatcfg }, [DCB_CMD_CEE_GET] = { RTM_GETDCB, dcbnl_cee_get }, |
33a03aadb dcbnl: Prepare fr... |
1603 |
}; |
661d2967b rtnetlink: Remove... |
1604 |
static int dcb_doit(struct sk_buff *skb, struct nlmsghdr *nlh) |
2f90b8657 ixgbe: this patch... |
1605 1606 1607 |
{ struct net *net = sock_net(skb->sk); struct net_device *netdev; |
7a282bc37 dcbnl: Use type s... |
1608 |
struct dcbmsg *dcb = nlmsg_data(nlh); |
2f90b8657 ixgbe: this patch... |
1609 |
struct nlattr *tb[DCB_ATTR_MAX + 1]; |
15e473046 netlink: Rename p... |
1610 |
u32 portid = skb ? NETLINK_CB(skb).portid : 0; |
2f90b8657 ixgbe: this patch... |
1611 |
int ret = -EINVAL; |
33a03aadb dcbnl: Prepare fr... |
1612 |
struct sk_buff *reply_skb; |
39912f9cf dcbnl: Silence ha... |
1613 |
struct nlmsghdr *reply_nlh = NULL; |
33a03aadb dcbnl: Prepare fr... |
1614 |
const struct reply_func *fn; |
2f90b8657 ixgbe: this patch... |
1615 |
|
90f62cf30 net: Use netlink_... |
1616 |
if ((nlh->nlmsg_type == RTM_SETDCB) && !netlink_capable(skb, CAP_NET_ADMIN)) |
dfc47ef86 net: Push capable... |
1617 |
return -EPERM; |
2f90b8657 ixgbe: this patch... |
1618 1619 1620 1621 |
ret = nlmsg_parse(nlh, sizeof(*dcb), tb, DCB_ATTR_MAX, dcbnl_rtnl_policy); if (ret < 0) return ret; |
33a03aadb dcbnl: Prepare fr... |
1622 1623 1624 1625 1626 1627 1628 |
if (dcb->cmd > DCB_CMD_MAX) return -EINVAL; /* check if a reply function has been defined for the command */ fn = &reply_funcs[dcb->cmd]; if (!fn->cb) return -EOPNOTSUPP; |
2f90b8657 ixgbe: this patch... |
1629 1630 |
if (!tb[DCB_ATTR_IFNAME]) return -EINVAL; |
d9ac62be5 dcb: use __dev_ge... |
1631 |
netdev = __dev_get_by_name(net, nla_data(tb[DCB_ATTR_IFNAME])); |
2f90b8657 ixgbe: this patch... |
1632 |
if (!netdev) |
3d1f48695 dcbnl: Return con... |
1633 |
return -ENODEV; |
2f90b8657 ixgbe: this patch... |
1634 |
|
d9ac62be5 dcb: use __dev_ge... |
1635 1636 |
if (!netdev->dcbnl_ops) return -EOPNOTSUPP; |
2f90b8657 ixgbe: this patch... |
1637 |
|
15e473046 netlink: Rename p... |
1638 |
reply_skb = dcbnl_newmsg(fn->type, dcb->cmd, portid, nlh->nlmsg_seq, |
33a03aadb dcbnl: Prepare fr... |
1639 |
nlh->nlmsg_flags, &reply_nlh); |
d9ac62be5 dcb: use __dev_ge... |
1640 1641 |
if (!reply_skb) return -ENOBUFS; |
33a03aadb dcbnl: Prepare fr... |
1642 1643 1644 1645 1646 1647 1648 1649 |
ret = fn->cb(netdev, nlh, nlh->nlmsg_seq, tb, reply_skb); if (ret < 0) { nlmsg_free(reply_skb); goto out; } nlmsg_end(reply_skb, reply_nlh); |
7c77ab24e net: Allow DCBnl ... |
1650 |
ret = rtnl_unicast(reply_skb, net, portid); |
2f90b8657 ixgbe: this patch... |
1651 |
out: |
2f90b8657 ixgbe: this patch... |
1652 1653 |
return ret; } |
716b31abb dcbnl: Move dcb a... |
1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 |
static struct dcb_app_type *dcb_app_lookup(const struct dcb_app *app, int ifindex, int prio) { struct dcb_app_type *itr; list_for_each_entry(itr, &dcb_app_list, list) { if (itr->app.selector == app->selector && itr->app.protocol == app->protocol && itr->ifindex == ifindex && (!prio || itr->app.priority == prio)) return itr; } return NULL; } |
4e4f2f697 dcbnl: Move dcb a... |
1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 |
static int dcb_app_add(const struct dcb_app *app, int ifindex) { struct dcb_app_type *entry; entry = kmalloc(sizeof(*entry), GFP_ATOMIC); if (!entry) return -ENOMEM; memcpy(&entry->app, app, sizeof(*app)); entry->ifindex = ifindex; list_add(&entry->list, &dcb_app_list); return 0; } |
9ab933ab2 dcbnl: add applic... |
1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 |
/** * dcb_getapp - retrieve the DCBX application user priority * * On success returns a non-zero 802.1p user priority bitmap * otherwise returns 0 as the invalid user priority bitmap to * indicate an error. */ u8 dcb_getapp(struct net_device *dev, struct dcb_app *app) { struct dcb_app_type *itr; u8 prio = 0; |
52cff74ee dcbnl : Disable s... |
1694 |
spin_lock_bh(&dcb_lock); |
716b31abb dcbnl: Move dcb a... |
1695 1696 |
if ((itr = dcb_app_lookup(app, dev->ifindex, 0))) prio = itr->app.priority; |
52cff74ee dcbnl : Disable s... |
1697 |
spin_unlock_bh(&dcb_lock); |
9ab933ab2 dcbnl: add applic... |
1698 1699 1700 1701 1702 1703 |
return prio; } EXPORT_SYMBOL(dcb_getapp); /** |
b6db2174c dcb: Add ieee_dcb... |
1704 |
* dcb_setapp - add CEE dcb application data to app list |
9ab933ab2 dcbnl: add applic... |
1705 |
* |
b6db2174c dcb: Add ieee_dcb... |
1706 1707 |
* Priority 0 is an invalid priority in CEE spec. This routine * removes applications from the app list if the priority is |
16eecd9be dcbnl : Fix misle... |
1708 |
* set to zero. Priority is expected to be 8-bit 802.1p user priority bitmap |
9ab933ab2 dcbnl: add applic... |
1709 |
*/ |
ab6baf980 dcb: fix return t... |
1710 |
int dcb_setapp(struct net_device *dev, struct dcb_app *new) |
9ab933ab2 dcbnl: add applic... |
1711 1712 |
{ struct dcb_app_type *itr; |
7ec79270d net: dcb: applica... |
1713 |
struct dcb_app_type event; |
4e4f2f697 dcbnl: Move dcb a... |
1714 |
int err = 0; |
7ec79270d net: dcb: applica... |
1715 |
|
e290ed813 dcb: Use ifindex ... |
1716 |
event.ifindex = dev->ifindex; |
7ec79270d net: dcb: applica... |
1717 |
memcpy(&event.app, new, sizeof(event.app)); |
6bd0e1cb1 dcb: add DCBX mod... |
1718 1719 |
if (dev->dcbnl_ops->getdcbx) event.dcbx = dev->dcbnl_ops->getdcbx(dev); |
9ab933ab2 dcbnl: add applic... |
1720 |
|
52cff74ee dcbnl : Disable s... |
1721 |
spin_lock_bh(&dcb_lock); |
9ab933ab2 dcbnl: add applic... |
1722 |
/* Search for existing match and replace */ |
716b31abb dcbnl: Move dcb a... |
1723 1724 1725 1726 1727 1728 |
if ((itr = dcb_app_lookup(new, dev->ifindex, 0))) { if (new->priority) itr->app.priority = new->priority; else { list_del(&itr->list); kfree(itr); |
9ab933ab2 dcbnl: add applic... |
1729 |
} |
716b31abb dcbnl: Move dcb a... |
1730 |
goto out; |
9ab933ab2 dcbnl: add applic... |
1731 1732 |
} /* App type does not exist add new application type */ |
4e4f2f697 dcbnl: Move dcb a... |
1733 1734 |
if (new->priority) err = dcb_app_add(new, dev->ifindex); |
9ab933ab2 dcbnl: add applic... |
1735 |
out: |
52cff74ee dcbnl : Disable s... |
1736 |
spin_unlock_bh(&dcb_lock); |
4e4f2f697 dcbnl: Move dcb a... |
1737 1738 1739 |
if (!err) call_dcbevent_notifiers(DCB_APP_EVENT, &event); return err; |
9ab933ab2 dcbnl: add applic... |
1740 1741 |
} EXPORT_SYMBOL(dcb_setapp); |
b6db2174c dcb: Add ieee_dcb... |
1742 |
/** |
a364c8cf8 dcb: Add dcb_ieee... |
1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 |
* dcb_ieee_getapp_mask - retrieve the IEEE DCB application priority * * Helper routine which on success returns a non-zero 802.1Qaz user * priority bitmap otherwise returns 0 to indicate the dcb_app was * not found in APP list. */ u8 dcb_ieee_getapp_mask(struct net_device *dev, struct dcb_app *app) { struct dcb_app_type *itr; u8 prio = 0; |
52cff74ee dcbnl : Disable s... |
1753 |
spin_lock_bh(&dcb_lock); |
716b31abb dcbnl: Move dcb a... |
1754 1755 |
if ((itr = dcb_app_lookup(app, dev->ifindex, 0))) prio |= 1 << itr->app.priority; |
52cff74ee dcbnl : Disable s... |
1756 |
spin_unlock_bh(&dcb_lock); |
a364c8cf8 dcb: Add dcb_ieee... |
1757 1758 1759 1760 1761 1762 |
return prio; } EXPORT_SYMBOL(dcb_ieee_getapp_mask); /** |
b6db2174c dcb: Add ieee_dcb... |
1763 1764 1765 1766 |
* dcb_ieee_setapp - add IEEE dcb application data to app list * * This adds Application data to the list. Multiple application * entries may exists for the same selector and protocol as long |
16eecd9be dcbnl : Fix misle... |
1767 1768 |
* as the priorities are different. Priority is expected to be a * 3-bit unsigned integer |
b6db2174c dcb: Add ieee_dcb... |
1769 1770 1771 |
*/ int dcb_ieee_setapp(struct net_device *dev, struct dcb_app *new) { |
b6db2174c dcb: Add ieee_dcb... |
1772 1773 |
struct dcb_app_type event; int err = 0; |
e290ed813 dcb: Use ifindex ... |
1774 |
event.ifindex = dev->ifindex; |
b6db2174c dcb: Add ieee_dcb... |
1775 |
memcpy(&event.app, new, sizeof(event.app)); |
6bd0e1cb1 dcb: add DCBX mod... |
1776 1777 |
if (dev->dcbnl_ops->getdcbx) event.dcbx = dev->dcbnl_ops->getdcbx(dev); |
b6db2174c dcb: Add ieee_dcb... |
1778 |
|
52cff74ee dcbnl : Disable s... |
1779 |
spin_lock_bh(&dcb_lock); |
b6db2174c dcb: Add ieee_dcb... |
1780 |
/* Search for existing match and abort if found */ |
716b31abb dcbnl: Move dcb a... |
1781 1782 1783 |
if (dcb_app_lookup(new, dev->ifindex, new->priority)) { err = -EEXIST; goto out; |
b6db2174c dcb: Add ieee_dcb... |
1784 |
} |
4e4f2f697 dcbnl: Move dcb a... |
1785 |
err = dcb_app_add(new, dev->ifindex); |
b6db2174c dcb: Add ieee_dcb... |
1786 |
out: |
52cff74ee dcbnl : Disable s... |
1787 |
spin_unlock_bh(&dcb_lock); |
b6db2174c dcb: Add ieee_dcb... |
1788 1789 1790 1791 1792 |
if (!err) call_dcbevent_notifiers(DCB_APP_EVENT, &event); return err; } EXPORT_SYMBOL(dcb_ieee_setapp); |
f9ae7e4b5 dcb: Add ieee_dcb... |
1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 |
/** * dcb_ieee_delapp - delete IEEE dcb application data from list * * This removes a matching APP data from the APP list */ int dcb_ieee_delapp(struct net_device *dev, struct dcb_app *del) { struct dcb_app_type *itr; struct dcb_app_type event; int err = -ENOENT; |
e290ed813 dcb: Use ifindex ... |
1803 |
event.ifindex = dev->ifindex; |
f9ae7e4b5 dcb: Add ieee_dcb... |
1804 |
memcpy(&event.app, del, sizeof(event.app)); |
6bd0e1cb1 dcb: add DCBX mod... |
1805 1806 |
if (dev->dcbnl_ops->getdcbx) event.dcbx = dev->dcbnl_ops->getdcbx(dev); |
f9ae7e4b5 dcb: Add ieee_dcb... |
1807 |
|
52cff74ee dcbnl : Disable s... |
1808 |
spin_lock_bh(&dcb_lock); |
f9ae7e4b5 dcb: Add ieee_dcb... |
1809 |
/* Search for existing match and remove it. */ |
716b31abb dcbnl: Move dcb a... |
1810 1811 1812 1813 |
if ((itr = dcb_app_lookup(del, dev->ifindex, del->priority))) { list_del(&itr->list); kfree(itr); err = 0; |
f9ae7e4b5 dcb: Add ieee_dcb... |
1814 |
} |
52cff74ee dcbnl : Disable s... |
1815 |
spin_unlock_bh(&dcb_lock); |
f9ae7e4b5 dcb: Add ieee_dcb... |
1816 1817 1818 1819 1820 |
if (!err) call_dcbevent_notifiers(DCB_APP_EVENT, &event); return err; } EXPORT_SYMBOL(dcb_ieee_delapp); |
2f90b8657 ixgbe: this patch... |
1821 1822 |
static int __init dcbnl_init(void) { |
9ab933ab2 dcbnl: add applic... |
1823 |
INIT_LIST_HEAD(&dcb_app_list); |
c7ac8679b rtnetlink: Comput... |
1824 1825 |
rtnl_register(PF_UNSPEC, RTM_GETDCB, dcb_doit, NULL, NULL); rtnl_register(PF_UNSPEC, RTM_SETDCB, dcb_doit, NULL, NULL); |
2f90b8657 ixgbe: this patch... |
1826 1827 1828 |
return 0; } |
36b9ad808 net/dcb: make dcb... |
1829 |
device_initcall(dcbnl_init); |