dcbnl.c revision 39912f9cf9603f0de085fb5ba916a7a88010ccd9
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 312f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck/** 322f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * Data Center Bridging (DCB) is a collection of Ethernet enhancements 332f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * intended to allow network traffic with differing requirements 342f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * (highly reliable, no drops vs. best effort vs. low latency) to operate 352f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * and co-exist on Ethernet. Current DCB features are: 362f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * 372f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * Enhanced Transmission Selection (aka Priority Grouping [PG]) - provides a 382f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * framework for assigning bandwidth guarantees to traffic classes. 392f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * 402f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * Priority-based Flow Control (PFC) - provides a flow control mechanism which 412f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * can work independently for each 802.1p priority. 422f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * 432f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * Congestion Notification - provides a mechanism for end-to-end congestion 442f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * control for protocols which do not have built-in congestion management. 452f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * 462f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * More information about the emerging standards for these Ethernet features 472f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * can be found at: http://www.ieee802.org/1/pages/dcbridges.html 482f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * 492f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * This file implements an rtnetlink interface to allow configuration of DCB 502f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck * features for capable devices. 512f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck */ 522f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 532f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander DuyckMODULE_AUTHOR("Lucy Liu, <lucy.liu@intel.com>"); 547a6b6f515f77d1c62a2f383b6dce18cb0af0cf4fJeff KirsherMODULE_DESCRIPTION("Data Center Bridging netlink interface"); 552f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander DuyckMODULE_LICENSE("GPL"); 562f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 572f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck/**************** DCB attribute policies *************************************/ 582f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 592f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck/* DCB netlink attributes policy */ 60b54452b07a7b1b8cc1385edba3ef2ef6d4679d5aAlexey Dobriyanstatic const struct nla_policy dcbnl_rtnl_policy[DCB_ATTR_MAX + 1] = { 61859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_ATTR_IFNAME] = {.type = NLA_NUL_STRING, .len = IFNAMSIZ - 1}, 62859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_ATTR_STATE] = {.type = NLA_U8}, 63859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_ATTR_PFC_CFG] = {.type = NLA_NESTED}, 64859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_ATTR_PG_CFG] = {.type = NLA_NESTED}, 65859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_ATTR_SET_ALL] = {.type = NLA_U8}, 662f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_ATTR_PERM_HWADDR] = {.type = NLA_FLAG}, 67859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_ATTR_CAP] = {.type = NLA_NESTED}, 68859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_ATTR_PFC_STATE] = {.type = NLA_U8}, 69859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_ATTR_BCN] = {.type = NLA_NESTED}, 706fa382af61338908e5713234bcee598423f661c3Yi Zou [DCB_ATTR_APP] = {.type = NLA_NESTED}, 713e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend [DCB_ATTR_IEEE] = {.type = NLA_NESTED}, 726241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid [DCB_ATTR_DCBX] = {.type = NLA_U8}, 73ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid [DCB_ATTR_FEATCFG] = {.type = NLA_NESTED}, 742f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck}; 752f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 762f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck/* DCB priority flow control to User Priority nested attributes */ 77b54452b07a7b1b8cc1385edba3ef2ef6d4679d5aAlexey Dobriyanstatic const struct nla_policy dcbnl_pfc_up_nest[DCB_PFC_UP_ATTR_MAX + 1] = { 782f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PFC_UP_ATTR_0] = {.type = NLA_U8}, 792f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PFC_UP_ATTR_1] = {.type = NLA_U8}, 802f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PFC_UP_ATTR_2] = {.type = NLA_U8}, 812f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PFC_UP_ATTR_3] = {.type = NLA_U8}, 822f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PFC_UP_ATTR_4] = {.type = NLA_U8}, 832f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PFC_UP_ATTR_5] = {.type = NLA_U8}, 842f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PFC_UP_ATTR_6] = {.type = NLA_U8}, 852f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PFC_UP_ATTR_7] = {.type = NLA_U8}, 862f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PFC_UP_ATTR_ALL] = {.type = NLA_FLAG}, 872f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck}; 882f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 892f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck/* DCB priority grouping nested attributes */ 90b54452b07a7b1b8cc1385edba3ef2ef6d4679d5aAlexey Dobriyanstatic const struct nla_policy dcbnl_pg_nest[DCB_PG_ATTR_MAX + 1] = { 912f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PG_ATTR_TC_0] = {.type = NLA_NESTED}, 922f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PG_ATTR_TC_1] = {.type = NLA_NESTED}, 932f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PG_ATTR_TC_2] = {.type = NLA_NESTED}, 942f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PG_ATTR_TC_3] = {.type = NLA_NESTED}, 952f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PG_ATTR_TC_4] = {.type = NLA_NESTED}, 962f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PG_ATTR_TC_5] = {.type = NLA_NESTED}, 972f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PG_ATTR_TC_6] = {.type = NLA_NESTED}, 982f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PG_ATTR_TC_7] = {.type = NLA_NESTED}, 992f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PG_ATTR_TC_ALL] = {.type = NLA_NESTED}, 1002f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PG_ATTR_BW_ID_0] = {.type = NLA_U8}, 1012f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PG_ATTR_BW_ID_1] = {.type = NLA_U8}, 1022f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PG_ATTR_BW_ID_2] = {.type = NLA_U8}, 1032f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PG_ATTR_BW_ID_3] = {.type = NLA_U8}, 1042f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PG_ATTR_BW_ID_4] = {.type = NLA_U8}, 1052f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PG_ATTR_BW_ID_5] = {.type = NLA_U8}, 1062f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PG_ATTR_BW_ID_6] = {.type = NLA_U8}, 1072f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PG_ATTR_BW_ID_7] = {.type = NLA_U8}, 1082f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_PG_ATTR_BW_ID_ALL] = {.type = NLA_FLAG}, 1092f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck}; 1102f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 1112f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck/* DCB traffic class nested attributes. */ 112b54452b07a7b1b8cc1385edba3ef2ef6d4679d5aAlexey Dobriyanstatic const struct nla_policy dcbnl_tc_param_nest[DCB_TC_ATTR_PARAM_MAX + 1] = { 1132f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_TC_ATTR_PARAM_PGID] = {.type = NLA_U8}, 1142f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_TC_ATTR_PARAM_UP_MAPPING] = {.type = NLA_U8}, 1152f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_TC_ATTR_PARAM_STRICT_PRIO] = {.type = NLA_U8}, 1162f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_TC_ATTR_PARAM_BW_PCT] = {.type = NLA_U8}, 1172f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck [DCB_TC_ATTR_PARAM_ALL] = {.type = NLA_FLAG}, 1182f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck}; 1192f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 12046132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck/* DCB capabilities nested attributes. */ 121b54452b07a7b1b8cc1385edba3ef2ef6d4679d5aAlexey Dobriyanstatic const struct nla_policy dcbnl_cap_nest[DCB_CAP_ATTR_MAX + 1] = { 12246132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck [DCB_CAP_ATTR_ALL] = {.type = NLA_FLAG}, 12346132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck [DCB_CAP_ATTR_PG] = {.type = NLA_U8}, 12446132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck [DCB_CAP_ATTR_PFC] = {.type = NLA_U8}, 12546132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck [DCB_CAP_ATTR_UP2TC] = {.type = NLA_U8}, 12646132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck [DCB_CAP_ATTR_PG_TCS] = {.type = NLA_U8}, 12746132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck [DCB_CAP_ATTR_PFC_TCS] = {.type = NLA_U8}, 12846132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck [DCB_CAP_ATTR_GSP] = {.type = NLA_U8}, 12946132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck [DCB_CAP_ATTR_BCN] = {.type = NLA_U8}, 1306241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid [DCB_CAP_ATTR_DCBX] = {.type = NLA_U8}, 13146132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck}; 1322f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 13333dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck/* DCB capabilities nested attributes. */ 134b54452b07a7b1b8cc1385edba3ef2ef6d4679d5aAlexey Dobriyanstatic const struct nla_policy dcbnl_numtcs_nest[DCB_NUMTCS_ATTR_MAX + 1] = { 13533dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck [DCB_NUMTCS_ATTR_ALL] = {.type = NLA_FLAG}, 13633dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck [DCB_NUMTCS_ATTR_PG] = {.type = NLA_U8}, 13733dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck [DCB_NUMTCS_ATTR_PFC] = {.type = NLA_U8}, 13833dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck}; 13933dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 140859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck/* DCB BCN nested attributes. */ 141b54452b07a7b1b8cc1385edba3ef2ef6d4679d5aAlexey Dobriyanstatic const struct nla_policy dcbnl_bcn_nest[DCB_BCN_ATTR_MAX + 1] = { 142859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_RP_0] = {.type = NLA_U8}, 143859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_RP_1] = {.type = NLA_U8}, 144859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_RP_2] = {.type = NLA_U8}, 145859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_RP_3] = {.type = NLA_U8}, 146859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_RP_4] = {.type = NLA_U8}, 147859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_RP_5] = {.type = NLA_U8}, 148859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_RP_6] = {.type = NLA_U8}, 149859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_RP_7] = {.type = NLA_U8}, 150859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_RP_ALL] = {.type = NLA_FLAG}, 151f4314e815e87b4ab1c9b1115dd5853cd20ca999cDon Skidmore [DCB_BCN_ATTR_BCNA_0] = {.type = NLA_U32}, 152f4314e815e87b4ab1c9b1115dd5853cd20ca999cDon Skidmore [DCB_BCN_ATTR_BCNA_1] = {.type = NLA_U32}, 153859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_ALPHA] = {.type = NLA_U32}, 154859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_BETA] = {.type = NLA_U32}, 155859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_GD] = {.type = NLA_U32}, 156859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_GI] = {.type = NLA_U32}, 157859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_TMAX] = {.type = NLA_U32}, 158859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_TD] = {.type = NLA_U32}, 159859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_RMIN] = {.type = NLA_U32}, 160859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_W] = {.type = NLA_U32}, 161859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_RD] = {.type = NLA_U32}, 162859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_RU] = {.type = NLA_U32}, 163859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_WRTT] = {.type = NLA_U32}, 164859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_RI] = {.type = NLA_U32}, 165859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_C] = {.type = NLA_U32}, 166859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck [DCB_BCN_ATTR_ALL] = {.type = NLA_FLAG}, 167859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck}; 168859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1696fa382af61338908e5713234bcee598423f661c3Yi Zou/* DCB APP nested attributes. */ 170b54452b07a7b1b8cc1385edba3ef2ef6d4679d5aAlexey Dobriyanstatic const struct nla_policy dcbnl_app_nest[DCB_APP_ATTR_MAX + 1] = { 1716fa382af61338908e5713234bcee598423f661c3Yi Zou [DCB_APP_ATTR_IDTYPE] = {.type = NLA_U8}, 1726fa382af61338908e5713234bcee598423f661c3Yi Zou [DCB_APP_ATTR_ID] = {.type = NLA_U16}, 1736fa382af61338908e5713234bcee598423f661c3Yi Zou [DCB_APP_ATTR_PRIORITY] = {.type = NLA_U8}, 1746fa382af61338908e5713234bcee598423f661c3Yi Zou}; 1756fa382af61338908e5713234bcee598423f661c3Yi Zou 1763e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend/* IEEE 802.1Qaz nested attributes. */ 1773e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabendstatic const struct nla_policy dcbnl_ieee_policy[DCB_ATTR_IEEE_MAX + 1] = { 1783e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend [DCB_ATTR_IEEE_ETS] = {.len = sizeof(struct ieee_ets)}, 1793e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend [DCB_ATTR_IEEE_PFC] = {.len = sizeof(struct ieee_pfc)}, 1803e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend [DCB_ATTR_IEEE_APP_TABLE] = {.type = NLA_NESTED}, 18108f10affe45051e18e0d8291c0a53aecef1b8a14Amir Vadai [DCB_ATTR_IEEE_MAXRATE] = {.len = sizeof(struct ieee_maxrate)}, 1823e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend}; 1833e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend 1843e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabendstatic const struct nla_policy dcbnl_ieee_app[DCB_ATTR_IEEE_APP_MAX + 1] = { 1853e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend [DCB_ATTR_IEEE_APP] = {.len = sizeof(struct dcb_app)}, 1863e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend}; 1873e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend 188ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid/* DCB number of traffic classes nested attributes. */ 189ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravidstatic const struct nla_policy dcbnl_featcfg_nest[DCB_FEATCFG_ATTR_MAX + 1] = { 190ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid [DCB_FEATCFG_ATTR_ALL] = {.type = NLA_FLAG}, 191ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid [DCB_FEATCFG_ATTR_PG] = {.type = NLA_U8}, 192ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid [DCB_FEATCFG_ATTR_PFC] = {.type = NLA_U8}, 193ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid [DCB_FEATCFG_ATTR_APP] = {.type = NLA_U8}, 194ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid}; 195ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 1969ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabendstatic LIST_HEAD(dcb_app_list); 1979ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabendstatic DEFINE_SPINLOCK(dcb_lock); 1989ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend 19933a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Grafstatic struct sk_buff *dcbnl_newmsg(int type, u8 cmd, u32 port, u32 seq, 20033a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf u32 flags, struct nlmsghdr **nlhp) 20133a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf{ 20233a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf struct sk_buff *skb; 20333a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf struct dcbmsg *dcb; 20433a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf struct nlmsghdr *nlh; 20533a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf 20633a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 20733a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf if (!skb) 20833a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf return NULL; 20933a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf 21033a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf nlh = nlmsg_put(skb, port, seq, type, sizeof(*dcb), flags); 21133a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf if (!nlh) { 21233a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf /* header should always fit, allocation must be buggy */ 21333a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf BUG(); 21433a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf } 21533a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf 21633a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf dcb = nlmsg_data(nlh); 21733a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf dcb->dcb_family = AF_UNSPEC; 21833a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf dcb->cmd = cmd; 21933a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf dcb->dcb_pad = 0; 22033a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf 22133a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf if (nlhp) 22233a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf *nlhp = nlh; 22333a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf 22433a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf return skb; 22533a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf} 22633a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf 2277be994138b188387691322921c08e19bddf6d3c5Thomas Grafstatic int dcbnl_getstate(struct net_device *netdev, struct nlmsghdr *nlh, 2287be994138b188387691322921c08e19bddf6d3c5Thomas Graf u32 seq, struct nlattr **tb, struct sk_buff *skb) 2292f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 2302f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck /* if (!tb[DCB_ATTR_STATE] || !netdev->dcbnl_ops->getstate) */ 2312f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!netdev->dcbnl_ops->getstate) 2323d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EOPNOTSUPP; 2332f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2347be994138b188387691322921c08e19bddf6d3c5Thomas Graf return nla_put_u8(skb, DCB_ATTR_STATE, 2357be994138b188387691322921c08e19bddf6d3c5Thomas Graf netdev->dcbnl_ops->getstate(netdev)); 2362f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 2372f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2387be994138b188387691322921c08e19bddf6d3c5Thomas Grafstatic int dcbnl_getpfccfg(struct net_device *netdev, struct nlmsghdr *nlh, 2397be994138b188387691322921c08e19bddf6d3c5Thomas Graf u32 seq, struct nlattr **tb, struct sk_buff *skb) 2402f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 2412f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct nlattr *data[DCB_PFC_UP_ATTR_MAX + 1], *nest; 2422f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u8 value; 2433d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf int ret; 2442f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck int i; 2452f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck int getall = 0; 2462f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2473d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf if (!tb[DCB_ATTR_PFC_CFG]) 2483d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EINVAL; 2493d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf 2503d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf if (!netdev->dcbnl_ops->getpfccfg) 2513d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EOPNOTSUPP; 2522f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2532f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = nla_parse_nested(data, DCB_PFC_UP_ATTR_MAX, 2542f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck tb[DCB_ATTR_PFC_CFG], 2552f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcbnl_pfc_up_nest); 2562f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 2573d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return ret; 2582f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2597be994138b188387691322921c08e19bddf6d3c5Thomas Graf nest = nla_nest_start(skb, DCB_ATTR_PFC_CFG); 2602f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!nest) 2613d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EMSGSIZE; 2622f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2632f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (data[DCB_PFC_UP_ATTR_ALL]) 2642f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck getall = 1; 2652f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2662f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck for (i = DCB_PFC_UP_ATTR_0; i <= DCB_PFC_UP_ATTR_7; i++) { 2672f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!getall && !data[i]) 2682f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck continue; 2692f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2702f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck netdev->dcbnl_ops->getpfccfg(netdev, i - DCB_PFC_UP_ATTR_0, 2712f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck &value); 2727be994138b188387691322921c08e19bddf6d3c5Thomas Graf ret = nla_put_u8(skb, i, value); 2732f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) { 2747be994138b188387691322921c08e19bddf6d3c5Thomas Graf nla_nest_cancel(skb, nest); 2753d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return ret; 2762f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 2772f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 2787be994138b188387691322921c08e19bddf6d3c5Thomas Graf nla_nest_end(skb, nest); 2792f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2802f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return 0; 2812f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 2822f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2837be994138b188387691322921c08e19bddf6d3c5Thomas Grafstatic int dcbnl_getperm_hwaddr(struct net_device *netdev, struct nlmsghdr *nlh, 2847be994138b188387691322921c08e19bddf6d3c5Thomas Graf u32 seq, struct nlattr **tb, struct sk_buff *skb) 2852f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 2862f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u8 perm_addr[MAX_ADDR_LEN]; 2872f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2882f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!netdev->dcbnl_ops->getpermhwaddr) 2893d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EOPNOTSUPP; 2902f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2912f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck netdev->dcbnl_ops->getpermhwaddr(netdev, perm_addr); 2922f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2937be994138b188387691322921c08e19bddf6d3c5Thomas Graf return nla_put(skb, DCB_ATTR_PERM_HWADDR, sizeof(perm_addr), perm_addr); 2942f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 2952f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2967be994138b188387691322921c08e19bddf6d3c5Thomas Grafstatic int dcbnl_getcap(struct net_device *netdev, struct nlmsghdr *nlh, 2977be994138b188387691322921c08e19bddf6d3c5Thomas Graf u32 seq, struct nlattr **tb, struct sk_buff *skb) 29846132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck{ 29946132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck struct nlattr *data[DCB_CAP_ATTR_MAX + 1], *nest; 30046132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck u8 value; 3013d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf int ret; 30246132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck int i; 30346132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck int getall = 0; 30446132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck 3053d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf if (!tb[DCB_ATTR_CAP]) 3063d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EINVAL; 3073d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf 3083d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf if (!netdev->dcbnl_ops->getcap) 3093d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EOPNOTSUPP; 31046132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck 31146132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck ret = nla_parse_nested(data, DCB_CAP_ATTR_MAX, tb[DCB_ATTR_CAP], 31246132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck dcbnl_cap_nest); 31346132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck if (ret) 3143d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return ret; 31546132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck 3167be994138b188387691322921c08e19bddf6d3c5Thomas Graf nest = nla_nest_start(skb, DCB_ATTR_CAP); 31746132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck if (!nest) 3183d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EMSGSIZE; 31946132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck 32046132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck if (data[DCB_CAP_ATTR_ALL]) 32146132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck getall = 1; 32246132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck 32346132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck for (i = DCB_CAP_ATTR_ALL+1; i <= DCB_CAP_ATTR_MAX; i++) { 32446132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck if (!getall && !data[i]) 32546132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck continue; 32646132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck 32746132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck if (!netdev->dcbnl_ops->getcap(netdev, i, &value)) { 3287be994138b188387691322921c08e19bddf6d3c5Thomas Graf ret = nla_put_u8(skb, i, value); 32946132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck if (ret) { 3307be994138b188387691322921c08e19bddf6d3c5Thomas Graf nla_nest_cancel(skb, nest); 3313d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return ret; 33246132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck } 33346132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck } 33446132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck } 3357be994138b188387691322921c08e19bddf6d3c5Thomas Graf nla_nest_end(skb, nest); 33646132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck 33746132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck return 0; 33846132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck} 33946132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck 3407be994138b188387691322921c08e19bddf6d3c5Thomas Grafstatic int dcbnl_getnumtcs(struct net_device *netdev, struct nlmsghdr *nlh, 3417be994138b188387691322921c08e19bddf6d3c5Thomas Graf u32 seq, struct nlattr **tb, struct sk_buff *skb) 34233dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck{ 34333dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck struct nlattr *data[DCB_NUMTCS_ATTR_MAX + 1], *nest; 34433dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck u8 value; 3453d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf int ret; 34633dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck int i; 34733dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck int getall = 0; 34833dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 3493d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf if (!tb[DCB_ATTR_NUMTCS]) 3503d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EINVAL; 3513d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf 3523d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf if (!netdev->dcbnl_ops->getnumtcs) 3533d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EOPNOTSUPP; 35433dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 35533dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck ret = nla_parse_nested(data, DCB_NUMTCS_ATTR_MAX, tb[DCB_ATTR_NUMTCS], 35633dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck dcbnl_numtcs_nest); 3573d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf if (ret) 3583d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return ret; 35933dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 3607be994138b188387691322921c08e19bddf6d3c5Thomas Graf nest = nla_nest_start(skb, DCB_ATTR_NUMTCS); 3613d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf if (!nest) 3623d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EMSGSIZE; 36333dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 36433dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck if (data[DCB_NUMTCS_ATTR_ALL]) 36533dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck getall = 1; 36633dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 36733dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck for (i = DCB_NUMTCS_ATTR_ALL+1; i <= DCB_NUMTCS_ATTR_MAX; i++) { 36833dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck if (!getall && !data[i]) 36933dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck continue; 37033dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 37133dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck ret = netdev->dcbnl_ops->getnumtcs(netdev, i, &value); 37233dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck if (!ret) { 3737be994138b188387691322921c08e19bddf6d3c5Thomas Graf ret = nla_put_u8(skb, i, value); 37433dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck if (ret) { 3757be994138b188387691322921c08e19bddf6d3c5Thomas Graf nla_nest_cancel(skb, nest); 3763d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return ret; 37733dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck } 3783d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf } else 3793d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EINVAL; 38033dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck } 3817be994138b188387691322921c08e19bddf6d3c5Thomas Graf nla_nest_end(skb, nest); 38233dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 38333dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck return 0; 38433dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck} 38533dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 3867be994138b188387691322921c08e19bddf6d3c5Thomas Grafstatic int dcbnl_setnumtcs(struct net_device *netdev, struct nlmsghdr *nlh, 3877be994138b188387691322921c08e19bddf6d3c5Thomas Graf u32 seq, struct nlattr **tb, struct sk_buff *skb) 38833dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck{ 38933dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck struct nlattr *data[DCB_NUMTCS_ATTR_MAX + 1]; 3903d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf int ret; 39133dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck u8 value; 39233dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck int i; 39333dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 3943d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf if (!tb[DCB_ATTR_NUMTCS]) 3953d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EINVAL; 3963d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf 3973d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf if (!netdev->dcbnl_ops->setnumtcs) 3983d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EOPNOTSUPP; 39933dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 40033dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck ret = nla_parse_nested(data, DCB_NUMTCS_ATTR_MAX, tb[DCB_ATTR_NUMTCS], 40133dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck dcbnl_numtcs_nest); 4027be994138b188387691322921c08e19bddf6d3c5Thomas Graf if (ret) 4033d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return ret; 40433dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 40533dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck for (i = DCB_NUMTCS_ATTR_ALL+1; i <= DCB_NUMTCS_ATTR_MAX; i++) { 40633dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck if (data[i] == NULL) 40733dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck continue; 40833dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 40933dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck value = nla_get_u8(data[i]); 41033dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 41133dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck ret = netdev->dcbnl_ops->setnumtcs(netdev, i, value); 41233dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck if (ret) 4137be994138b188387691322921c08e19bddf6d3c5Thomas Graf break; 41433dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck } 41533dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 4167be994138b188387691322921c08e19bddf6d3c5Thomas Graf return nla_put_u8(skb, DCB_ATTR_NUMTCS, !!ret); 41733dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck} 41833dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 4197be994138b188387691322921c08e19bddf6d3c5Thomas Grafstatic int dcbnl_getpfcstate(struct net_device *netdev, struct nlmsghdr *nlh, 4207be994138b188387691322921c08e19bddf6d3c5Thomas Graf u32 seq, struct nlattr **tb, struct sk_buff *skb) 4210eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck{ 4220eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck if (!netdev->dcbnl_ops->getpfcstate) 4233d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EOPNOTSUPP; 4240eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck 4257be994138b188387691322921c08e19bddf6d3c5Thomas Graf return nla_put_u8(skb, DCB_ATTR_PFC_STATE, 4267be994138b188387691322921c08e19bddf6d3c5Thomas Graf netdev->dcbnl_ops->getpfcstate(netdev)); 4270eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck} 4280eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck 4297be994138b188387691322921c08e19bddf6d3c5Thomas Grafstatic int dcbnl_setpfcstate(struct net_device *netdev, struct nlmsghdr *nlh, 4307be994138b188387691322921c08e19bddf6d3c5Thomas Graf u32 seq, struct nlattr **tb, struct sk_buff *skb) 4310eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck{ 4320eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck u8 value; 4330eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck 4343d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf if (!tb[DCB_ATTR_PFC_STATE]) 4357be994138b188387691322921c08e19bddf6d3c5Thomas Graf return -EINVAL; 4360eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck 4373d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf if (!netdev->dcbnl_ops->setpfcstate) 4383d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EOPNOTSUPP; 4393d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf 4400eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck value = nla_get_u8(tb[DCB_ATTR_PFC_STATE]); 4410eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck 4420eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck netdev->dcbnl_ops->setpfcstate(netdev, value); 4430eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck 4447be994138b188387691322921c08e19bddf6d3c5Thomas Graf return nla_put_u8(skb, DCB_ATTR_PFC_STATE, 0); 4450eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck} 4460eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck 4477be994138b188387691322921c08e19bddf6d3c5Thomas Grafstatic int dcbnl_getapp(struct net_device *netdev, struct nlmsghdr *nlh, 4487be994138b188387691322921c08e19bddf6d3c5Thomas Graf u32 seq, struct nlattr **tb, struct sk_buff *skb) 449579496865cf4ea429146382d62047ffdbaab0deeYi Zou{ 450579496865cf4ea429146382d62047ffdbaab0deeYi Zou struct nlattr *app_nest; 451579496865cf4ea429146382d62047ffdbaab0deeYi Zou struct nlattr *app_tb[DCB_APP_ATTR_MAX + 1]; 452579496865cf4ea429146382d62047ffdbaab0deeYi Zou u16 id; 453579496865cf4ea429146382d62047ffdbaab0deeYi Zou u8 up, idtype; 4543d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf int ret; 455579496865cf4ea429146382d62047ffdbaab0deeYi Zou 4563dce38a02d6370dca690cd923619d4b00024b723John Fastabend if (!tb[DCB_ATTR_APP]) 4573d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EINVAL; 458579496865cf4ea429146382d62047ffdbaab0deeYi Zou 459579496865cf4ea429146382d62047ffdbaab0deeYi Zou ret = nla_parse_nested(app_tb, DCB_APP_ATTR_MAX, tb[DCB_ATTR_APP], 460579496865cf4ea429146382d62047ffdbaab0deeYi Zou dcbnl_app_nest); 461579496865cf4ea429146382d62047ffdbaab0deeYi Zou if (ret) 4623d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return ret; 463579496865cf4ea429146382d62047ffdbaab0deeYi Zou 464579496865cf4ea429146382d62047ffdbaab0deeYi Zou /* all must be non-null */ 465579496865cf4ea429146382d62047ffdbaab0deeYi Zou if ((!app_tb[DCB_APP_ATTR_IDTYPE]) || 466579496865cf4ea429146382d62047ffdbaab0deeYi Zou (!app_tb[DCB_APP_ATTR_ID])) 4673d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EINVAL; 468579496865cf4ea429146382d62047ffdbaab0deeYi Zou 469579496865cf4ea429146382d62047ffdbaab0deeYi Zou /* either by eth type or by socket number */ 470579496865cf4ea429146382d62047ffdbaab0deeYi Zou idtype = nla_get_u8(app_tb[DCB_APP_ATTR_IDTYPE]); 471579496865cf4ea429146382d62047ffdbaab0deeYi Zou if ((idtype != DCB_APP_IDTYPE_ETHTYPE) && 472579496865cf4ea429146382d62047ffdbaab0deeYi Zou (idtype != DCB_APP_IDTYPE_PORTNUM)) 4733d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EINVAL; 474579496865cf4ea429146382d62047ffdbaab0deeYi Zou 475579496865cf4ea429146382d62047ffdbaab0deeYi Zou id = nla_get_u16(app_tb[DCB_APP_ATTR_ID]); 4763dce38a02d6370dca690cd923619d4b00024b723John Fastabend 4773dce38a02d6370dca690cd923619d4b00024b723John Fastabend if (netdev->dcbnl_ops->getapp) { 4783dce38a02d6370dca690cd923619d4b00024b723John Fastabend up = netdev->dcbnl_ops->getapp(netdev, idtype, id); 4793dce38a02d6370dca690cd923619d4b00024b723John Fastabend } else { 4803dce38a02d6370dca690cd923619d4b00024b723John Fastabend struct dcb_app app = { 4813dce38a02d6370dca690cd923619d4b00024b723John Fastabend .selector = idtype, 4823dce38a02d6370dca690cd923619d4b00024b723John Fastabend .protocol = id, 4833dce38a02d6370dca690cd923619d4b00024b723John Fastabend }; 4843dce38a02d6370dca690cd923619d4b00024b723John Fastabend up = dcb_getapp(netdev, &app); 4853dce38a02d6370dca690cd923619d4b00024b723John Fastabend } 486579496865cf4ea429146382d62047ffdbaab0deeYi Zou 4877be994138b188387691322921c08e19bddf6d3c5Thomas Graf app_nest = nla_nest_start(skb, DCB_ATTR_APP); 488d3337de52af7fb0ebe605b02b740be4ee7dee9ebJesper Juhl if (!app_nest) 4893d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EMSGSIZE; 490d3337de52af7fb0ebe605b02b740be4ee7dee9ebJesper Juhl 4917be994138b188387691322921c08e19bddf6d3c5Thomas Graf ret = nla_put_u8(skb, DCB_APP_ATTR_IDTYPE, idtype); 492579496865cf4ea429146382d62047ffdbaab0deeYi Zou if (ret) 493579496865cf4ea429146382d62047ffdbaab0deeYi Zou goto out_cancel; 494579496865cf4ea429146382d62047ffdbaab0deeYi Zou 4957be994138b188387691322921c08e19bddf6d3c5Thomas Graf ret = nla_put_u16(skb, DCB_APP_ATTR_ID, id); 496579496865cf4ea429146382d62047ffdbaab0deeYi Zou if (ret) 497579496865cf4ea429146382d62047ffdbaab0deeYi Zou goto out_cancel; 498579496865cf4ea429146382d62047ffdbaab0deeYi Zou 4997be994138b188387691322921c08e19bddf6d3c5Thomas Graf ret = nla_put_u8(skb, DCB_APP_ATTR_PRIORITY, up); 500579496865cf4ea429146382d62047ffdbaab0deeYi Zou if (ret) 501579496865cf4ea429146382d62047ffdbaab0deeYi Zou goto out_cancel; 502579496865cf4ea429146382d62047ffdbaab0deeYi Zou 5037be994138b188387691322921c08e19bddf6d3c5Thomas Graf nla_nest_end(skb, app_nest); 504579496865cf4ea429146382d62047ffdbaab0deeYi Zou 5053d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return 0; 506579496865cf4ea429146382d62047ffdbaab0deeYi Zou 507579496865cf4ea429146382d62047ffdbaab0deeYi Zouout_cancel: 5087be994138b188387691322921c08e19bddf6d3c5Thomas Graf nla_nest_cancel(skb, app_nest); 509579496865cf4ea429146382d62047ffdbaab0deeYi Zou return ret; 510579496865cf4ea429146382d62047ffdbaab0deeYi Zou} 511579496865cf4ea429146382d62047ffdbaab0deeYi Zou 5127be994138b188387691322921c08e19bddf6d3c5Thomas Grafstatic int dcbnl_setapp(struct net_device *netdev, struct nlmsghdr *nlh, 5137be994138b188387691322921c08e19bddf6d3c5Thomas Graf u32 seq, struct nlattr **tb, struct sk_buff *skb) 514579496865cf4ea429146382d62047ffdbaab0deeYi Zou{ 5153d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf int ret; 516579496865cf4ea429146382d62047ffdbaab0deeYi Zou u16 id; 517579496865cf4ea429146382d62047ffdbaab0deeYi Zou u8 up, idtype; 518579496865cf4ea429146382d62047ffdbaab0deeYi Zou struct nlattr *app_tb[DCB_APP_ATTR_MAX + 1]; 519579496865cf4ea429146382d62047ffdbaab0deeYi Zou 5209ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend if (!tb[DCB_ATTR_APP]) 5213d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EINVAL; 522579496865cf4ea429146382d62047ffdbaab0deeYi Zou 523579496865cf4ea429146382d62047ffdbaab0deeYi Zou ret = nla_parse_nested(app_tb, DCB_APP_ATTR_MAX, tb[DCB_ATTR_APP], 524579496865cf4ea429146382d62047ffdbaab0deeYi Zou dcbnl_app_nest); 525579496865cf4ea429146382d62047ffdbaab0deeYi Zou if (ret) 5263d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return ret; 527579496865cf4ea429146382d62047ffdbaab0deeYi Zou 528579496865cf4ea429146382d62047ffdbaab0deeYi Zou /* all must be non-null */ 529579496865cf4ea429146382d62047ffdbaab0deeYi Zou if ((!app_tb[DCB_APP_ATTR_IDTYPE]) || 530579496865cf4ea429146382d62047ffdbaab0deeYi Zou (!app_tb[DCB_APP_ATTR_ID]) || 531579496865cf4ea429146382d62047ffdbaab0deeYi Zou (!app_tb[DCB_APP_ATTR_PRIORITY])) 5323d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EINVAL; 533579496865cf4ea429146382d62047ffdbaab0deeYi Zou 534579496865cf4ea429146382d62047ffdbaab0deeYi Zou /* either by eth type or by socket number */ 535579496865cf4ea429146382d62047ffdbaab0deeYi Zou idtype = nla_get_u8(app_tb[DCB_APP_ATTR_IDTYPE]); 536579496865cf4ea429146382d62047ffdbaab0deeYi Zou if ((idtype != DCB_APP_IDTYPE_ETHTYPE) && 537579496865cf4ea429146382d62047ffdbaab0deeYi Zou (idtype != DCB_APP_IDTYPE_PORTNUM)) 5383d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EINVAL; 539579496865cf4ea429146382d62047ffdbaab0deeYi Zou 540579496865cf4ea429146382d62047ffdbaab0deeYi Zou id = nla_get_u16(app_tb[DCB_APP_ATTR_ID]); 541579496865cf4ea429146382d62047ffdbaab0deeYi Zou up = nla_get_u8(app_tb[DCB_APP_ATTR_PRIORITY]); 542579496865cf4ea429146382d62047ffdbaab0deeYi Zou 5439ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend if (netdev->dcbnl_ops->setapp) { 5443d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf ret = netdev->dcbnl_ops->setapp(netdev, idtype, id, up); 5459ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend } else { 5469ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend struct dcb_app app; 5479ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend app.selector = idtype; 5489ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend app.protocol = id; 5499ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend app.priority = up; 5503d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf ret = dcb_setapp(netdev, &app); 5519ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend } 5529ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend 5537be994138b188387691322921c08e19bddf6d3c5Thomas Graf ret = nla_put_u8(skb, DCB_ATTR_APP, ret); 554081579840b4b2421e37bc67e3b089b7ca64ef040John Fastabend dcbnl_cee_notify(netdev, RTM_SETDCB, DCB_CMD_SAPP, seq, 0); 5553d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf 556579496865cf4ea429146382d62047ffdbaab0deeYi Zou return ret; 557579496865cf4ea429146382d62047ffdbaab0deeYi Zou} 558579496865cf4ea429146382d62047ffdbaab0deeYi Zou 5597be994138b188387691322921c08e19bddf6d3c5Thomas Grafstatic int __dcbnl_pg_getcfg(struct net_device *netdev, struct nlmsghdr *nlh, 5607be994138b188387691322921c08e19bddf6d3c5Thomas Graf struct nlattr **tb, struct sk_buff *skb, int dir) 5612f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 5622f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct nlattr *pg_nest, *param_nest, *data; 5632f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct nlattr *pg_tb[DCB_PG_ATTR_MAX + 1]; 5642f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct nlattr *param_tb[DCB_TC_ATTR_PARAM_MAX + 1]; 5652f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u8 prio, pgid, tc_pct, up_map; 5663d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf int ret; 5672f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck int getall = 0; 5682f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck int i; 5692f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 5703d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf if (!tb[DCB_ATTR_PG_CFG]) 5713d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EINVAL; 5723d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf 5733d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf if (!netdev->dcbnl_ops->getpgtccfgtx || 5742f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck !netdev->dcbnl_ops->getpgtccfgrx || 5752f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck !netdev->dcbnl_ops->getpgbwgcfgtx || 5762f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck !netdev->dcbnl_ops->getpgbwgcfgrx) 5773d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EOPNOTSUPP; 5782f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 5792f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = nla_parse_nested(pg_tb, DCB_PG_ATTR_MAX, 5802f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck tb[DCB_ATTR_PG_CFG], dcbnl_pg_nest); 5812f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 5823d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return ret; 5832f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 5847be994138b188387691322921c08e19bddf6d3c5Thomas Graf pg_nest = nla_nest_start(skb, DCB_ATTR_PG_CFG); 5852f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!pg_nest) 5863d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EMSGSIZE; 5872f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 5882f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (pg_tb[DCB_PG_ATTR_TC_ALL]) 5892f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck getall = 1; 5902f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 5912f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck for (i = DCB_PG_ATTR_TC_0; i <= DCB_PG_ATTR_TC_7; i++) { 5922f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!getall && !pg_tb[i]) 5932f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck continue; 5942f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 5952f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (pg_tb[DCB_PG_ATTR_TC_ALL]) 5962f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck data = pg_tb[DCB_PG_ATTR_TC_ALL]; 5972f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck else 5982f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck data = pg_tb[i]; 5992f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = nla_parse_nested(param_tb, DCB_TC_ATTR_PARAM_MAX, 6002f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck data, dcbnl_tc_param_nest); 6012f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 6022f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err_pg; 6032f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 6047be994138b188387691322921c08e19bddf6d3c5Thomas Graf param_nest = nla_nest_start(skb, i); 6052f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!param_nest) 6062f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err_pg; 6072f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 6082f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck pgid = DCB_ATTR_VALUE_UNDEFINED; 6092f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck prio = DCB_ATTR_VALUE_UNDEFINED; 6102f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck tc_pct = DCB_ATTR_VALUE_UNDEFINED; 6112f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck up_map = DCB_ATTR_VALUE_UNDEFINED; 6122f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 6132f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (dir) { 6142f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck /* Rx */ 6152f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck netdev->dcbnl_ops->getpgtccfgrx(netdev, 6162f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck i - DCB_PG_ATTR_TC_0, &prio, 6172f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck &pgid, &tc_pct, &up_map); 6182f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } else { 6192f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck /* Tx */ 6202f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck netdev->dcbnl_ops->getpgtccfgtx(netdev, 6212f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck i - DCB_PG_ATTR_TC_0, &prio, 6222f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck &pgid, &tc_pct, &up_map); 6232f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 6242f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 6252f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (param_tb[DCB_TC_ATTR_PARAM_PGID] || 6262f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck param_tb[DCB_TC_ATTR_PARAM_ALL]) { 6277be994138b188387691322921c08e19bddf6d3c5Thomas Graf ret = nla_put_u8(skb, 6282f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck DCB_TC_ATTR_PARAM_PGID, pgid); 6292f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 6302f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err_param; 6312f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 6322f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (param_tb[DCB_TC_ATTR_PARAM_UP_MAPPING] || 6332f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck param_tb[DCB_TC_ATTR_PARAM_ALL]) { 6347be994138b188387691322921c08e19bddf6d3c5Thomas Graf ret = nla_put_u8(skb, 6352f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck DCB_TC_ATTR_PARAM_UP_MAPPING, up_map); 6362f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 6372f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err_param; 6382f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 6392f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (param_tb[DCB_TC_ATTR_PARAM_STRICT_PRIO] || 6402f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck param_tb[DCB_TC_ATTR_PARAM_ALL]) { 6417be994138b188387691322921c08e19bddf6d3c5Thomas Graf ret = nla_put_u8(skb, 6422f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck DCB_TC_ATTR_PARAM_STRICT_PRIO, prio); 6432f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 6442f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err_param; 6452f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 6462f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (param_tb[DCB_TC_ATTR_PARAM_BW_PCT] || 6472f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck param_tb[DCB_TC_ATTR_PARAM_ALL]) { 6487be994138b188387691322921c08e19bddf6d3c5Thomas Graf ret = nla_put_u8(skb, DCB_TC_ATTR_PARAM_BW_PCT, 6492f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck tc_pct); 6502f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 6512f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err_param; 6522f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 6537be994138b188387691322921c08e19bddf6d3c5Thomas Graf nla_nest_end(skb, param_nest); 6542f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 6552f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 6562f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (pg_tb[DCB_PG_ATTR_BW_ID_ALL]) 6572f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck getall = 1; 6582f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck else 6592f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck getall = 0; 6602f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 6612f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck for (i = DCB_PG_ATTR_BW_ID_0; i <= DCB_PG_ATTR_BW_ID_7; i++) { 6622f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!getall && !pg_tb[i]) 6632f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck continue; 6642f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 6652f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck tc_pct = DCB_ATTR_VALUE_UNDEFINED; 6662f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 6672f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (dir) { 6682f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck /* Rx */ 6692f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck netdev->dcbnl_ops->getpgbwgcfgrx(netdev, 6702f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck i - DCB_PG_ATTR_BW_ID_0, &tc_pct); 6712f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } else { 6722f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck /* Tx */ 6732f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck netdev->dcbnl_ops->getpgbwgcfgtx(netdev, 6742f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck i - DCB_PG_ATTR_BW_ID_0, &tc_pct); 6752f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 6767be994138b188387691322921c08e19bddf6d3c5Thomas Graf ret = nla_put_u8(skb, i, tc_pct); 6772f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 6782f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err_pg; 6792f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 6802f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 6817be994138b188387691322921c08e19bddf6d3c5Thomas Graf nla_nest_end(skb, pg_nest); 6822f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 6832f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return 0; 6842f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 6852f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckerr_param: 6867be994138b188387691322921c08e19bddf6d3c5Thomas Graf nla_nest_cancel(skb, param_nest); 6872f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckerr_pg: 6887be994138b188387691322921c08e19bddf6d3c5Thomas Graf nla_nest_cancel(skb, pg_nest); 6893d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf 6903d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EMSGSIZE; 6912f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 6922f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 6937be994138b188387691322921c08e19bddf6d3c5Thomas Grafstatic int dcbnl_pgtx_getcfg(struct net_device *netdev, struct nlmsghdr *nlh, 6947be994138b188387691322921c08e19bddf6d3c5Thomas Graf u32 seq, struct nlattr **tb, struct sk_buff *skb) 6952f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 6967be994138b188387691322921c08e19bddf6d3c5Thomas Graf return __dcbnl_pg_getcfg(netdev, nlh, tb, skb, 0); 6972f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 6982f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 6997be994138b188387691322921c08e19bddf6d3c5Thomas Grafstatic int dcbnl_pgrx_getcfg(struct net_device *netdev, struct nlmsghdr *nlh, 7007be994138b188387691322921c08e19bddf6d3c5Thomas Graf u32 seq, struct nlattr **tb, struct sk_buff *skb) 7012f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 7027be994138b188387691322921c08e19bddf6d3c5Thomas Graf return __dcbnl_pg_getcfg(netdev, nlh, tb, skb, 1); 7032f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 7042f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7057be994138b188387691322921c08e19bddf6d3c5Thomas Grafstatic int dcbnl_setstate(struct net_device *netdev, struct nlmsghdr *nlh, 7067be994138b188387691322921c08e19bddf6d3c5Thomas Graf u32 seq, struct nlattr **tb, struct sk_buff *skb) 7072f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 7082f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u8 value; 7092f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7103d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf if (!tb[DCB_ATTR_STATE]) 7117be994138b188387691322921c08e19bddf6d3c5Thomas Graf return -EINVAL; 7122f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7133d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf if (!netdev->dcbnl_ops->setstate) 7143d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EOPNOTSUPP; 7153d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf 7162f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck value = nla_get_u8(tb[DCB_ATTR_STATE]); 7172f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7187be994138b188387691322921c08e19bddf6d3c5Thomas Graf return nla_put_u8(skb, DCB_ATTR_STATE, 7197be994138b188387691322921c08e19bddf6d3c5Thomas Graf netdev->dcbnl_ops->setstate(netdev, value)); 7202f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 7212f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7227be994138b188387691322921c08e19bddf6d3c5Thomas Grafstatic int dcbnl_setpfccfg(struct net_device *netdev, struct nlmsghdr *nlh, 7237be994138b188387691322921c08e19bddf6d3c5Thomas Graf u32 seq, struct nlattr **tb, struct sk_buff *skb) 7242f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 7252f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct nlattr *data[DCB_PFC_UP_ATTR_MAX + 1]; 7262f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck int i; 7273d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf int ret; 7282f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u8 value; 7292f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7303d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf if (!tb[DCB_ATTR_PFC_CFG]) 7313d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EINVAL; 7323d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf 7333d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf if (!netdev->dcbnl_ops->setpfccfg) 7343d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EOPNOTSUPP; 7352f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7362f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = nla_parse_nested(data, DCB_PFC_UP_ATTR_MAX, 7372f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck tb[DCB_ATTR_PFC_CFG], 7382f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcbnl_pfc_up_nest); 7392f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 7403d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return ret; 7412f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7422f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck for (i = DCB_PFC_UP_ATTR_0; i <= DCB_PFC_UP_ATTR_7; i++) { 7432f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (data[i] == NULL) 7442f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck continue; 7452f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck value = nla_get_u8(data[i]); 7462f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck netdev->dcbnl_ops->setpfccfg(netdev, 7472f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck data[i]->nla_type - DCB_PFC_UP_ATTR_0, value); 7482f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 7492f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7507be994138b188387691322921c08e19bddf6d3c5Thomas Graf return nla_put_u8(skb, DCB_ATTR_PFC_CFG, 0); 7512f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 7522f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7537be994138b188387691322921c08e19bddf6d3c5Thomas Grafstatic int dcbnl_setall(struct net_device *netdev, struct nlmsghdr *nlh, 7547be994138b188387691322921c08e19bddf6d3c5Thomas Graf u32 seq, struct nlattr **tb, struct sk_buff *skb) 7552f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 7563d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf int ret; 7572f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7583d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf if (!tb[DCB_ATTR_SET_ALL]) 7593d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EINVAL; 7603d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf 7613d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf if (!netdev->dcbnl_ops->setall) 7623d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EOPNOTSUPP; 7632f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7647be994138b188387691322921c08e19bddf6d3c5Thomas Graf ret = nla_put_u8(skb, DCB_ATTR_SET_ALL, 7657be994138b188387691322921c08e19bddf6d3c5Thomas Graf netdev->dcbnl_ops->setall(netdev)); 766081579840b4b2421e37bc67e3b089b7ca64ef040John Fastabend dcbnl_cee_notify(netdev, RTM_SETDCB, DCB_CMD_SET_ALL, seq, 0); 7672f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7682f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return ret; 7692f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 7702f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7717be994138b188387691322921c08e19bddf6d3c5Thomas Grafstatic int __dcbnl_pg_setcfg(struct net_device *netdev, struct nlmsghdr *nlh, 7727be994138b188387691322921c08e19bddf6d3c5Thomas Graf u32 seq, struct nlattr **tb, struct sk_buff *skb, 7737be994138b188387691322921c08e19bddf6d3c5Thomas Graf int dir) 7742f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 7752f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct nlattr *pg_tb[DCB_PG_ATTR_MAX + 1]; 7762f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct nlattr *param_tb[DCB_TC_ATTR_PARAM_MAX + 1]; 7773d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf int ret; 7782f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck int i; 7792f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u8 pgid; 7802f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u8 up_map; 7812f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u8 prio; 7822f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u8 tc_pct; 7832f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7843d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf if (!tb[DCB_ATTR_PG_CFG]) 7853d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EINVAL; 7863d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf 7873d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf if (!netdev->dcbnl_ops->setpgtccfgtx || 7882f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck !netdev->dcbnl_ops->setpgtccfgrx || 7892f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck !netdev->dcbnl_ops->setpgbwgcfgtx || 7902f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck !netdev->dcbnl_ops->setpgbwgcfgrx) 7913d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EOPNOTSUPP; 7922f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7932f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = nla_parse_nested(pg_tb, DCB_PG_ATTR_MAX, 7942f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck tb[DCB_ATTR_PG_CFG], dcbnl_pg_nest); 7952f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 7963d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return ret; 7972f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7982f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck for (i = DCB_PG_ATTR_TC_0; i <= DCB_PG_ATTR_TC_7; i++) { 7992f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!pg_tb[i]) 8002f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck continue; 8012f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8022f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = nla_parse_nested(param_tb, DCB_TC_ATTR_PARAM_MAX, 8032f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck pg_tb[i], dcbnl_tc_param_nest); 8042f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 8053d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return ret; 8062f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8072f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck pgid = DCB_ATTR_VALUE_UNDEFINED; 8082f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck prio = DCB_ATTR_VALUE_UNDEFINED; 8092f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck tc_pct = DCB_ATTR_VALUE_UNDEFINED; 8102f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck up_map = DCB_ATTR_VALUE_UNDEFINED; 8112f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8122f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (param_tb[DCB_TC_ATTR_PARAM_STRICT_PRIO]) 8132f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck prio = 8142f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nla_get_u8(param_tb[DCB_TC_ATTR_PARAM_STRICT_PRIO]); 8152f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8162f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (param_tb[DCB_TC_ATTR_PARAM_PGID]) 8172f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck pgid = nla_get_u8(param_tb[DCB_TC_ATTR_PARAM_PGID]); 8182f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8192f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (param_tb[DCB_TC_ATTR_PARAM_BW_PCT]) 8202f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck tc_pct = nla_get_u8(param_tb[DCB_TC_ATTR_PARAM_BW_PCT]); 8212f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8222f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (param_tb[DCB_TC_ATTR_PARAM_UP_MAPPING]) 8232f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck up_map = 8242f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nla_get_u8(param_tb[DCB_TC_ATTR_PARAM_UP_MAPPING]); 8252f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8262f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck /* dir: Tx = 0, Rx = 1 */ 8272f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (dir) { 8282f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck /* Rx */ 8292f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck netdev->dcbnl_ops->setpgtccfgrx(netdev, 8302f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck i - DCB_PG_ATTR_TC_0, 8312f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck prio, pgid, tc_pct, up_map); 8322f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } else { 8332f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck /* Tx */ 8342f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck netdev->dcbnl_ops->setpgtccfgtx(netdev, 8352f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck i - DCB_PG_ATTR_TC_0, 8362f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck prio, pgid, tc_pct, up_map); 8372f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 8382f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 8392f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8402f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck for (i = DCB_PG_ATTR_BW_ID_0; i <= DCB_PG_ATTR_BW_ID_7; i++) { 8412f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!pg_tb[i]) 8422f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck continue; 8432f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8442f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck tc_pct = nla_get_u8(pg_tb[i]); 8452f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8462f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck /* dir: Tx = 0, Rx = 1 */ 8472f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (dir) { 8482f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck /* Rx */ 8492f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck netdev->dcbnl_ops->setpgbwgcfgrx(netdev, 8502f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck i - DCB_PG_ATTR_BW_ID_0, tc_pct); 8512f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } else { 8522f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck /* Tx */ 8532f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck netdev->dcbnl_ops->setpgbwgcfgtx(netdev, 8542f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck i - DCB_PG_ATTR_BW_ID_0, tc_pct); 8552f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 8562f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 8572f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8583d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return nla_put_u8(skb, 8593d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf (dir ? DCB_CMD_PGRX_SCFG : DCB_CMD_PGTX_SCFG), 0); 8602f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 8612f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8627be994138b188387691322921c08e19bddf6d3c5Thomas Grafstatic int dcbnl_pgtx_setcfg(struct net_device *netdev, struct nlmsghdr *nlh, 8637be994138b188387691322921c08e19bddf6d3c5Thomas Graf u32 seq, struct nlattr **tb, struct sk_buff *skb) 8642f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 8657be994138b188387691322921c08e19bddf6d3c5Thomas Graf return __dcbnl_pg_setcfg(netdev, nlh, seq, tb, skb, 0); 8662f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 8672f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8687be994138b188387691322921c08e19bddf6d3c5Thomas Grafstatic int dcbnl_pgrx_setcfg(struct net_device *netdev, struct nlmsghdr *nlh, 8697be994138b188387691322921c08e19bddf6d3c5Thomas Graf u32 seq, struct nlattr **tb, struct sk_buff *skb) 8702f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 8717be994138b188387691322921c08e19bddf6d3c5Thomas Graf return __dcbnl_pg_setcfg(netdev, nlh, seq, tb, skb, 1); 8722f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 8732f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8747be994138b188387691322921c08e19bddf6d3c5Thomas Grafstatic int dcbnl_bcn_getcfg(struct net_device *netdev, struct nlmsghdr *nlh, 8757be994138b188387691322921c08e19bddf6d3c5Thomas Graf u32 seq, struct nlattr **tb, struct sk_buff *skb) 876859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck{ 877859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck struct nlattr *bcn_nest; 878859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck struct nlattr *bcn_tb[DCB_BCN_ATTR_MAX + 1]; 879859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck u8 value_byte; 880859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck u32 value_integer; 8813d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf int ret; 882859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck bool getall = false; 883859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck int i; 884859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 8853d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf if (!tb[DCB_ATTR_BCN]) 8863d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EINVAL; 8873d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf 8883d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf if (!netdev->dcbnl_ops->getbcnrp || 889859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck !netdev->dcbnl_ops->getbcncfg) 8903d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EOPNOTSUPP; 891859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 892859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck ret = nla_parse_nested(bcn_tb, DCB_BCN_ATTR_MAX, 893859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck tb[DCB_ATTR_BCN], dcbnl_bcn_nest); 894859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck if (ret) 8953d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return ret; 896859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 8977be994138b188387691322921c08e19bddf6d3c5Thomas Graf bcn_nest = nla_nest_start(skb, DCB_ATTR_BCN); 898859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck if (!bcn_nest) 8993d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EMSGSIZE; 900859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 901859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck if (bcn_tb[DCB_BCN_ATTR_ALL]) 902859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck getall = true; 903859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 904859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck for (i = DCB_BCN_ATTR_RP_0; i <= DCB_BCN_ATTR_RP_7; i++) { 905859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck if (!getall && !bcn_tb[i]) 906859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck continue; 907859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 908859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck netdev->dcbnl_ops->getbcnrp(netdev, i - DCB_BCN_ATTR_RP_0, 909859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck &value_byte); 9107be994138b188387691322921c08e19bddf6d3c5Thomas Graf ret = nla_put_u8(skb, i, value_byte); 911859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck if (ret) 912859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck goto err_bcn; 913859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck } 914859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 915f4314e815e87b4ab1c9b1115dd5853cd20ca999cDon Skidmore for (i = DCB_BCN_ATTR_BCNA_0; i <= DCB_BCN_ATTR_RI; i++) { 916859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck if (!getall && !bcn_tb[i]) 917859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck continue; 918859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 919859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck netdev->dcbnl_ops->getbcncfg(netdev, i, 920859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck &value_integer); 9217be994138b188387691322921c08e19bddf6d3c5Thomas Graf ret = nla_put_u32(skb, i, value_integer); 922859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck if (ret) 923859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck goto err_bcn; 924859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck } 925859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 9267be994138b188387691322921c08e19bddf6d3c5Thomas Graf nla_nest_end(skb, bcn_nest); 927859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 928859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck return 0; 929859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 930859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyckerr_bcn: 9317be994138b188387691322921c08e19bddf6d3c5Thomas Graf nla_nest_cancel(skb, bcn_nest); 932859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck return ret; 933859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck} 934859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 9357be994138b188387691322921c08e19bddf6d3c5Thomas Grafstatic int dcbnl_bcn_setcfg(struct net_device *netdev, struct nlmsghdr *nlh, 9367be994138b188387691322921c08e19bddf6d3c5Thomas Graf u32 seq, struct nlattr **tb, struct sk_buff *skb) 937859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck{ 938859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck struct nlattr *data[DCB_BCN_ATTR_MAX + 1]; 939859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck int i; 9403d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf int ret; 941859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck u8 value_byte; 942859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck u32 value_int; 943859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 9443d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf if (!tb[DCB_ATTR_BCN]) 9453d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EINVAL; 9463d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf 9473d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf if (!netdev->dcbnl_ops->setbcncfg || 948f64f9e719261a87818dd192a3a2352e5b20fbd0fJoe Perches !netdev->dcbnl_ops->setbcnrp) 9493d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EOPNOTSUPP; 950859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 951859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck ret = nla_parse_nested(data, DCB_BCN_ATTR_MAX, 952859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck tb[DCB_ATTR_BCN], 953859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck dcbnl_pfc_up_nest); 954859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck if (ret) 9553d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return ret; 956859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 957859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck for (i = DCB_BCN_ATTR_RP_0; i <= DCB_BCN_ATTR_RP_7; i++) { 958859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck if (data[i] == NULL) 959859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck continue; 960859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck value_byte = nla_get_u8(data[i]); 961859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck netdev->dcbnl_ops->setbcnrp(netdev, 962859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck data[i]->nla_type - DCB_BCN_ATTR_RP_0, value_byte); 963859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck } 964859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 965f4314e815e87b4ab1c9b1115dd5853cd20ca999cDon Skidmore for (i = DCB_BCN_ATTR_BCNA_0; i <= DCB_BCN_ATTR_RI; i++) { 966859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck if (data[i] == NULL) 967859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck continue; 968859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck value_int = nla_get_u32(data[i]); 969859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck netdev->dcbnl_ops->setbcncfg(netdev, 970859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck i, value_int); 971859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck } 972859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 9733d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return nla_put_u8(skb, DCB_ATTR_BCN, 0); 974859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck} 975859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 976dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravidstatic int dcbnl_build_peer_app(struct net_device *netdev, struct sk_buff* skb, 977dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid int app_nested_type, int app_info_type, 978dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid int app_entry_type) 979eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid{ 980eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid struct dcb_peer_app_info info; 981eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid struct dcb_app *table = NULL; 982eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops; 983eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid u16 app_count; 984eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid int err; 985eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid 986eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid 987eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid /** 988eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid * retrieve the peer app configuration form the driver. If the driver 989eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid * handlers fail exit without doing anything 990eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid */ 991eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid err = ops->peer_getappinfo(netdev, &info, &app_count); 992eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid if (!err && app_count) { 993eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid table = kmalloc(sizeof(struct dcb_app) * app_count, GFP_KERNEL); 994eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid if (!table) 995eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid return -ENOMEM; 996eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid 997eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid err = ops->peer_getapptable(netdev, table); 998eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid } 999eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid 1000eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid if (!err) { 1001eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid u16 i; 1002eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid struct nlattr *app; 1003eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid 1004eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid /** 1005eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid * build the message, from here on the only possible failure 1006eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid * is due to the skb size 1007eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid */ 1008eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid err = -EMSGSIZE; 1009eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid 1010dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid app = nla_nest_start(skb, app_nested_type); 1011eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid if (!app) 1012eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid goto nla_put_failure; 1013eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid 10141eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller if (app_info_type && 10151eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller nla_put(skb, app_info_type, sizeof(info), &info)) 10161eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller goto nla_put_failure; 1017eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid 10181eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller for (i = 0; i < app_count; i++) { 10191eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller if (nla_put(skb, app_entry_type, sizeof(struct dcb_app), 10201eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller &table[i])) 10211eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller goto nla_put_failure; 10221eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller } 1023eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid nla_nest_end(skb, app); 1024eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid } 1025eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid err = 0; 1026eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid 1027eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravidnla_put_failure: 1028eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid kfree(table); 1029eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid return err; 1030eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid} 10313e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend 10323e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend/* Handle IEEE 802.1Qaz GET commands. */ 1033314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabendstatic int dcbnl_ieee_fill(struct sk_buff *skb, struct net_device *netdev) 10343e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend{ 10359ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend struct nlattr *ieee, *app; 10369ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend struct dcb_app_type *itr; 10373e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops; 1038c7797baf9f3900996ca800ab6298f95957bb4606John Fastabend int dcbx; 10393d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf int err; 10403e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend 10411eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller if (nla_put_string(skb, DCB_ATTR_IFNAME, netdev->name)) 10423d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EMSGSIZE; 10433d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf 10443e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend ieee = nla_nest_start(skb, DCB_ATTR_IEEE); 10453e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend if (!ieee) 10463d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EMSGSIZE; 10473e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend 10483e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend if (ops->ieee_getets) { 10493e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend struct ieee_ets ets; 10503e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend err = ops->ieee_getets(netdev, &ets); 10511eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller if (!err && 10521eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller nla_put(skb, DCB_ATTR_IEEE_ETS, sizeof(ets), &ets)) 10533d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EMSGSIZE; 10543e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend } 10553e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend 105608f10affe45051e18e0d8291c0a53aecef1b8a14Amir Vadai if (ops->ieee_getmaxrate) { 105708f10affe45051e18e0d8291c0a53aecef1b8a14Amir Vadai struct ieee_maxrate maxrate; 105808f10affe45051e18e0d8291c0a53aecef1b8a14Amir Vadai err = ops->ieee_getmaxrate(netdev, &maxrate); 105908f10affe45051e18e0d8291c0a53aecef1b8a14Amir Vadai if (!err) { 106008f10affe45051e18e0d8291c0a53aecef1b8a14Amir Vadai err = nla_put(skb, DCB_ATTR_IEEE_MAXRATE, 106108f10affe45051e18e0d8291c0a53aecef1b8a14Amir Vadai sizeof(maxrate), &maxrate); 106208f10affe45051e18e0d8291c0a53aecef1b8a14Amir Vadai if (err) 10633d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EMSGSIZE; 106408f10affe45051e18e0d8291c0a53aecef1b8a14Amir Vadai } 106508f10affe45051e18e0d8291c0a53aecef1b8a14Amir Vadai } 106608f10affe45051e18e0d8291c0a53aecef1b8a14Amir Vadai 10673e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend if (ops->ieee_getpfc) { 10683e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend struct ieee_pfc pfc; 10693e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend err = ops->ieee_getpfc(netdev, &pfc); 10701eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller if (!err && 10711eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller nla_put(skb, DCB_ATTR_IEEE_PFC, sizeof(pfc), &pfc)) 10723d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EMSGSIZE; 10733e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend } 10743e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend 10759ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend app = nla_nest_start(skb, DCB_ATTR_IEEE_APP_TABLE); 10769ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend if (!app) 10773d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EMSGSIZE; 10789ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend 10799ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend spin_lock(&dcb_lock); 10809ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend list_for_each_entry(itr, &dcb_app_list, list) { 1081e290ed81307ca7d92675f0d9c683add693c2f377Mark Rustad if (itr->ifindex == netdev->ifindex) { 108270bfa2d2e1bfd90ef26758b5e2749f043a940037Dan Carpenter err = nla_put(skb, DCB_ATTR_IEEE_APP, sizeof(itr->app), 108370bfa2d2e1bfd90ef26758b5e2749f043a940037Dan Carpenter &itr->app); 108470bfa2d2e1bfd90ef26758b5e2749f043a940037Dan Carpenter if (err) { 108570bfa2d2e1bfd90ef26758b5e2749f043a940037Dan Carpenter spin_unlock(&dcb_lock); 10863d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EMSGSIZE; 108770bfa2d2e1bfd90ef26758b5e2749f043a940037Dan Carpenter } 108870bfa2d2e1bfd90ef26758b5e2749f043a940037Dan Carpenter } 10899ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend } 1090c7797baf9f3900996ca800ab6298f95957bb4606John Fastabend 1091c7797baf9f3900996ca800ab6298f95957bb4606John Fastabend if (netdev->dcbnl_ops->getdcbx) 1092c7797baf9f3900996ca800ab6298f95957bb4606John Fastabend dcbx = netdev->dcbnl_ops->getdcbx(netdev); 1093c7797baf9f3900996ca800ab6298f95957bb4606John Fastabend else 1094c7797baf9f3900996ca800ab6298f95957bb4606John Fastabend dcbx = -EOPNOTSUPP; 1095c7797baf9f3900996ca800ab6298f95957bb4606John Fastabend 10969ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend spin_unlock(&dcb_lock); 10979ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend nla_nest_end(skb, app); 10989ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend 1099eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid /* get peer info if available */ 1100eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid if (ops->ieee_peer_getets) { 1101eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid struct ieee_ets 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; 1110eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid err = ops->ieee_peer_getpfc(netdev, &pfc); 11111eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller if (!err && 11121eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller nla_put(skb, DCB_ATTR_IEEE_PEER_PFC, sizeof(pfc), &pfc)) 11133d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EMSGSIZE; 1114eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid } 1115eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid 1116eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid if (ops->peer_getappinfo && ops->peer_getapptable) { 1117dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid err = dcbnl_build_peer_app(netdev, skb, 1118dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid DCB_ATTR_IEEE_PEER_APP, 1119dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid DCB_ATTR_IEEE_APP_UNSPEC, 1120dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid DCB_ATTR_IEEE_APP); 1121eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid if (err) 11223d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EMSGSIZE; 1123eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid } 1124eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid 11253e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend nla_nest_end(skb, ieee); 1126c7797baf9f3900996ca800ab6298f95957bb4606John Fastabend if (dcbx >= 0) { 1127c7797baf9f3900996ca800ab6298f95957bb4606John Fastabend err = nla_put_u8(skb, DCB_ATTR_DCBX, dcbx); 1128c7797baf9f3900996ca800ab6298f95957bb4606John Fastabend if (err) 11293d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EMSGSIZE; 1130c7797baf9f3900996ca800ab6298f95957bb4606John Fastabend } 11313e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend 1132314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend return 0; 11333e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend} 11343e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend 11355b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravidstatic int dcbnl_cee_pg_fill(struct sk_buff *skb, struct net_device *dev, 11365b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid int dir) 11375b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid{ 11385b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid u8 pgid, up_map, prio, tc_pct; 11395b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid const struct dcbnl_rtnl_ops *ops = dev->dcbnl_ops; 11405b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid int i = dir ? DCB_ATTR_CEE_TX_PG : DCB_ATTR_CEE_RX_PG; 11415b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid struct nlattr *pg = nla_nest_start(skb, i); 11425b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 11435b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (!pg) 11443d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EMSGSIZE; 11455b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 11465b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid for (i = DCB_PG_ATTR_TC_0; i <= DCB_PG_ATTR_TC_7; i++) { 11475b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid struct nlattr *tc_nest = nla_nest_start(skb, i); 11485b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 11495b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (!tc_nest) 11503d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EMSGSIZE; 11515b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 11525b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid pgid = DCB_ATTR_VALUE_UNDEFINED; 11535b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid prio = DCB_ATTR_VALUE_UNDEFINED; 11545b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid tc_pct = DCB_ATTR_VALUE_UNDEFINED; 11555b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid up_map = DCB_ATTR_VALUE_UNDEFINED; 11565b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 11575b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (!dir) 11585b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid ops->getpgtccfgrx(dev, i - DCB_PG_ATTR_TC_0, 11595b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid &prio, &pgid, &tc_pct, &up_map); 11605b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid else 11615b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid ops->getpgtccfgtx(dev, i - DCB_PG_ATTR_TC_0, 11625b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid &prio, &pgid, &tc_pct, &up_map); 11635b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 11641eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller if (nla_put_u8(skb, DCB_TC_ATTR_PARAM_PGID, pgid) || 11651eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller nla_put_u8(skb, DCB_TC_ATTR_PARAM_UP_MAPPING, up_map) || 11661eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller nla_put_u8(skb, DCB_TC_ATTR_PARAM_STRICT_PRIO, prio) || 11671eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller nla_put_u8(skb, DCB_TC_ATTR_PARAM_BW_PCT, tc_pct)) 11683d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EMSGSIZE; 11695b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid nla_nest_end(skb, tc_nest); 11705b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid } 11715b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 11725b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid for (i = DCB_PG_ATTR_BW_ID_0; i <= DCB_PG_ATTR_BW_ID_7; i++) { 11735b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid tc_pct = DCB_ATTR_VALUE_UNDEFINED; 11745b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 11755b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (!dir) 11765b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid ops->getpgbwgcfgrx(dev, i - DCB_PG_ATTR_BW_ID_0, 11775b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid &tc_pct); 11785b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid else 11795b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid ops->getpgbwgcfgtx(dev, i - DCB_PG_ATTR_BW_ID_0, 11805b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid &tc_pct); 11811eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller if (nla_put_u8(skb, i, tc_pct)) 11823d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EMSGSIZE; 11835b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid } 11845b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid nla_nest_end(skb, pg); 11855b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid return 0; 11865b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid} 11875b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 11885b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravidstatic int dcbnl_cee_fill(struct sk_buff *skb, struct net_device *netdev) 11895b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid{ 11905b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid struct nlattr *cee, *app; 11915b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid struct dcb_app_type *itr; 11925b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops; 11935b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid int dcbx, i, err = -EMSGSIZE; 11945b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid u8 value; 11955b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 11961eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller if (nla_put_string(skb, DCB_ATTR_IFNAME, netdev->name)) 11971eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller goto nla_put_failure; 11985b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid cee = nla_nest_start(skb, DCB_ATTR_CEE); 11995b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (!cee) 12005b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid goto nla_put_failure; 12015b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 12025b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid /* local pg */ 12035b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (ops->getpgtccfgtx && ops->getpgbwgcfgtx) { 12045b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid err = dcbnl_cee_pg_fill(skb, netdev, 1); 12055b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (err) 12065b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid goto nla_put_failure; 12075b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid } 12085b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 12095b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (ops->getpgtccfgrx && ops->getpgbwgcfgrx) { 12105b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid err = dcbnl_cee_pg_fill(skb, netdev, 0); 12115b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (err) 12125b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid goto nla_put_failure; 12135b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid } 12145b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 12155b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid /* local pfc */ 12165b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (ops->getpfccfg) { 12175b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid struct nlattr *pfc_nest = nla_nest_start(skb, DCB_ATTR_CEE_PFC); 12185b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 12195b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (!pfc_nest) 12205b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid goto nla_put_failure; 12215b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 12225b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid for (i = DCB_PFC_UP_ATTR_0; i <= DCB_PFC_UP_ATTR_7; i++) { 12235b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid ops->getpfccfg(netdev, i - DCB_PFC_UP_ATTR_0, &value); 12241eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller if (nla_put_u8(skb, i, value)) 12251eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller goto nla_put_failure; 12265b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid } 12275b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid nla_nest_end(skb, pfc_nest); 12285b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid } 12295b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 12305b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid /* local app */ 12315b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid spin_lock(&dcb_lock); 12325b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid app = nla_nest_start(skb, DCB_ATTR_CEE_APP_TABLE); 12335b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (!app) 123440f5d72a4fc098c47068e3888cfb055922f6519fDan Carpenter goto dcb_unlock; 12355b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 12365b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid list_for_each_entry(itr, &dcb_app_list, list) { 1237e290ed81307ca7d92675f0d9c683add693c2f377Mark Rustad if (itr->ifindex == netdev->ifindex) { 12385b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid struct nlattr *app_nest = nla_nest_start(skb, 12395b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid DCB_ATTR_APP); 12405b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (!app_nest) 12415b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid goto dcb_unlock; 12425b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 12435b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid err = nla_put_u8(skb, DCB_APP_ATTR_IDTYPE, 12445b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid itr->app.selector); 12455b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (err) 12465b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid goto dcb_unlock; 12475b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 12485b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid err = nla_put_u16(skb, DCB_APP_ATTR_ID, 12495b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid itr->app.protocol); 12505b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (err) 12515b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid goto dcb_unlock; 12525b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 12535b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid err = nla_put_u8(skb, DCB_APP_ATTR_PRIORITY, 12545b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid itr->app.priority); 12555b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (err) 12565b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid goto dcb_unlock; 12575b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 12585b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid nla_nest_end(skb, app_nest); 12595b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid } 12605b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid } 12615b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid nla_nest_end(skb, app); 12625b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 12635b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (netdev->dcbnl_ops->getdcbx) 12645b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid dcbx = netdev->dcbnl_ops->getdcbx(netdev); 12655b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid else 12665b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid dcbx = -EOPNOTSUPP; 12675b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 12685b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid spin_unlock(&dcb_lock); 12695b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 12705b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid /* features flags */ 12715b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (ops->getfeatcfg) { 12725b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid struct nlattr *feat = nla_nest_start(skb, DCB_ATTR_CEE_FEAT); 12735b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (!feat) 12745b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid goto nla_put_failure; 12755b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 12765b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid for (i = DCB_FEATCFG_ATTR_ALL + 1; i <= DCB_FEATCFG_ATTR_MAX; 12775b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid i++) 12781eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller if (!ops->getfeatcfg(netdev, i, &value) && 12791eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller nla_put_u8(skb, i, value)) 12801eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller goto nla_put_failure; 12815b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 12825b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid nla_nest_end(skb, feat); 12835b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid } 12845b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 12855b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid /* peer info if available */ 12865b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (ops->cee_peer_getpg) { 12875b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid struct cee_pg pg; 12885b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid err = ops->cee_peer_getpg(netdev, &pg); 12891eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller if (!err && 12901eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller nla_put(skb, DCB_ATTR_CEE_PEER_PG, sizeof(pg), &pg)) 12911eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller goto nla_put_failure; 12925b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid } 12935b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 12945b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (ops->cee_peer_getpfc) { 12955b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid struct cee_pfc pfc; 12965b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid err = ops->cee_peer_getpfc(netdev, &pfc); 12971eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller if (!err && 12981eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller nla_put(skb, DCB_ATTR_CEE_PEER_PFC, sizeof(pfc), &pfc)) 12991eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller goto nla_put_failure; 13005b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid } 13015b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 13025b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (ops->peer_getappinfo && ops->peer_getapptable) { 13035b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid err = dcbnl_build_peer_app(netdev, skb, 13045b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid DCB_ATTR_CEE_PEER_APP_TABLE, 13055b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid DCB_ATTR_CEE_PEER_APP_INFO, 13065b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid DCB_ATTR_CEE_PEER_APP); 13075b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (err) 13085b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid goto nla_put_failure; 13095b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid } 13105b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid nla_nest_end(skb, cee); 13115b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 13125b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid /* DCBX state */ 13135b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (dcbx >= 0) { 13145b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid err = nla_put_u8(skb, DCB_ATTR_DCBX, dcbx); 13155b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (err) 13165b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid goto nla_put_failure; 13175b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid } 13185b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid return 0; 13195b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 13205b7f7626743e0912958981343b47ac0ab2206b1cShmulik Raviddcb_unlock: 13215b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid spin_unlock(&dcb_lock); 13225b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravidnla_put_failure: 13235b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid return err; 13245b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid} 13255b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 13265b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravidstatic int dcbnl_notify(struct net_device *dev, int event, int cmd, 13275b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid u32 seq, u32 pid, int dcbx_ver) 1328314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend{ 1329314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend struct net *net = dev_net(dev); 1330314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend struct sk_buff *skb; 1331314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend struct nlmsghdr *nlh; 1332314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend const struct dcbnl_rtnl_ops *ops = dev->dcbnl_ops; 1333314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend int err; 1334314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend 1335314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend if (!ops) 1336314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend return -EOPNOTSUPP; 1337314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend 1338ab6d470735682a6e1ba889a66f56eb1640242096Thomas Graf skb = dcbnl_newmsg(event, cmd, pid, seq, 0, &nlh); 1339314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend if (!skb) 1340314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend return -ENOBUFS; 1341314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend 13425b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (dcbx_ver == DCB_CAP_DCBX_VER_IEEE) 13435b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid err = dcbnl_ieee_fill(skb, dev); 13445b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid else 13455b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid err = dcbnl_cee_fill(skb, dev); 13465b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 1347314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend if (err < 0) { 1348314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend /* Report error to broadcast listeners */ 1349ab6d470735682a6e1ba889a66f56eb1640242096Thomas Graf nlmsg_free(skb); 1350314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend rtnl_set_sk_err(net, RTNLGRP_DCB, err); 1351314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend } else { 1352314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend /* End nlmsg and notify broadcast listeners */ 1353314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend nlmsg_end(skb, nlh); 1354314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend rtnl_notify(skb, net, 0, RTNLGRP_DCB, NULL, GFP_KERNEL); 1355314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend } 1356314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend 1357314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend return err; 1358314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend} 13595b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 13605b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravidint dcbnl_ieee_notify(struct net_device *dev, int event, int cmd, 13615b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid u32 seq, u32 pid) 13625b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid{ 13635b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid return dcbnl_notify(dev, event, cmd, seq, pid, DCB_CAP_DCBX_VER_IEEE); 13645b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid} 13655b7f7626743e0912958981343b47ac0ab2206b1cShmulik RavidEXPORT_SYMBOL(dcbnl_ieee_notify); 13665b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 13675b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravidint dcbnl_cee_notify(struct net_device *dev, int event, int cmd, 13685b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid u32 seq, u32 pid) 13695b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid{ 13705b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid return dcbnl_notify(dev, event, cmd, seq, pid, DCB_CAP_DCBX_VER_CEE); 13715b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid} 13725b7f7626743e0912958981343b47ac0ab2206b1cShmulik RavidEXPORT_SYMBOL(dcbnl_cee_notify); 1373314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend 1374314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend/* Handle IEEE 802.1Qaz SET commands. If any requested operation can not 1375314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend * be completed the entire msg is aborted and error value is returned. 1376314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend * No attempt is made to reconcile the case where only part of the 1377314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend * cmd can be completed. 1378314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend */ 13797be994138b188387691322921c08e19bddf6d3c5Thomas Grafstatic int dcbnl_ieee_set(struct net_device *netdev, struct nlmsghdr *nlh, 13807be994138b188387691322921c08e19bddf6d3c5Thomas Graf u32 seq, struct nlattr **tb, struct sk_buff *skb) 1381314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend{ 1382314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops; 1383314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend struct nlattr *ieee[DCB_ATTR_IEEE_MAX + 1]; 13843d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf int err; 1385314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend 1386314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend if (!ops) 13873d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -EOPNOTSUPP; 1388314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend 13894003b65871c101eb5ce8f37a325feac54aa5c681John Fastabend if (!tb[DCB_ATTR_IEEE]) 13904003b65871c101eb5ce8f37a325feac54aa5c681John Fastabend return -EINVAL; 13914003b65871c101eb5ce8f37a325feac54aa5c681John Fastabend 1392314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend err = nla_parse_nested(ieee, DCB_ATTR_IEEE_MAX, 1393314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend tb[DCB_ATTR_IEEE], dcbnl_ieee_policy); 1394314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend if (err) 1395314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend return err; 1396314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend 1397314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend if (ieee[DCB_ATTR_IEEE_ETS] && ops->ieee_setets) { 1398314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend struct ieee_ets *ets = nla_data(ieee[DCB_ATTR_IEEE_ETS]); 1399314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend err = ops->ieee_setets(netdev, ets); 1400314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend if (err) 1401314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend goto err; 1402314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend } 1403314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend 140408f10affe45051e18e0d8291c0a53aecef1b8a14Amir Vadai if (ieee[DCB_ATTR_IEEE_MAXRATE] && ops->ieee_setmaxrate) { 140508f10affe45051e18e0d8291c0a53aecef1b8a14Amir Vadai struct ieee_maxrate *maxrate = 140608f10affe45051e18e0d8291c0a53aecef1b8a14Amir Vadai nla_data(ieee[DCB_ATTR_IEEE_MAXRATE]); 140708f10affe45051e18e0d8291c0a53aecef1b8a14Amir Vadai err = ops->ieee_setmaxrate(netdev, maxrate); 140808f10affe45051e18e0d8291c0a53aecef1b8a14Amir Vadai if (err) 140908f10affe45051e18e0d8291c0a53aecef1b8a14Amir Vadai goto err; 141008f10affe45051e18e0d8291c0a53aecef1b8a14Amir Vadai } 141108f10affe45051e18e0d8291c0a53aecef1b8a14Amir Vadai 1412314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend if (ieee[DCB_ATTR_IEEE_PFC] && ops->ieee_setpfc) { 1413314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend struct ieee_pfc *pfc = nla_data(ieee[DCB_ATTR_IEEE_PFC]); 1414314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend err = ops->ieee_setpfc(netdev, pfc); 1415314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend if (err) 1416314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend goto err; 1417314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend } 1418314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend 1419314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend if (ieee[DCB_ATTR_IEEE_APP_TABLE]) { 1420314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend struct nlattr *attr; 1421314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend int rem; 1422314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend 1423314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend nla_for_each_nested(attr, ieee[DCB_ATTR_IEEE_APP_TABLE], rem) { 1424314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend struct dcb_app *app_data; 1425314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend if (nla_type(attr) != DCB_ATTR_IEEE_APP) 1426314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend continue; 1427314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend app_data = nla_data(attr); 1428314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend if (ops->ieee_setapp) 1429314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend err = ops->ieee_setapp(netdev, app_data); 1430314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend else 1431b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend err = dcb_ieee_setapp(netdev, app_data); 1432314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend if (err) 1433314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend goto err; 1434314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend } 1435314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend } 1436314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend 1437314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabenderr: 14387be994138b188387691322921c08e19bddf6d3c5Thomas Graf err = nla_put_u8(skb, DCB_ATTR_IEEE, err); 14395b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid dcbnl_ieee_notify(netdev, RTM_SETDCB, DCB_CMD_IEEE_SET, seq, 0); 1440314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend return err; 1441314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend} 1442314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend 14437be994138b188387691322921c08e19bddf6d3c5Thomas Grafstatic int dcbnl_ieee_get(struct net_device *netdev, struct nlmsghdr *nlh, 14447be994138b188387691322921c08e19bddf6d3c5Thomas Graf u32 seq, struct nlattr **tb, struct sk_buff *skb) 1445314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend{ 1446314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops; 1447314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend 1448314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend if (!ops) 1449314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend return -EOPNOTSUPP; 1450314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend 14517be994138b188387691322921c08e19bddf6d3c5Thomas Graf return dcbnl_ieee_fill(skb, netdev); 1452314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend} 1453f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend 14547be994138b188387691322921c08e19bddf6d3c5Thomas Grafstatic int dcbnl_ieee_del(struct net_device *netdev, struct nlmsghdr *nlh, 14557be994138b188387691322921c08e19bddf6d3c5Thomas Graf u32 seq, struct nlattr **tb, struct sk_buff *skb) 1456f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend{ 1457f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops; 1458f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend struct nlattr *ieee[DCB_ATTR_IEEE_MAX + 1]; 14593d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf int err; 1460f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend 1461f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend if (!ops) 1462f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend return -EOPNOTSUPP; 1463f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend 1464f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend if (!tb[DCB_ATTR_IEEE]) 1465f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend return -EINVAL; 1466f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend 1467f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend err = nla_parse_nested(ieee, DCB_ATTR_IEEE_MAX, 1468f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend tb[DCB_ATTR_IEEE], dcbnl_ieee_policy); 1469f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend if (err) 1470f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend return err; 1471f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend 1472f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend if (ieee[DCB_ATTR_IEEE_APP_TABLE]) { 1473f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend struct nlattr *attr; 1474f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend int rem; 1475f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend 1476f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend nla_for_each_nested(attr, ieee[DCB_ATTR_IEEE_APP_TABLE], rem) { 1477f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend struct dcb_app *app_data; 1478f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend 1479f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend if (nla_type(attr) != DCB_ATTR_IEEE_APP) 1480f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend continue; 1481f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend app_data = nla_data(attr); 1482f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend if (ops->ieee_delapp) 1483f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend err = ops->ieee_delapp(netdev, app_data); 1484f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend else 1485f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend err = dcb_ieee_delapp(netdev, app_data); 1486f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend if (err) 1487f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend goto err; 1488f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend } 1489f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend } 1490f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend 1491f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabenderr: 14927be994138b188387691322921c08e19bddf6d3c5Thomas Graf err = nla_put_u8(skb, DCB_ATTR_IEEE, err); 14935b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid dcbnl_ieee_notify(netdev, RTM_SETDCB, DCB_CMD_IEEE_DEL, seq, 0); 1494f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend return err; 1495f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend} 1496f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend 1497f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend 14986241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid/* DCBX configuration */ 14997be994138b188387691322921c08e19bddf6d3c5Thomas Grafstatic int dcbnl_getdcbx(struct net_device *netdev, struct nlmsghdr *nlh, 15007be994138b188387691322921c08e19bddf6d3c5Thomas Graf u32 seq, struct nlattr **tb, struct sk_buff *skb) 15016241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid{ 15026241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid if (!netdev->dcbnl_ops->getdcbx) 15037f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid return -EOPNOTSUPP; 15046241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid 15057be994138b188387691322921c08e19bddf6d3c5Thomas Graf return nla_put_u8(skb, DCB_ATTR_DCBX, 15067be994138b188387691322921c08e19bddf6d3c5Thomas Graf netdev->dcbnl_ops->getdcbx(netdev)); 15076241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid} 15086241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid 15097be994138b188387691322921c08e19bddf6d3c5Thomas Grafstatic int dcbnl_setdcbx(struct net_device *netdev, struct nlmsghdr *nlh, 15107be994138b188387691322921c08e19bddf6d3c5Thomas Graf u32 seq, struct nlattr **tb, struct sk_buff *skb) 15116241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid{ 15126241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid u8 value; 15136241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid 15147f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid if (!netdev->dcbnl_ops->setdcbx) 15157f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid return -EOPNOTSUPP; 15167f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid 15177f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid if (!tb[DCB_ATTR_DCBX]) 15187f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid return -EINVAL; 15196241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid 15206241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid value = nla_get_u8(tb[DCB_ATTR_DCBX]); 15216241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid 15227be994138b188387691322921c08e19bddf6d3c5Thomas Graf return nla_put_u8(skb, DCB_ATTR_DCBX, 15237be994138b188387691322921c08e19bddf6d3c5Thomas Graf netdev->dcbnl_ops->setdcbx(netdev, value)); 15246241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid} 15256241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid 15267be994138b188387691322921c08e19bddf6d3c5Thomas Grafstatic int dcbnl_getfeatcfg(struct net_device *netdev, struct nlmsghdr *nlh, 15277be994138b188387691322921c08e19bddf6d3c5Thomas Graf u32 seq, struct nlattr **tb, struct sk_buff *skb) 1528ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid{ 1529ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid struct nlattr *data[DCB_FEATCFG_ATTR_MAX + 1], *nest; 1530ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid u8 value; 15317f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid int ret, i; 1532ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid int getall = 0; 1533ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 15347f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid if (!netdev->dcbnl_ops->getfeatcfg) 15357f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid return -EOPNOTSUPP; 15367f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid 15377f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid if (!tb[DCB_ATTR_FEATCFG]) 15387f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid return -EINVAL; 1539ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 1540ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid ret = nla_parse_nested(data, DCB_FEATCFG_ATTR_MAX, tb[DCB_ATTR_FEATCFG], 1541ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid dcbnl_featcfg_nest); 15427f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid if (ret) 15437be994138b188387691322921c08e19bddf6d3c5Thomas Graf return ret; 1544ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 15457be994138b188387691322921c08e19bddf6d3c5Thomas Graf nest = nla_nest_start(skb, DCB_ATTR_FEATCFG); 15467be994138b188387691322921c08e19bddf6d3c5Thomas Graf if (!nest) 15477be994138b188387691322921c08e19bddf6d3c5Thomas Graf return -EMSGSIZE; 1548ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 1549ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid if (data[DCB_FEATCFG_ATTR_ALL]) 1550ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid getall = 1; 1551ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 1552ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid for (i = DCB_FEATCFG_ATTR_ALL+1; i <= DCB_FEATCFG_ATTR_MAX; i++) { 1553ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid if (!getall && !data[i]) 1554ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid continue; 1555ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 1556ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid ret = netdev->dcbnl_ops->getfeatcfg(netdev, i, &value); 15577f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid if (!ret) 15587be994138b188387691322921c08e19bddf6d3c5Thomas Graf ret = nla_put_u8(skb, i, value); 1559ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 15607f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid if (ret) { 15617be994138b188387691322921c08e19bddf6d3c5Thomas Graf nla_nest_cancel(skb, nest); 15627f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid goto nla_put_failure; 15637f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid } 1564ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid } 15657be994138b188387691322921c08e19bddf6d3c5Thomas Graf nla_nest_end(skb, nest); 1566ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 15677f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravidnla_put_failure: 1568ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid return ret; 1569ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid} 1570ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 15717be994138b188387691322921c08e19bddf6d3c5Thomas Grafstatic int dcbnl_setfeatcfg(struct net_device *netdev, struct nlmsghdr *nlh, 15727be994138b188387691322921c08e19bddf6d3c5Thomas Graf u32 seq, struct nlattr **tb, struct sk_buff *skb) 1573ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid{ 1574ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid struct nlattr *data[DCB_FEATCFG_ATTR_MAX + 1]; 15757f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid int ret, i; 1576ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid u8 value; 1577ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 15787f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid if (!netdev->dcbnl_ops->setfeatcfg) 15797f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid return -ENOTSUPP; 15807f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid 15817f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid if (!tb[DCB_ATTR_FEATCFG]) 15827f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid return -EINVAL; 1583ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 1584ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid ret = nla_parse_nested(data, DCB_FEATCFG_ATTR_MAX, tb[DCB_ATTR_FEATCFG], 1585ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid dcbnl_featcfg_nest); 1586ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 15877f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid if (ret) 1588ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid goto err; 1589ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 1590ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid for (i = DCB_FEATCFG_ATTR_ALL+1; i <= DCB_FEATCFG_ATTR_MAX; i++) { 1591ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid if (data[i] == NULL) 1592ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid continue; 1593ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 1594ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid value = nla_get_u8(data[i]); 1595ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 1596ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid ret = netdev->dcbnl_ops->setfeatcfg(netdev, i, value); 1597ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 1598ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid if (ret) 15997f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid goto err; 1600ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid } 1601ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Raviderr: 16027be994138b188387691322921c08e19bddf6d3c5Thomas Graf ret = nla_put_u8(skb, DCB_ATTR_FEATCFG, ret); 16037f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid 1604ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid return ret; 1605ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid} 1606ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 1607dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid/* Handle CEE DCBX GET commands. */ 16087be994138b188387691322921c08e19bddf6d3c5Thomas Grafstatic int dcbnl_cee_get(struct net_device *netdev, struct nlmsghdr *nlh, 16097be994138b188387691322921c08e19bddf6d3c5Thomas Graf u32 seq, struct nlattr **tb, struct sk_buff *skb) 1610dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid{ 1611dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops; 1612dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid 1613dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid if (!ops) 1614dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid return -EOPNOTSUPP; 1615dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid 16167be994138b188387691322921c08e19bddf6d3c5Thomas Graf return dcbnl_cee_fill(skb, netdev); 1617dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid} 1618dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid 161933a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Grafstruct reply_func { 162033a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf /* reply netlink message type */ 162133a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf int type; 162233a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf 162333a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf /* function to fill message contents */ 162433a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf int (*cb)(struct net_device *, struct nlmsghdr *, u32, 162533a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf struct nlattr **, struct sk_buff *); 162633a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf}; 162733a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf 162833a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Grafstatic const struct reply_func reply_funcs[DCB_CMD_MAX+1] = { 16297be994138b188387691322921c08e19bddf6d3c5Thomas Graf [DCB_CMD_GSTATE] = { RTM_GETDCB, dcbnl_getstate }, 16307be994138b188387691322921c08e19bddf6d3c5Thomas Graf [DCB_CMD_SSTATE] = { RTM_SETDCB, dcbnl_setstate }, 16317be994138b188387691322921c08e19bddf6d3c5Thomas Graf [DCB_CMD_PFC_GCFG] = { RTM_GETDCB, dcbnl_getpfccfg }, 16327be994138b188387691322921c08e19bddf6d3c5Thomas Graf [DCB_CMD_PFC_SCFG] = { RTM_SETDCB, dcbnl_setpfccfg }, 16337be994138b188387691322921c08e19bddf6d3c5Thomas Graf [DCB_CMD_GPERM_HWADDR] = { RTM_GETDCB, dcbnl_getperm_hwaddr }, 16347be994138b188387691322921c08e19bddf6d3c5Thomas Graf [DCB_CMD_GCAP] = { RTM_GETDCB, dcbnl_getcap }, 16357be994138b188387691322921c08e19bddf6d3c5Thomas Graf [DCB_CMD_GNUMTCS] = { RTM_GETDCB, dcbnl_getnumtcs }, 16367be994138b188387691322921c08e19bddf6d3c5Thomas Graf [DCB_CMD_SNUMTCS] = { RTM_SETDCB, dcbnl_setnumtcs }, 16377be994138b188387691322921c08e19bddf6d3c5Thomas Graf [DCB_CMD_PFC_GSTATE] = { RTM_GETDCB, dcbnl_getpfcstate }, 16387be994138b188387691322921c08e19bddf6d3c5Thomas Graf [DCB_CMD_PFC_SSTATE] = { RTM_SETDCB, dcbnl_setpfcstate }, 16397be994138b188387691322921c08e19bddf6d3c5Thomas Graf [DCB_CMD_GAPP] = { RTM_GETDCB, dcbnl_getapp }, 16407be994138b188387691322921c08e19bddf6d3c5Thomas Graf [DCB_CMD_SAPP] = { RTM_SETDCB, dcbnl_setapp }, 16417be994138b188387691322921c08e19bddf6d3c5Thomas Graf [DCB_CMD_PGTX_GCFG] = { RTM_GETDCB, dcbnl_pgtx_getcfg }, 16427be994138b188387691322921c08e19bddf6d3c5Thomas Graf [DCB_CMD_PGTX_SCFG] = { RTM_SETDCB, dcbnl_pgtx_setcfg }, 16437be994138b188387691322921c08e19bddf6d3c5Thomas Graf [DCB_CMD_PGRX_GCFG] = { RTM_GETDCB, dcbnl_pgrx_getcfg }, 16447be994138b188387691322921c08e19bddf6d3c5Thomas Graf [DCB_CMD_PGRX_SCFG] = { RTM_SETDCB, dcbnl_pgrx_setcfg }, 16457be994138b188387691322921c08e19bddf6d3c5Thomas Graf [DCB_CMD_SET_ALL] = { RTM_SETDCB, dcbnl_setall }, 16467be994138b188387691322921c08e19bddf6d3c5Thomas Graf [DCB_CMD_BCN_GCFG] = { RTM_GETDCB, dcbnl_bcn_getcfg }, 16477be994138b188387691322921c08e19bddf6d3c5Thomas Graf [DCB_CMD_BCN_SCFG] = { RTM_SETDCB, dcbnl_bcn_setcfg }, 16487be994138b188387691322921c08e19bddf6d3c5Thomas Graf [DCB_CMD_IEEE_GET] = { RTM_GETDCB, dcbnl_ieee_get }, 16497be994138b188387691322921c08e19bddf6d3c5Thomas Graf [DCB_CMD_IEEE_SET] = { RTM_SETDCB, dcbnl_ieee_set }, 16507be994138b188387691322921c08e19bddf6d3c5Thomas Graf [DCB_CMD_IEEE_DEL] = { RTM_SETDCB, dcbnl_ieee_del }, 16517be994138b188387691322921c08e19bddf6d3c5Thomas Graf [DCB_CMD_GDCBX] = { RTM_GETDCB, dcbnl_getdcbx }, 16527be994138b188387691322921c08e19bddf6d3c5Thomas Graf [DCB_CMD_SDCBX] = { RTM_SETDCB, dcbnl_setdcbx }, 16537be994138b188387691322921c08e19bddf6d3c5Thomas Graf [DCB_CMD_GFEATCFG] = { RTM_GETDCB, dcbnl_getfeatcfg }, 16547be994138b188387691322921c08e19bddf6d3c5Thomas Graf [DCB_CMD_SFEATCFG] = { RTM_SETDCB, dcbnl_setfeatcfg }, 16557be994138b188387691322921c08e19bddf6d3c5Thomas Graf [DCB_CMD_CEE_GET] = { RTM_GETDCB, dcbnl_cee_get }, 165633a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf}; 165733a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf 16582f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckstatic int dcb_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) 16592f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 16602f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct net *net = sock_net(skb->sk); 16612f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct net_device *netdev; 16627a282bc37f8a1e7b46907d78724177d20214b137Thomas Graf struct dcbmsg *dcb = nlmsg_data(nlh); 16632f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct nlattr *tb[DCB_ATTR_MAX + 1]; 16642f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u32 pid = skb ? NETLINK_CB(skb).pid : 0; 16652f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck int ret = -EINVAL; 166633a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf struct sk_buff *reply_skb; 166739912f9cf9603f0de085fb5ba916a7a88010ccd9Thomas Graf struct nlmsghdr *reply_nlh = NULL; 166833a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf const struct reply_func *fn; 16692f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 167009ad9bc752519cc167d0a573e1acf69b5c707c67Octavian Purdila if (!net_eq(net, &init_net)) 16712f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return -EINVAL; 16722f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 16732f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = nlmsg_parse(nlh, sizeof(*dcb), tb, DCB_ATTR_MAX, 16742f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcbnl_rtnl_policy); 16752f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret < 0) 16762f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return ret; 16772f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 167833a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf if (dcb->cmd > DCB_CMD_MAX) 167933a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf return -EINVAL; 168033a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf 168133a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf /* check if a reply function has been defined for the command */ 168233a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf fn = &reply_funcs[dcb->cmd]; 168333a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf if (!fn->cb) 168433a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf return -EOPNOTSUPP; 168533a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf 16862f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!tb[DCB_ATTR_IFNAME]) 16872f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return -EINVAL; 16882f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 16892f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck netdev = dev_get_by_name(&init_net, nla_data(tb[DCB_ATTR_IFNAME])); 16902f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!netdev) 16913d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf return -ENODEV; 16922f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 16933d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf if (!netdev->dcbnl_ops) { 16943d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf ret = -EOPNOTSUPP; 16953d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf goto out; 16963d1f486952b750f1cca53cf22d4f769db5aba4f0Thomas Graf } 16972f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 169833a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf reply_skb = dcbnl_newmsg(fn->type, dcb->cmd, pid, nlh->nlmsg_seq, 169933a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf nlh->nlmsg_flags, &reply_nlh); 170033a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf if (!reply_skb) { 170133a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf ret = -ENOBUFS; 170233a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf goto out; 170333a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf } 170433a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf 170533a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf ret = fn->cb(netdev, nlh, nlh->nlmsg_seq, tb, reply_skb); 170633a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf if (ret < 0) { 170733a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf nlmsg_free(reply_skb); 170833a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf goto out; 170933a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf } 171033a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf 171133a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf nlmsg_end(reply_skb, reply_nlh); 171233a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf 171333a03aadb52fa05d28aba6d8f0c03c7b3b905897Thomas Graf ret = rtnl_unicast(reply_skb, &init_net, pid); 17142f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckout: 17152f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dev_put(netdev); 17162f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return ret; 17172f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 17182f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 1719716b31abbd39baab307c0a7b38dce9a20c16c62dThomas Grafstatic struct dcb_app_type *dcb_app_lookup(const struct dcb_app *app, 1720716b31abbd39baab307c0a7b38dce9a20c16c62dThomas Graf int ifindex, int prio) 1721716b31abbd39baab307c0a7b38dce9a20c16c62dThomas Graf{ 1722716b31abbd39baab307c0a7b38dce9a20c16c62dThomas Graf struct dcb_app_type *itr; 1723716b31abbd39baab307c0a7b38dce9a20c16c62dThomas Graf 1724716b31abbd39baab307c0a7b38dce9a20c16c62dThomas Graf list_for_each_entry(itr, &dcb_app_list, list) { 1725716b31abbd39baab307c0a7b38dce9a20c16c62dThomas Graf if (itr->app.selector == app->selector && 1726716b31abbd39baab307c0a7b38dce9a20c16c62dThomas Graf itr->app.protocol == app->protocol && 1727716b31abbd39baab307c0a7b38dce9a20c16c62dThomas Graf itr->ifindex == ifindex && 1728716b31abbd39baab307c0a7b38dce9a20c16c62dThomas Graf (!prio || itr->app.priority == prio)) 1729716b31abbd39baab307c0a7b38dce9a20c16c62dThomas Graf return itr; 1730716b31abbd39baab307c0a7b38dce9a20c16c62dThomas Graf } 1731716b31abbd39baab307c0a7b38dce9a20c16c62dThomas Graf 1732716b31abbd39baab307c0a7b38dce9a20c16c62dThomas Graf return NULL; 1733716b31abbd39baab307c0a7b38dce9a20c16c62dThomas Graf} 1734716b31abbd39baab307c0a7b38dce9a20c16c62dThomas Graf 17354e4f2f69704be0ae218d91fb827e5a6987fe262fThomas Grafstatic int dcb_app_add(const struct dcb_app *app, int ifindex) 17364e4f2f69704be0ae218d91fb827e5a6987fe262fThomas Graf{ 17374e4f2f69704be0ae218d91fb827e5a6987fe262fThomas Graf struct dcb_app_type *entry; 17384e4f2f69704be0ae218d91fb827e5a6987fe262fThomas Graf 17394e4f2f69704be0ae218d91fb827e5a6987fe262fThomas Graf entry = kmalloc(sizeof(*entry), GFP_ATOMIC); 17404e4f2f69704be0ae218d91fb827e5a6987fe262fThomas Graf if (!entry) 17414e4f2f69704be0ae218d91fb827e5a6987fe262fThomas Graf return -ENOMEM; 17424e4f2f69704be0ae218d91fb827e5a6987fe262fThomas Graf 17434e4f2f69704be0ae218d91fb827e5a6987fe262fThomas Graf memcpy(&entry->app, app, sizeof(*app)); 17444e4f2f69704be0ae218d91fb827e5a6987fe262fThomas Graf entry->ifindex = ifindex; 17454e4f2f69704be0ae218d91fb827e5a6987fe262fThomas Graf list_add(&entry->list, &dcb_app_list); 17464e4f2f69704be0ae218d91fb827e5a6987fe262fThomas Graf 17474e4f2f69704be0ae218d91fb827e5a6987fe262fThomas Graf return 0; 17484e4f2f69704be0ae218d91fb827e5a6987fe262fThomas Graf} 17494e4f2f69704be0ae218d91fb827e5a6987fe262fThomas Graf 17509ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend/** 17519ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend * dcb_getapp - retrieve the DCBX application user priority 17529ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend * 17539ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend * On success returns a non-zero 802.1p user priority bitmap 17549ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend * otherwise returns 0 as the invalid user priority bitmap to 17559ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend * indicate an error. 17569ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend */ 17579ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabendu8 dcb_getapp(struct net_device *dev, struct dcb_app *app) 17589ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend{ 17599ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend struct dcb_app_type *itr; 17609ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend u8 prio = 0; 17619ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend 17629ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend spin_lock(&dcb_lock); 1763716b31abbd39baab307c0a7b38dce9a20c16c62dThomas Graf if ((itr = dcb_app_lookup(app, dev->ifindex, 0))) 1764716b31abbd39baab307c0a7b38dce9a20c16c62dThomas Graf prio = itr->app.priority; 17659ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend spin_unlock(&dcb_lock); 17669ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend 17679ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend return prio; 17689ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend} 17699ab933ab2cc80f04690d6aa385b1110075c5e507John FastabendEXPORT_SYMBOL(dcb_getapp); 17709ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend 17719ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend/** 1772b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend * dcb_setapp - add CEE dcb application data to app list 17739ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend * 1774b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend * Priority 0 is an invalid priority in CEE spec. This routine 1775b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend * removes applications from the app list if the priority is 1776b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend * set to zero. 17779ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend */ 1778ab6baf980b095c70a56c5eb2f58166aef8a0edc8John Fastabendint dcb_setapp(struct net_device *dev, struct dcb_app *new) 17799ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend{ 17809ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend struct dcb_app_type *itr; 17817ec79270d7de0c8ca602c47cb25a9652ec28f37fJohn Fastabend struct dcb_app_type event; 17824e4f2f69704be0ae218d91fb827e5a6987fe262fThomas Graf int err = 0; 17837ec79270d7de0c8ca602c47cb25a9652ec28f37fJohn Fastabend 1784e290ed81307ca7d92675f0d9c683add693c2f377Mark Rustad event.ifindex = dev->ifindex; 17857ec79270d7de0c8ca602c47cb25a9652ec28f37fJohn Fastabend memcpy(&event.app, new, sizeof(event.app)); 17866bd0e1cb10b6d14dda4a8806d0a2f4f0bbf01931John Fastabend if (dev->dcbnl_ops->getdcbx) 17876bd0e1cb10b6d14dda4a8806d0a2f4f0bbf01931John Fastabend event.dcbx = dev->dcbnl_ops->getdcbx(dev); 17889ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend 17899ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend spin_lock(&dcb_lock); 17909ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend /* Search for existing match and replace */ 1791716b31abbd39baab307c0a7b38dce9a20c16c62dThomas Graf if ((itr = dcb_app_lookup(new, dev->ifindex, 0))) { 1792716b31abbd39baab307c0a7b38dce9a20c16c62dThomas Graf if (new->priority) 1793716b31abbd39baab307c0a7b38dce9a20c16c62dThomas Graf itr->app.priority = new->priority; 1794716b31abbd39baab307c0a7b38dce9a20c16c62dThomas Graf else { 1795716b31abbd39baab307c0a7b38dce9a20c16c62dThomas Graf list_del(&itr->list); 1796716b31abbd39baab307c0a7b38dce9a20c16c62dThomas Graf kfree(itr); 17979ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend } 1798716b31abbd39baab307c0a7b38dce9a20c16c62dThomas Graf goto out; 17999ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend } 18009ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend /* App type does not exist add new application type */ 18014e4f2f69704be0ae218d91fb827e5a6987fe262fThomas Graf if (new->priority) 18024e4f2f69704be0ae218d91fb827e5a6987fe262fThomas Graf err = dcb_app_add(new, dev->ifindex); 18039ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabendout: 18049ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend spin_unlock(&dcb_lock); 18054e4f2f69704be0ae218d91fb827e5a6987fe262fThomas Graf if (!err) 18064e4f2f69704be0ae218d91fb827e5a6987fe262fThomas Graf call_dcbevent_notifiers(DCB_APP_EVENT, &event); 18074e4f2f69704be0ae218d91fb827e5a6987fe262fThomas Graf return err; 18089ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend} 18099ab933ab2cc80f04690d6aa385b1110075c5e507John FastabendEXPORT_SYMBOL(dcb_setapp); 18109ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend 1811b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend/** 1812a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabend * dcb_ieee_getapp_mask - retrieve the IEEE DCB application priority 1813a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabend * 1814a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabend * Helper routine which on success returns a non-zero 802.1Qaz user 1815a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabend * priority bitmap otherwise returns 0 to indicate the dcb_app was 1816a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabend * not found in APP list. 1817a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabend */ 1818a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabendu8 dcb_ieee_getapp_mask(struct net_device *dev, struct dcb_app *app) 1819a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabend{ 1820a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabend struct dcb_app_type *itr; 1821a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabend u8 prio = 0; 1822a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabend 1823a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabend spin_lock(&dcb_lock); 1824716b31abbd39baab307c0a7b38dce9a20c16c62dThomas Graf if ((itr = dcb_app_lookup(app, dev->ifindex, 0))) 1825716b31abbd39baab307c0a7b38dce9a20c16c62dThomas Graf prio |= 1 << itr->app.priority; 1826a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabend spin_unlock(&dcb_lock); 1827a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabend 1828a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabend return prio; 1829a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabend} 1830a364c8cf80251849bab207be8c9e66253c8ca8f8John FastabendEXPORT_SYMBOL(dcb_ieee_getapp_mask); 1831a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabend 1832a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabend/** 1833b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend * dcb_ieee_setapp - add IEEE dcb application data to app list 1834b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend * 1835b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend * This adds Application data to the list. Multiple application 1836b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend * entries may exists for the same selector and protocol as long 1837b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend * as the priorities are different. 1838b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend */ 1839b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabendint dcb_ieee_setapp(struct net_device *dev, struct dcb_app *new) 1840b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend{ 1841b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend struct dcb_app_type event; 1842b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend int err = 0; 1843b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend 1844e290ed81307ca7d92675f0d9c683add693c2f377Mark Rustad event.ifindex = dev->ifindex; 1845b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend memcpy(&event.app, new, sizeof(event.app)); 18466bd0e1cb10b6d14dda4a8806d0a2f4f0bbf01931John Fastabend if (dev->dcbnl_ops->getdcbx) 18476bd0e1cb10b6d14dda4a8806d0a2f4f0bbf01931John Fastabend event.dcbx = dev->dcbnl_ops->getdcbx(dev); 1848b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend 1849b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend spin_lock(&dcb_lock); 1850b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend /* Search for existing match and abort if found */ 1851716b31abbd39baab307c0a7b38dce9a20c16c62dThomas Graf if (dcb_app_lookup(new, dev->ifindex, new->priority)) { 1852716b31abbd39baab307c0a7b38dce9a20c16c62dThomas Graf err = -EEXIST; 1853716b31abbd39baab307c0a7b38dce9a20c16c62dThomas Graf goto out; 1854b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend } 1855b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend 18564e4f2f69704be0ae218d91fb827e5a6987fe262fThomas Graf err = dcb_app_add(new, dev->ifindex); 1857b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabendout: 1858b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend spin_unlock(&dcb_lock); 1859b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend if (!err) 1860b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend call_dcbevent_notifiers(DCB_APP_EVENT, &event); 1861b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend return err; 1862b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend} 1863b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John FastabendEXPORT_SYMBOL(dcb_ieee_setapp); 1864b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend 1865f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend/** 1866f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend * dcb_ieee_delapp - delete IEEE dcb application data from list 1867f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend * 1868f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend * This removes a matching APP data from the APP list 1869f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend */ 1870f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabendint dcb_ieee_delapp(struct net_device *dev, struct dcb_app *del) 1871f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend{ 1872f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend struct dcb_app_type *itr; 1873f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend struct dcb_app_type event; 1874f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend int err = -ENOENT; 1875f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend 1876e290ed81307ca7d92675f0d9c683add693c2f377Mark Rustad event.ifindex = dev->ifindex; 1877f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend memcpy(&event.app, del, sizeof(event.app)); 18786bd0e1cb10b6d14dda4a8806d0a2f4f0bbf01931John Fastabend if (dev->dcbnl_ops->getdcbx) 18796bd0e1cb10b6d14dda4a8806d0a2f4f0bbf01931John Fastabend event.dcbx = dev->dcbnl_ops->getdcbx(dev); 1880f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend 1881f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend spin_lock(&dcb_lock); 1882f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend /* Search for existing match and remove it. */ 1883716b31abbd39baab307c0a7b38dce9a20c16c62dThomas Graf if ((itr = dcb_app_lookup(del, dev->ifindex, del->priority))) { 1884716b31abbd39baab307c0a7b38dce9a20c16c62dThomas Graf list_del(&itr->list); 1885716b31abbd39baab307c0a7b38dce9a20c16c62dThomas Graf kfree(itr); 1886716b31abbd39baab307c0a7b38dce9a20c16c62dThomas Graf err = 0; 1887f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend } 1888f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend 1889f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend spin_unlock(&dcb_lock); 1890f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend if (!err) 1891f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend call_dcbevent_notifiers(DCB_APP_EVENT, &event); 1892f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend return err; 1893f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend} 1894f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John FastabendEXPORT_SYMBOL(dcb_ieee_delapp); 1895f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend 18967c14c3f10e6dcd7f70e49f77b6e1ae605c4861e6Shmulik Ravidstatic void dcb_flushapp(void) 18979ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend{ 18989ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend struct dcb_app_type *app; 18992a8fe003741aa90b6b9453e90af4bbb7bc42918cDan Carpenter struct dcb_app_type *tmp; 19009ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend 19019ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend spin_lock(&dcb_lock); 19022a8fe003741aa90b6b9453e90af4bbb7bc42918cDan Carpenter list_for_each_entry_safe(app, tmp, &dcb_app_list, list) { 19039ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend list_del(&app->list); 19049ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend kfree(app); 19059ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend } 19069ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend spin_unlock(&dcb_lock); 19079ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend} 19089ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend 19092f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckstatic int __init dcbnl_init(void) 19102f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 19119ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend INIT_LIST_HEAD(&dcb_app_list); 19129ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend 1913c7ac8679bec9397afe8918f788cbcef88c38da54Greg Rose rtnl_register(PF_UNSPEC, RTM_GETDCB, dcb_doit, NULL, NULL); 1914c7ac8679bec9397afe8918f788cbcef88c38da54Greg Rose rtnl_register(PF_UNSPEC, RTM_SETDCB, dcb_doit, NULL, NULL); 19152f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 19162f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return 0; 19172f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 19182f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckmodule_init(dcbnl_init); 19192f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 19202f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckstatic void __exit dcbnl_exit(void) 19212f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 19222f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck rtnl_unregister(PF_UNSPEC, RTM_GETDCB); 19232f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck rtnl_unregister(PF_UNSPEC, RTM_SETDCB); 19249ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend dcb_flushapp(); 19252f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 19262f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckmodule_exit(dcbnl_exit); 1927