12f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck/* 2698e1d23cfc15312be2e7665014afd98c49ae9a1Mark Rustad * Copyright (c) 2008-2011, Intel Corporation. 32f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * 42f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * This program is free software; you can redistribute it and/or modify it 52f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * under the terms and conditions of the GNU General Public License, 62f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * version 2, as published by the Free Software Foundation. 72f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * 82f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * This program is distributed in the hope it will be useful, but WITHOUT 92f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 102f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 112f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * more details. 122f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * 132f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * You should have received a copy of the GNU General Public License along with 142f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * this program; if not, write to the Free Software Foundation, Inc., 59 Temple 152f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * Place - Suite 330, Boston, MA 02111-1307 USA. 162f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * 172f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * Author: Lucy Liu <lucy.liu@intel.com> 182f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck */ 192f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 202f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck#include <linux/netdevice.h> 212f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck#include <linux/netlink.h> 225a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h> 232f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck#include <net/netlink.h> 242f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck#include <net/rtnetlink.h> 252f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck#include <linux/dcbnl.h> 2696b99684e365f28d49bdb1221ca022b75cb91a98John Fastabend#include <net/dcbevent.h> 272f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck#include <linux/rtnetlink.h> 283a9a231d977222eea36eae091df2c358e03ac839Paul Gortmaker#include <linux/module.h> 292f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck#include <net/sock.h> 302f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 31ae86b9e3846f6fc5509dee721f2bdba1db8ab96aBen Hutchings/* Data Center Bridging (DCB) is a collection of Ethernet enhancements 322f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * intended to allow network traffic with differing requirements 332f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * (highly reliable, no drops vs. best effort vs. low latency) to operate 342f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * and co-exist on Ethernet. Current DCB features are: 352f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * 362f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * Enhanced Transmission Selection (aka Priority Grouping [PG]) - provides a 372f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * framework for assigning bandwidth guarantees to traffic classes. 382f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * 392f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * Priority-based Flow Control (PFC) - provides a flow control mechanism which 402f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * can work independently for each 802.1p priority. 412f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * 422f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * Congestion Notification - provides a mechanism for end-to-end congestion 432f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * control for protocols which do not have built-in congestion management. 442f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * 452f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * More information about the emerging standards for these Ethernet features 462f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * can be found at: http://www.ieee802.org/1/pages/dcbridges.html 472f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * 482f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * This file implements an rtnetlink interface to allow configuration of DCB 492f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * features for capable devices. 502f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck */ 512f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 522f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander DuyckMODULE_AUTHOR("Lucy Liu, <lucy.liu@intel.com>"); 537a6b6f515f77d1c62a2f383b6dce18cb0af0cf4fJeff KirsherMODULE_DESCRIPTION("Data Center Bridging netlink interface"); 542f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander DuyckMODULE_LICENSE("GPL"); 552f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 562f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck/**************** DCB attribute policies *************************************/ 572f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 582f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck/* DCB netlink attributes policy */ 59b54452b07a7b1b8cc1385edba3ef2ef6d4679d5aAlexey Dobriyanstatic const struct nla_policy dcbnl_rtnl_policy[DCB_ATTR_MAX + 1] = { 60859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_ATTR_IFNAME] = {.type = NLA_NUL_STRING, .len = IFNAMSIZ - 1}, 61859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_ATTR_STATE] = {.type = NLA_U8}, 62859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_ATTR_PFC_CFG] = {.type = NLA_NESTED}, 63859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_ATTR_PG_CFG] = {.type = NLA_NESTED}, 64859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_ATTR_SET_ALL] = {.type = NLA_U8}, 652f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_ATTR_PERM_HWADDR] = {.type = NLA_FLAG}, 66859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_ATTR_CAP] = {.type = NLA_NESTED}, 67859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_ATTR_PFC_STATE] = {.type = NLA_U8}, 68859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_ATTR_BCN] = {.type = NLA_NESTED}, 696fa382af61338908e5713234bcee598423f661c3Yi Zou [DCB_ATTR_APP] = {.type = NLA_NESTED}, 703e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend [DCB_ATTR_IEEE] = {.type = NLA_NESTED}, 716241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid [DCB_ATTR_DCBX] = {.type = NLA_U8}, 72ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid [DCB_ATTR_FEATCFG] = {.type = NLA_NESTED}, 732f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck}; 742f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 752f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck/* DCB priority flow control to User Priority nested attributes */ 76b54452b07a7b1b8cc1385edba3ef2ef6d4679d5aAlexey Dobriyanstatic const struct nla_policy dcbnl_pfc_up_nest[DCB_PFC_UP_ATTR_MAX + 1] = { 772f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PFC_UP_ATTR_0] = {.type = NLA_U8}, 782f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PFC_UP_ATTR_1] = {.type = NLA_U8}, 792f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PFC_UP_ATTR_2] = {.type = NLA_U8}, 802f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PFC_UP_ATTR_3] = {.type = NLA_U8}, 812f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PFC_UP_ATTR_4] = {.type = NLA_U8}, 822f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PFC_UP_ATTR_5] = {.type = NLA_U8}, 832f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PFC_UP_ATTR_6] = {.type = NLA_U8}, 842f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PFC_UP_ATTR_7] = {.type = NLA_U8}, 852f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PFC_UP_ATTR_ALL] = {.type = NLA_FLAG}, 862f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck}; 872f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 882f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck/* DCB priority grouping nested attributes */ 89b54452b07a7b1b8cc1385edba3ef2ef6d4679d5aAlexey Dobriyanstatic const struct nla_policy dcbnl_pg_nest[DCB_PG_ATTR_MAX + 1] = { 902f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PG_ATTR_TC_0] = {.type = NLA_NESTED}, 912f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PG_ATTR_TC_1] = {.type = NLA_NESTED}, 922f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PG_ATTR_TC_2] = {.type = NLA_NESTED}, 932f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PG_ATTR_TC_3] = {.type = NLA_NESTED}, 942f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PG_ATTR_TC_4] = {.type = NLA_NESTED}, 952f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PG_ATTR_TC_5] = {.type = NLA_NESTED}, 962f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PG_ATTR_TC_6] = {.type = NLA_NESTED}, 972f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PG_ATTR_TC_7] = {.type = NLA_NESTED}, 982f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PG_ATTR_TC_ALL] = {.type = NLA_NESTED}, 992f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PG_ATTR_BW_ID_0] = {.type = NLA_U8}, 1002f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PG_ATTR_BW_ID_1] = {.type = NLA_U8}, 1012f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PG_ATTR_BW_ID_2] = {.type = NLA_U8}, 1022f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PG_ATTR_BW_ID_3] = {.type = NLA_U8}, 1032f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PG_ATTR_BW_ID_4] = {.type = NLA_U8}, 1042f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PG_ATTR_BW_ID_5] = {.type = NLA_U8}, 1052f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PG_ATTR_BW_ID_6] = {.type = NLA_U8}, 1062f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PG_ATTR_BW_ID_7] = {.type = NLA_U8}, 1072f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PG_ATTR_BW_ID_ALL] = {.type = NLA_FLAG}, 1082f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck}; 1092f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 1102f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck/* DCB traffic class nested attributes. */ 111b54452b07a7b1b8cc1385edba3ef2ef6d4679d5aAlexey Dobriyanstatic const struct nla_policy dcbnl_tc_param_nest[DCB_TC_ATTR_PARAM_MAX + 1] = { 1122f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_TC_ATTR_PARAM_PGID] = {.type = NLA_U8}, 1132f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_TC_ATTR_PARAM_UP_MAPPING] = {.type = NLA_U8}, 1142f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_TC_ATTR_PARAM_STRICT_PRIO] = {.type = NLA_U8}, 1152f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_TC_ATTR_PARAM_BW_PCT] = {.type = NLA_U8}, 1162f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_TC_ATTR_PARAM_ALL] = {.type = NLA_FLAG}, 1172f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck}; 1182f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 11946132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck/* DCB capabilities nested attributes. */ 120b54452b07a7b1b8cc1385edba3ef2ef6d4679d5aAlexey Dobriyanstatic const struct nla_policy dcbnl_cap_nest[DCB_CAP_ATTR_MAX + 1] = { 12146132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck [DCB_CAP_ATTR_ALL] = {.type = NLA_FLAG}, 12246132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck [DCB_CAP_ATTR_PG] = {.type = NLA_U8}, 12346132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck [DCB_CAP_ATTR_PFC] = {.type = NLA_U8}, 12446132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck [DCB_CAP_ATTR_UP2TC] = {.type = NLA_U8}, 12546132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck [DCB_CAP_ATTR_PG_TCS] = {.type = NLA_U8}, 12646132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck [DCB_CAP_ATTR_PFC_TCS] = {.type = NLA_U8}, 12746132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck [DCB_CAP_ATTR_GSP] = {.type = NLA_U8}, 12846132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck [DCB_CAP_ATTR_BCN] = {.type = NLA_U8}, 1296241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid [DCB_CAP_ATTR_DCBX] = {.type = NLA_U8}, 13046132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck}; 1312f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 13233dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck/* DCB capabilities nested attributes. */ 133b54452b07a7b1b8cc1385edba3ef2ef6d4679d5aAlexey Dobriyanstatic const struct nla_policy dcbnl_numtcs_nest[DCB_NUMTCS_ATTR_MAX + 1] = { 13433dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck [DCB_NUMTCS_ATTR_ALL] = {.type = NLA_FLAG}, 13533dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck [DCB_NUMTCS_ATTR_PG] = {.type = NLA_U8}, 13633dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck [DCB_NUMTCS_ATTR_PFC] = {.type = NLA_U8}, 13733dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck}; 13833dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 139859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck/* DCB BCN nested attributes. */ 140b54452b07a7b1b8cc1385edba3ef2ef6d4679d5aAlexey Dobriyanstatic const struct nla_policy dcbnl_bcn_nest[DCB_BCN_ATTR_MAX + 1] = { 141859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_RP_0] = {.type = NLA_U8}, 142859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_RP_1] = {.type = NLA_U8}, 143859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_RP_2] = {.type = NLA_U8}, 144859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_RP_3] = {.type = NLA_U8}, 145859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_RP_4] = {.type = NLA_U8}, 146859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_RP_5] = {.type = NLA_U8}, 147859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_RP_6] = {.type = NLA_U8}, 148859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_RP_7] = {.type = NLA_U8}, 149859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_RP_ALL] = {.type = NLA_FLAG}, 150f4314e815e87b4ab1c9b1115dd5853cd20ca999cDon Skidmore [DCB_BCN_ATTR_BCNA_0] = {.type = NLA_U32}, 151f4314e815e87b4ab1c9b1115dd5853cd20ca999cDon Skidmore [DCB_BCN_ATTR_BCNA_1] = {.type = NLA_U32}, 152859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_ALPHA] = {.type = NLA_U32}, 153859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_BETA] = {.type = NLA_U32}, 154859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_GD] = {.type = NLA_U32}, 155859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_GI] = {.type = NLA_U32}, 156859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_TMAX] = {.type = NLA_U32}, 157859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_TD] = {.type = NLA_U32}, 158859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_RMIN] = {.type = NLA_U32}, 159859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_W] = {.type = NLA_U32}, 160859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_RD] = {.type = NLA_U32}, 161859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_RU] = {.type = NLA_U32}, 162859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_WRTT] = {.type = NLA_U32}, 163859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_RI] = {.type = NLA_U32}, 164859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_C] = {.type = NLA_U32}, 165859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_ALL] = {.type = NLA_FLAG}, 166859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck}; 167859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1686fa382af61338908e5713234bcee598423f661c3Yi Zou/* DCB APP nested attributes. */ 169b54452b07a7b1b8cc1385edba3ef2ef6d4679d5aAlexey Dobriyanstatic const struct nla_policy dcbnl_app_nest[DCB_APP_ATTR_MAX + 1] = { 1706fa382af61338908e5713234bcee598423f661c3Yi Zou [DCB_APP_ATTR_IDTYPE] = {.type = NLA_U8}, 1716fa382af61338908e5713234bcee598423f661c3Yi Zou [DCB_APP_ATTR_ID] = {.type = NLA_U16}, 1726fa382af61338908e5713234bcee598423f661c3Yi Zou [DCB_APP_ATTR_PRIORITY] = {.type = NLA_U8}, 1736fa382af61338908e5713234bcee598423f661c3Yi Zou}; 1746fa382af61338908e5713234bcee598423f661c3Yi Zou 1753e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend/* IEEE 802.1Qaz nested attributes. */ 1763e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabendstatic const struct nla_policy dcbnl_ieee_policy[DCB_ATTR_IEEE_MAX + 1] = { 1773e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend [DCB_ATTR_IEEE_ETS] = {.len = sizeof(struct ieee_ets)}, 1783e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend [DCB_ATTR_IEEE_PFC] = {.len = sizeof(struct ieee_pfc)}, 1793e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend [DCB_ATTR_IEEE_APP_TABLE] = {.type = NLA_NESTED}, 18008f10affe45051e18e0d8291c0a53aecef1b8a14Amir Vadai [DCB_ATTR_IEEE_MAXRATE] = {.len = sizeof(struct ieee_maxrate)}, 1813e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend}; 1823e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend 1833e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabendstatic const struct nla_policy dcbnl_ieee_app[DCB_ATTR_IEEE_APP_MAX + 1] = { 1843e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend [DCB_ATTR_IEEE_APP] = {.len = sizeof(struct dcb_app)}, 1853e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend}; 1863e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend 187ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid/* DCB number of traffic classes nested attributes. */ 188ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravidstatic const struct nla_policy dcbnl_featcfg_nest[DCB_FEATCFG_ATTR_MAX + 1] = { 189ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid [DCB_FEATCFG_ATTR_ALL] = {.type = NLA_FLAG}, 190ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid [DCB_FEATCFG_ATTR_PG] = {.type = NLA_U8}, 191ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid [DCB_FEATCFG_ATTR_PFC] = {.type = NLA_U8}, 192ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid [DCB_FEATCFG_ATTR_APP] = {.type = NLA_U8}, 193ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid}; 194ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 1959ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabendstatic LIST_HEAD(dcb_app_list); 1969ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabendstatic DEFINE_SPINLOCK(dcb_lock); 1979ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend 19833a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Grafstatic struct sk_buff *dcbnl_newmsg(int type, u8 cmd, u32 port, u32 seq, 19933a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf u32 flags, struct nlmsghdr **nlhp) 20033a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf{ 20133a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf struct sk_buff *skb; 20233a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf struct dcbmsg *dcb; 20333a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf struct nlmsghdr *nlh; 20433a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf 20533a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 20633a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf if (!skb) 20733a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf return NULL; 20833a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf 20933a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf nlh = nlmsg_put(skb, port, seq, type, sizeof(*dcb), flags); 210b3908e22ad8bb6074934496ef171fd83605d7d3eThomas Graf BUG_ON(!nlh); 21133a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf 21233a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf dcb = nlmsg_data(nlh); 21333a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf dcb->dcb_family = AF_UNSPEC; 21433a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf dcb->cmd = cmd; 21533a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf dcb->dcb_pad = 0; 21633a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf 21733a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf if (nlhp) 21833a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf *nlhp = nlh; 21933a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf 22033a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf return skb; 22133a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf} 22233a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf 2237be994138b188387691322921c08e19bddf6d3c5Thomas Grafstatic int dcbnl_getstate(struct net_device *netdev, struct nlmsghdr *nlh, 2247be994138b188387691322921c08e19bddf6d3c5Thomas Graf u32 seq, struct nlattr **tb, struct sk_buff *skb) 2252f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 2262f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck /* if (!tb[DCB_ATTR_STATE] || !netdev->dcbnl_ops->getstate) */ 2272f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!netdev->dcbnl_ops->getstate) 2283d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EOPNOTSUPP; 2292f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2307be994138b188387691322921c08e19bddf6d3c5Thomas Graf return nla_put_u8(skb, DCB_ATTR_STATE, 2317be994138b188387691322921c08e19bddf6d3c5Thomas Graf netdev->dcbnl_ops->getstate(netdev)); 2322f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 2332f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2347be994138b188387691322921c08e19bddf6d3c5Thomas Grafstatic int dcbnl_getpfccfg(struct net_device *netdev, struct nlmsghdr *nlh, 2357be994138b188387691322921c08e19bddf6d3c5Thomas Graf u32 seq, struct nlattr **tb, struct sk_buff *skb) 2362f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 2372f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct nlattr *data[DCB_PFC_UP_ATTR_MAX + 1], *nest; 2382f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u8 value; 2393d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf int ret; 2402f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck int i; 2412f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck int getall = 0; 2422f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2433d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf if (!tb[DCB_ATTR_PFC_CFG]) 2443d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EINVAL; 2453d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf 2463d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf if (!netdev->dcbnl_ops->getpfccfg) 2473d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EOPNOTSUPP; 2482f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2492f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = nla_parse_nested(data, DCB_PFC_UP_ATTR_MAX, 2502f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck tb[DCB_ATTR_PFC_CFG], 2512f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcbnl_pfc_up_nest); 2522f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 2533d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return ret; 2542f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2557be994138b188387691322921c08e19bddf6d3c5Thomas Graf nest = nla_nest_start(skb, DCB_ATTR_PFC_CFG); 2562f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!nest) 2573d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EMSGSIZE; 2582f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2592f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (data[DCB_PFC_UP_ATTR_ALL]) 2602f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck getall = 1; 2612f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2622f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck for (i = DCB_PFC_UP_ATTR_0; i <= DCB_PFC_UP_ATTR_7; i++) { 2632f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!getall && !data[i]) 2642f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck continue; 2652f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2662f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck netdev->dcbnl_ops->getpfccfg(netdev, i - DCB_PFC_UP_ATTR_0, 2672f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck &value); 2687be994138b188387691322921c08e19bddf6d3c5Thomas Graf ret = nla_put_u8(skb, i, value); 2692f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) { 2707be994138b188387691322921c08e19bddf6d3c5Thomas Graf nla_nest_cancel(skb, nest); 2713d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return ret; 2722f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 2732f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 2747be994138b188387691322921c08e19bddf6d3c5Thomas Graf nla_nest_end(skb, nest); 2752f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2762f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return 0; 2772f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 2782f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2797be994138b188387691322921c08e19bddf6d3c5Thomas Grafstatic int dcbnl_getperm_hwaddr(struct net_device *netdev, struct nlmsghdr *nlh, 2807be994138b188387691322921c08e19bddf6d3c5Thomas Graf u32 seq, struct nlattr **tb, struct sk_buff *skb) 2812f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 2822f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u8 perm_addr[MAX_ADDR_LEN]; 2832f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2842f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!netdev->dcbnl_ops->getpermhwaddr) 2853d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EOPNOTSUPP; 2862f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 28729cd8ae0e1a39e239a3a7b67da1986add1199fc0Mathias Krause memset(perm_addr, 0, sizeof(perm_addr)); 2882f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck netdev->dcbnl_ops->getpermhwaddr(netdev, perm_addr); 2892f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2907be994138b188387691322921c08e19bddf6d3c5Thomas Graf return nla_put(skb, DCB_ATTR_PERM_HWADDR, sizeof(perm_addr), perm_addr); 2912f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 2922f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2937be994138b188387691322921c08e19bddf6d3c5Thomas Grafstatic int dcbnl_getcap(struct net_device *netdev, struct nlmsghdr *nlh, 2947be994138b188387691322921c08e19bddf6d3c5Thomas Graf u32 seq, struct nlattr **tb, struct sk_buff *skb) 29546132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck{ 29646132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck struct nlattr *data[DCB_CAP_ATTR_MAX + 1], *nest; 29746132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck u8 value; 2983d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf int ret; 29946132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck int i; 30046132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck int getall = 0; 30146132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck 3023d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf if (!tb[DCB_ATTR_CAP]) 3033d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EINVAL; 3043d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf 3053d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf if (!netdev->dcbnl_ops->getcap) 3063d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EOPNOTSUPP; 30746132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck 30846132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck ret = nla_parse_nested(data, DCB_CAP_ATTR_MAX, tb[DCB_ATTR_CAP], 30946132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck dcbnl_cap_nest); 31046132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck if (ret) 3113d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return ret; 31246132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck 3137be994138b188387691322921c08e19bddf6d3c5Thomas Graf nest = nla_nest_start(skb, DCB_ATTR_CAP); 31446132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck if (!nest) 3153d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EMSGSIZE; 31646132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck 31746132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck if (data[DCB_CAP_ATTR_ALL]) 31846132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck getall = 1; 31946132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck 32046132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck for (i = DCB_CAP_ATTR_ALL+1; i <= DCB_CAP_ATTR_MAX; i++) { 32146132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck if (!getall && !data[i]) 32246132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck continue; 32346132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck 32446132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck if (!netdev->dcbnl_ops->getcap(netdev, i, &value)) { 3257be994138b188387691322921c08e19bddf6d3c5Thomas Graf ret = nla_put_u8(skb, i, value); 32646132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck if (ret) { 3277be994138b188387691322921c08e19bddf6d3c5Thomas Graf nla_nest_cancel(skb, nest); 3283d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return ret; 32946132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck } 33046132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck } 33146132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck } 3327be994138b188387691322921c08e19bddf6d3c5Thomas Graf nla_nest_end(skb, nest); 33346132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck 33446132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck return 0; 33546132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck} 33646132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck 3377be994138b188387691322921c08e19bddf6d3c5Thomas Grafstatic int dcbnl_getnumtcs(struct net_device *netdev, struct nlmsghdr *nlh, 3387be994138b188387691322921c08e19bddf6d3c5Thomas Graf u32 seq, struct nlattr **tb, struct sk_buff *skb) 33933dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck{ 34033dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck struct nlattr *data[DCB_NUMTCS_ATTR_MAX + 1], *nest; 34133dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck u8 value; 3423d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf int ret; 34333dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck int i; 34433dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck int getall = 0; 34533dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 3463d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf if (!tb[DCB_ATTR_NUMTCS]) 3473d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EINVAL; 3483d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf 3493d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf if (!netdev->dcbnl_ops->getnumtcs) 3503d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EOPNOTSUPP; 35133dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 35233dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck ret = nla_parse_nested(data, DCB_NUMTCS_ATTR_MAX, tb[DCB_ATTR_NUMTCS], 35333dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck dcbnl_numtcs_nest); 3543d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf if (ret) 3553d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return ret; 35633dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 3577be994138b188387691322921c08e19bddf6d3c5Thomas Graf nest = nla_nest_start(skb, DCB_ATTR_NUMTCS); 3583d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf if (!nest) 3593d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EMSGSIZE; 36033dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 36133dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck if (data[DCB_NUMTCS_ATTR_ALL]) 36233dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck getall = 1; 36333dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 36433dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck for (i = DCB_NUMTCS_ATTR_ALL+1; i <= DCB_NUMTCS_ATTR_MAX; i++) { 36533dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck if (!getall && !data[i]) 36633dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck continue; 36733dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 36833dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck ret = netdev->dcbnl_ops->getnumtcs(netdev, i, &value); 36933dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck if (!ret) { 3707be994138b188387691322921c08e19bddf6d3c5Thomas Graf ret = nla_put_u8(skb, i, value); 37133dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck if (ret) { 3727be994138b188387691322921c08e19bddf6d3c5Thomas Graf nla_nest_cancel(skb, nest); 3733d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return ret; 37433dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck } 3753d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf } else 3763d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EINVAL; 37733dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck } 3787be994138b188387691322921c08e19bddf6d3c5Thomas Graf nla_nest_end(skb, nest); 37933dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 38033dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck return 0; 38133dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck} 38233dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 3837be994138b188387691322921c08e19bddf6d3c5Thomas Grafstatic int dcbnl_setnumtcs(struct net_device *netdev, struct nlmsghdr *nlh, 3847be994138b188387691322921c08e19bddf6d3c5Thomas Graf u32 seq, struct nlattr **tb, struct sk_buff *skb) 38533dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck{ 38633dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck struct nlattr *data[DCB_NUMTCS_ATTR_MAX + 1]; 3873d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf int ret; 38833dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck u8 value; 38933dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck int i; 39033dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 3913d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf if (!tb[DCB_ATTR_NUMTCS]) 3923d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EINVAL; 3933d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf 3943d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf if (!netdev->dcbnl_ops->setnumtcs) 3953d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EOPNOTSUPP; 39633dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 39733dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck ret = nla_parse_nested(data, DCB_NUMTCS_ATTR_MAX, tb[DCB_ATTR_NUMTCS], 39833dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck dcbnl_numtcs_nest); 3997be994138b188387691322921c08e19bddf6d3c5Thomas Graf if (ret) 4003d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return ret; 40133dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 40233dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck for (i = DCB_NUMTCS_ATTR_ALL+1; i <= DCB_NUMTCS_ATTR_MAX; i++) { 40333dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck if (data[i] == NULL) 40433dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck continue; 40533dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 40633dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck value = nla_get_u8(data[i]); 40733dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 40833dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck ret = netdev->dcbnl_ops->setnumtcs(netdev, i, value); 40933dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck if (ret) 4107be994138b188387691322921c08e19bddf6d3c5Thomas Graf break; 41133dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck } 41233dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 4137be994138b188387691322921c08e19bddf6d3c5Thomas Graf return nla_put_u8(skb, DCB_ATTR_NUMTCS, !!ret); 41433dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck} 41533dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 4167be994138b188387691322921c08e19bddf6d3c5Thomas Grafstatic int dcbnl_getpfcstate(struct net_device *netdev, struct nlmsghdr *nlh, 4177be994138b188387691322921c08e19bddf6d3c5Thomas Graf u32 seq, struct nlattr **tb, struct sk_buff *skb) 4180eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck{ 4190eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck if (!netdev->dcbnl_ops->getpfcstate) 4203d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EOPNOTSUPP; 4210eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck 4227be994138b188387691322921c08e19bddf6d3c5Thomas Graf return nla_put_u8(skb, DCB_ATTR_PFC_STATE, 4237be994138b188387691322921c08e19bddf6d3c5Thomas Graf netdev->dcbnl_ops->getpfcstate(netdev)); 4240eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck} 4250eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck 4267be994138b188387691322921c08e19bddf6d3c5Thomas Grafstatic int dcbnl_setpfcstate(struct net_device *netdev, struct nlmsghdr *nlh, 4277be994138b188387691322921c08e19bddf6d3c5Thomas Graf u32 seq, struct nlattr **tb, struct sk_buff *skb) 4280eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck{ 4290eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck u8 value; 4300eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck 4313d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf if (!tb[DCB_ATTR_PFC_STATE]) 4327be994138b188387691322921c08e19bddf6d3c5Thomas Graf return -EINVAL; 4330eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck 4343d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf if (!netdev->dcbnl_ops->setpfcstate) 4353d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EOPNOTSUPP; 4363d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf 4370eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck value = nla_get_u8(tb[DCB_ATTR_PFC_STATE]); 4380eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck 4390eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck netdev->dcbnl_ops->setpfcstate(netdev, value); 4400eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck 4417be994138b188387691322921c08e19bddf6d3c5Thomas Graf return nla_put_u8(skb, DCB_ATTR_PFC_STATE, 0); 4420eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck} 4430eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck 4447be994138b188387691322921c08e19bddf6d3c5Thomas Grafstatic int dcbnl_getapp(struct net_device *netdev, struct nlmsghdr *nlh, 4457be994138b188387691322921c08e19bddf6d3c5Thomas Graf u32 seq, struct nlattr **tb, struct sk_buff *skb) 446579496865cf4ea429146382d62047ffdbaab0deeYi Zou{ 447579496865cf4ea429146382d62047ffdbaab0deeYi Zou struct nlattr *app_nest; 448579496865cf4ea429146382d62047ffdbaab0deeYi Zou struct nlattr *app_tb[DCB_APP_ATTR_MAX + 1]; 449579496865cf4ea429146382d62047ffdbaab0deeYi Zou u16 id; 450579496865cf4ea429146382d62047ffdbaab0deeYi Zou u8 up, idtype; 4513d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf int ret; 452579496865cf4ea429146382d62047ffdbaab0deeYi Zou 4533dce38a02d6370dca690cd923619d4b00024b723John Fastabend if (!tb[DCB_ATTR_APP]) 4543d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EINVAL; 455579496865cf4ea429146382d62047ffdbaab0deeYi Zou 456579496865cf4ea429146382d62047ffdbaab0deeYi Zou ret = nla_parse_nested(app_tb, DCB_APP_ATTR_MAX, tb[DCB_ATTR_APP], 457579496865cf4ea429146382d62047ffdbaab0deeYi Zou dcbnl_app_nest); 458579496865cf4ea429146382d62047ffdbaab0deeYi Zou if (ret) 4593d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return ret; 460579496865cf4ea429146382d62047ffdbaab0deeYi Zou 461579496865cf4ea429146382d62047ffdbaab0deeYi Zou /* all must be non-null */ 462579496865cf4ea429146382d62047ffdbaab0deeYi Zou if ((!app_tb[DCB_APP_ATTR_IDTYPE]) || 463579496865cf4ea429146382d62047ffdbaab0deeYi Zou (!app_tb[DCB_APP_ATTR_ID])) 4643d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EINVAL; 465579496865cf4ea429146382d62047ffdbaab0deeYi Zou 466579496865cf4ea429146382d62047ffdbaab0deeYi Zou /* either by eth type or by socket number */ 467579496865cf4ea429146382d62047ffdbaab0deeYi Zou idtype = nla_get_u8(app_tb[DCB_APP_ATTR_IDTYPE]); 468579496865cf4ea429146382d62047ffdbaab0deeYi Zou if ((idtype != DCB_APP_IDTYPE_ETHTYPE) && 469579496865cf4ea429146382d62047ffdbaab0deeYi Zou (idtype != DCB_APP_IDTYPE_PORTNUM)) 4703d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EINVAL; 471579496865cf4ea429146382d62047ffdbaab0deeYi Zou 472579496865cf4ea429146382d62047ffdbaab0deeYi Zou id = nla_get_u16(app_tb[DCB_APP_ATTR_ID]); 4733dce38a02d6370dca690cd923619d4b00024b723John Fastabend 4743dce38a02d6370dca690cd923619d4b00024b723John Fastabend if (netdev->dcbnl_ops->getapp) { 4753dce38a02d6370dca690cd923619d4b00024b723John Fastabend up = netdev->dcbnl_ops->getapp(netdev, idtype, id); 4763dce38a02d6370dca690cd923619d4b00024b723John Fastabend } else { 4773dce38a02d6370dca690cd923619d4b00024b723John Fastabend struct dcb_app app = { 4783dce38a02d6370dca690cd923619d4b00024b723John Fastabend .selector = idtype, 4793dce38a02d6370dca690cd923619d4b00024b723John Fastabend .protocol = id, 4803dce38a02d6370dca690cd923619d4b00024b723John Fastabend }; 4813dce38a02d6370dca690cd923619d4b00024b723John Fastabend up = dcb_getapp(netdev, &app); 4823dce38a02d6370dca690cd923619d4b00024b723John Fastabend } 483579496865cf4ea429146382d62047ffdbaab0deeYi Zou 4847be994138b188387691322921c08e19bddf6d3c5Thomas Graf app_nest = nla_nest_start(skb, DCB_ATTR_APP); 485d3337de52af7fb0ebe605b02b740be4ee7dee9ebJesper Juhl if (!app_nest) 4863d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EMSGSIZE; 487d3337de52af7fb0ebe605b02b740be4ee7dee9ebJesper Juhl 4887be994138b188387691322921c08e19bddf6d3c5Thomas Graf ret = nla_put_u8(skb, DCB_APP_ATTR_IDTYPE, idtype); 489579496865cf4ea429146382d62047ffdbaab0deeYi Zou if (ret) 490579496865cf4ea429146382d62047ffdbaab0deeYi Zou goto out_cancel; 491579496865cf4ea429146382d62047ffdbaab0deeYi Zou 4927be994138b188387691322921c08e19bddf6d3c5Thomas Graf ret = nla_put_u16(skb, DCB_APP_ATTR_ID, id); 493579496865cf4ea429146382d62047ffdbaab0deeYi Zou if (ret) 494579496865cf4ea429146382d62047ffdbaab0deeYi Zou goto out_cancel; 495579496865cf4ea429146382d62047ffdbaab0deeYi Zou 4967be994138b188387691322921c08e19bddf6d3c5Thomas Graf ret = nla_put_u8(skb, DCB_APP_ATTR_PRIORITY, up); 497579496865cf4ea429146382d62047ffdbaab0deeYi Zou if (ret) 498579496865cf4ea429146382d62047ffdbaab0deeYi Zou goto out_cancel; 499579496865cf4ea429146382d62047ffdbaab0deeYi Zou 5007be994138b188387691322921c08e19bddf6d3c5Thomas Graf nla_nest_end(skb, app_nest); 501579496865cf4ea429146382d62047ffdbaab0deeYi Zou 5023d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return 0; 503579496865cf4ea429146382d62047ffdbaab0deeYi Zou 504579496865cf4ea429146382d62047ffdbaab0deeYi Zouout_cancel: 5057be994138b188387691322921c08e19bddf6d3c5Thomas Graf nla_nest_cancel(skb, app_nest); 506579496865cf4ea429146382d62047ffdbaab0deeYi Zou return ret; 507579496865cf4ea429146382d62047ffdbaab0deeYi Zou} 508579496865cf4ea429146382d62047ffdbaab0deeYi Zou 5097be994138b188387691322921c08e19bddf6d3c5Thomas Grafstatic int dcbnl_setapp(struct net_device *netdev, struct nlmsghdr *nlh, 5107be994138b188387691322921c08e19bddf6d3c5Thomas Graf u32 seq, struct nlattr **tb, struct sk_buff *skb) 511579496865cf4ea429146382d62047ffdbaab0deeYi Zou{ 5123d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf int ret; 513579496865cf4ea429146382d62047ffdbaab0deeYi Zou u16 id; 514579496865cf4ea429146382d62047ffdbaab0deeYi Zou u8 up, idtype; 515579496865cf4ea429146382d62047ffdbaab0deeYi Zou struct nlattr *app_tb[DCB_APP_ATTR_MAX + 1]; 516579496865cf4ea429146382d62047ffdbaab0deeYi Zou 5179ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend if (!tb[DCB_ATTR_APP]) 5183d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EINVAL; 519579496865cf4ea429146382d62047ffdbaab0deeYi Zou 520579496865cf4ea429146382d62047ffdbaab0deeYi Zou ret = nla_parse_nested(app_tb, DCB_APP_ATTR_MAX, tb[DCB_ATTR_APP], 521579496865cf4ea429146382d62047ffdbaab0deeYi Zou dcbnl_app_nest); 522579496865cf4ea429146382d62047ffdbaab0deeYi Zou if (ret) 5233d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return ret; 524579496865cf4ea429146382d62047ffdbaab0deeYi Zou 525579496865cf4ea429146382d62047ffdbaab0deeYi Zou /* all must be non-null */ 526579496865cf4ea429146382d62047ffdbaab0deeYi Zou if ((!app_tb[DCB_APP_ATTR_IDTYPE]) || 527579496865cf4ea429146382d62047ffdbaab0deeYi Zou (!app_tb[DCB_APP_ATTR_ID]) || 528579496865cf4ea429146382d62047ffdbaab0deeYi Zou (!app_tb[DCB_APP_ATTR_PRIORITY])) 5293d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EINVAL; 530579496865cf4ea429146382d62047ffdbaab0deeYi Zou 531579496865cf4ea429146382d62047ffdbaab0deeYi Zou /* either by eth type or by socket number */ 532579496865cf4ea429146382d62047ffdbaab0deeYi Zou idtype = nla_get_u8(app_tb[DCB_APP_ATTR_IDTYPE]); 533579496865cf4ea429146382d62047ffdbaab0deeYi Zou if ((idtype != DCB_APP_IDTYPE_ETHTYPE) && 534579496865cf4ea429146382d62047ffdbaab0deeYi Zou (idtype != DCB_APP_IDTYPE_PORTNUM)) 5353d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EINVAL; 536579496865cf4ea429146382d62047ffdbaab0deeYi Zou 537579496865cf4ea429146382d62047ffdbaab0deeYi Zou id = nla_get_u16(app_tb[DCB_APP_ATTR_ID]); 538579496865cf4ea429146382d62047ffdbaab0deeYi Zou up = nla_get_u8(app_tb[DCB_APP_ATTR_PRIORITY]); 539579496865cf4ea429146382d62047ffdbaab0deeYi Zou 5409ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend if (netdev->dcbnl_ops->setapp) { 5413d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf ret = netdev->dcbnl_ops->setapp(netdev, idtype, id, up); 5429ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend } else { 5439ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend struct dcb_app app; 5449ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend app.selector = idtype; 5459ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend app.protocol = id; 5469ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend app.priority = up; 5473d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf ret = dcb_setapp(netdev, &app); 5489ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend } 5499ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend 5507be994138b188387691322921c08e19bddf6d3c5Thomas Graf ret = nla_put_u8(skb, DCB_ATTR_APP, ret); 551081579840b4b2421e37bc67e3b089b7ca64ef040John Fastabend dcbnl_cee_notify(netdev, RTM_SETDCB, DCB_CMD_SAPP, seq, 0); 5523d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf 553579496865cf4ea429146382d62047ffdbaab0deeYi Zou return ret; 554579496865cf4ea429146382d62047ffdbaab0deeYi Zou} 555579496865cf4ea429146382d62047ffdbaab0deeYi Zou 5567be994138b188387691322921c08e19bddf6d3c5Thomas Grafstatic int __dcbnl_pg_getcfg(struct net_device *netdev, struct nlmsghdr *nlh, 5577be994138b188387691322921c08e19bddf6d3c5Thomas Graf struct nlattr **tb, struct sk_buff *skb, int dir) 5582f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 5592f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct nlattr *pg_nest, *param_nest, *data; 5602f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct nlattr *pg_tb[DCB_PG_ATTR_MAX + 1]; 5612f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct nlattr *param_tb[DCB_TC_ATTR_PARAM_MAX + 1]; 5622f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u8 prio, pgid, tc_pct, up_map; 5633d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf int ret; 5642f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck int getall = 0; 5652f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck int i; 5662f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 5673d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf if (!tb[DCB_ATTR_PG_CFG]) 5683d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EINVAL; 5693d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf 5703d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf if (!netdev->dcbnl_ops->getpgtccfgtx || 5712f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck !netdev->dcbnl_ops->getpgtccfgrx || 5722f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck !netdev->dcbnl_ops->getpgbwgcfgtx || 5732f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck !netdev->dcbnl_ops->getpgbwgcfgrx) 5743d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EOPNOTSUPP; 5752f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 5762f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = nla_parse_nested(pg_tb, DCB_PG_ATTR_MAX, 5772f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck tb[DCB_ATTR_PG_CFG], dcbnl_pg_nest); 5782f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 5793d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return ret; 5802f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 5817be994138b188387691322921c08e19bddf6d3c5Thomas Graf pg_nest = nla_nest_start(skb, DCB_ATTR_PG_CFG); 5822f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!pg_nest) 5833d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EMSGSIZE; 5842f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 5852f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (pg_tb[DCB_PG_ATTR_TC_ALL]) 5862f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck getall = 1; 5872f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 5882f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck for (i = DCB_PG_ATTR_TC_0; i <= DCB_PG_ATTR_TC_7; i++) { 5892f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!getall && !pg_tb[i]) 5902f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck continue; 5912f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 5922f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (pg_tb[DCB_PG_ATTR_TC_ALL]) 5932f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck data = pg_tb[DCB_PG_ATTR_TC_ALL]; 5942f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck else 5952f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck data = pg_tb[i]; 5962f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = nla_parse_nested(param_tb, DCB_TC_ATTR_PARAM_MAX, 5972f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck data, dcbnl_tc_param_nest); 5982f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 5992f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err_pg; 6002f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 6017be994138b188387691322921c08e19bddf6d3c5Thomas Graf param_nest = nla_nest_start(skb, i); 6022f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!param_nest) 6032f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err_pg; 6042f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 6052f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck pgid = DCB_ATTR_VALUE_UNDEFINED; 6062f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck prio = DCB_ATTR_VALUE_UNDEFINED; 6072f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck tc_pct = DCB_ATTR_VALUE_UNDEFINED; 6082f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck up_map = DCB_ATTR_VALUE_UNDEFINED; 6092f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 6102f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (dir) { 6112f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck /* Rx */ 6122f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck netdev->dcbnl_ops->getpgtccfgrx(netdev, 6132f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck i - DCB_PG_ATTR_TC_0, &prio, 6142f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck &pgid, &tc_pct, &up_map); 6152f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } else { 6162f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck /* Tx */ 6172f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck netdev->dcbnl_ops->getpgtccfgtx(netdev, 6182f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck i - DCB_PG_ATTR_TC_0, &prio, 6192f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck &pgid, &tc_pct, &up_map); 6202f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 6212f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 6222f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (param_tb[DCB_TC_ATTR_PARAM_PGID] || 6232f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck param_tb[DCB_TC_ATTR_PARAM_ALL]) { 6247be994138b188387691322921c08e19bddf6d3c5Thomas Graf ret = nla_put_u8(skb, 6252f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck DCB_TC_ATTR_PARAM_PGID, pgid); 6262f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 6272f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err_param; 6282f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 6292f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (param_tb[DCB_TC_ATTR_PARAM_UP_MAPPING] || 6302f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck param_tb[DCB_TC_ATTR_PARAM_ALL]) { 6317be994138b188387691322921c08e19bddf6d3c5Thomas Graf ret = nla_put_u8(skb, 6322f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck DCB_TC_ATTR_PARAM_UP_MAPPING, up_map); 6332f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 6342f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err_param; 6352f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 6362f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (param_tb[DCB_TC_ATTR_PARAM_STRICT_PRIO] || 6372f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck param_tb[DCB_TC_ATTR_PARAM_ALL]) { 6387be994138b188387691322921c08e19bddf6d3c5Thomas Graf ret = nla_put_u8(skb, 6392f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck DCB_TC_ATTR_PARAM_STRICT_PRIO, prio); 6402f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 6412f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err_param; 6422f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 6432f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (param_tb[DCB_TC_ATTR_PARAM_BW_PCT] || 6442f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck param_tb[DCB_TC_ATTR_PARAM_ALL]) { 6457be994138b188387691322921c08e19bddf6d3c5Thomas Graf ret = nla_put_u8(skb, DCB_TC_ATTR_PARAM_BW_PCT, 6462f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck tc_pct); 6472f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 6482f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err_param; 6492f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 6507be994138b188387691322921c08e19bddf6d3c5Thomas Graf nla_nest_end(skb, param_nest); 6512f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 6522f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 6532f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (pg_tb[DCB_PG_ATTR_BW_ID_ALL]) 6542f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck getall = 1; 6552f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck else 6562f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck getall = 0; 6572f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 6582f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck for (i = DCB_PG_ATTR_BW_ID_0; i <= DCB_PG_ATTR_BW_ID_7; i++) { 6592f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!getall && !pg_tb[i]) 6602f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck continue; 6612f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 6622f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck tc_pct = DCB_ATTR_VALUE_UNDEFINED; 6632f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 6642f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (dir) { 6652f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck /* Rx */ 6662f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck netdev->dcbnl_ops->getpgbwgcfgrx(netdev, 6672f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck i - DCB_PG_ATTR_BW_ID_0, &tc_pct); 6682f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } else { 6692f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck /* Tx */ 6702f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck netdev->dcbnl_ops->getpgbwgcfgtx(netdev, 6712f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck i - DCB_PG_ATTR_BW_ID_0, &tc_pct); 6722f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 6737be994138b188387691322921c08e19bddf6d3c5Thomas Graf ret = nla_put_u8(skb, i, tc_pct); 6742f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 6752f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err_pg; 6762f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 6772f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 6787be994138b188387691322921c08e19bddf6d3c5Thomas Graf nla_nest_end(skb, pg_nest); 6792f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 6802f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return 0; 6812f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 6822f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckerr_param: 6837be994138b188387691322921c08e19bddf6d3c5Thomas Graf nla_nest_cancel(skb, param_nest); 6842f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckerr_pg: 6857be994138b188387691322921c08e19bddf6d3c5Thomas Graf nla_nest_cancel(skb, pg_nest); 6863d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf 6873d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EMSGSIZE; 6882f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 6892f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 6907be994138b188387691322921c08e19bddf6d3c5Thomas Grafstatic int dcbnl_pgtx_getcfg(struct net_device *netdev, struct nlmsghdr *nlh, 6917be994138b188387691322921c08e19bddf6d3c5Thomas Graf u32 seq, struct nlattr **tb, struct sk_buff *skb) 6922f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 6937be994138b188387691322921c08e19bddf6d3c5Thomas Graf return __dcbnl_pg_getcfg(netdev, nlh, tb, skb, 0); 6942f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 6952f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 6967be994138b188387691322921c08e19bddf6d3c5Thomas Grafstatic int dcbnl_pgrx_getcfg(struct net_device *netdev, struct nlmsghdr *nlh, 6977be994138b188387691322921c08e19bddf6d3c5Thomas Graf u32 seq, struct nlattr **tb, struct sk_buff *skb) 6982f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 6997be994138b188387691322921c08e19bddf6d3c5Thomas Graf return __dcbnl_pg_getcfg(netdev, nlh, tb, skb, 1); 7002f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 7012f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7027be994138b188387691322921c08e19bddf6d3c5Thomas Grafstatic int dcbnl_setstate(struct net_device *netdev, struct nlmsghdr *nlh, 7037be994138b188387691322921c08e19bddf6d3c5Thomas Graf u32 seq, struct nlattr **tb, struct sk_buff *skb) 7042f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 7052f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u8 value; 7062f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7073d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf if (!tb[DCB_ATTR_STATE]) 7087be994138b188387691322921c08e19bddf6d3c5Thomas Graf return -EINVAL; 7092f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7103d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf if (!netdev->dcbnl_ops->setstate) 7113d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EOPNOTSUPP; 7123d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf 7132f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck value = nla_get_u8(tb[DCB_ATTR_STATE]); 7142f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7157be994138b188387691322921c08e19bddf6d3c5Thomas Graf return nla_put_u8(skb, DCB_ATTR_STATE, 7167be994138b188387691322921c08e19bddf6d3c5Thomas Graf netdev->dcbnl_ops->setstate(netdev, value)); 7172f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 7182f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7197be994138b188387691322921c08e19bddf6d3c5Thomas Grafstatic int dcbnl_setpfccfg(struct net_device *netdev, struct nlmsghdr *nlh, 7207be994138b188387691322921c08e19bddf6d3c5Thomas Graf u32 seq, struct nlattr **tb, struct sk_buff *skb) 7212f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 7222f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct nlattr *data[DCB_PFC_UP_ATTR_MAX + 1]; 7232f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck int i; 7243d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf int ret; 7252f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u8 value; 7262f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7273d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf if (!tb[DCB_ATTR_PFC_CFG]) 7283d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EINVAL; 7293d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf 7303d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf if (!netdev->dcbnl_ops->setpfccfg) 7313d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EOPNOTSUPP; 7322f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7332f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = nla_parse_nested(data, DCB_PFC_UP_ATTR_MAX, 7342f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck tb[DCB_ATTR_PFC_CFG], 7352f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcbnl_pfc_up_nest); 7362f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 7373d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return ret; 7382f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7392f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck for (i = DCB_PFC_UP_ATTR_0; i <= DCB_PFC_UP_ATTR_7; i++) { 7402f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (data[i] == NULL) 7412f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck continue; 7422f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck value = nla_get_u8(data[i]); 7432f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck netdev->dcbnl_ops->setpfccfg(netdev, 7442f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck data[i]->nla_type - DCB_PFC_UP_ATTR_0, value); 7452f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 7462f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7477be994138b188387691322921c08e19bddf6d3c5Thomas Graf return nla_put_u8(skb, DCB_ATTR_PFC_CFG, 0); 7482f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 7492f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7507be994138b188387691322921c08e19bddf6d3c5Thomas Grafstatic int dcbnl_setall(struct net_device *netdev, struct nlmsghdr *nlh, 7517be994138b188387691322921c08e19bddf6d3c5Thomas Graf u32 seq, struct nlattr **tb, struct sk_buff *skb) 7522f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 7533d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf int ret; 7542f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7553d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf if (!tb[DCB_ATTR_SET_ALL]) 7563d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EINVAL; 7573d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf 7583d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf if (!netdev->dcbnl_ops->setall) 7593d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EOPNOTSUPP; 7602f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7617be994138b188387691322921c08e19bddf6d3c5Thomas Graf ret = nla_put_u8(skb, DCB_ATTR_SET_ALL, 7627be994138b188387691322921c08e19bddf6d3c5Thomas Graf netdev->dcbnl_ops->setall(netdev)); 763081579840b4b2421e37bc67e3b089b7ca64ef040John Fastabend dcbnl_cee_notify(netdev, RTM_SETDCB, DCB_CMD_SET_ALL, seq, 0); 7642f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7652f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return ret; 7662f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 7672f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7687be994138b188387691322921c08e19bddf6d3c5Thomas Grafstatic int __dcbnl_pg_setcfg(struct net_device *netdev, struct nlmsghdr *nlh, 7697be994138b188387691322921c08e19bddf6d3c5Thomas Graf u32 seq, struct nlattr **tb, struct sk_buff *skb, 7707be994138b188387691322921c08e19bddf6d3c5Thomas Graf int dir) 7712f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 7722f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct nlattr *pg_tb[DCB_PG_ATTR_MAX + 1]; 7732f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct nlattr *param_tb[DCB_TC_ATTR_PARAM_MAX + 1]; 7743d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf int ret; 7752f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck int i; 7762f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u8 pgid; 7772f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u8 up_map; 7782f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u8 prio; 7792f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u8 tc_pct; 7802f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7813d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf if (!tb[DCB_ATTR_PG_CFG]) 7823d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EINVAL; 7833d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf 7843d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf if (!netdev->dcbnl_ops->setpgtccfgtx || 7852f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck !netdev->dcbnl_ops->setpgtccfgrx || 7862f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck !netdev->dcbnl_ops->setpgbwgcfgtx || 7872f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck !netdev->dcbnl_ops->setpgbwgcfgrx) 7883d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EOPNOTSUPP; 7892f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7902f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = nla_parse_nested(pg_tb, DCB_PG_ATTR_MAX, 7912f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck tb[DCB_ATTR_PG_CFG], dcbnl_pg_nest); 7922f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 7933d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return ret; 7942f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7952f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck for (i = DCB_PG_ATTR_TC_0; i <= DCB_PG_ATTR_TC_7; i++) { 7962f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!pg_tb[i]) 7972f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck continue; 7982f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7992f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = nla_parse_nested(param_tb, DCB_TC_ATTR_PARAM_MAX, 8002f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck pg_tb[i], dcbnl_tc_param_nest); 8012f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 8023d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return ret; 8032f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8042f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck pgid = DCB_ATTR_VALUE_UNDEFINED; 8052f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck prio = DCB_ATTR_VALUE_UNDEFINED; 8062f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck tc_pct = DCB_ATTR_VALUE_UNDEFINED; 8072f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck up_map = DCB_ATTR_VALUE_UNDEFINED; 8082f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8092f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (param_tb[DCB_TC_ATTR_PARAM_STRICT_PRIO]) 8102f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck prio = 8112f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nla_get_u8(param_tb[DCB_TC_ATTR_PARAM_STRICT_PRIO]); 8122f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8132f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (param_tb[DCB_TC_ATTR_PARAM_PGID]) 8142f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck pgid = nla_get_u8(param_tb[DCB_TC_ATTR_PARAM_PGID]); 8152f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8162f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (param_tb[DCB_TC_ATTR_PARAM_BW_PCT]) 8172f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck tc_pct = nla_get_u8(param_tb[DCB_TC_ATTR_PARAM_BW_PCT]); 8182f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8192f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (param_tb[DCB_TC_ATTR_PARAM_UP_MAPPING]) 8202f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck up_map = 8212f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nla_get_u8(param_tb[DCB_TC_ATTR_PARAM_UP_MAPPING]); 8222f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8232f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck /* dir: Tx = 0, Rx = 1 */ 8242f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (dir) { 8252f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck /* Rx */ 8262f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck netdev->dcbnl_ops->setpgtccfgrx(netdev, 8272f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck i - DCB_PG_ATTR_TC_0, 8282f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck prio, pgid, tc_pct, up_map); 8292f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } else { 8302f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck /* Tx */ 8312f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck netdev->dcbnl_ops->setpgtccfgtx(netdev, 8322f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck i - DCB_PG_ATTR_TC_0, 8332f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck prio, pgid, tc_pct, up_map); 8342f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 8352f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 8362f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8372f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck for (i = DCB_PG_ATTR_BW_ID_0; i <= DCB_PG_ATTR_BW_ID_7; i++) { 8382f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!pg_tb[i]) 8392f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck continue; 8402f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8412f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck tc_pct = nla_get_u8(pg_tb[i]); 8422f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8432f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck /* dir: Tx = 0, Rx = 1 */ 8442f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (dir) { 8452f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck /* Rx */ 8462f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck netdev->dcbnl_ops->setpgbwgcfgrx(netdev, 8472f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck i - DCB_PG_ATTR_BW_ID_0, tc_pct); 8482f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } else { 8492f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck /* Tx */ 8502f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck netdev->dcbnl_ops->setpgbwgcfgtx(netdev, 8512f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck i - DCB_PG_ATTR_BW_ID_0, tc_pct); 8522f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 8532f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 8542f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 855bb1dfefdc62fa68107c4c9f1374cb856743a9434John Fastabend return nla_put_u8(skb, DCB_ATTR_PG_CFG, 0); 8562f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 8572f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8587be994138b188387691322921c08e19bddf6d3c5Thomas Grafstatic int dcbnl_pgtx_setcfg(struct net_device *netdev, struct nlmsghdr *nlh, 8597be994138b188387691322921c08e19bddf6d3c5Thomas Graf u32 seq, struct nlattr **tb, struct sk_buff *skb) 8602f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 8617be994138b188387691322921c08e19bddf6d3c5Thomas Graf return __dcbnl_pg_setcfg(netdev, nlh, seq, tb, skb, 0); 8622f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 8632f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8647be994138b188387691322921c08e19bddf6d3c5Thomas Grafstatic int dcbnl_pgrx_setcfg(struct net_device *netdev, struct nlmsghdr *nlh, 8657be994138b188387691322921c08e19bddf6d3c5Thomas Graf u32 seq, struct nlattr **tb, struct sk_buff *skb) 8662f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 8677be994138b188387691322921c08e19bddf6d3c5Thomas Graf return __dcbnl_pg_setcfg(netdev, nlh, seq, tb, skb, 1); 8682f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 8692f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8707be994138b188387691322921c08e19bddf6d3c5Thomas Grafstatic int dcbnl_bcn_getcfg(struct net_device *netdev, struct nlmsghdr *nlh, 8717be994138b188387691322921c08e19bddf6d3c5Thomas Graf u32 seq, struct nlattr **tb, struct sk_buff *skb) 872859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck{ 873859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck struct nlattr *bcn_nest; 874859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck struct nlattr *bcn_tb[DCB_BCN_ATTR_MAX + 1]; 875859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck u8 value_byte; 876859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck u32 value_integer; 8773d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf int ret; 878859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck bool getall = false; 879859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck int i; 880859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 8813d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf if (!tb[DCB_ATTR_BCN]) 8823d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EINVAL; 8833d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf 8843d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf if (!netdev->dcbnl_ops->getbcnrp || 885859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck !netdev->dcbnl_ops->getbcncfg) 8863d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EOPNOTSUPP; 887859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 888859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck ret = nla_parse_nested(bcn_tb, DCB_BCN_ATTR_MAX, 889859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck tb[DCB_ATTR_BCN], dcbnl_bcn_nest); 890859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck if (ret) 8913d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return ret; 892859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 8937be994138b188387691322921c08e19bddf6d3c5Thomas Graf bcn_nest = nla_nest_start(skb, DCB_ATTR_BCN); 894859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck if (!bcn_nest) 8953d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EMSGSIZE; 896859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 897859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck if (bcn_tb[DCB_BCN_ATTR_ALL]) 898859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck getall = true; 899859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 900859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck for (i = DCB_BCN_ATTR_RP_0; i <= DCB_BCN_ATTR_RP_7; i++) { 901859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck if (!getall && !bcn_tb[i]) 902859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck continue; 903859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 904859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck netdev->dcbnl_ops->getbcnrp(netdev, i - DCB_BCN_ATTR_RP_0, 905859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck &value_byte); 9067be994138b188387691322921c08e19bddf6d3c5Thomas Graf ret = nla_put_u8(skb, i, value_byte); 907859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck if (ret) 908859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck goto err_bcn; 909859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck } 910859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 911f4314e815e87b4ab1c9b1115dd5853cd20ca999cDon Skidmore for (i = DCB_BCN_ATTR_BCNA_0; i <= DCB_BCN_ATTR_RI; i++) { 912859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck if (!getall && !bcn_tb[i]) 913859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck continue; 914859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 915859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck netdev->dcbnl_ops->getbcncfg(netdev, i, 916859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck &value_integer); 9177be994138b188387691322921c08e19bddf6d3c5Thomas Graf ret = nla_put_u32(skb, i, value_integer); 918859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck if (ret) 919859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck goto err_bcn; 920859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck } 921859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 9227be994138b188387691322921c08e19bddf6d3c5Thomas Graf nla_nest_end(skb, bcn_nest); 923859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 924859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck return 0; 925859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 926859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyckerr_bcn: 9277be994138b188387691322921c08e19bddf6d3c5Thomas Graf nla_nest_cancel(skb, bcn_nest); 928859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck return ret; 929859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck} 930859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 9317be994138b188387691322921c08e19bddf6d3c5Thomas Grafstatic int dcbnl_bcn_setcfg(struct net_device *netdev, struct nlmsghdr *nlh, 9327be994138b188387691322921c08e19bddf6d3c5Thomas Graf u32 seq, struct nlattr **tb, struct sk_buff *skb) 933859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck{ 934859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck struct nlattr *data[DCB_BCN_ATTR_MAX + 1]; 935859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck int i; 9363d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf int ret; 937859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck u8 value_byte; 938859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck u32 value_int; 939859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 9403d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf if (!tb[DCB_ATTR_BCN]) 9413d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EINVAL; 9423d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf 9433d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf if (!netdev->dcbnl_ops->setbcncfg || 944f64f9e719261a87818dd192a3a2352e5b20fbd0fJoe Perches !netdev->dcbnl_ops->setbcnrp) 9453d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EOPNOTSUPP; 946859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 947859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck ret = nla_parse_nested(data, DCB_BCN_ATTR_MAX, 948859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck tb[DCB_ATTR_BCN], 949859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck dcbnl_pfc_up_nest); 950859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck if (ret) 9513d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return ret; 952859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 953859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck for (i = DCB_BCN_ATTR_RP_0; i <= DCB_BCN_ATTR_RP_7; i++) { 954859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck if (data[i] == NULL) 955859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck continue; 956859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck value_byte = nla_get_u8(data[i]); 957859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck netdev->dcbnl_ops->setbcnrp(netdev, 958859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck data[i]->nla_type - DCB_BCN_ATTR_RP_0, value_byte); 959859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck } 960859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 961f4314e815e87b4ab1c9b1115dd5853cd20ca999cDon Skidmore for (i = DCB_BCN_ATTR_BCNA_0; i <= DCB_BCN_ATTR_RI; i++) { 962859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck if (data[i] == NULL) 963859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck continue; 964859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck value_int = nla_get_u32(data[i]); 965859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck netdev->dcbnl_ops->setbcncfg(netdev, 966859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck i, value_int); 967859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck } 968859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 9693d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return nla_put_u8(skb, DCB_ATTR_BCN, 0); 970859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck} 971859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 972dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravidstatic int dcbnl_build_peer_app(struct net_device *netdev, struct sk_buff* skb, 973dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid int app_nested_type, int app_info_type, 974dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid int app_entry_type) 975eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid{ 976eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid struct dcb_peer_app_info info; 977eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid struct dcb_app *table = NULL; 978eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops; 979eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid u16 app_count; 980eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid int err; 981eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid 982eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid 983eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid /** 984eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid * retrieve the peer app configuration form the driver. If the driver 985eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid * handlers fail exit without doing anything 986eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid */ 987eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid err = ops->peer_getappinfo(netdev, &info, &app_count); 988eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid if (!err && app_count) { 989eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid table = kmalloc(sizeof(struct dcb_app) * app_count, GFP_KERNEL); 990eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid if (!table) 991eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid return -ENOMEM; 992eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid 993eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid err = ops->peer_getapptable(netdev, table); 994eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid } 995eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid 996eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid if (!err) { 997eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid u16 i; 998eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid struct nlattr *app; 999eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid 1000eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid /** 1001eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid * build the message, from here on the only possible failure 1002eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid * is due to the skb size 1003eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid */ 1004eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid err = -EMSGSIZE; 1005eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid 1006dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid app = nla_nest_start(skb, app_nested_type); 1007eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid if (!app) 1008eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid goto nla_put_failure; 1009eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid 10101eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller if (app_info_type && 10111eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller nla_put(skb, app_info_type, sizeof(info), &info)) 10121eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller goto nla_put_failure; 1013eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid 10141eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller for (i = 0; i < app_count; i++) { 10151eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller if (nla_put(skb, app_entry_type, sizeof(struct dcb_app), 10161eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller &table[i])) 10171eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller goto nla_put_failure; 10181eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller } 1019eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid nla_nest_end(skb, app); 1020eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid } 1021eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid err = 0; 1022eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid 1023eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravidnla_put_failure: 1024eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid kfree(table); 1025eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid return err; 1026eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid} 10273e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend 10283e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend/* Handle IEEE 802.1Qaz GET commands. */ 1029314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabendstatic int dcbnl_ieee_fill(struct sk_buff *skb, struct net_device *netdev) 10303e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend{ 10319ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend struct nlattr *ieee, *app; 10329ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend struct dcb_app_type *itr; 10333e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops; 1034c7797baf9f3900996ca800ab6298f95957bb4606John Fastabend int dcbx; 10353d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf int err; 10363e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend 10371eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller if (nla_put_string(skb, DCB_ATTR_IFNAME, netdev->name)) 10383d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EMSGSIZE; 10393d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf 10403e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend ieee = nla_nest_start(skb, DCB_ATTR_IEEE); 10413e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend if (!ieee) 10423d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EMSGSIZE; 10433e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend 10443e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend if (ops->ieee_getets) { 10453e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend struct ieee_ets ets; 104629cd8ae0e1a39e239a3a7b67da1986add1199fc0Mathias Krause memset(&ets, 0, sizeof(ets)); 10473e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend err = ops->ieee_getets(netdev, &ets); 10481eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller if (!err && 10491eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller nla_put(skb, DCB_ATTR_IEEE_ETS, sizeof(ets), &ets)) 10503d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EMSGSIZE; 10513e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend } 10523e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend 105308f10affe45051e18e0d8291c0a53aecef1b8a14Amir Vadai if (ops->ieee_getmaxrate) { 105408f10affe45051e18e0d8291c0a53aecef1b8a14Amir Vadai struct ieee_maxrate maxrate; 105529cd8ae0e1a39e239a3a7b67da1986add1199fc0Mathias Krause memset(&maxrate, 0, sizeof(maxrate)); 105608f10affe45051e18e0d8291c0a53aecef1b8a14Amir Vadai err = ops->ieee_getmaxrate(netdev, &maxrate); 105708f10affe45051e18e0d8291c0a53aecef1b8a14Amir Vadai if (!err) { 105808f10affe45051e18e0d8291c0a53aecef1b8a14Amir Vadai err = nla_put(skb, DCB_ATTR_IEEE_MAXRATE, 105908f10affe45051e18e0d8291c0a53aecef1b8a14Amir Vadai sizeof(maxrate), &maxrate); 106008f10affe45051e18e0d8291c0a53aecef1b8a14Amir Vadai if (err) 10613d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EMSGSIZE; 106208f10affe45051e18e0d8291c0a53aecef1b8a14Amir Vadai } 106308f10affe45051e18e0d8291c0a53aecef1b8a14Amir Vadai } 106408f10affe45051e18e0d8291c0a53aecef1b8a14Amir Vadai 10653e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend if (ops->ieee_getpfc) { 10663e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend struct ieee_pfc pfc; 106729cd8ae0e1a39e239a3a7b67da1986add1199fc0Mathias Krause memset(&pfc, 0, sizeof(pfc)); 10683e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend err = ops->ieee_getpfc(netdev, &pfc); 10691eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller if (!err && 10701eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller nla_put(skb, DCB_ATTR_IEEE_PFC, sizeof(pfc), &pfc)) 10713d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EMSGSIZE; 10723e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend } 10733e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend 10749ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend app = nla_nest_start(skb, DCB_ATTR_IEEE_APP_TABLE); 10759ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend if (!app) 10763d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EMSGSIZE; 10779ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend 10789ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend spin_lock(&dcb_lock); 10799ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend list_for_each_entry(itr, &dcb_app_list, list) { 1080e290ed81307ca7d92675f0d9c683add693c2f377Mark Rustad if (itr->ifindex == netdev->ifindex) { 108170bfa2d2e1bfd90ef26758b5e2749f043a940037Dan Carpenter err = nla_put(skb, DCB_ATTR_IEEE_APP, sizeof(itr->app), 108270bfa2d2e1bfd90ef26758b5e2749f043a940037Dan Carpenter &itr->app); 108370bfa2d2e1bfd90ef26758b5e2749f043a940037Dan Carpenter if (err) { 108470bfa2d2e1bfd90ef26758b5e2749f043a940037Dan Carpenter spin_unlock(&dcb_lock); 10853d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EMSGSIZE; 108670bfa2d2e1bfd90ef26758b5e2749f043a940037Dan Carpenter } 108770bfa2d2e1bfd90ef26758b5e2749f043a940037Dan Carpenter } 10889ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend } 1089c7797baf9f3900996ca800ab6298f95957bb4606John Fastabend 1090c7797baf9f3900996ca800ab6298f95957bb4606John Fastabend if (netdev->dcbnl_ops->getdcbx) 1091c7797baf9f3900996ca800ab6298f95957bb4606John Fastabend dcbx = netdev->dcbnl_ops->getdcbx(netdev); 1092c7797baf9f3900996ca800ab6298f95957bb4606John Fastabend else 1093c7797baf9f3900996ca800ab6298f95957bb4606John Fastabend dcbx = -EOPNOTSUPP; 1094c7797baf9f3900996ca800ab6298f95957bb4606John Fastabend 10959ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend spin_unlock(&dcb_lock); 10969ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend nla_nest_end(skb, app); 10979ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend 1098eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid /* get peer info if available */ 1099eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid if (ops->ieee_peer_getets) { 1100eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid struct ieee_ets ets; 110129cd8ae0e1a39e239a3a7b67da1986add1199fc0Mathias Krause memset(&ets, 0, sizeof(ets)); 1102eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid err = ops->ieee_peer_getets(netdev, &ets); 11031eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller if (!err && 11041eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller nla_put(skb, DCB_ATTR_IEEE_PEER_ETS, sizeof(ets), &ets)) 11053d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EMSGSIZE; 1106eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid } 1107eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid 1108eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid if (ops->ieee_peer_getpfc) { 1109eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid struct ieee_pfc pfc; 111029cd8ae0e1a39e239a3a7b67da1986add1199fc0Mathias Krause memset(&pfc, 0, sizeof(pfc)); 1111eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid err = ops->ieee_peer_getpfc(netdev, &pfc); 11121eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller if (!err && 11131eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller nla_put(skb, DCB_ATTR_IEEE_PEER_PFC, sizeof(pfc), &pfc)) 11143d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EMSGSIZE; 1115eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid } 1116eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid 1117eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid if (ops->peer_getappinfo && ops->peer_getapptable) { 1118dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid err = dcbnl_build_peer_app(netdev, skb, 1119dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid DCB_ATTR_IEEE_PEER_APP, 1120dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid DCB_ATTR_IEEE_APP_UNSPEC, 1121dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid DCB_ATTR_IEEE_APP); 1122eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid if (err) 11233d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EMSGSIZE; 1124eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid } 1125eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid 11263e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend nla_nest_end(skb, ieee); 1127c7797baf9f3900996ca800ab6298f95957bb4606John Fastabend if (dcbx >= 0) { 1128c7797baf9f3900996ca800ab6298f95957bb4606John Fastabend err = nla_put_u8(skb, DCB_ATTR_DCBX, dcbx); 1129c7797baf9f3900996ca800ab6298f95957bb4606John Fastabend if (err) 11303d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EMSGSIZE; 1131c7797baf9f3900996ca800ab6298f95957bb4606John Fastabend } 11323e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend 1133314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend return 0; 11343e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend} 11353e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend 11365b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravidstatic int dcbnl_cee_pg_fill(struct sk_buff *skb, struct net_device *dev, 11375b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid int dir) 11385b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid{ 11395b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid u8 pgid, up_map, prio, tc_pct; 11405b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid const struct dcbnl_rtnl_ops *ops = dev->dcbnl_ops; 11415b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid int i = dir ? DCB_ATTR_CEE_TX_PG : DCB_ATTR_CEE_RX_PG; 11425b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid struct nlattr *pg = nla_nest_start(skb, i); 11435b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 11445b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (!pg) 11453d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EMSGSIZE; 11465b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 11475b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid for (i = DCB_PG_ATTR_TC_0; i <= DCB_PG_ATTR_TC_7; i++) { 11485b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid struct nlattr *tc_nest = nla_nest_start(skb, i); 11495b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 11505b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (!tc_nest) 11513d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EMSGSIZE; 11525b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 11535b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid pgid = DCB_ATTR_VALUE_UNDEFINED; 11545b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid prio = DCB_ATTR_VALUE_UNDEFINED; 11555b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid tc_pct = DCB_ATTR_VALUE_UNDEFINED; 11565b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid up_map = DCB_ATTR_VALUE_UNDEFINED; 11575b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 11585b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (!dir) 11595b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid ops->getpgtccfgrx(dev, i - DCB_PG_ATTR_TC_0, 11605b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid &prio, &pgid, &tc_pct, &up_map); 11615b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid else 11625b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid ops->getpgtccfgtx(dev, i - DCB_PG_ATTR_TC_0, 11635b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid &prio, &pgid, &tc_pct, &up_map); 11645b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 11651eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller if (nla_put_u8(skb, DCB_TC_ATTR_PARAM_PGID, pgid) || 11661eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller nla_put_u8(skb, DCB_TC_ATTR_PARAM_UP_MAPPING, up_map) || 11671eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller nla_put_u8(skb, DCB_TC_ATTR_PARAM_STRICT_PRIO, prio) || 11681eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller nla_put_u8(skb, DCB_TC_ATTR_PARAM_BW_PCT, tc_pct)) 11693d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EMSGSIZE; 11705b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid nla_nest_end(skb, tc_nest); 11715b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid } 11725b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 11735b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid for (i = DCB_PG_ATTR_BW_ID_0; i <= DCB_PG_ATTR_BW_ID_7; i++) { 11745b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid tc_pct = DCB_ATTR_VALUE_UNDEFINED; 11755b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 11765b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (!dir) 11775b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid ops->getpgbwgcfgrx(dev, i - DCB_PG_ATTR_BW_ID_0, 11785b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid &tc_pct); 11795b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid else 11805b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid ops->getpgbwgcfgtx(dev, i - DCB_PG_ATTR_BW_ID_0, 11815b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid &tc_pct); 11821eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller if (nla_put_u8(skb, i, tc_pct)) 11833d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EMSGSIZE; 11845b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid } 11855b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid nla_nest_end(skb, pg); 11865b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid return 0; 11875b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid} 11885b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 11895b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravidstatic int dcbnl_cee_fill(struct sk_buff *skb, struct net_device *netdev) 11905b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid{ 11915b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid struct nlattr *cee, *app; 11925b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid struct dcb_app_type *itr; 11935b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops; 11945b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid int dcbx, i, err = -EMSGSIZE; 11955b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid u8 value; 11965b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 11971eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller if (nla_put_string(skb, DCB_ATTR_IFNAME, netdev->name)) 11981eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller goto nla_put_failure; 11995b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid cee = nla_nest_start(skb, DCB_ATTR_CEE); 12005b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (!cee) 12015b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid goto nla_put_failure; 12025b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 12035b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid /* local pg */ 12045b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (ops->getpgtccfgtx && ops->getpgbwgcfgtx) { 12055b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid err = dcbnl_cee_pg_fill(skb, netdev, 1); 12065b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (err) 12075b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid goto nla_put_failure; 12085b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid } 12095b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 12105b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (ops->getpgtccfgrx && ops->getpgbwgcfgrx) { 12115b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid err = dcbnl_cee_pg_fill(skb, netdev, 0); 12125b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (err) 12135b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid goto nla_put_failure; 12145b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid } 12155b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 12165b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid /* local pfc */ 12175b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (ops->getpfccfg) { 12185b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid struct nlattr *pfc_nest = nla_nest_start(skb, DCB_ATTR_CEE_PFC); 12195b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 12205b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (!pfc_nest) 12215b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid goto nla_put_failure; 12225b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 12235b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid for (i = DCB_PFC_UP_ATTR_0; i <= DCB_PFC_UP_ATTR_7; i++) { 12245b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid ops->getpfccfg(netdev, i - DCB_PFC_UP_ATTR_0, &value); 12251eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller if (nla_put_u8(skb, i, value)) 12261eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller goto nla_put_failure; 12275b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid } 12285b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid nla_nest_end(skb, pfc_nest); 12295b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid } 12305b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 12315b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid /* local app */ 12325b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid spin_lock(&dcb_lock); 12335b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid app = nla_nest_start(skb, DCB_ATTR_CEE_APP_TABLE); 12345b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (!app) 123540f5d72a4fc098c47068e3888cfb055922f6519fDan Carpenter goto dcb_unlock; 12365b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 12375b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid list_for_each_entry(itr, &dcb_app_list, list) { 1238e290ed81307ca7d92675f0d9c683add693c2f377Mark Rustad if (itr->ifindex == netdev->ifindex) { 12395b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid struct nlattr *app_nest = nla_nest_start(skb, 12405b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid DCB_ATTR_APP); 12415b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (!app_nest) 12425b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid goto dcb_unlock; 12435b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 12445b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid err = nla_put_u8(skb, DCB_APP_ATTR_IDTYPE, 12455b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid itr->app.selector); 12465b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (err) 12475b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid goto dcb_unlock; 12485b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 12495b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid err = nla_put_u16(skb, DCB_APP_ATTR_ID, 12505b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid itr->app.protocol); 12515b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (err) 12525b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid goto dcb_unlock; 12535b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 12545b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid err = nla_put_u8(skb, DCB_APP_ATTR_PRIORITY, 12555b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid itr->app.priority); 12565b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (err) 12575b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid goto dcb_unlock; 12585b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 12595b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid nla_nest_end(skb, app_nest); 12605b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid } 12615b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid } 12625b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid nla_nest_end(skb, app); 12635b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 12645b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (netdev->dcbnl_ops->getdcbx) 12655b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid dcbx = netdev->dcbnl_ops->getdcbx(netdev); 12665b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid else 12675b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid dcbx = -EOPNOTSUPP; 12685b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 12695b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid spin_unlock(&dcb_lock); 12705b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 12715b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid /* features flags */ 12725b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (ops->getfeatcfg) { 12735b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid struct nlattr *feat = nla_nest_start(skb, DCB_ATTR_CEE_FEAT); 12745b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (!feat) 12755b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid goto nla_put_failure; 12765b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 12775b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid for (i = DCB_FEATCFG_ATTR_ALL + 1; i <= DCB_FEATCFG_ATTR_MAX; 12785b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid i++) 12791eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller if (!ops->getfeatcfg(netdev, i, &value) && 12801eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller nla_put_u8(skb, i, value)) 12811eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller goto nla_put_failure; 12825b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 12835b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid nla_nest_end(skb, feat); 12845b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid } 12855b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 12865b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid /* peer info if available */ 12875b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (ops->cee_peer_getpg) { 12885b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid struct cee_pg pg; 128929cd8ae0e1a39e239a3a7b67da1986add1199fc0Mathias Krause memset(&pg, 0, sizeof(pg)); 12905b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid err = ops->cee_peer_getpg(netdev, &pg); 12911eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller if (!err && 12921eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller nla_put(skb, DCB_ATTR_CEE_PEER_PG, sizeof(pg), &pg)) 12931eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller goto nla_put_failure; 12945b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid } 12955b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 12965b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (ops->cee_peer_getpfc) { 12975b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid struct cee_pfc pfc; 129829cd8ae0e1a39e239a3a7b67da1986add1199fc0Mathias Krause memset(&pfc, 0, sizeof(pfc)); 12995b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid err = ops->cee_peer_getpfc(netdev, &pfc); 13001eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller if (!err && 13011eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller nla_put(skb, DCB_ATTR_CEE_PEER_PFC, sizeof(pfc), &pfc)) 13021eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller goto nla_put_failure; 13035b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid } 13045b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 13055b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (ops->peer_getappinfo && ops->peer_getapptable) { 13065b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid err = dcbnl_build_peer_app(netdev, skb, 13075b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid DCB_ATTR_CEE_PEER_APP_TABLE, 13085b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid DCB_ATTR_CEE_PEER_APP_INFO, 13095b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid DCB_ATTR_CEE_PEER_APP); 13105b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (err) 13115b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid goto nla_put_failure; 13125b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid } 13135b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid nla_nest_end(skb, cee); 13145b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 13155b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid /* DCBX state */ 13165b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (dcbx >= 0) { 13175b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid err = nla_put_u8(skb, DCB_ATTR_DCBX, dcbx); 13185b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (err) 13195b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid goto nla_put_failure; 13205b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid } 13215b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid return 0; 13225b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 13235b7f7626743e0912958981343b47ac0ab2206b1cShmulik Raviddcb_unlock: 13245b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid spin_unlock(&dcb_lock); 13255b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravidnla_put_failure: 13265b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid return err; 13275b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid} 13285b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 13295b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravidstatic int dcbnl_notify(struct net_device *dev, int event, int cmd, 133015e473046cb6e5d18a4d0057e61d76315230382bEric W. Biederman u32 seq, u32 portid, int dcbx_ver) 1331314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend{ 1332314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend struct net *net = dev_net(dev); 1333314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend struct sk_buff *skb; 1334314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend struct nlmsghdr *nlh; 1335314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend const struct dcbnl_rtnl_ops *ops = dev->dcbnl_ops; 1336314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend int err; 1337314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend 1338314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend if (!ops) 1339314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend return -EOPNOTSUPP; 1340314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend 134115e473046cb6e5d18a4d0057e61d76315230382bEric W. Biederman skb = dcbnl_newmsg(event, cmd, portid, seq, 0, &nlh); 1342314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend if (!skb) 1343314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend return -ENOBUFS; 1344314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend 13455b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (dcbx_ver == DCB_CAP_DCBX_VER_IEEE) 13465b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid err = dcbnl_ieee_fill(skb, dev); 13475b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid else 13485b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid err = dcbnl_cee_fill(skb, dev); 13495b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 1350314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend if (err < 0) { 1351314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend /* Report error to broadcast listeners */ 1352ab6d470735682a6e1ba889a66f56eb1640242096Thomas Graf nlmsg_free(skb); 1353314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend rtnl_set_sk_err(net, RTNLGRP_DCB, err); 1354314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend } else { 1355314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend /* End nlmsg and notify broadcast listeners */ 1356314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend nlmsg_end(skb, nlh); 1357314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend rtnl_notify(skb, net, 0, RTNLGRP_DCB, NULL, GFP_KERNEL); 1358314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend } 1359314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend 1360314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend return err; 1361314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend} 13625b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 13635b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravidint dcbnl_ieee_notify(struct net_device *dev, int event, int cmd, 136415e473046cb6e5d18a4d0057e61d76315230382bEric W. Biederman u32 seq, u32 portid) 13655b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid{ 136615e473046cb6e5d18a4d0057e61d76315230382bEric W. Biederman return dcbnl_notify(dev, event, cmd, seq, portid, DCB_CAP_DCBX_VER_IEEE); 13675b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid} 13685b7f7626743e0912958981343b47ac0ab2206b1cShmulik RavidEXPORT_SYMBOL(dcbnl_ieee_notify); 13695b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 13705b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravidint dcbnl_cee_notify(struct net_device *dev, int event, int cmd, 137115e473046cb6e5d18a4d0057e61d76315230382bEric W. Biederman u32 seq, u32 portid) 13725b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid{ 137315e473046cb6e5d18a4d0057e61d76315230382bEric W. Biederman return dcbnl_notify(dev, event, cmd, seq, portid, DCB_CAP_DCBX_VER_CEE); 13745b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid} 13755b7f7626743e0912958981343b47ac0ab2206b1cShmulik RavidEXPORT_SYMBOL(dcbnl_cee_notify); 1376314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend 1377314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend/* Handle IEEE 802.1Qaz SET commands. If any requested operation can not 1378314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend * be completed the entire msg is aborted and error value is returned. 1379314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend * No attempt is made to reconcile the case where only part of the 1380314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend * cmd can be completed. 1381314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend */ 13827be994138b188387691322921c08e19bddf6d3c5Thomas Grafstatic int dcbnl_ieee_set(struct net_device *netdev, struct nlmsghdr *nlh, 13837be994138b188387691322921c08e19bddf6d3c5Thomas Graf u32 seq, struct nlattr **tb, struct sk_buff *skb) 1384314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend{ 1385314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops; 1386314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend struct nlattr *ieee[DCB_ATTR_IEEE_MAX + 1]; 13873d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf int err; 1388314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend 1389314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend if (!ops) 13903d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EOPNOTSUPP; 1391314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend 13924003b65871c101eb5ce8f37a325feac54aa5c681John Fastabend if (!tb[DCB_ATTR_IEEE]) 13934003b65871c101eb5ce8f37a325feac54aa5c681John Fastabend return -EINVAL; 13944003b65871c101eb5ce8f37a325feac54aa5c681John Fastabend 1395314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend err = nla_parse_nested(ieee, DCB_ATTR_IEEE_MAX, 1396314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend tb[DCB_ATTR_IEEE], dcbnl_ieee_policy); 1397314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend if (err) 1398314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend return err; 1399314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend 1400314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend if (ieee[DCB_ATTR_IEEE_ETS] && ops->ieee_setets) { 1401314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend struct ieee_ets *ets = nla_data(ieee[DCB_ATTR_IEEE_ETS]); 1402314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend err = ops->ieee_setets(netdev, ets); 1403314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend if (err) 1404314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend goto err; 1405314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend } 1406314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend 140708f10affe45051e18e0d8291c0a53aecef1b8a14Amir Vadai if (ieee[DCB_ATTR_IEEE_MAXRATE] && ops->ieee_setmaxrate) { 140808f10affe45051e18e0d8291c0a53aecef1b8a14Amir Vadai struct ieee_maxrate *maxrate = 140908f10affe45051e18e0d8291c0a53aecef1b8a14Amir Vadai nla_data(ieee[DCB_ATTR_IEEE_MAXRATE]); 141008f10affe45051e18e0d8291c0a53aecef1b8a14Amir Vadai err = ops->ieee_setmaxrate(netdev, maxrate); 141108f10affe45051e18e0d8291c0a53aecef1b8a14Amir Vadai if (err) 141208f10affe45051e18e0d8291c0a53aecef1b8a14Amir Vadai goto err; 141308f10affe45051e18e0d8291c0a53aecef1b8a14Amir Vadai } 141408f10affe45051e18e0d8291c0a53aecef1b8a14Amir Vadai 1415314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend if (ieee[DCB_ATTR_IEEE_PFC] && ops->ieee_setpfc) { 1416314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend struct ieee_pfc *pfc = nla_data(ieee[DCB_ATTR_IEEE_PFC]); 1417314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend err = ops->ieee_setpfc(netdev, pfc); 1418314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend if (err) 1419314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend goto err; 1420314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend } 1421314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend 1422314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend if (ieee[DCB_ATTR_IEEE_APP_TABLE]) { 1423314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend struct nlattr *attr; 1424314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend int rem; 1425314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend 1426314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend nla_for_each_nested(attr, ieee[DCB_ATTR_IEEE_APP_TABLE], rem) { 1427314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend struct dcb_app *app_data; 1428314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend if (nla_type(attr) != DCB_ATTR_IEEE_APP) 1429314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend continue; 1430314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend app_data = nla_data(attr); 1431314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend if (ops->ieee_setapp) 1432314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend err = ops->ieee_setapp(netdev, app_data); 1433314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend else 1434b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend err = dcb_ieee_setapp(netdev, app_data); 1435314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend if (err) 1436314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend goto err; 1437314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend } 1438314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend } 1439314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend 1440314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabenderr: 14417be994138b188387691322921c08e19bddf6d3c5Thomas Graf err = nla_put_u8(skb, DCB_ATTR_IEEE, err); 14425b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid dcbnl_ieee_notify(netdev, RTM_SETDCB, DCB_CMD_IEEE_SET, seq, 0); 1443314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend return err; 1444314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend} 1445314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend 14467be994138b188387691322921c08e19bddf6d3c5Thomas Grafstatic int dcbnl_ieee_get(struct net_device *netdev, struct nlmsghdr *nlh, 14477be994138b188387691322921c08e19bddf6d3c5Thomas Graf u32 seq, struct nlattr **tb, struct sk_buff *skb) 1448314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend{ 1449314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops; 1450314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend 1451314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend if (!ops) 1452314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend return -EOPNOTSUPP; 1453314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend 14547be994138b188387691322921c08e19bddf6d3c5Thomas Graf return dcbnl_ieee_fill(skb, netdev); 1455314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend} 1456f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend 14577be994138b188387691322921c08e19bddf6d3c5Thomas Grafstatic int dcbnl_ieee_del(struct net_device *netdev, struct nlmsghdr *nlh, 14587be994138b188387691322921c08e19bddf6d3c5Thomas Graf u32 seq, struct nlattr **tb, struct sk_buff *skb) 1459f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend{ 1460f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops; 1461f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend struct nlattr *ieee[DCB_ATTR_IEEE_MAX + 1]; 14623d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf int err; 1463f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend 1464f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend if (!ops) 1465f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend return -EOPNOTSUPP; 1466f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend 1467f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend if (!tb[DCB_ATTR_IEEE]) 1468f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend return -EINVAL; 1469f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend 1470f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend err = nla_parse_nested(ieee, DCB_ATTR_IEEE_MAX, 1471f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend tb[DCB_ATTR_IEEE], dcbnl_ieee_policy); 1472f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend if (err) 1473f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend return err; 1474f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend 1475f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend if (ieee[DCB_ATTR_IEEE_APP_TABLE]) { 1476f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend struct nlattr *attr; 1477f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend int rem; 1478f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend 1479f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend nla_for_each_nested(attr, ieee[DCB_ATTR_IEEE_APP_TABLE], rem) { 1480f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend struct dcb_app *app_data; 1481f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend 1482f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend if (nla_type(attr) != DCB_ATTR_IEEE_APP) 1483f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend continue; 1484f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend app_data = nla_data(attr); 1485f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend if (ops->ieee_delapp) 1486f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend err = ops->ieee_delapp(netdev, app_data); 1487f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend else 1488f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend err = dcb_ieee_delapp(netdev, app_data); 1489f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend if (err) 1490f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend goto err; 1491f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend } 1492f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend } 1493f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend 1494f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabenderr: 14957be994138b188387691322921c08e19bddf6d3c5Thomas Graf err = nla_put_u8(skb, DCB_ATTR_IEEE, err); 14965b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid dcbnl_ieee_notify(netdev, RTM_SETDCB, DCB_CMD_IEEE_DEL, seq, 0); 1497f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend return err; 1498f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend} 1499f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend 1500f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend 15016241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid/* DCBX configuration */ 15027be994138b188387691322921c08e19bddf6d3c5Thomas Grafstatic int dcbnl_getdcbx(struct net_device *netdev, struct nlmsghdr *nlh, 15037be994138b188387691322921c08e19bddf6d3c5Thomas Graf u32 seq, struct nlattr **tb, struct sk_buff *skb) 15046241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid{ 15056241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid if (!netdev->dcbnl_ops->getdcbx) 15067f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid return -EOPNOTSUPP; 15076241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid 15087be994138b188387691322921c08e19bddf6d3c5Thomas Graf return nla_put_u8(skb, DCB_ATTR_DCBX, 15097be994138b188387691322921c08e19bddf6d3c5Thomas Graf netdev->dcbnl_ops->getdcbx(netdev)); 15106241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid} 15116241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid 15127be994138b188387691322921c08e19bddf6d3c5Thomas Grafstatic int dcbnl_setdcbx(struct net_device *netdev, struct nlmsghdr *nlh, 15137be994138b188387691322921c08e19bddf6d3c5Thomas Graf u32 seq, struct nlattr **tb, struct sk_buff *skb) 15146241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid{ 15156241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid u8 value; 15166241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid 15177f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid if (!netdev->dcbnl_ops->setdcbx) 15187f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid return -EOPNOTSUPP; 15197f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid 15207f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid if (!tb[DCB_ATTR_DCBX]) 15217f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid return -EINVAL; 15226241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid 15236241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid value = nla_get_u8(tb[DCB_ATTR_DCBX]); 15246241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid 15257be994138b188387691322921c08e19bddf6d3c5Thomas Graf return nla_put_u8(skb, DCB_ATTR_DCBX, 15267be994138b188387691322921c08e19bddf6d3c5Thomas Graf netdev->dcbnl_ops->setdcbx(netdev, value)); 15276241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid} 15286241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid 15297be994138b188387691322921c08e19bddf6d3c5Thomas Grafstatic int dcbnl_getfeatcfg(struct net_device *netdev, struct nlmsghdr *nlh, 15307be994138b188387691322921c08e19bddf6d3c5Thomas Graf u32 seq, struct nlattr **tb, struct sk_buff *skb) 1531ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid{ 1532ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid struct nlattr *data[DCB_FEATCFG_ATTR_MAX + 1], *nest; 1533ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid u8 value; 15347f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid int ret, i; 1535ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid int getall = 0; 1536ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 15377f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid if (!netdev->dcbnl_ops->getfeatcfg) 15387f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid return -EOPNOTSUPP; 15397f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid 15407f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid if (!tb[DCB_ATTR_FEATCFG]) 15417f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid return -EINVAL; 1542ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 1543ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid ret = nla_parse_nested(data, DCB_FEATCFG_ATTR_MAX, tb[DCB_ATTR_FEATCFG], 1544ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid dcbnl_featcfg_nest); 15457f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid if (ret) 15467be994138b188387691322921c08e19bddf6d3c5Thomas Graf return ret; 1547ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 15487be994138b188387691322921c08e19bddf6d3c5Thomas Graf nest = nla_nest_start(skb, DCB_ATTR_FEATCFG); 15497be994138b188387691322921c08e19bddf6d3c5Thomas Graf if (!nest) 15507be994138b188387691322921c08e19bddf6d3c5Thomas Graf return -EMSGSIZE; 1551ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 1552ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid if (data[DCB_FEATCFG_ATTR_ALL]) 1553ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid getall = 1; 1554ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 1555ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid for (i = DCB_FEATCFG_ATTR_ALL+1; i <= DCB_FEATCFG_ATTR_MAX; i++) { 1556ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid if (!getall && !data[i]) 1557ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid continue; 1558ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 1559ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid ret = netdev->dcbnl_ops->getfeatcfg(netdev, i, &value); 15607f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid if (!ret) 15617be994138b188387691322921c08e19bddf6d3c5Thomas Graf ret = nla_put_u8(skb, i, value); 1562ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 15637f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid if (ret) { 15647be994138b188387691322921c08e19bddf6d3c5Thomas Graf nla_nest_cancel(skb, nest); 15657f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid goto nla_put_failure; 15667f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid } 1567ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid } 15687be994138b188387691322921c08e19bddf6d3c5Thomas Graf nla_nest_end(skb, nest); 1569ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 15707f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravidnla_put_failure: 1571ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid return ret; 1572ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid} 1573ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 15747be994138b188387691322921c08e19bddf6d3c5Thomas Grafstatic int dcbnl_setfeatcfg(struct net_device *netdev, struct nlmsghdr *nlh, 15757be994138b188387691322921c08e19bddf6d3c5Thomas Graf u32 seq, struct nlattr **tb, struct sk_buff *skb) 1576ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid{ 1577ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid struct nlattr *data[DCB_FEATCFG_ATTR_MAX + 1]; 15787f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid int ret, i; 1579ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid u8 value; 1580ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 15817f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid if (!netdev->dcbnl_ops->setfeatcfg) 15827f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid return -ENOTSUPP; 15837f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid 15847f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid if (!tb[DCB_ATTR_FEATCFG]) 15857f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid return -EINVAL; 1586ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 1587ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid ret = nla_parse_nested(data, DCB_FEATCFG_ATTR_MAX, tb[DCB_ATTR_FEATCFG], 1588ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid dcbnl_featcfg_nest); 1589ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 15907f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid if (ret) 1591ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid goto err; 1592ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 1593ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid for (i = DCB_FEATCFG_ATTR_ALL+1; i <= DCB_FEATCFG_ATTR_MAX; i++) { 1594ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid if (data[i] == NULL) 1595ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid continue; 1596ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 1597ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid value = nla_get_u8(data[i]); 1598ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 1599ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid ret = netdev->dcbnl_ops->setfeatcfg(netdev, i, value); 1600ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 1601ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid if (ret) 16027f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid goto err; 1603ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid } 1604ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Raviderr: 16057be994138b188387691322921c08e19bddf6d3c5Thomas Graf ret = nla_put_u8(skb, DCB_ATTR_FEATCFG, ret); 16067f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid 1607ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid return ret; 1608ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid} 1609ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 1610dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid/* Handle CEE DCBX GET commands. */ 16117be994138b188387691322921c08e19bddf6d3c5Thomas Grafstatic int dcbnl_cee_get(struct net_device *netdev, struct nlmsghdr *nlh, 16127be994138b188387691322921c08e19bddf6d3c5Thomas Graf u32 seq, struct nlattr **tb, struct sk_buff *skb) 1613dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid{ 1614dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops; 1615dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid 1616dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid if (!ops) 1617dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid return -EOPNOTSUPP; 1618dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid 16197be994138b188387691322921c08e19bddf6d3c5Thomas Graf return dcbnl_cee_fill(skb, netdev); 1620dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid} 1621dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid 162233a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Grafstruct reply_func { 162333a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf /* reply netlink message type */ 162433a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf int type; 162533a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf 162633a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf /* function to fill message contents */ 162733a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf int (*cb)(struct net_device *, struct nlmsghdr *, u32, 162833a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf struct nlattr **, struct sk_buff *); 162933a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf}; 163033a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf 163133a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Grafstatic const struct reply_func reply_funcs[DCB_CMD_MAX+1] = { 16327be994138b188387691322921c08e19bddf6d3c5Thomas Graf [DCB_CMD_GSTATE] = { RTM_GETDCB, dcbnl_getstate }, 16337be994138b188387691322921c08e19bddf6d3c5Thomas Graf [DCB_CMD_SSTATE] = { RTM_SETDCB, dcbnl_setstate }, 16347be994138b188387691322921c08e19bddf6d3c5Thomas Graf [DCB_CMD_PFC_GCFG] = { RTM_GETDCB, dcbnl_getpfccfg }, 16357be994138b188387691322921c08e19bddf6d3c5Thomas Graf [DCB_CMD_PFC_SCFG] = { RTM_SETDCB, dcbnl_setpfccfg }, 16367be994138b188387691322921c08e19bddf6d3c5Thomas Graf [DCB_CMD_GPERM_HWADDR] = { RTM_GETDCB, dcbnl_getperm_hwaddr }, 16377be994138b188387691322921c08e19bddf6d3c5Thomas Graf [DCB_CMD_GCAP] = { RTM_GETDCB, dcbnl_getcap }, 16387be994138b188387691322921c08e19bddf6d3c5Thomas Graf [DCB_CMD_GNUMTCS] = { RTM_GETDCB, dcbnl_getnumtcs }, 16397be994138b188387691322921c08e19bddf6d3c5Thomas Graf [DCB_CMD_SNUMTCS] = { RTM_SETDCB, dcbnl_setnumtcs }, 16407be994138b188387691322921c08e19bddf6d3c5Thomas Graf [DCB_CMD_PFC_GSTATE] = { RTM_GETDCB, dcbnl_getpfcstate }, 16417be994138b188387691322921c08e19bddf6d3c5Thomas Graf [DCB_CMD_PFC_SSTATE] = { RTM_SETDCB, dcbnl_setpfcstate }, 16427be994138b188387691322921c08e19bddf6d3c5Thomas Graf [DCB_CMD_GAPP] = { RTM_GETDCB, dcbnl_getapp }, 16437be994138b188387691322921c08e19bddf6d3c5Thomas Graf [DCB_CMD_SAPP] = { RTM_SETDCB, dcbnl_setapp }, 16447be994138b188387691322921c08e19bddf6d3c5Thomas Graf [DCB_CMD_PGTX_GCFG] = { RTM_GETDCB, dcbnl_pgtx_getcfg }, 16457be994138b188387691322921c08e19bddf6d3c5Thomas Graf [DCB_CMD_PGTX_SCFG] = { RTM_SETDCB, dcbnl_pgtx_setcfg }, 16467be994138b188387691322921c08e19bddf6d3c5Thomas Graf [DCB_CMD_PGRX_GCFG] = { RTM_GETDCB, dcbnl_pgrx_getcfg }, 16477be994138b188387691322921c08e19bddf6d3c5Thomas Graf [DCB_CMD_PGRX_SCFG] = { RTM_SETDCB, dcbnl_pgrx_setcfg }, 16487be994138b188387691322921c08e19bddf6d3c5Thomas Graf [DCB_CMD_SET_ALL] = { RTM_SETDCB, dcbnl_setall }, 16497be994138b188387691322921c08e19bddf6d3c5Thomas Graf [DCB_CMD_BCN_GCFG] = { RTM_GETDCB, dcbnl_bcn_getcfg }, 16507be994138b188387691322921c08e19bddf6d3c5Thomas Graf [DCB_CMD_BCN_SCFG] = { RTM_SETDCB, dcbnl_bcn_setcfg }, 16517be994138b188387691322921c08e19bddf6d3c5Thomas Graf [DCB_CMD_IEEE_GET] = { RTM_GETDCB, dcbnl_ieee_get }, 16527be994138b188387691322921c08e19bddf6d3c5Thomas Graf [DCB_CMD_IEEE_SET] = { RTM_SETDCB, dcbnl_ieee_set }, 16537be994138b188387691322921c08e19bddf6d3c5Thomas Graf [DCB_CMD_IEEE_DEL] = { RTM_SETDCB, dcbnl_ieee_del }, 16547be994138b188387691322921c08e19bddf6d3c5Thomas Graf [DCB_CMD_GDCBX] = { RTM_GETDCB, dcbnl_getdcbx }, 16557be994138b188387691322921c08e19bddf6d3c5Thomas Graf [DCB_CMD_SDCBX] = { RTM_SETDCB, dcbnl_setdcbx }, 16567be994138b188387691322921c08e19bddf6d3c5Thomas Graf [DCB_CMD_GFEATCFG] = { RTM_GETDCB, dcbnl_getfeatcfg }, 16577be994138b188387691322921c08e19bddf6d3c5Thomas Graf [DCB_CMD_SFEATCFG] = { RTM_SETDCB, dcbnl_setfeatcfg }, 16587be994138b188387691322921c08e19bddf6d3c5Thomas Graf [DCB_CMD_CEE_GET] = { RTM_GETDCB, dcbnl_cee_get }, 165933a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf}; 166033a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf 1661661d2967b3f1b34eeaa7e212e7b9bbe8ee072b59Thomas Grafstatic int dcb_doit(struct sk_buff *skb, struct nlmsghdr *nlh) 16622f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 16632f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct net *net = sock_net(skb->sk); 16642f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct net_device *netdev; 16657a282bc37f8a1e7b46907d78724177d20214b137Thomas Graf struct dcbmsg *dcb = nlmsg_data(nlh); 16662f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct nlattr *tb[DCB_ATTR_MAX + 1]; 166715e473046cb6e5d18a4d0057e61d76315230382bEric W. Biederman u32 portid = skb ? NETLINK_CB(skb).portid : 0; 16682f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck int ret = -EINVAL; 166933a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf struct sk_buff *reply_skb; 167039912f9cf9603f0de085fb5ba916a7a88010ccd9Thomas Graf struct nlmsghdr *reply_nlh = NULL; 167133a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf const struct reply_func *fn; 16722f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 1673dfc47ef8639facd77210e74be831943c2fdd9c74Eric W. Biederman if ((nlh->nlmsg_type == RTM_SETDCB) && !capable(CAP_NET_ADMIN)) 1674dfc47ef8639facd77210e74be831943c2fdd9c74Eric W. Biederman return -EPERM; 1675dfc47ef8639facd77210e74be831943c2fdd9c74Eric W. Biederman 16762f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = nlmsg_parse(nlh, sizeof(*dcb), tb, DCB_ATTR_MAX, 16772f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcbnl_rtnl_policy); 16782f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret < 0) 16792f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return ret; 16802f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 168133a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf if (dcb->cmd > DCB_CMD_MAX) 168233a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf return -EINVAL; 168333a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf 168433a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf /* check if a reply function has been defined for the command */ 168533a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf fn = &reply_funcs[dcb->cmd]; 168633a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf if (!fn->cb) 168733a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf return -EOPNOTSUPP; 168833a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf 16892f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!tb[DCB_ATTR_IFNAME]) 16902f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return -EINVAL; 16912f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 16927c77ab24e30bad7598b5cfda93be6f32ed439c2fJohn Fastabend netdev = dev_get_by_name(net, nla_data(tb[DCB_ATTR_IFNAME])); 16932f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!netdev) 16943d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -ENODEV; 16952f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 16963d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf if (!netdev->dcbnl_ops) { 16973d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf ret = -EOPNOTSUPP; 16983d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf goto out; 16993d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf } 17002f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 170115e473046cb6e5d18a4d0057e61d76315230382bEric W. Biederman reply_skb = dcbnl_newmsg(fn->type, dcb->cmd, portid, nlh->nlmsg_seq, 170233a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf nlh->nlmsg_flags, &reply_nlh); 170333a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf if (!reply_skb) { 170433a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf ret = -ENOBUFS; 170533a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf goto out; 170633a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf } 170733a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf 170833a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf ret = fn->cb(netdev, nlh, nlh->nlmsg_seq, tb, reply_skb); 170933a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf if (ret < 0) { 171033a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf nlmsg_free(reply_skb); 171133a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf goto out; 171233a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf } 171333a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf 171433a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf nlmsg_end(reply_skb, reply_nlh); 171533a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf 17167c77ab24e30bad7598b5cfda93be6f32ed439c2fJohn Fastabend ret = rtnl_unicast(reply_skb, net, portid); 17172f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckout: 17182f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dev_put(netdev); 17192f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return ret; 17202f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 17212f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 1722716b31abbd39baab307c0a7b38dce9a20c16c62dThomas Grafstatic struct dcb_app_type *dcb_app_lookup(const struct dcb_app *app, 1723716b31abbd39baab307c0a7b38dce9a20c16c62dThomas Graf int ifindex, int prio) 1724716b31abbd39baab307c0a7b38dce9a20c16c62dThomas Graf{ 1725716b31abbd39baab307c0a7b38dce9a20c16c62dThomas Graf struct dcb_app_type *itr; 1726716b31abbd39baab307c0a7b38dce9a20c16c62dThomas Graf 1727716b31abbd39baab307c0a7b38dce9a20c16c62dThomas Graf list_for_each_entry(itr, &dcb_app_list, list) { 1728716b31abbd39baab307c0a7b38dce9a20c16c62dThomas Graf if (itr->app.selector == app->selector && 1729716b31abbd39baab307c0a7b38dce9a20c16c62dThomas Graf itr->app.protocol == app->protocol && 1730716b31abbd39baab307c0a7b38dce9a20c16c62dThomas Graf itr->ifindex == ifindex && 1731716b31abbd39baab307c0a7b38dce9a20c16c62dThomas Graf (!prio || itr->app.priority == prio)) 1732716b31abbd39baab307c0a7b38dce9a20c16c62dThomas Graf return itr; 1733716b31abbd39baab307c0a7b38dce9a20c16c62dThomas Graf } 1734716b31abbd39baab307c0a7b38dce9a20c16c62dThomas Graf 1735716b31abbd39baab307c0a7b38dce9a20c16c62dThomas Graf return NULL; 1736716b31abbd39baab307c0a7b38dce9a20c16c62dThomas Graf} 1737716b31abbd39baab307c0a7b38dce9a20c16c62dThomas Graf 17384e4f2f69704be0ae218d91fb827e5a6987fe262fThomas Grafstatic int dcb_app_add(const struct dcb_app *app, int ifindex) 17394e4f2f69704be0ae218d91fb827e5a6987fe262fThomas Graf{ 17404e4f2f69704be0ae218d91fb827e5a6987fe262fThomas Graf struct dcb_app_type *entry; 17414e4f2f69704be0ae218d91fb827e5a6987fe262fThomas Graf 17424e4f2f69704be0ae218d91fb827e5a6987fe262fThomas Graf entry = kmalloc(sizeof(*entry), GFP_ATOMIC); 17434e4f2f69704be0ae218d91fb827e5a6987fe262fThomas Graf if (!entry) 17444e4f2f69704be0ae218d91fb827e5a6987fe262fThomas Graf return -ENOMEM; 17454e4f2f69704be0ae218d91fb827e5a6987fe262fThomas Graf 17464e4f2f69704be0ae218d91fb827e5a6987fe262fThomas Graf memcpy(&entry->app, app, sizeof(*app)); 17474e4f2f69704be0ae218d91fb827e5a6987fe262fThomas Graf entry->ifindex = ifindex; 17484e4f2f69704be0ae218d91fb827e5a6987fe262fThomas Graf list_add(&entry->list, &dcb_app_list); 17494e4f2f69704be0ae218d91fb827e5a6987fe262fThomas Graf 17504e4f2f69704be0ae218d91fb827e5a6987fe262fThomas Graf return 0; 17514e4f2f69704be0ae218d91fb827e5a6987fe262fThomas Graf} 17524e4f2f69704be0ae218d91fb827e5a6987fe262fThomas Graf 17539ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend/** 17549ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend * dcb_getapp - retrieve the DCBX application user priority 17559ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend * 17569ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend * On success returns a non-zero 802.1p user priority bitmap 17579ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend * otherwise returns 0 as the invalid user priority bitmap to 17589ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend * indicate an error. 17599ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend */ 17609ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabendu8 dcb_getapp(struct net_device *dev, struct dcb_app *app) 17619ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend{ 17629ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend struct dcb_app_type *itr; 17639ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend u8 prio = 0; 17649ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend 17659ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend spin_lock(&dcb_lock); 1766716b31abbd39baab307c0a7b38dce9a20c16c62dThomas Graf if ((itr = dcb_app_lookup(app, dev->ifindex, 0))) 1767716b31abbd39baab307c0a7b38dce9a20c16c62dThomas Graf prio = itr->app.priority; 17689ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend spin_unlock(&dcb_lock); 17699ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend 17709ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend return prio; 17719ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend} 17729ab933ab2cc80f04690d6aa385b1110075c5e507John FastabendEXPORT_SYMBOL(dcb_getapp); 17739ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend 17749ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend/** 1775b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend * dcb_setapp - add CEE dcb application data to app list 17769ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend * 1777b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend * Priority 0 is an invalid priority in CEE spec. This routine 1778b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend * removes applications from the app list if the priority is 1779b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend * set to zero. 17809ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend */ 1781ab6baf980b095c70a56c5eb2f58166aef8a0edc8John Fastabendint dcb_setapp(struct net_device *dev, struct dcb_app *new) 17829ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend{ 17839ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend struct dcb_app_type *itr; 17847ec79270d7de0c8ca602c47cb25a9652ec28f37fJohn Fastabend struct dcb_app_type event; 17854e4f2f69704be0ae218d91fb827e5a6987fe262fThomas Graf int err = 0; 17867ec79270d7de0c8ca602c47cb25a9652ec28f37fJohn Fastabend 1787e290ed81307ca7d92675f0d9c683add693c2f377Mark Rustad event.ifindex = dev->ifindex; 17887ec79270d7de0c8ca602c47cb25a9652ec28f37fJohn Fastabend memcpy(&event.app, new, sizeof(event.app)); 17896bd0e1cb10b6d14dda4a8806d0a2f4f0bbf01931John Fastabend if (dev->dcbnl_ops->getdcbx) 17906bd0e1cb10b6d14dda4a8806d0a2f4f0bbf01931John Fastabend event.dcbx = dev->dcbnl_ops->getdcbx(dev); 17919ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend 17929ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend spin_lock(&dcb_lock); 17939ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend /* Search for existing match and replace */ 1794716b31abbd39baab307c0a7b38dce9a20c16c62dThomas Graf if ((itr = dcb_app_lookup(new, dev->ifindex, 0))) { 1795716b31abbd39baab307c0a7b38dce9a20c16c62dThomas Graf if (new->priority) 1796716b31abbd39baab307c0a7b38dce9a20c16c62dThomas Graf itr->app.priority = new->priority; 1797716b31abbd39baab307c0a7b38dce9a20c16c62dThomas Graf else { 1798716b31abbd39baab307c0a7b38dce9a20c16c62dThomas Graf list_del(&itr->list); 1799716b31abbd39baab307c0a7b38dce9a20c16c62dThomas Graf kfree(itr); 18009ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend } 1801716b31abbd39baab307c0a7b38dce9a20c16c62dThomas Graf goto out; 18029ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend } 18039ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend /* App type does not exist add new application type */ 18044e4f2f69704be0ae218d91fb827e5a6987fe262fThomas Graf if (new->priority) 18054e4f2f69704be0ae218d91fb827e5a6987fe262fThomas Graf err = dcb_app_add(new, dev->ifindex); 18069ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabendout: 18079ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend spin_unlock(&dcb_lock); 18084e4f2f69704be0ae218d91fb827e5a6987fe262fThomas Graf if (!err) 18094e4f2f69704be0ae218d91fb827e5a6987fe262fThomas Graf call_dcbevent_notifiers(DCB_APP_EVENT, &event); 18104e4f2f69704be0ae218d91fb827e5a6987fe262fThomas Graf return err; 18119ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend} 18129ab933ab2cc80f04690d6aa385b1110075c5e507John FastabendEXPORT_SYMBOL(dcb_setapp); 18139ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend 1814b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend/** 1815a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabend * dcb_ieee_getapp_mask - retrieve the IEEE DCB application priority 1816a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabend * 1817a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabend * Helper routine which on success returns a non-zero 802.1Qaz user 1818a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabend * priority bitmap otherwise returns 0 to indicate the dcb_app was 1819a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabend * not found in APP list. 1820a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabend */ 1821a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabendu8 dcb_ieee_getapp_mask(struct net_device *dev, struct dcb_app *app) 1822a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabend{ 1823a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabend struct dcb_app_type *itr; 1824a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabend u8 prio = 0; 1825a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabend 1826a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabend spin_lock(&dcb_lock); 1827716b31abbd39baab307c0a7b38dce9a20c16c62dThomas Graf if ((itr = dcb_app_lookup(app, dev->ifindex, 0))) 1828716b31abbd39baab307c0a7b38dce9a20c16c62dThomas Graf prio |= 1 << itr->app.priority; 1829a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabend spin_unlock(&dcb_lock); 1830a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabend 1831a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabend return prio; 1832a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabend} 1833a364c8cf80251849bab207be8c9e66253c8ca8f8John FastabendEXPORT_SYMBOL(dcb_ieee_getapp_mask); 1834a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabend 1835a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabend/** 1836b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend * dcb_ieee_setapp - add IEEE dcb application data to app list 1837b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend * 1838b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend * This adds Application data to the list. Multiple application 1839b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend * entries may exists for the same selector and protocol as long 1840b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend * as the priorities are different. 1841b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend */ 1842b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabendint dcb_ieee_setapp(struct net_device *dev, struct dcb_app *new) 1843b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend{ 1844b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend struct dcb_app_type event; 1845b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend int err = 0; 1846b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend 1847e290ed81307ca7d92675f0d9c683add693c2f377Mark Rustad event.ifindex = dev->ifindex; 1848b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend memcpy(&event.app, new, sizeof(event.app)); 18496bd0e1cb10b6d14dda4a8806d0a2f4f0bbf01931John Fastabend if (dev->dcbnl_ops->getdcbx) 18506bd0e1cb10b6d14dda4a8806d0a2f4f0bbf01931John Fastabend event.dcbx = dev->dcbnl_ops->getdcbx(dev); 1851b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend 1852b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend spin_lock(&dcb_lock); 1853b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend /* Search for existing match and abort if found */ 1854716b31abbd39baab307c0a7b38dce9a20c16c62dThomas Graf if (dcb_app_lookup(new, dev->ifindex, new->priority)) { 1855716b31abbd39baab307c0a7b38dce9a20c16c62dThomas Graf err = -EEXIST; 1856716b31abbd39baab307c0a7b38dce9a20c16c62dThomas Graf goto out; 1857b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend } 1858b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend 18594e4f2f69704be0ae218d91fb827e5a6987fe262fThomas Graf err = dcb_app_add(new, dev->ifindex); 1860b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabendout: 1861b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend spin_unlock(&dcb_lock); 1862b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend if (!err) 1863b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend call_dcbevent_notifiers(DCB_APP_EVENT, &event); 1864b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend return err; 1865b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend} 1866b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John FastabendEXPORT_SYMBOL(dcb_ieee_setapp); 1867b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend 1868f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend/** 1869f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend * dcb_ieee_delapp - delete IEEE dcb application data from list 1870f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend * 1871f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend * This removes a matching APP data from the APP list 1872f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend */ 1873f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabendint dcb_ieee_delapp(struct net_device *dev, struct dcb_app *del) 1874f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend{ 1875f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend struct dcb_app_type *itr; 1876f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend struct dcb_app_type event; 1877f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend int err = -ENOENT; 1878f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend 1879e290ed81307ca7d92675f0d9c683add693c2f377Mark Rustad event.ifindex = dev->ifindex; 1880f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend memcpy(&event.app, del, sizeof(event.app)); 18816bd0e1cb10b6d14dda4a8806d0a2f4f0bbf01931John Fastabend if (dev->dcbnl_ops->getdcbx) 18826bd0e1cb10b6d14dda4a8806d0a2f4f0bbf01931John Fastabend event.dcbx = dev->dcbnl_ops->getdcbx(dev); 1883f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend 1884f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend spin_lock(&dcb_lock); 1885f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend /* Search for existing match and remove it. */ 1886716b31abbd39baab307c0a7b38dce9a20c16c62dThomas Graf if ((itr = dcb_app_lookup(del, dev->ifindex, del->priority))) { 1887716b31abbd39baab307c0a7b38dce9a20c16c62dThomas Graf list_del(&itr->list); 1888716b31abbd39baab307c0a7b38dce9a20c16c62dThomas Graf kfree(itr); 1889716b31abbd39baab307c0a7b38dce9a20c16c62dThomas Graf err = 0; 1890f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend } 1891f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend 1892f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend spin_unlock(&dcb_lock); 1893f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend if (!err) 1894f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend call_dcbevent_notifiers(DCB_APP_EVENT, &event); 1895f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend return err; 1896f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend} 1897f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John FastabendEXPORT_SYMBOL(dcb_ieee_delapp); 1898f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend 18997c14c3f10e6dcd7f70e49f77b6e1ae605c4861e6Shmulik Ravidstatic void dcb_flushapp(void) 19009ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend{ 19019ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend struct dcb_app_type *app; 19022a8fe003741aa90b6b9453e90af4bbb7bc42918cDan Carpenter struct dcb_app_type *tmp; 19039ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend 19049ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend spin_lock(&dcb_lock); 19052a8fe003741aa90b6b9453e90af4bbb7bc42918cDan Carpenter list_for_each_entry_safe(app, tmp, &dcb_app_list, list) { 19069ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend list_del(&app->list); 19079ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend kfree(app); 19089ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend } 19099ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend spin_unlock(&dcb_lock); 19109ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend} 19119ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend 19122f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckstatic int __init dcbnl_init(void) 19132f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 19149ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend INIT_LIST_HEAD(&dcb_app_list); 19159ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend 1916c7ac8679bec9397afe8918f788cbcef88c38da54Greg Rose rtnl_register(PF_UNSPEC, RTM_GETDCB, dcb_doit, NULL, NULL); 1917c7ac8679bec9397afe8918f788cbcef88c38da54Greg Rose rtnl_register(PF_UNSPEC, RTM_SETDCB, dcb_doit, NULL, NULL); 19182f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 19192f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return 0; 19202f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 19212f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckmodule_init(dcbnl_init); 19222f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 19232f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckstatic void __exit dcbnl_exit(void) 19242f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 19252f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck rtnl_unregister(PF_UNSPEC, RTM_GETDCB); 19262f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck rtnl_unregister(PF_UNSPEC, RTM_SETDCB); 19279ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend dcb_flushapp(); 19282f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 19292f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckmodule_exit(dcbnl_exit); 1930