dcbnl.c revision 081579840b4b2421e37bc67e3b089b7ca64ef040
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 1992f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck/* standard netlink reply call */ 2002f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckstatic int dcbnl_reply(u8 value, u8 event, u8 cmd, u8 attr, u32 pid, 2012f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u32 seq, u16 flags) 2022f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 2032f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct sk_buff *dcbnl_skb; 2042f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct dcbmsg *dcb; 2052f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct nlmsghdr *nlh; 2062f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck int ret = -EINVAL; 2072f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2082f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcbnl_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 2092f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!dcbnl_skb) 2102f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return ret; 2112f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2122f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nlh = NLMSG_NEW(dcbnl_skb, pid, seq, event, sizeof(*dcb), flags); 2132f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2142f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcb = NLMSG_DATA(nlh); 2152f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcb->dcb_family = AF_UNSPEC; 2162f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcb->cmd = cmd; 2172f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcb->dcb_pad = 0; 2182f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2192f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = nla_put_u8(dcbnl_skb, attr, value); 2202f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 2212f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err; 2222f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2232f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck /* end the message, assign the nlmsg_len. */ 2242f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nlmsg_end(dcbnl_skb, nlh); 2252f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = rtnl_unicast(dcbnl_skb, &init_net, pid); 2262f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 2277eaf5077b37bb33dbd44e569ff88566d6fe286e9John Fastabend return -EINVAL; 2282f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2292f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return 0; 2302f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duycknlmsg_failure: 2312f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckerr: 232858eb711ba64f8a001d7003295b8078bcab33b6dRoel Kluin kfree_skb(dcbnl_skb); 2332f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return ret; 2342f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 2352f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2362f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckstatic int dcbnl_getstate(struct net_device *netdev, struct nlattr **tb, 2372f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u32 pid, u32 seq, u16 flags) 2382f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 2392f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck int ret = -EINVAL; 2402f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2412f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck /* if (!tb[DCB_ATTR_STATE] || !netdev->dcbnl_ops->getstate) */ 2422f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!netdev->dcbnl_ops->getstate) 2432f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return ret; 2442f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2452f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = dcbnl_reply(netdev->dcbnl_ops->getstate(netdev), RTM_GETDCB, 2462f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck DCB_CMD_GSTATE, DCB_ATTR_STATE, pid, seq, flags); 2472f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2482f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return ret; 2492f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 2502f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2512f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckstatic int dcbnl_getpfccfg(struct net_device *netdev, struct nlattr **tb, 2522f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u32 pid, u32 seq, u16 flags) 2532f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 2542f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct sk_buff *dcbnl_skb; 2552f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct nlmsghdr *nlh; 2562f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct dcbmsg *dcb; 2572f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct nlattr *data[DCB_PFC_UP_ATTR_MAX + 1], *nest; 2582f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u8 value; 2592f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck int ret = -EINVAL; 2602f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck int i; 2612f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck int getall = 0; 2622f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2632f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!tb[DCB_ATTR_PFC_CFG] || !netdev->dcbnl_ops->getpfccfg) 2642f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return ret; 2652f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2662f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = nla_parse_nested(data, DCB_PFC_UP_ATTR_MAX, 2672f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck tb[DCB_ATTR_PFC_CFG], 2682f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcbnl_pfc_up_nest); 2692f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 2702f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err_out; 2712f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2722f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcbnl_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 2732f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!dcbnl_skb) 2742f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err_out; 2752f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2762f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nlh = NLMSG_NEW(dcbnl_skb, pid, seq, RTM_GETDCB, sizeof(*dcb), flags); 2772f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2782f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcb = NLMSG_DATA(nlh); 2792f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcb->dcb_family = AF_UNSPEC; 2802f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcb->cmd = DCB_CMD_PFC_GCFG; 2812f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2822f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nest = nla_nest_start(dcbnl_skb, DCB_ATTR_PFC_CFG); 2832f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!nest) 2842f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err; 2852f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2862f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (data[DCB_PFC_UP_ATTR_ALL]) 2872f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck getall = 1; 2882f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2892f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck for (i = DCB_PFC_UP_ATTR_0; i <= DCB_PFC_UP_ATTR_7; i++) { 2902f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!getall && !data[i]) 2912f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck continue; 2922f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2932f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck netdev->dcbnl_ops->getpfccfg(netdev, i - DCB_PFC_UP_ATTR_0, 2942f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck &value); 2952f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = nla_put_u8(dcbnl_skb, i, value); 2962f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 2972f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) { 2982f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nla_nest_cancel(dcbnl_skb, nest); 2992f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err; 3002f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 3012f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 3022f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nla_nest_end(dcbnl_skb, nest); 3032f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 3042f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nlmsg_end(dcbnl_skb, nlh); 3052f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 3062f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = rtnl_unicast(dcbnl_skb, &init_net, pid); 3072f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 3087eaf5077b37bb33dbd44e569ff88566d6fe286e9John Fastabend goto err_out; 3092f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 3102f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return 0; 3112f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duycknlmsg_failure: 3122f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckerr: 313858eb711ba64f8a001d7003295b8078bcab33b6dRoel Kluin kfree_skb(dcbnl_skb); 3142f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckerr_out: 3152f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return -EINVAL; 3162f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 3172f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 3182f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckstatic int dcbnl_getperm_hwaddr(struct net_device *netdev, struct nlattr **tb, 3192f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u32 pid, u32 seq, u16 flags) 3202f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 3212f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct sk_buff *dcbnl_skb; 3222f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct nlmsghdr *nlh; 3232f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct dcbmsg *dcb; 3242f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u8 perm_addr[MAX_ADDR_LEN]; 3252f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck int ret = -EINVAL; 3262f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 3272f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!netdev->dcbnl_ops->getpermhwaddr) 3282f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return ret; 3292f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 3302f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcbnl_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 3312f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!dcbnl_skb) 3322f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err_out; 3332f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 3342f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nlh = NLMSG_NEW(dcbnl_skb, pid, seq, RTM_GETDCB, sizeof(*dcb), flags); 3352f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 3362f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcb = NLMSG_DATA(nlh); 3372f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcb->dcb_family = AF_UNSPEC; 3382f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcb->cmd = DCB_CMD_GPERM_HWADDR; 3392f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 3402f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck netdev->dcbnl_ops->getpermhwaddr(netdev, perm_addr); 3412f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 3422f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = nla_put(dcbnl_skb, DCB_ATTR_PERM_HWADDR, sizeof(perm_addr), 3432f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck perm_addr); 3442f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 3452f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nlmsg_end(dcbnl_skb, nlh); 3462f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 3472f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = rtnl_unicast(dcbnl_skb, &init_net, pid); 3482f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 3497eaf5077b37bb33dbd44e569ff88566d6fe286e9John Fastabend goto err_out; 3502f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 3512f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return 0; 3522f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 3532f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duycknlmsg_failure: 354858eb711ba64f8a001d7003295b8078bcab33b6dRoel Kluin kfree_skb(dcbnl_skb); 3552f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckerr_out: 3562f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return -EINVAL; 3572f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 3582f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 35946132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyckstatic int dcbnl_getcap(struct net_device *netdev, struct nlattr **tb, 36046132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck u32 pid, u32 seq, u16 flags) 36146132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck{ 36246132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck struct sk_buff *dcbnl_skb; 36346132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck struct nlmsghdr *nlh; 36446132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck struct dcbmsg *dcb; 36546132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck struct nlattr *data[DCB_CAP_ATTR_MAX + 1], *nest; 36646132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck u8 value; 36746132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck int ret = -EINVAL; 36846132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck int i; 36946132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck int getall = 0; 37046132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck 37146132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck if (!tb[DCB_ATTR_CAP] || !netdev->dcbnl_ops->getcap) 37246132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck return ret; 37346132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck 37446132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck ret = nla_parse_nested(data, DCB_CAP_ATTR_MAX, tb[DCB_ATTR_CAP], 37546132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck dcbnl_cap_nest); 37646132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck if (ret) 37746132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck goto err_out; 37846132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck 37946132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck dcbnl_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 38046132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck if (!dcbnl_skb) 38146132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck goto err_out; 38246132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck 38346132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck nlh = NLMSG_NEW(dcbnl_skb, pid, seq, RTM_GETDCB, sizeof(*dcb), flags); 38446132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck 38546132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck dcb = NLMSG_DATA(nlh); 38646132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck dcb->dcb_family = AF_UNSPEC; 38746132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck dcb->cmd = DCB_CMD_GCAP; 38846132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck 38946132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck nest = nla_nest_start(dcbnl_skb, DCB_ATTR_CAP); 39046132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck if (!nest) 39146132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck goto err; 39246132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck 39346132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck if (data[DCB_CAP_ATTR_ALL]) 39446132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck getall = 1; 39546132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck 39646132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck for (i = DCB_CAP_ATTR_ALL+1; i <= DCB_CAP_ATTR_MAX; i++) { 39746132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck if (!getall && !data[i]) 39846132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck continue; 39946132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck 40046132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck if (!netdev->dcbnl_ops->getcap(netdev, i, &value)) { 40146132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck ret = nla_put_u8(dcbnl_skb, i, value); 40246132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck 40346132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck if (ret) { 40446132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck nla_nest_cancel(dcbnl_skb, nest); 40546132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck goto err; 40646132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck } 40746132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck } 40846132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck } 40946132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck nla_nest_end(dcbnl_skb, nest); 41046132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck 41146132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck nlmsg_end(dcbnl_skb, nlh); 41246132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck 41346132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck ret = rtnl_unicast(dcbnl_skb, &init_net, pid); 41446132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck if (ret) 4157eaf5077b37bb33dbd44e569ff88566d6fe286e9John Fastabend goto err_out; 41646132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck 41746132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck return 0; 41846132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duycknlmsg_failure: 41946132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyckerr: 420858eb711ba64f8a001d7003295b8078bcab33b6dRoel Kluin kfree_skb(dcbnl_skb); 42146132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyckerr_out: 42246132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck return -EINVAL; 42346132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck} 42446132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck 42533dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyckstatic int dcbnl_getnumtcs(struct net_device *netdev, struct nlattr **tb, 42633dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck u32 pid, u32 seq, u16 flags) 42733dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck{ 42833dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck struct sk_buff *dcbnl_skb; 42933dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck struct nlmsghdr *nlh; 43033dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck struct dcbmsg *dcb; 43133dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck struct nlattr *data[DCB_NUMTCS_ATTR_MAX + 1], *nest; 43233dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck u8 value; 43333dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck int ret = -EINVAL; 43433dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck int i; 43533dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck int getall = 0; 43633dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 43733dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck if (!tb[DCB_ATTR_NUMTCS] || !netdev->dcbnl_ops->getnumtcs) 43833dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck return ret; 43933dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 44033dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck ret = nla_parse_nested(data, DCB_NUMTCS_ATTR_MAX, tb[DCB_ATTR_NUMTCS], 44133dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck dcbnl_numtcs_nest); 44233dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck if (ret) { 44333dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck ret = -EINVAL; 44433dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck goto err_out; 44533dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck } 44633dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 44733dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck dcbnl_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 44833dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck if (!dcbnl_skb) { 44933dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck ret = -EINVAL; 45033dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck goto err_out; 45133dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck } 45233dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 45333dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck nlh = NLMSG_NEW(dcbnl_skb, pid, seq, RTM_GETDCB, sizeof(*dcb), flags); 45433dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 45533dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck dcb = NLMSG_DATA(nlh); 45633dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck dcb->dcb_family = AF_UNSPEC; 45733dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck dcb->cmd = DCB_CMD_GNUMTCS; 45833dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 45933dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck nest = nla_nest_start(dcbnl_skb, DCB_ATTR_NUMTCS); 46033dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck if (!nest) { 46133dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck ret = -EINVAL; 46233dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck goto err; 46333dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck } 46433dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 46533dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck if (data[DCB_NUMTCS_ATTR_ALL]) 46633dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck getall = 1; 46733dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 46833dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck for (i = DCB_NUMTCS_ATTR_ALL+1; i <= DCB_NUMTCS_ATTR_MAX; i++) { 46933dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck if (!getall && !data[i]) 47033dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck continue; 47133dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 47233dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck ret = netdev->dcbnl_ops->getnumtcs(netdev, i, &value); 47333dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck if (!ret) { 47433dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck ret = nla_put_u8(dcbnl_skb, i, value); 47533dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 47633dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck if (ret) { 47733dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck nla_nest_cancel(dcbnl_skb, nest); 47833dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck ret = -EINVAL; 47933dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck goto err; 48033dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck } 48133dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck } else { 48233dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck goto err; 48333dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck } 48433dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck } 48533dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck nla_nest_end(dcbnl_skb, nest); 48633dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 48733dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck nlmsg_end(dcbnl_skb, nlh); 48833dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 48933dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck ret = rtnl_unicast(dcbnl_skb, &init_net, pid); 49033dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck if (ret) { 49133dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck ret = -EINVAL; 4927eaf5077b37bb33dbd44e569ff88566d6fe286e9John Fastabend goto err_out; 49333dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck } 49433dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 49533dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck return 0; 49633dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duycknlmsg_failure: 49733dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyckerr: 498858eb711ba64f8a001d7003295b8078bcab33b6dRoel Kluin kfree_skb(dcbnl_skb); 49933dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyckerr_out: 50033dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck return ret; 50133dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck} 50233dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 50333dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyckstatic int dcbnl_setnumtcs(struct net_device *netdev, struct nlattr **tb, 50433dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck u32 pid, u32 seq, u16 flags) 50533dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck{ 50633dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck struct nlattr *data[DCB_NUMTCS_ATTR_MAX + 1]; 50733dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck int ret = -EINVAL; 50833dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck u8 value; 50933dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck int i; 51033dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 5118b124a8e14c04378466ddfe63e41fc5035f957ebDon Skidmore if (!tb[DCB_ATTR_NUMTCS] || !netdev->dcbnl_ops->setnumtcs) 51233dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck return ret; 51333dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 51433dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck ret = nla_parse_nested(data, DCB_NUMTCS_ATTR_MAX, tb[DCB_ATTR_NUMTCS], 51533dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck dcbnl_numtcs_nest); 51633dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 51733dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck if (ret) { 51833dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck ret = -EINVAL; 51933dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck goto err; 52033dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck } 52133dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 52233dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck for (i = DCB_NUMTCS_ATTR_ALL+1; i <= DCB_NUMTCS_ATTR_MAX; i++) { 52333dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck if (data[i] == NULL) 52433dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck continue; 52533dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 52633dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck value = nla_get_u8(data[i]); 52733dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 52833dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck ret = netdev->dcbnl_ops->setnumtcs(netdev, i, value); 52933dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 53033dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck if (ret) 53133dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck goto operr; 53233dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck } 53333dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 53433dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyckoperr: 53533dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck ret = dcbnl_reply(!!ret, RTM_SETDCB, DCB_CMD_SNUMTCS, 53633dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck DCB_ATTR_NUMTCS, pid, seq, flags); 53733dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 53833dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyckerr: 53933dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck return ret; 54033dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck} 54133dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck 5420eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyckstatic int dcbnl_getpfcstate(struct net_device *netdev, struct nlattr **tb, 5430eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck u32 pid, u32 seq, u16 flags) 5440eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck{ 5450eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck int ret = -EINVAL; 5460eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck 5470eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck if (!netdev->dcbnl_ops->getpfcstate) 5480eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck return ret; 5490eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck 5500eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck ret = dcbnl_reply(netdev->dcbnl_ops->getpfcstate(netdev), RTM_GETDCB, 5510eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck DCB_CMD_PFC_GSTATE, DCB_ATTR_PFC_STATE, 5520eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck pid, seq, flags); 5530eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck 5540eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck return ret; 5550eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck} 5560eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck 5570eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyckstatic int dcbnl_setpfcstate(struct net_device *netdev, struct nlattr **tb, 5580eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck u32 pid, u32 seq, u16 flags) 5590eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck{ 5600eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck int ret = -EINVAL; 5610eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck u8 value; 5620eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck 5630eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck if (!tb[DCB_ATTR_PFC_STATE] || !netdev->dcbnl_ops->setpfcstate) 5640eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck return ret; 5650eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck 5660eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck value = nla_get_u8(tb[DCB_ATTR_PFC_STATE]); 5670eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck 5680eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck netdev->dcbnl_ops->setpfcstate(netdev, value); 5690eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck 5700eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck ret = dcbnl_reply(0, RTM_SETDCB, DCB_CMD_PFC_SSTATE, DCB_ATTR_PFC_STATE, 5710eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck pid, seq, flags); 5720eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck 5730eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck return ret; 5740eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck} 5750eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck 576579496865cf4ea429146382d62047ffdbaab0deeYi Zoustatic int dcbnl_getapp(struct net_device *netdev, struct nlattr **tb, 577579496865cf4ea429146382d62047ffdbaab0deeYi Zou u32 pid, u32 seq, u16 flags) 578579496865cf4ea429146382d62047ffdbaab0deeYi Zou{ 579579496865cf4ea429146382d62047ffdbaab0deeYi Zou struct sk_buff *dcbnl_skb; 580579496865cf4ea429146382d62047ffdbaab0deeYi Zou struct nlmsghdr *nlh; 581579496865cf4ea429146382d62047ffdbaab0deeYi Zou struct dcbmsg *dcb; 582579496865cf4ea429146382d62047ffdbaab0deeYi Zou struct nlattr *app_nest; 583579496865cf4ea429146382d62047ffdbaab0deeYi Zou struct nlattr *app_tb[DCB_APP_ATTR_MAX + 1]; 584579496865cf4ea429146382d62047ffdbaab0deeYi Zou u16 id; 585579496865cf4ea429146382d62047ffdbaab0deeYi Zou u8 up, idtype; 586579496865cf4ea429146382d62047ffdbaab0deeYi Zou int ret = -EINVAL; 587579496865cf4ea429146382d62047ffdbaab0deeYi Zou 5883dce38a02d6370dca690cd923619d4b00024b723John Fastabend if (!tb[DCB_ATTR_APP]) 589579496865cf4ea429146382d62047ffdbaab0deeYi Zou goto out; 590579496865cf4ea429146382d62047ffdbaab0deeYi Zou 591579496865cf4ea429146382d62047ffdbaab0deeYi Zou ret = nla_parse_nested(app_tb, DCB_APP_ATTR_MAX, tb[DCB_ATTR_APP], 592579496865cf4ea429146382d62047ffdbaab0deeYi Zou dcbnl_app_nest); 593579496865cf4ea429146382d62047ffdbaab0deeYi Zou if (ret) 594579496865cf4ea429146382d62047ffdbaab0deeYi Zou goto out; 595579496865cf4ea429146382d62047ffdbaab0deeYi Zou 596579496865cf4ea429146382d62047ffdbaab0deeYi Zou ret = -EINVAL; 597579496865cf4ea429146382d62047ffdbaab0deeYi Zou /* all must be non-null */ 598579496865cf4ea429146382d62047ffdbaab0deeYi Zou if ((!app_tb[DCB_APP_ATTR_IDTYPE]) || 599579496865cf4ea429146382d62047ffdbaab0deeYi Zou (!app_tb[DCB_APP_ATTR_ID])) 600579496865cf4ea429146382d62047ffdbaab0deeYi Zou goto out; 601579496865cf4ea429146382d62047ffdbaab0deeYi Zou 602579496865cf4ea429146382d62047ffdbaab0deeYi Zou /* either by eth type or by socket number */ 603579496865cf4ea429146382d62047ffdbaab0deeYi Zou idtype = nla_get_u8(app_tb[DCB_APP_ATTR_IDTYPE]); 604579496865cf4ea429146382d62047ffdbaab0deeYi Zou if ((idtype != DCB_APP_IDTYPE_ETHTYPE) && 605579496865cf4ea429146382d62047ffdbaab0deeYi Zou (idtype != DCB_APP_IDTYPE_PORTNUM)) 606579496865cf4ea429146382d62047ffdbaab0deeYi Zou goto out; 607579496865cf4ea429146382d62047ffdbaab0deeYi Zou 608579496865cf4ea429146382d62047ffdbaab0deeYi Zou id = nla_get_u16(app_tb[DCB_APP_ATTR_ID]); 6093dce38a02d6370dca690cd923619d4b00024b723John Fastabend 6103dce38a02d6370dca690cd923619d4b00024b723John Fastabend if (netdev->dcbnl_ops->getapp) { 6113dce38a02d6370dca690cd923619d4b00024b723John Fastabend up = netdev->dcbnl_ops->getapp(netdev, idtype, id); 6123dce38a02d6370dca690cd923619d4b00024b723John Fastabend } else { 6133dce38a02d6370dca690cd923619d4b00024b723John Fastabend struct dcb_app app = { 6143dce38a02d6370dca690cd923619d4b00024b723John Fastabend .selector = idtype, 6153dce38a02d6370dca690cd923619d4b00024b723John Fastabend .protocol = id, 6163dce38a02d6370dca690cd923619d4b00024b723John Fastabend }; 6173dce38a02d6370dca690cd923619d4b00024b723John Fastabend up = dcb_getapp(netdev, &app); 6183dce38a02d6370dca690cd923619d4b00024b723John Fastabend } 619579496865cf4ea429146382d62047ffdbaab0deeYi Zou 620579496865cf4ea429146382d62047ffdbaab0deeYi Zou /* send this back */ 621579496865cf4ea429146382d62047ffdbaab0deeYi Zou dcbnl_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 622579496865cf4ea429146382d62047ffdbaab0deeYi Zou if (!dcbnl_skb) 623579496865cf4ea429146382d62047ffdbaab0deeYi Zou goto out; 624579496865cf4ea429146382d62047ffdbaab0deeYi Zou 625579496865cf4ea429146382d62047ffdbaab0deeYi Zou nlh = NLMSG_NEW(dcbnl_skb, pid, seq, RTM_GETDCB, sizeof(*dcb), flags); 626579496865cf4ea429146382d62047ffdbaab0deeYi Zou dcb = NLMSG_DATA(nlh); 627579496865cf4ea429146382d62047ffdbaab0deeYi Zou dcb->dcb_family = AF_UNSPEC; 628579496865cf4ea429146382d62047ffdbaab0deeYi Zou dcb->cmd = DCB_CMD_GAPP; 629579496865cf4ea429146382d62047ffdbaab0deeYi Zou 630579496865cf4ea429146382d62047ffdbaab0deeYi Zou app_nest = nla_nest_start(dcbnl_skb, DCB_ATTR_APP); 631d3337de52af7fb0ebe605b02b740be4ee7dee9ebJesper Juhl if (!app_nest) 632d3337de52af7fb0ebe605b02b740be4ee7dee9ebJesper Juhl goto out_cancel; 633d3337de52af7fb0ebe605b02b740be4ee7dee9ebJesper Juhl 634579496865cf4ea429146382d62047ffdbaab0deeYi Zou ret = nla_put_u8(dcbnl_skb, DCB_APP_ATTR_IDTYPE, idtype); 635579496865cf4ea429146382d62047ffdbaab0deeYi Zou if (ret) 636579496865cf4ea429146382d62047ffdbaab0deeYi Zou goto out_cancel; 637579496865cf4ea429146382d62047ffdbaab0deeYi Zou 638579496865cf4ea429146382d62047ffdbaab0deeYi Zou ret = nla_put_u16(dcbnl_skb, DCB_APP_ATTR_ID, id); 639579496865cf4ea429146382d62047ffdbaab0deeYi Zou if (ret) 640579496865cf4ea429146382d62047ffdbaab0deeYi Zou goto out_cancel; 641579496865cf4ea429146382d62047ffdbaab0deeYi Zou 642579496865cf4ea429146382d62047ffdbaab0deeYi Zou ret = nla_put_u8(dcbnl_skb, DCB_APP_ATTR_PRIORITY, up); 643579496865cf4ea429146382d62047ffdbaab0deeYi Zou if (ret) 644579496865cf4ea429146382d62047ffdbaab0deeYi Zou goto out_cancel; 645579496865cf4ea429146382d62047ffdbaab0deeYi Zou 646579496865cf4ea429146382d62047ffdbaab0deeYi Zou nla_nest_end(dcbnl_skb, app_nest); 647579496865cf4ea429146382d62047ffdbaab0deeYi Zou nlmsg_end(dcbnl_skb, nlh); 648579496865cf4ea429146382d62047ffdbaab0deeYi Zou 649579496865cf4ea429146382d62047ffdbaab0deeYi Zou ret = rtnl_unicast(dcbnl_skb, &init_net, pid); 650579496865cf4ea429146382d62047ffdbaab0deeYi Zou if (ret) 651579496865cf4ea429146382d62047ffdbaab0deeYi Zou goto nlmsg_failure; 652579496865cf4ea429146382d62047ffdbaab0deeYi Zou 653579496865cf4ea429146382d62047ffdbaab0deeYi Zou goto out; 654579496865cf4ea429146382d62047ffdbaab0deeYi Zou 655579496865cf4ea429146382d62047ffdbaab0deeYi Zouout_cancel: 656579496865cf4ea429146382d62047ffdbaab0deeYi Zou nla_nest_cancel(dcbnl_skb, app_nest); 657579496865cf4ea429146382d62047ffdbaab0deeYi Zounlmsg_failure: 658579496865cf4ea429146382d62047ffdbaab0deeYi Zou kfree_skb(dcbnl_skb); 659579496865cf4ea429146382d62047ffdbaab0deeYi Zouout: 660579496865cf4ea429146382d62047ffdbaab0deeYi Zou return ret; 661579496865cf4ea429146382d62047ffdbaab0deeYi Zou} 662579496865cf4ea429146382d62047ffdbaab0deeYi Zou 663579496865cf4ea429146382d62047ffdbaab0deeYi Zoustatic int dcbnl_setapp(struct net_device *netdev, struct nlattr **tb, 664579496865cf4ea429146382d62047ffdbaab0deeYi Zou u32 pid, u32 seq, u16 flags) 665579496865cf4ea429146382d62047ffdbaab0deeYi Zou{ 6669ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend int err, ret = -EINVAL; 667579496865cf4ea429146382d62047ffdbaab0deeYi Zou u16 id; 668579496865cf4ea429146382d62047ffdbaab0deeYi Zou u8 up, idtype; 669579496865cf4ea429146382d62047ffdbaab0deeYi Zou struct nlattr *app_tb[DCB_APP_ATTR_MAX + 1]; 670579496865cf4ea429146382d62047ffdbaab0deeYi Zou 6719ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend if (!tb[DCB_ATTR_APP]) 672579496865cf4ea429146382d62047ffdbaab0deeYi Zou goto out; 673579496865cf4ea429146382d62047ffdbaab0deeYi Zou 674579496865cf4ea429146382d62047ffdbaab0deeYi Zou ret = nla_parse_nested(app_tb, DCB_APP_ATTR_MAX, tb[DCB_ATTR_APP], 675579496865cf4ea429146382d62047ffdbaab0deeYi Zou dcbnl_app_nest); 676579496865cf4ea429146382d62047ffdbaab0deeYi Zou if (ret) 677579496865cf4ea429146382d62047ffdbaab0deeYi Zou goto out; 678579496865cf4ea429146382d62047ffdbaab0deeYi Zou 679579496865cf4ea429146382d62047ffdbaab0deeYi Zou ret = -EINVAL; 680579496865cf4ea429146382d62047ffdbaab0deeYi Zou /* all must be non-null */ 681579496865cf4ea429146382d62047ffdbaab0deeYi Zou if ((!app_tb[DCB_APP_ATTR_IDTYPE]) || 682579496865cf4ea429146382d62047ffdbaab0deeYi Zou (!app_tb[DCB_APP_ATTR_ID]) || 683579496865cf4ea429146382d62047ffdbaab0deeYi Zou (!app_tb[DCB_APP_ATTR_PRIORITY])) 684579496865cf4ea429146382d62047ffdbaab0deeYi Zou goto out; 685579496865cf4ea429146382d62047ffdbaab0deeYi Zou 686579496865cf4ea429146382d62047ffdbaab0deeYi Zou /* either by eth type or by socket number */ 687579496865cf4ea429146382d62047ffdbaab0deeYi Zou idtype = nla_get_u8(app_tb[DCB_APP_ATTR_IDTYPE]); 688579496865cf4ea429146382d62047ffdbaab0deeYi Zou if ((idtype != DCB_APP_IDTYPE_ETHTYPE) && 689579496865cf4ea429146382d62047ffdbaab0deeYi Zou (idtype != DCB_APP_IDTYPE_PORTNUM)) 690579496865cf4ea429146382d62047ffdbaab0deeYi Zou goto out; 691579496865cf4ea429146382d62047ffdbaab0deeYi Zou 692579496865cf4ea429146382d62047ffdbaab0deeYi Zou id = nla_get_u16(app_tb[DCB_APP_ATTR_ID]); 693579496865cf4ea429146382d62047ffdbaab0deeYi Zou up = nla_get_u8(app_tb[DCB_APP_ATTR_PRIORITY]); 694579496865cf4ea429146382d62047ffdbaab0deeYi Zou 6959ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend if (netdev->dcbnl_ops->setapp) { 6969ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend err = netdev->dcbnl_ops->setapp(netdev, idtype, id, up); 6979ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend } else { 6989ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend struct dcb_app app; 6999ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend app.selector = idtype; 7009ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend app.protocol = id; 7019ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend app.priority = up; 7029ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend err = dcb_setapp(netdev, &app); 7039ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend } 7049ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend 7059ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend ret = dcbnl_reply(err, RTM_SETDCB, DCB_CMD_SAPP, DCB_ATTR_APP, 7069ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend pid, seq, flags); 707081579840b4b2421e37bc67e3b089b7ca64ef040John Fastabend dcbnl_cee_notify(netdev, RTM_SETDCB, DCB_CMD_SAPP, seq, 0); 708579496865cf4ea429146382d62047ffdbaab0deeYi Zouout: 709579496865cf4ea429146382d62047ffdbaab0deeYi Zou return ret; 710579496865cf4ea429146382d62047ffdbaab0deeYi Zou} 711579496865cf4ea429146382d62047ffdbaab0deeYi Zou 7122f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckstatic int __dcbnl_pg_getcfg(struct net_device *netdev, struct nlattr **tb, 7132f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u32 pid, u32 seq, u16 flags, int dir) 7142f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 7152f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct sk_buff *dcbnl_skb; 7162f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct nlmsghdr *nlh; 7172f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct dcbmsg *dcb; 7182f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct nlattr *pg_nest, *param_nest, *data; 7192f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct nlattr *pg_tb[DCB_PG_ATTR_MAX + 1]; 7202f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct nlattr *param_tb[DCB_TC_ATTR_PARAM_MAX + 1]; 7212f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u8 prio, pgid, tc_pct, up_map; 7222f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck int ret = -EINVAL; 7232f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck int getall = 0; 7242f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck int i; 7252f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7262f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!tb[DCB_ATTR_PG_CFG] || 7272f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck !netdev->dcbnl_ops->getpgtccfgtx || 7282f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck !netdev->dcbnl_ops->getpgtccfgrx || 7292f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck !netdev->dcbnl_ops->getpgbwgcfgtx || 7302f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck !netdev->dcbnl_ops->getpgbwgcfgrx) 7312f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return ret; 7322f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7332f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = nla_parse_nested(pg_tb, DCB_PG_ATTR_MAX, 7342f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck tb[DCB_ATTR_PG_CFG], dcbnl_pg_nest); 7352f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7362f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 7372f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err_out; 7382f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7392f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcbnl_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 7402f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!dcbnl_skb) 7412f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err_out; 7422f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7432f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nlh = NLMSG_NEW(dcbnl_skb, pid, seq, RTM_GETDCB, sizeof(*dcb), flags); 7442f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7452f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcb = NLMSG_DATA(nlh); 7462f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcb->dcb_family = AF_UNSPEC; 7472f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcb->cmd = (dir) ? DCB_CMD_PGRX_GCFG : DCB_CMD_PGTX_GCFG; 7482f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7492f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck pg_nest = nla_nest_start(dcbnl_skb, DCB_ATTR_PG_CFG); 7502f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!pg_nest) 7512f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err; 7522f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7532f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (pg_tb[DCB_PG_ATTR_TC_ALL]) 7542f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck getall = 1; 7552f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7562f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck for (i = DCB_PG_ATTR_TC_0; i <= DCB_PG_ATTR_TC_7; i++) { 7572f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!getall && !pg_tb[i]) 7582f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck continue; 7592f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7602f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (pg_tb[DCB_PG_ATTR_TC_ALL]) 7612f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck data = pg_tb[DCB_PG_ATTR_TC_ALL]; 7622f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck else 7632f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck data = pg_tb[i]; 7642f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = nla_parse_nested(param_tb, DCB_TC_ATTR_PARAM_MAX, 7652f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck data, dcbnl_tc_param_nest); 7662f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 7672f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err_pg; 7682f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7692f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck param_nest = nla_nest_start(dcbnl_skb, i); 7702f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!param_nest) 7712f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err_pg; 7722f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7732f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck pgid = DCB_ATTR_VALUE_UNDEFINED; 7742f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck prio = DCB_ATTR_VALUE_UNDEFINED; 7752f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck tc_pct = DCB_ATTR_VALUE_UNDEFINED; 7762f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck up_map = DCB_ATTR_VALUE_UNDEFINED; 7772f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7782f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (dir) { 7792f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck /* Rx */ 7802f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck netdev->dcbnl_ops->getpgtccfgrx(netdev, 7812f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck i - DCB_PG_ATTR_TC_0, &prio, 7822f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck &pgid, &tc_pct, &up_map); 7832f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } else { 7842f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck /* Tx */ 7852f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck netdev->dcbnl_ops->getpgtccfgtx(netdev, 7862f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck i - DCB_PG_ATTR_TC_0, &prio, 7872f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck &pgid, &tc_pct, &up_map); 7882f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 7892f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 7902f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (param_tb[DCB_TC_ATTR_PARAM_PGID] || 7912f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck param_tb[DCB_TC_ATTR_PARAM_ALL]) { 7922f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = nla_put_u8(dcbnl_skb, 7932f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck DCB_TC_ATTR_PARAM_PGID, pgid); 7942f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 7952f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err_param; 7962f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 7972f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (param_tb[DCB_TC_ATTR_PARAM_UP_MAPPING] || 7982f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck param_tb[DCB_TC_ATTR_PARAM_ALL]) { 7992f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = nla_put_u8(dcbnl_skb, 8002f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck DCB_TC_ATTR_PARAM_UP_MAPPING, up_map); 8012f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 8022f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err_param; 8032f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 8042f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (param_tb[DCB_TC_ATTR_PARAM_STRICT_PRIO] || 8052f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck param_tb[DCB_TC_ATTR_PARAM_ALL]) { 8062f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = nla_put_u8(dcbnl_skb, 8072f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck DCB_TC_ATTR_PARAM_STRICT_PRIO, prio); 8082f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 8092f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err_param; 8102f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 8112f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (param_tb[DCB_TC_ATTR_PARAM_BW_PCT] || 8122f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck param_tb[DCB_TC_ATTR_PARAM_ALL]) { 8132f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = nla_put_u8(dcbnl_skb, DCB_TC_ATTR_PARAM_BW_PCT, 8142f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck tc_pct); 8152f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 8162f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err_param; 8172f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 8182f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nla_nest_end(dcbnl_skb, param_nest); 8192f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 8202f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8212f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (pg_tb[DCB_PG_ATTR_BW_ID_ALL]) 8222f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck getall = 1; 8232f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck else 8242f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck getall = 0; 8252f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8262f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck for (i = DCB_PG_ATTR_BW_ID_0; i <= DCB_PG_ATTR_BW_ID_7; i++) { 8272f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!getall && !pg_tb[i]) 8282f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck continue; 8292f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8302f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck tc_pct = DCB_ATTR_VALUE_UNDEFINED; 8312f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8322f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (dir) { 8332f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck /* Rx */ 8342f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck netdev->dcbnl_ops->getpgbwgcfgrx(netdev, 8352f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck i - DCB_PG_ATTR_BW_ID_0, &tc_pct); 8362f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } else { 8372f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck /* Tx */ 8382f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck netdev->dcbnl_ops->getpgbwgcfgtx(netdev, 8392f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck i - DCB_PG_ATTR_BW_ID_0, &tc_pct); 8402f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 8412f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = nla_put_u8(dcbnl_skb, i, tc_pct); 8422f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8432f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 8442f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err_pg; 8452f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 8462f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8472f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nla_nest_end(dcbnl_skb, pg_nest); 8482f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8492f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nlmsg_end(dcbnl_skb, nlh); 8502f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8512f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = rtnl_unicast(dcbnl_skb, &init_net, pid); 8522f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 8537eaf5077b37bb33dbd44e569ff88566d6fe286e9John Fastabend goto err_out; 8542f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8552f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return 0; 8562f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8572f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckerr_param: 8582f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nla_nest_cancel(dcbnl_skb, param_nest); 8592f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckerr_pg: 8602f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nla_nest_cancel(dcbnl_skb, pg_nest); 8612f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duycknlmsg_failure: 8622f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckerr: 863858eb711ba64f8a001d7003295b8078bcab33b6dRoel Kluin kfree_skb(dcbnl_skb); 8642f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckerr_out: 8652f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = -EINVAL; 8662f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return ret; 8672f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 8682f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8692f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckstatic int dcbnl_pgtx_getcfg(struct net_device *netdev, struct nlattr **tb, 8702f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u32 pid, u32 seq, u16 flags) 8712f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 8722f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return __dcbnl_pg_getcfg(netdev, tb, pid, seq, flags, 0); 8732f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 8742f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8752f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckstatic int dcbnl_pgrx_getcfg(struct net_device *netdev, struct nlattr **tb, 8762f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u32 pid, u32 seq, u16 flags) 8772f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 8782f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return __dcbnl_pg_getcfg(netdev, tb, pid, seq, flags, 1); 8792f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 8802f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8812f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckstatic int dcbnl_setstate(struct net_device *netdev, struct nlattr **tb, 8822f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u32 pid, u32 seq, u16 flags) 8832f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 8842f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck int ret = -EINVAL; 8852f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u8 value; 8862f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8872f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!tb[DCB_ATTR_STATE] || !netdev->dcbnl_ops->setstate) 8882f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return ret; 8892f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8902f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck value = nla_get_u8(tb[DCB_ATTR_STATE]); 8912f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8921486a61ebcd2711532f8163d30babc40e11e7b40Don Skidmore ret = dcbnl_reply(netdev->dcbnl_ops->setstate(netdev, value), 8931486a61ebcd2711532f8163d30babc40e11e7b40Don Skidmore RTM_SETDCB, DCB_CMD_SSTATE, DCB_ATTR_STATE, 8942f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck pid, seq, flags); 8952f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8962f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return ret; 8972f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 8982f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 8992f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckstatic int dcbnl_setpfccfg(struct net_device *netdev, struct nlattr **tb, 9002f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u32 pid, u32 seq, u16 flags) 9012f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 9022f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct nlattr *data[DCB_PFC_UP_ATTR_MAX + 1]; 9032f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck int i; 9042f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck int ret = -EINVAL; 9052f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u8 value; 9062f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 9072f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!tb[DCB_ATTR_PFC_CFG] || !netdev->dcbnl_ops->setpfccfg) 9082f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return ret; 9092f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 9102f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = nla_parse_nested(data, DCB_PFC_UP_ATTR_MAX, 9112f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck tb[DCB_ATTR_PFC_CFG], 9122f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcbnl_pfc_up_nest); 9132f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 9142f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err; 9152f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 9162f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck for (i = DCB_PFC_UP_ATTR_0; i <= DCB_PFC_UP_ATTR_7; i++) { 9172f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (data[i] == NULL) 9182f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck continue; 9192f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck value = nla_get_u8(data[i]); 9202f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck netdev->dcbnl_ops->setpfccfg(netdev, 9212f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck data[i]->nla_type - DCB_PFC_UP_ATTR_0, value); 9222f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 9232f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 9242f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = dcbnl_reply(0, RTM_SETDCB, DCB_CMD_PFC_SCFG, DCB_ATTR_PFC_CFG, 9252f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck pid, seq, flags); 9262f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckerr: 9272f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return ret; 9282f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 9292f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 9302f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckstatic int dcbnl_setall(struct net_device *netdev, struct nlattr **tb, 9312f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u32 pid, u32 seq, u16 flags) 9322f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 9332f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck int ret = -EINVAL; 9342f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 9352f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!tb[DCB_ATTR_SET_ALL] || !netdev->dcbnl_ops->setall) 9362f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return ret; 9372f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 9382f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = dcbnl_reply(netdev->dcbnl_ops->setall(netdev), RTM_SETDCB, 9392f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck DCB_CMD_SET_ALL, DCB_ATTR_SET_ALL, pid, seq, flags); 940081579840b4b2421e37bc67e3b089b7ca64ef040John Fastabend dcbnl_cee_notify(netdev, RTM_SETDCB, DCB_CMD_SET_ALL, seq, 0); 9412f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 9422f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return ret; 9432f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 9442f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 9452f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckstatic int __dcbnl_pg_setcfg(struct net_device *netdev, struct nlattr **tb, 9462f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u32 pid, u32 seq, u16 flags, int dir) 9472f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 9482f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct nlattr *pg_tb[DCB_PG_ATTR_MAX + 1]; 9492f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct nlattr *param_tb[DCB_TC_ATTR_PARAM_MAX + 1]; 9502f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck int ret = -EINVAL; 9512f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck int i; 9522f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u8 pgid; 9532f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u8 up_map; 9542f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u8 prio; 9552f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u8 tc_pct; 9562f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 9572f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!tb[DCB_ATTR_PG_CFG] || 9582f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck !netdev->dcbnl_ops->setpgtccfgtx || 9592f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck !netdev->dcbnl_ops->setpgtccfgrx || 9602f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck !netdev->dcbnl_ops->setpgbwgcfgtx || 9612f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck !netdev->dcbnl_ops->setpgbwgcfgrx) 9622f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return ret; 9632f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 9642f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = nla_parse_nested(pg_tb, DCB_PG_ATTR_MAX, 9652f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck tb[DCB_ATTR_PG_CFG], dcbnl_pg_nest); 9662f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 9672f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err; 9682f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 9692f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck for (i = DCB_PG_ATTR_TC_0; i <= DCB_PG_ATTR_TC_7; i++) { 9702f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!pg_tb[i]) 9712f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck continue; 9722f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 9732f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = nla_parse_nested(param_tb, DCB_TC_ATTR_PARAM_MAX, 9742f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck pg_tb[i], dcbnl_tc_param_nest); 9752f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret) 9762f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto err; 9772f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 9782f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck pgid = DCB_ATTR_VALUE_UNDEFINED; 9792f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck prio = DCB_ATTR_VALUE_UNDEFINED; 9802f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck tc_pct = DCB_ATTR_VALUE_UNDEFINED; 9812f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck up_map = DCB_ATTR_VALUE_UNDEFINED; 9822f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 9832f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (param_tb[DCB_TC_ATTR_PARAM_STRICT_PRIO]) 9842f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck prio = 9852f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nla_get_u8(param_tb[DCB_TC_ATTR_PARAM_STRICT_PRIO]); 9862f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 9872f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (param_tb[DCB_TC_ATTR_PARAM_PGID]) 9882f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck pgid = nla_get_u8(param_tb[DCB_TC_ATTR_PARAM_PGID]); 9892f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 9902f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (param_tb[DCB_TC_ATTR_PARAM_BW_PCT]) 9912f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck tc_pct = nla_get_u8(param_tb[DCB_TC_ATTR_PARAM_BW_PCT]); 9922f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 9932f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (param_tb[DCB_TC_ATTR_PARAM_UP_MAPPING]) 9942f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck up_map = 9952f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nla_get_u8(param_tb[DCB_TC_ATTR_PARAM_UP_MAPPING]); 9962f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 9972f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck /* dir: Tx = 0, Rx = 1 */ 9982f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (dir) { 9992f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck /* Rx */ 10002f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck netdev->dcbnl_ops->setpgtccfgrx(netdev, 10012f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck i - DCB_PG_ATTR_TC_0, 10022f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck prio, pgid, tc_pct, up_map); 10032f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } else { 10042f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck /* Tx */ 10052f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck netdev->dcbnl_ops->setpgtccfgtx(netdev, 10062f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck i - DCB_PG_ATTR_TC_0, 10072f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck prio, pgid, tc_pct, up_map); 10082f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 10092f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 10102f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 10112f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck for (i = DCB_PG_ATTR_BW_ID_0; i <= DCB_PG_ATTR_BW_ID_7; i++) { 10122f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!pg_tb[i]) 10132f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck continue; 10142f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 10152f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck tc_pct = nla_get_u8(pg_tb[i]); 10162f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 10172f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck /* dir: Tx = 0, Rx = 1 */ 10182f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (dir) { 10192f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck /* Rx */ 10202f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck netdev->dcbnl_ops->setpgbwgcfgrx(netdev, 10212f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck i - DCB_PG_ATTR_BW_ID_0, tc_pct); 10222f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } else { 10232f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck /* Tx */ 10242f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck netdev->dcbnl_ops->setpgbwgcfgtx(netdev, 10252f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck i - DCB_PG_ATTR_BW_ID_0, tc_pct); 10262f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 10272f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 10282f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 10292f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = dcbnl_reply(0, RTM_SETDCB, 10302f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck (dir ? DCB_CMD_PGRX_SCFG : DCB_CMD_PGTX_SCFG), 10312f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck DCB_ATTR_PG_CFG, pid, seq, flags); 10322f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 10332f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckerr: 10342f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return ret; 10352f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 10362f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 10372f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckstatic int dcbnl_pgtx_setcfg(struct net_device *netdev, struct nlattr **tb, 10382f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u32 pid, u32 seq, u16 flags) 10392f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 10402f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return __dcbnl_pg_setcfg(netdev, tb, pid, seq, flags, 0); 10412f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 10422f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 10432f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckstatic int dcbnl_pgrx_setcfg(struct net_device *netdev, struct nlattr **tb, 10442f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u32 pid, u32 seq, u16 flags) 10452f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 10462f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return __dcbnl_pg_setcfg(netdev, tb, pid, seq, flags, 1); 10472f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 10482f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 1049859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyckstatic int dcbnl_bcn_getcfg(struct net_device *netdev, struct nlattr **tb, 1050859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck u32 pid, u32 seq, u16 flags) 1051859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck{ 1052859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck struct sk_buff *dcbnl_skb; 1053859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck struct nlmsghdr *nlh; 1054859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck struct dcbmsg *dcb; 1055859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck struct nlattr *bcn_nest; 1056859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck struct nlattr *bcn_tb[DCB_BCN_ATTR_MAX + 1]; 1057859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck u8 value_byte; 1058859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck u32 value_integer; 1059859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck int ret = -EINVAL; 1060859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck bool getall = false; 1061859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck int i; 1062859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1063859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck if (!tb[DCB_ATTR_BCN] || !netdev->dcbnl_ops->getbcnrp || 1064859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck !netdev->dcbnl_ops->getbcncfg) 1065859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck return ret; 1066859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1067859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck ret = nla_parse_nested(bcn_tb, DCB_BCN_ATTR_MAX, 1068859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck tb[DCB_ATTR_BCN], dcbnl_bcn_nest); 1069859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1070859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck if (ret) 1071859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck goto err_out; 1072859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1073859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck dcbnl_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 1074859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck if (!dcbnl_skb) 1075859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck goto err_out; 1076859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1077859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck nlh = NLMSG_NEW(dcbnl_skb, pid, seq, RTM_GETDCB, sizeof(*dcb), flags); 1078859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1079859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck dcb = NLMSG_DATA(nlh); 1080859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck dcb->dcb_family = AF_UNSPEC; 1081859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck dcb->cmd = DCB_CMD_BCN_GCFG; 1082859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1083859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck bcn_nest = nla_nest_start(dcbnl_skb, DCB_ATTR_BCN); 1084859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck if (!bcn_nest) 1085859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck goto err; 1086859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1087859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck if (bcn_tb[DCB_BCN_ATTR_ALL]) 1088859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck getall = true; 1089859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1090859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck for (i = DCB_BCN_ATTR_RP_0; i <= DCB_BCN_ATTR_RP_7; i++) { 1091859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck if (!getall && !bcn_tb[i]) 1092859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck continue; 1093859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1094859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck netdev->dcbnl_ops->getbcnrp(netdev, i - DCB_BCN_ATTR_RP_0, 1095859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck &value_byte); 1096859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck ret = nla_put_u8(dcbnl_skb, i, value_byte); 1097859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck if (ret) 1098859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck goto err_bcn; 1099859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck } 1100859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1101f4314e815e87b4ab1c9b1115dd5853cd20ca999cDon Skidmore for (i = DCB_BCN_ATTR_BCNA_0; i <= DCB_BCN_ATTR_RI; i++) { 1102859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck if (!getall && !bcn_tb[i]) 1103859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck continue; 1104859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1105859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck netdev->dcbnl_ops->getbcncfg(netdev, i, 1106859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck &value_integer); 1107859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck ret = nla_put_u32(dcbnl_skb, i, value_integer); 1108859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck if (ret) 1109859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck goto err_bcn; 1110859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck } 1111859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1112859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck nla_nest_end(dcbnl_skb, bcn_nest); 1113859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1114859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck nlmsg_end(dcbnl_skb, nlh); 1115859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1116859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck ret = rtnl_unicast(dcbnl_skb, &init_net, pid); 1117859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck if (ret) 11187eaf5077b37bb33dbd44e569ff88566d6fe286e9John Fastabend goto err_out; 1119859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1120859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck return 0; 1121859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1122859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyckerr_bcn: 1123859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck nla_nest_cancel(dcbnl_skb, bcn_nest); 1124859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duycknlmsg_failure: 1125859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyckerr: 1126858eb711ba64f8a001d7003295b8078bcab33b6dRoel Kluin kfree_skb(dcbnl_skb); 1127859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyckerr_out: 1128859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck ret = -EINVAL; 1129859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck return ret; 1130859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck} 1131859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1132859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyckstatic int dcbnl_bcn_setcfg(struct net_device *netdev, struct nlattr **tb, 1133859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck u32 pid, u32 seq, u16 flags) 1134859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck{ 1135859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck struct nlattr *data[DCB_BCN_ATTR_MAX + 1]; 1136859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck int i; 1137859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck int ret = -EINVAL; 1138859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck u8 value_byte; 1139859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck u32 value_int; 1140859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1141f64f9e719261a87818dd192a3a2352e5b20fbd0fJoe Perches if (!tb[DCB_ATTR_BCN] || !netdev->dcbnl_ops->setbcncfg || 1142f64f9e719261a87818dd192a3a2352e5b20fbd0fJoe Perches !netdev->dcbnl_ops->setbcnrp) 1143859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck return ret; 1144859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1145859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck ret = nla_parse_nested(data, DCB_BCN_ATTR_MAX, 1146859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck tb[DCB_ATTR_BCN], 1147859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck dcbnl_pfc_up_nest); 1148859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck if (ret) 1149859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck goto err; 1150859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1151859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck for (i = DCB_BCN_ATTR_RP_0; i <= DCB_BCN_ATTR_RP_7; i++) { 1152859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck if (data[i] == NULL) 1153859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck continue; 1154859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck value_byte = nla_get_u8(data[i]); 1155859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck netdev->dcbnl_ops->setbcnrp(netdev, 1156859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck data[i]->nla_type - DCB_BCN_ATTR_RP_0, value_byte); 1157859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck } 1158859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1159f4314e815e87b4ab1c9b1115dd5853cd20ca999cDon Skidmore for (i = DCB_BCN_ATTR_BCNA_0; i <= DCB_BCN_ATTR_RI; i++) { 1160859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck if (data[i] == NULL) 1161859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck continue; 1162859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck value_int = nla_get_u32(data[i]); 1163859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck netdev->dcbnl_ops->setbcncfg(netdev, 1164859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck i, value_int); 1165859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck } 1166859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1167859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck ret = dcbnl_reply(0, RTM_SETDCB, DCB_CMD_BCN_SCFG, DCB_ATTR_BCN, 1168859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck pid, seq, flags); 1169859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyckerr: 1170859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck return ret; 1171859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck} 1172859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck 1173dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravidstatic int dcbnl_build_peer_app(struct net_device *netdev, struct sk_buff* skb, 1174dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid int app_nested_type, int app_info_type, 1175dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid int app_entry_type) 1176eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid{ 1177eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid struct dcb_peer_app_info info; 1178eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid struct dcb_app *table = NULL; 1179eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops; 1180eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid u16 app_count; 1181eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid int err; 1182eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid 1183eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid 1184eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid /** 1185eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid * retrieve the peer app configuration form the driver. If the driver 1186eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid * handlers fail exit without doing anything 1187eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid */ 1188eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid err = ops->peer_getappinfo(netdev, &info, &app_count); 1189eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid if (!err && app_count) { 1190eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid table = kmalloc(sizeof(struct dcb_app) * app_count, GFP_KERNEL); 1191eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid if (!table) 1192eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid return -ENOMEM; 1193eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid 1194eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid err = ops->peer_getapptable(netdev, table); 1195eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid } 1196eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid 1197eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid if (!err) { 1198eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid u16 i; 1199eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid struct nlattr *app; 1200eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid 1201eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid /** 1202eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid * build the message, from here on the only possible failure 1203eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid * is due to the skb size 1204eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid */ 1205eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid err = -EMSGSIZE; 1206eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid 1207dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid app = nla_nest_start(skb, app_nested_type); 1208eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid if (!app) 1209eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid goto nla_put_failure; 1210eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid 12111eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller if (app_info_type && 12121eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller nla_put(skb, app_info_type, sizeof(info), &info)) 12131eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller goto nla_put_failure; 1214eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid 12151eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller for (i = 0; i < app_count; i++) { 12161eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller if (nla_put(skb, app_entry_type, sizeof(struct dcb_app), 12171eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller &table[i])) 12181eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller goto nla_put_failure; 12191eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller } 1220eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid nla_nest_end(skb, app); 1221eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid } 1222eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid err = 0; 1223eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid 1224eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravidnla_put_failure: 1225eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid kfree(table); 1226eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid return err; 1227eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid} 12283e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend 12293e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend/* Handle IEEE 802.1Qaz GET commands. */ 1230314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabendstatic int dcbnl_ieee_fill(struct sk_buff *skb, struct net_device *netdev) 12313e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend{ 12329ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend struct nlattr *ieee, *app; 12339ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend struct dcb_app_type *itr; 12343e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops; 1235c7797baf9f3900996ca800ab6298f95957bb4606John Fastabend int dcbx; 1236314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend int err = -EMSGSIZE; 12373e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend 12381eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller if (nla_put_string(skb, DCB_ATTR_IFNAME, netdev->name)) 12391eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller goto nla_put_failure; 12403e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend ieee = nla_nest_start(skb, DCB_ATTR_IEEE); 12413e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend if (!ieee) 12423e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend goto nla_put_failure; 12433e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend 12443e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend if (ops->ieee_getets) { 12453e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend struct ieee_ets ets; 12463e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend err = ops->ieee_getets(netdev, &ets); 12471eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller if (!err && 12481eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller nla_put(skb, DCB_ATTR_IEEE_ETS, sizeof(ets), &ets)) 12491eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller goto nla_put_failure; 12503e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend } 12513e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend 125208f10affe45051e18e0d8291c0a53aecef1b8a14Amir Vadai if (ops->ieee_getmaxrate) { 125308f10affe45051e18e0d8291c0a53aecef1b8a14Amir Vadai struct ieee_maxrate maxrate; 125408f10affe45051e18e0d8291c0a53aecef1b8a14Amir Vadai err = ops->ieee_getmaxrate(netdev, &maxrate); 125508f10affe45051e18e0d8291c0a53aecef1b8a14Amir Vadai if (!err) { 125608f10affe45051e18e0d8291c0a53aecef1b8a14Amir Vadai err = nla_put(skb, DCB_ATTR_IEEE_MAXRATE, 125708f10affe45051e18e0d8291c0a53aecef1b8a14Amir Vadai sizeof(maxrate), &maxrate); 125808f10affe45051e18e0d8291c0a53aecef1b8a14Amir Vadai if (err) 125908f10affe45051e18e0d8291c0a53aecef1b8a14Amir Vadai goto nla_put_failure; 126008f10affe45051e18e0d8291c0a53aecef1b8a14Amir Vadai } 126108f10affe45051e18e0d8291c0a53aecef1b8a14Amir Vadai } 126208f10affe45051e18e0d8291c0a53aecef1b8a14Amir Vadai 12633e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend if (ops->ieee_getpfc) { 12643e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend struct ieee_pfc pfc; 12653e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend err = ops->ieee_getpfc(netdev, &pfc); 12661eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller if (!err && 12671eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller nla_put(skb, DCB_ATTR_IEEE_PFC, sizeof(pfc), &pfc)) 12681eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller goto nla_put_failure; 12693e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend } 12703e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend 12719ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend app = nla_nest_start(skb, DCB_ATTR_IEEE_APP_TABLE); 12729ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend if (!app) 12739ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend goto nla_put_failure; 12749ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend 12759ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend spin_lock(&dcb_lock); 12769ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend list_for_each_entry(itr, &dcb_app_list, list) { 1277e290ed81307ca7d92675f0d9c683add693c2f377Mark Rustad if (itr->ifindex == netdev->ifindex) { 127870bfa2d2e1bfd90ef26758b5e2749f043a940037Dan Carpenter err = nla_put(skb, DCB_ATTR_IEEE_APP, sizeof(itr->app), 127970bfa2d2e1bfd90ef26758b5e2749f043a940037Dan Carpenter &itr->app); 128070bfa2d2e1bfd90ef26758b5e2749f043a940037Dan Carpenter if (err) { 128170bfa2d2e1bfd90ef26758b5e2749f043a940037Dan Carpenter spin_unlock(&dcb_lock); 128270bfa2d2e1bfd90ef26758b5e2749f043a940037Dan Carpenter goto nla_put_failure; 128370bfa2d2e1bfd90ef26758b5e2749f043a940037Dan Carpenter } 128470bfa2d2e1bfd90ef26758b5e2749f043a940037Dan Carpenter } 12859ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend } 1286c7797baf9f3900996ca800ab6298f95957bb4606John Fastabend 1287c7797baf9f3900996ca800ab6298f95957bb4606John Fastabend if (netdev->dcbnl_ops->getdcbx) 1288c7797baf9f3900996ca800ab6298f95957bb4606John Fastabend dcbx = netdev->dcbnl_ops->getdcbx(netdev); 1289c7797baf9f3900996ca800ab6298f95957bb4606John Fastabend else 1290c7797baf9f3900996ca800ab6298f95957bb4606John Fastabend dcbx = -EOPNOTSUPP; 1291c7797baf9f3900996ca800ab6298f95957bb4606John Fastabend 12929ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend spin_unlock(&dcb_lock); 12939ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend nla_nest_end(skb, app); 12949ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend 1295eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid /* get peer info if available */ 1296eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid if (ops->ieee_peer_getets) { 1297eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid struct ieee_ets ets; 1298eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid err = ops->ieee_peer_getets(netdev, &ets); 12991eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller if (!err && 13001eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller nla_put(skb, DCB_ATTR_IEEE_PEER_ETS, sizeof(ets), &ets)) 13011eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller goto nla_put_failure; 1302eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid } 1303eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid 1304eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid if (ops->ieee_peer_getpfc) { 1305eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid struct ieee_pfc pfc; 1306eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid err = ops->ieee_peer_getpfc(netdev, &pfc); 13071eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller if (!err && 13081eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller nla_put(skb, DCB_ATTR_IEEE_PEER_PFC, sizeof(pfc), &pfc)) 13091eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller goto nla_put_failure; 1310eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid } 1311eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid 1312eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid if (ops->peer_getappinfo && ops->peer_getapptable) { 1313dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid err = dcbnl_build_peer_app(netdev, skb, 1314dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid DCB_ATTR_IEEE_PEER_APP, 1315dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid DCB_ATTR_IEEE_APP_UNSPEC, 1316dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid DCB_ATTR_IEEE_APP); 1317eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid if (err) 1318eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid goto nla_put_failure; 1319eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid } 1320eed84713bc47ce2f7d675914f297ad9b6227a587Shmulik Ravid 13213e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend nla_nest_end(skb, ieee); 1322c7797baf9f3900996ca800ab6298f95957bb4606John Fastabend if (dcbx >= 0) { 1323c7797baf9f3900996ca800ab6298f95957bb4606John Fastabend err = nla_put_u8(skb, DCB_ATTR_DCBX, dcbx); 1324c7797baf9f3900996ca800ab6298f95957bb4606John Fastabend if (err) 1325c7797baf9f3900996ca800ab6298f95957bb4606John Fastabend goto nla_put_failure; 1326c7797baf9f3900996ca800ab6298f95957bb4606John Fastabend } 13273e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend 1328314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend return 0; 1329314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend 13303e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabendnla_put_failure: 1331314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend return err; 13323e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend} 13333e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend 13345b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravidstatic int dcbnl_cee_pg_fill(struct sk_buff *skb, struct net_device *dev, 13355b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid int dir) 13365b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid{ 13375b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid u8 pgid, up_map, prio, tc_pct; 13385b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid const struct dcbnl_rtnl_ops *ops = dev->dcbnl_ops; 13395b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid int i = dir ? DCB_ATTR_CEE_TX_PG : DCB_ATTR_CEE_RX_PG; 13405b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid struct nlattr *pg = nla_nest_start(skb, i); 13415b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 13425b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (!pg) 13435b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid goto nla_put_failure; 13445b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 13455b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid for (i = DCB_PG_ATTR_TC_0; i <= DCB_PG_ATTR_TC_7; i++) { 13465b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid struct nlattr *tc_nest = nla_nest_start(skb, i); 13475b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 13485b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (!tc_nest) 13495b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid goto nla_put_failure; 13505b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 13515b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid pgid = DCB_ATTR_VALUE_UNDEFINED; 13525b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid prio = DCB_ATTR_VALUE_UNDEFINED; 13535b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid tc_pct = DCB_ATTR_VALUE_UNDEFINED; 13545b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid up_map = DCB_ATTR_VALUE_UNDEFINED; 13555b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 13565b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (!dir) 13575b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid ops->getpgtccfgrx(dev, i - DCB_PG_ATTR_TC_0, 13585b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid &prio, &pgid, &tc_pct, &up_map); 13595b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid else 13605b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid ops->getpgtccfgtx(dev, i - DCB_PG_ATTR_TC_0, 13615b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid &prio, &pgid, &tc_pct, &up_map); 13625b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 13631eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller if (nla_put_u8(skb, DCB_TC_ATTR_PARAM_PGID, pgid) || 13641eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller nla_put_u8(skb, DCB_TC_ATTR_PARAM_UP_MAPPING, up_map) || 13651eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller nla_put_u8(skb, DCB_TC_ATTR_PARAM_STRICT_PRIO, prio) || 13661eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller nla_put_u8(skb, DCB_TC_ATTR_PARAM_BW_PCT, tc_pct)) 13671eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller goto nla_put_failure; 13685b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid nla_nest_end(skb, tc_nest); 13695b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid } 13705b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 13715b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid for (i = DCB_PG_ATTR_BW_ID_0; i <= DCB_PG_ATTR_BW_ID_7; i++) { 13725b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid tc_pct = DCB_ATTR_VALUE_UNDEFINED; 13735b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 13745b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (!dir) 13755b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid ops->getpgbwgcfgrx(dev, i - DCB_PG_ATTR_BW_ID_0, 13765b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid &tc_pct); 13775b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid else 13785b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid ops->getpgbwgcfgtx(dev, i - DCB_PG_ATTR_BW_ID_0, 13795b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid &tc_pct); 13801eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller if (nla_put_u8(skb, i, tc_pct)) 13811eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller goto nla_put_failure; 13825b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid } 13835b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid nla_nest_end(skb, pg); 13845b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid return 0; 13855b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 13865b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravidnla_put_failure: 13875b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid return -EMSGSIZE; 13885b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid} 13895b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 13905b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravidstatic int dcbnl_cee_fill(struct sk_buff *skb, struct net_device *netdev) 13915b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid{ 13925b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid struct nlattr *cee, *app; 13935b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid struct dcb_app_type *itr; 13945b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops; 13955b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid int dcbx, i, err = -EMSGSIZE; 13965b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid u8 value; 13975b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 13981eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller if (nla_put_string(skb, DCB_ATTR_IFNAME, netdev->name)) 13991eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller goto nla_put_failure; 14005b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid cee = nla_nest_start(skb, DCB_ATTR_CEE); 14015b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (!cee) 14025b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid goto nla_put_failure; 14035b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 14045b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid /* local pg */ 14055b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (ops->getpgtccfgtx && ops->getpgbwgcfgtx) { 14065b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid err = dcbnl_cee_pg_fill(skb, netdev, 1); 14075b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (err) 14085b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid goto nla_put_failure; 14095b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid } 14105b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 14115b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (ops->getpgtccfgrx && ops->getpgbwgcfgrx) { 14125b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid err = dcbnl_cee_pg_fill(skb, netdev, 0); 14135b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (err) 14145b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid goto nla_put_failure; 14155b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid } 14165b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 14175b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid /* local pfc */ 14185b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (ops->getpfccfg) { 14195b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid struct nlattr *pfc_nest = nla_nest_start(skb, DCB_ATTR_CEE_PFC); 14205b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 14215b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (!pfc_nest) 14225b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid goto nla_put_failure; 14235b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 14245b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid for (i = DCB_PFC_UP_ATTR_0; i <= DCB_PFC_UP_ATTR_7; i++) { 14255b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid ops->getpfccfg(netdev, i - DCB_PFC_UP_ATTR_0, &value); 14261eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller if (nla_put_u8(skb, i, value)) 14271eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller goto nla_put_failure; 14285b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid } 14295b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid nla_nest_end(skb, pfc_nest); 14305b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid } 14315b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 14325b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid /* local app */ 14335b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid spin_lock(&dcb_lock); 14345b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid app = nla_nest_start(skb, DCB_ATTR_CEE_APP_TABLE); 14355b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (!app) 143640f5d72a4fc098c47068e3888cfb055922f6519fDan Carpenter goto dcb_unlock; 14375b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 14385b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid list_for_each_entry(itr, &dcb_app_list, list) { 1439e290ed81307ca7d92675f0d9c683add693c2f377Mark Rustad if (itr->ifindex == netdev->ifindex) { 14405b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid struct nlattr *app_nest = nla_nest_start(skb, 14415b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid DCB_ATTR_APP); 14425b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (!app_nest) 14435b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid goto dcb_unlock; 14445b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 14455b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid err = nla_put_u8(skb, DCB_APP_ATTR_IDTYPE, 14465b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid itr->app.selector); 14475b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (err) 14485b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid goto dcb_unlock; 14495b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 14505b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid err = nla_put_u16(skb, DCB_APP_ATTR_ID, 14515b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid itr->app.protocol); 14525b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (err) 14535b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid goto dcb_unlock; 14545b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 14555b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid err = nla_put_u8(skb, DCB_APP_ATTR_PRIORITY, 14565b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid itr->app.priority); 14575b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (err) 14585b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid goto dcb_unlock; 14595b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 14605b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid nla_nest_end(skb, app_nest); 14615b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid } 14625b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid } 14635b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid nla_nest_end(skb, app); 14645b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 14655b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (netdev->dcbnl_ops->getdcbx) 14665b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid dcbx = netdev->dcbnl_ops->getdcbx(netdev); 14675b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid else 14685b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid dcbx = -EOPNOTSUPP; 14695b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 14705b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid spin_unlock(&dcb_lock); 14715b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 14725b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid /* features flags */ 14735b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (ops->getfeatcfg) { 14745b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid struct nlattr *feat = nla_nest_start(skb, DCB_ATTR_CEE_FEAT); 14755b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (!feat) 14765b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid goto nla_put_failure; 14775b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 14785b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid for (i = DCB_FEATCFG_ATTR_ALL + 1; i <= DCB_FEATCFG_ATTR_MAX; 14795b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid i++) 14801eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller if (!ops->getfeatcfg(netdev, i, &value) && 14811eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller nla_put_u8(skb, i, value)) 14821eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller goto nla_put_failure; 14835b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 14845b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid nla_nest_end(skb, feat); 14855b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid } 14865b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 14875b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid /* peer info if available */ 14885b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (ops->cee_peer_getpg) { 14895b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid struct cee_pg pg; 14905b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid err = ops->cee_peer_getpg(netdev, &pg); 14911eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller if (!err && 14921eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller nla_put(skb, DCB_ATTR_CEE_PEER_PG, sizeof(pg), &pg)) 14931eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller goto nla_put_failure; 14945b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid } 14955b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 14965b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (ops->cee_peer_getpfc) { 14975b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid struct cee_pfc pfc; 14985b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid err = ops->cee_peer_getpfc(netdev, &pfc); 14991eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller if (!err && 15001eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller nla_put(skb, DCB_ATTR_CEE_PEER_PFC, sizeof(pfc), &pfc)) 15011eb4c977778b5ab8e8fba9022687f0a5941d681aDavid S. Miller goto nla_put_failure; 15025b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid } 15035b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 15045b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (ops->peer_getappinfo && ops->peer_getapptable) { 15055b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid err = dcbnl_build_peer_app(netdev, skb, 15065b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid DCB_ATTR_CEE_PEER_APP_TABLE, 15075b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid DCB_ATTR_CEE_PEER_APP_INFO, 15085b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid DCB_ATTR_CEE_PEER_APP); 15095b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (err) 15105b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid goto nla_put_failure; 15115b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid } 15125b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid nla_nest_end(skb, cee); 15135b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 15145b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid /* DCBX state */ 15155b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (dcbx >= 0) { 15165b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid err = nla_put_u8(skb, DCB_ATTR_DCBX, dcbx); 15175b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (err) 15185b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid goto nla_put_failure; 15195b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid } 15205b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid return 0; 15215b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 15225b7f7626743e0912958981343b47ac0ab2206b1cShmulik Raviddcb_unlock: 15235b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid spin_unlock(&dcb_lock); 15245b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravidnla_put_failure: 15255b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid return err; 15265b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid} 15275b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 15285b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravidstatic int dcbnl_notify(struct net_device *dev, int event, int cmd, 15295b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid u32 seq, u32 pid, int dcbx_ver) 1530314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend{ 1531314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend struct net *net = dev_net(dev); 1532314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend struct sk_buff *skb; 1533314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend struct nlmsghdr *nlh; 1534314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend struct dcbmsg *dcb; 1535314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend const struct dcbnl_rtnl_ops *ops = dev->dcbnl_ops; 1536314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend int err; 1537314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend 1538314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend if (!ops) 1539314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend return -EOPNOTSUPP; 1540314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend 1541314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 1542314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend if (!skb) 1543314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend return -ENOBUFS; 1544314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend 1545314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend nlh = nlmsg_put(skb, pid, 0, event, sizeof(*dcb), 0); 1546314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend if (nlh == NULL) { 15474d054f2f1445aceedab3f9642692d55d2caa7ec6Dan Carpenter nlmsg_free(skb); 1548314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend return -EMSGSIZE; 1549314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend } 1550314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend 1551314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend dcb = NLMSG_DATA(nlh); 1552314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend dcb->dcb_family = AF_UNSPEC; 1553314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend dcb->cmd = cmd; 1554314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend 15555b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (dcbx_ver == DCB_CAP_DCBX_VER_IEEE) 15565b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid err = dcbnl_ieee_fill(skb, dev); 15575b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid else 15585b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid err = dcbnl_cee_fill(skb, dev); 15595b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 1560314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend if (err < 0) { 1561314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend /* Report error to broadcast listeners */ 1562314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend nlmsg_cancel(skb, nlh); 1563314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend kfree_skb(skb); 1564314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend rtnl_set_sk_err(net, RTNLGRP_DCB, err); 1565314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend } else { 1566314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend /* End nlmsg and notify broadcast listeners */ 1567314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend nlmsg_end(skb, nlh); 1568314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend rtnl_notify(skb, net, 0, RTNLGRP_DCB, NULL, GFP_KERNEL); 1569314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend } 1570314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend 1571314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend return err; 1572314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend} 15735b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 15745b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravidint dcbnl_ieee_notify(struct net_device *dev, int event, int cmd, 15755b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid u32 seq, u32 pid) 15765b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid{ 15775b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid return dcbnl_notify(dev, event, cmd, seq, pid, DCB_CAP_DCBX_VER_IEEE); 15785b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid} 15795b7f7626743e0912958981343b47ac0ab2206b1cShmulik RavidEXPORT_SYMBOL(dcbnl_ieee_notify); 15805b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid 15815b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravidint dcbnl_cee_notify(struct net_device *dev, int event, int cmd, 15825b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid u32 seq, u32 pid) 15835b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid{ 15845b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid return dcbnl_notify(dev, event, cmd, seq, pid, DCB_CAP_DCBX_VER_CEE); 15855b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid} 15865b7f7626743e0912958981343b47ac0ab2206b1cShmulik RavidEXPORT_SYMBOL(dcbnl_cee_notify); 1587314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend 1588314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend/* Handle IEEE 802.1Qaz SET commands. If any requested operation can not 1589314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend * be completed the entire msg is aborted and error value is returned. 1590314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend * No attempt is made to reconcile the case where only part of the 1591314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend * cmd can be completed. 1592314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend */ 1593314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabendstatic int dcbnl_ieee_set(struct net_device *netdev, struct nlattr **tb, 1594314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend u32 pid, u32 seq, u16 flags) 1595314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend{ 1596314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops; 1597314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend struct nlattr *ieee[DCB_ATTR_IEEE_MAX + 1]; 1598314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend int err = -EOPNOTSUPP; 1599314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend 1600314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend if (!ops) 1601314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend return err; 1602314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend 16034003b65871c101eb5ce8f37a325feac54aa5c681John Fastabend if (!tb[DCB_ATTR_IEEE]) 16044003b65871c101eb5ce8f37a325feac54aa5c681John Fastabend return -EINVAL; 16054003b65871c101eb5ce8f37a325feac54aa5c681John Fastabend 1606314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend err = nla_parse_nested(ieee, DCB_ATTR_IEEE_MAX, 1607314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend tb[DCB_ATTR_IEEE], dcbnl_ieee_policy); 1608314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend if (err) 1609314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend return err; 1610314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend 1611314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend if (ieee[DCB_ATTR_IEEE_ETS] && ops->ieee_setets) { 1612314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend struct ieee_ets *ets = nla_data(ieee[DCB_ATTR_IEEE_ETS]); 1613314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend err = ops->ieee_setets(netdev, ets); 1614314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend if (err) 1615314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend goto err; 1616314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend } 1617314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend 161808f10affe45051e18e0d8291c0a53aecef1b8a14Amir Vadai if (ieee[DCB_ATTR_IEEE_MAXRATE] && ops->ieee_setmaxrate) { 161908f10affe45051e18e0d8291c0a53aecef1b8a14Amir Vadai struct ieee_maxrate *maxrate = 162008f10affe45051e18e0d8291c0a53aecef1b8a14Amir Vadai nla_data(ieee[DCB_ATTR_IEEE_MAXRATE]); 162108f10affe45051e18e0d8291c0a53aecef1b8a14Amir Vadai err = ops->ieee_setmaxrate(netdev, maxrate); 162208f10affe45051e18e0d8291c0a53aecef1b8a14Amir Vadai if (err) 162308f10affe45051e18e0d8291c0a53aecef1b8a14Amir Vadai goto err; 162408f10affe45051e18e0d8291c0a53aecef1b8a14Amir Vadai } 162508f10affe45051e18e0d8291c0a53aecef1b8a14Amir Vadai 1626314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend if (ieee[DCB_ATTR_IEEE_PFC] && ops->ieee_setpfc) { 1627314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend struct ieee_pfc *pfc = nla_data(ieee[DCB_ATTR_IEEE_PFC]); 1628314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend err = ops->ieee_setpfc(netdev, pfc); 1629314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend if (err) 1630314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend goto err; 1631314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend } 1632314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend 1633314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend if (ieee[DCB_ATTR_IEEE_APP_TABLE]) { 1634314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend struct nlattr *attr; 1635314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend int rem; 1636314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend 1637314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend nla_for_each_nested(attr, ieee[DCB_ATTR_IEEE_APP_TABLE], rem) { 1638314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend struct dcb_app *app_data; 1639314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend if (nla_type(attr) != DCB_ATTR_IEEE_APP) 1640314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend continue; 1641314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend app_data = nla_data(attr); 1642314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend if (ops->ieee_setapp) 1643314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend err = ops->ieee_setapp(netdev, app_data); 1644314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend else 1645b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend err = dcb_ieee_setapp(netdev, app_data); 1646314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend if (err) 1647314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend goto err; 1648314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend } 1649314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend } 1650314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend 1651314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabenderr: 1652314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend dcbnl_reply(err, RTM_SETDCB, DCB_CMD_IEEE_SET, DCB_ATTR_IEEE, 1653314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend pid, seq, flags); 16545b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid dcbnl_ieee_notify(netdev, RTM_SETDCB, DCB_CMD_IEEE_SET, seq, 0); 1655314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend return err; 1656314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend} 1657314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend 1658314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabendstatic int dcbnl_ieee_get(struct net_device *netdev, struct nlattr **tb, 1659314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend u32 pid, u32 seq, u16 flags) 1660314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend{ 1661314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend struct net *net = dev_net(netdev); 1662314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend struct sk_buff *skb; 1663314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend struct nlmsghdr *nlh; 1664314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend struct dcbmsg *dcb; 1665314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops; 1666314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend int err; 1667314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend 1668314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend if (!ops) 1669314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend return -EOPNOTSUPP; 1670314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend 1671314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 1672314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend if (!skb) 1673314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend return -ENOBUFS; 1674314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend 1675314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend nlh = nlmsg_put(skb, pid, seq, RTM_GETDCB, sizeof(*dcb), flags); 1676314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend if (nlh == NULL) { 16774d054f2f1445aceedab3f9642692d55d2caa7ec6Dan Carpenter nlmsg_free(skb); 1678314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend return -EMSGSIZE; 1679314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend } 1680314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend 1681314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend dcb = NLMSG_DATA(nlh); 1682314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend dcb->dcb_family = AF_UNSPEC; 1683314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend dcb->cmd = DCB_CMD_IEEE_GET; 1684314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend 1685314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend err = dcbnl_ieee_fill(skb, netdev); 1686314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend 1687314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend if (err < 0) { 1688314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend nlmsg_cancel(skb, nlh); 1689314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend kfree_skb(skb); 1690314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend } else { 1691314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend nlmsg_end(skb, nlh); 1692314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend err = rtnl_unicast(skb, net, pid); 1693314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend } 1694314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend 1695314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend return err; 1696314b4778ed579f29b6d46ba90dbf31314c13805fJohn Fastabend} 1697f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend 1698f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabendstatic int dcbnl_ieee_del(struct net_device *netdev, struct nlattr **tb, 1699f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend u32 pid, u32 seq, u16 flags) 1700f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend{ 1701f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops; 1702f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend struct nlattr *ieee[DCB_ATTR_IEEE_MAX + 1]; 1703f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend int err = -EOPNOTSUPP; 1704f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend 1705f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend if (!ops) 1706f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend return -EOPNOTSUPP; 1707f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend 1708f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend if (!tb[DCB_ATTR_IEEE]) 1709f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend return -EINVAL; 1710f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend 1711f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend err = nla_parse_nested(ieee, DCB_ATTR_IEEE_MAX, 1712f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend tb[DCB_ATTR_IEEE], dcbnl_ieee_policy); 1713f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend if (err) 1714f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend return err; 1715f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend 1716f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend if (ieee[DCB_ATTR_IEEE_APP_TABLE]) { 1717f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend struct nlattr *attr; 1718f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend int rem; 1719f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend 1720f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend nla_for_each_nested(attr, ieee[DCB_ATTR_IEEE_APP_TABLE], rem) { 1721f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend struct dcb_app *app_data; 1722f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend 1723f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend if (nla_type(attr) != DCB_ATTR_IEEE_APP) 1724f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend continue; 1725f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend app_data = nla_data(attr); 1726f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend if (ops->ieee_delapp) 1727f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend err = ops->ieee_delapp(netdev, app_data); 1728f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend else 1729f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend err = dcb_ieee_delapp(netdev, app_data); 1730f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend if (err) 1731f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend goto err; 1732f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend } 1733f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend } 1734f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend 1735f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabenderr: 1736f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend dcbnl_reply(err, RTM_SETDCB, DCB_CMD_IEEE_DEL, DCB_ATTR_IEEE, 1737f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend pid, seq, flags); 17385b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid dcbnl_ieee_notify(netdev, RTM_SETDCB, DCB_CMD_IEEE_DEL, seq, 0); 1739f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend return err; 1740f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend} 1741f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend 1742f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend 17436241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid/* DCBX configuration */ 17446241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravidstatic int dcbnl_getdcbx(struct net_device *netdev, struct nlattr **tb, 17456241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid u32 pid, u32 seq, u16 flags) 17466241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid{ 17477f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid int ret; 17486241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid 17496241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid if (!netdev->dcbnl_ops->getdcbx) 17507f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid return -EOPNOTSUPP; 17516241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid 17526241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid ret = dcbnl_reply(netdev->dcbnl_ops->getdcbx(netdev), RTM_GETDCB, 17536241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid DCB_CMD_GDCBX, DCB_ATTR_DCBX, pid, seq, flags); 17546241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid 17556241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid return ret; 17566241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid} 17576241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid 17586241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravidstatic int dcbnl_setdcbx(struct net_device *netdev, struct nlattr **tb, 17596241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid u32 pid, u32 seq, u16 flags) 17606241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid{ 17617f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid int ret; 17626241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid u8 value; 17636241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid 17647f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid if (!netdev->dcbnl_ops->setdcbx) 17657f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid return -EOPNOTSUPP; 17667f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid 17677f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid if (!tb[DCB_ATTR_DCBX]) 17687f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid return -EINVAL; 17696241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid 17706241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid value = nla_get_u8(tb[DCB_ATTR_DCBX]); 17716241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid 17726241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid ret = dcbnl_reply(netdev->dcbnl_ops->setdcbx(netdev, value), 17736241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid RTM_SETDCB, DCB_CMD_SDCBX, DCB_ATTR_DCBX, 17746241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid pid, seq, flags); 17756241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid 17766241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid return ret; 17776241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid} 17786241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid 1779ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravidstatic int dcbnl_getfeatcfg(struct net_device *netdev, struct nlattr **tb, 1780ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid u32 pid, u32 seq, u16 flags) 1781ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid{ 1782ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid struct sk_buff *dcbnl_skb; 1783ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid struct nlmsghdr *nlh; 1784ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid struct dcbmsg *dcb; 1785ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid struct nlattr *data[DCB_FEATCFG_ATTR_MAX + 1], *nest; 1786ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid u8 value; 17877f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid int ret, i; 1788ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid int getall = 0; 1789ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 17907f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid if (!netdev->dcbnl_ops->getfeatcfg) 17917f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid return -EOPNOTSUPP; 17927f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid 17937f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid if (!tb[DCB_ATTR_FEATCFG]) 17947f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid return -EINVAL; 1795ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 1796ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid ret = nla_parse_nested(data, DCB_FEATCFG_ATTR_MAX, tb[DCB_ATTR_FEATCFG], 1797ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid dcbnl_featcfg_nest); 17987f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid if (ret) 1799ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid goto err_out; 1800ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 1801ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid dcbnl_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 1802ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid if (!dcbnl_skb) { 18037f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid ret = -ENOBUFS; 1804ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid goto err_out; 1805ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid } 1806ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 1807ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid nlh = NLMSG_NEW(dcbnl_skb, pid, seq, RTM_GETDCB, sizeof(*dcb), flags); 1808ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 1809ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid dcb = NLMSG_DATA(nlh); 1810ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid dcb->dcb_family = AF_UNSPEC; 1811ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid dcb->cmd = DCB_CMD_GFEATCFG; 1812ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 1813ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid nest = nla_nest_start(dcbnl_skb, DCB_ATTR_FEATCFG); 1814ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid if (!nest) { 18157f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid ret = -EMSGSIZE; 18167f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid goto nla_put_failure; 1817ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid } 1818ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 1819ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid if (data[DCB_FEATCFG_ATTR_ALL]) 1820ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid getall = 1; 1821ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 1822ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid for (i = DCB_FEATCFG_ATTR_ALL+1; i <= DCB_FEATCFG_ATTR_MAX; i++) { 1823ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid if (!getall && !data[i]) 1824ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid continue; 1825ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 1826ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid ret = netdev->dcbnl_ops->getfeatcfg(netdev, i, &value); 18277f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid if (!ret) 1828ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid ret = nla_put_u8(dcbnl_skb, i, value); 1829ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 18307f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid if (ret) { 18317f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid nla_nest_cancel(dcbnl_skb, nest); 18327f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid goto nla_put_failure; 18337f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid } 1834ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid } 1835ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid nla_nest_end(dcbnl_skb, nest); 1836ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 1837ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid nlmsg_end(dcbnl_skb, nlh); 1838ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 18397f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid return rtnl_unicast(dcbnl_skb, &init_net, pid); 18407f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravidnla_put_failure: 18417f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid nlmsg_cancel(dcbnl_skb, nlh); 1842ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravidnlmsg_failure: 1843ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid kfree_skb(dcbnl_skb); 1844ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Raviderr_out: 1845ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid return ret; 1846ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid} 1847ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 1848ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravidstatic int dcbnl_setfeatcfg(struct net_device *netdev, struct nlattr **tb, 1849ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid u32 pid, u32 seq, u16 flags) 1850ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid{ 1851ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid struct nlattr *data[DCB_FEATCFG_ATTR_MAX + 1]; 18527f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid int ret, i; 1853ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid u8 value; 1854ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 18557f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid if (!netdev->dcbnl_ops->setfeatcfg) 18567f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid return -ENOTSUPP; 18577f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid 18587f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid if (!tb[DCB_ATTR_FEATCFG]) 18597f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid return -EINVAL; 1860ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 1861ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid ret = nla_parse_nested(data, DCB_FEATCFG_ATTR_MAX, tb[DCB_ATTR_FEATCFG], 1862ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid dcbnl_featcfg_nest); 1863ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 18647f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid if (ret) 1865ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid goto err; 1866ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 1867ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid for (i = DCB_FEATCFG_ATTR_ALL+1; i <= DCB_FEATCFG_ATTR_MAX; i++) { 1868ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid if (data[i] == NULL) 1869ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid continue; 1870ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 1871ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid value = nla_get_u8(data[i]); 1872ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 1873ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid ret = netdev->dcbnl_ops->setfeatcfg(netdev, i, value); 1874ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 1875ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid if (ret) 18767f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid goto err; 1877ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid } 1878ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Raviderr: 18797f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid dcbnl_reply(ret, RTM_SETDCB, DCB_CMD_SFEATCFG, DCB_ATTR_FEATCFG, 18807f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid pid, seq, flags); 18817f891cf1fc0d5d5c5b359caec77e5383e1d55986Shmulik Ravid 1882ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid return ret; 1883ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid} 1884ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid 1885dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid/* Handle CEE DCBX GET commands. */ 1886dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravidstatic int dcbnl_cee_get(struct net_device *netdev, struct nlattr **tb, 1887dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid u32 pid, u32 seq, u16 flags) 1888dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid{ 18895b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid struct net *net = dev_net(netdev); 1890dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid struct sk_buff *skb; 1891dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid struct nlmsghdr *nlh; 1892dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid struct dcbmsg *dcb; 1893dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops; 18945b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid int err; 1895dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid 1896dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid if (!ops) 1897dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid return -EOPNOTSUPP; 1898dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid 1899dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 1900dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid if (!skb) 1901dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid return -ENOBUFS; 1902dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid 19035b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid nlh = nlmsg_put(skb, pid, seq, RTM_GETDCB, sizeof(*dcb), flags); 19045b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (nlh == NULL) { 19055b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid nlmsg_free(skb); 19065b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid return -EMSGSIZE; 19075b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid } 1908dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid 1909dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid dcb = NLMSG_DATA(nlh); 1910dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid dcb->dcb_family = AF_UNSPEC; 1911dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid dcb->cmd = DCB_CMD_CEE_GET; 1912dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid 19135b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid err = dcbnl_cee_fill(skb, netdev); 191437cf4d1a9b0903b874a638d0f8649873ddde8a12Shmulik Ravid 19155b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid if (err < 0) { 19165b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid nlmsg_cancel(skb, nlh); 19175b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid nlmsg_free(skb); 19185b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid } else { 19195b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid nlmsg_end(skb, nlh); 19205b7f7626743e0912958981343b47ac0ab2206b1cShmulik Ravid err = rtnl_unicast(skb, net, pid); 192137cf4d1a9b0903b874a638d0f8649873ddde8a12Shmulik Ravid } 192237cf4d1a9b0903b874a638d0f8649873ddde8a12Shmulik Ravid return err; 1923dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid} 1924dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid 19252f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckstatic int dcb_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) 19262f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 19272f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct net *net = sock_net(skb->sk); 19282f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct net_device *netdev; 19292f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct dcbmsg *dcb = (struct dcbmsg *)NLMSG_DATA(nlh); 19302f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck struct nlattr *tb[DCB_ATTR_MAX + 1]; 19312f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck u32 pid = skb ? NETLINK_CB(skb).pid : 0; 19322f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck int ret = -EINVAL; 19332f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 193409ad9bc752519cc167d0a573e1acf69b5c707c67Octavian Purdila if (!net_eq(net, &init_net)) 19352f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return -EINVAL; 19362f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 19372f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = nlmsg_parse(nlh, sizeof(*dcb), tb, DCB_ATTR_MAX, 19382f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dcbnl_rtnl_policy); 19392f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (ret < 0) 19402f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return ret; 19412f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 19422f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!tb[DCB_ATTR_IFNAME]) 19432f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return -EINVAL; 19442f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 19452f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck netdev = dev_get_by_name(&init_net, nla_data(tb[DCB_ATTR_IFNAME])); 19462f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!netdev) 19472f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return -EINVAL; 19482f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 19492f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck if (!netdev->dcbnl_ops) 19502f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto errout; 19512f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 19522f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck switch (dcb->cmd) { 19532f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck case DCB_CMD_GSTATE: 19542f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = dcbnl_getstate(netdev, tb, pid, nlh->nlmsg_seq, 19552f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nlh->nlmsg_flags); 19562f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto out; 19572f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck case DCB_CMD_PFC_GCFG: 19582f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = dcbnl_getpfccfg(netdev, tb, pid, nlh->nlmsg_seq, 19592f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nlh->nlmsg_flags); 19602f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto out; 19612f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck case DCB_CMD_GPERM_HWADDR: 19622f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = dcbnl_getperm_hwaddr(netdev, tb, pid, nlh->nlmsg_seq, 19632f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nlh->nlmsg_flags); 19642f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto out; 19652f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck case DCB_CMD_PGTX_GCFG: 19662f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = dcbnl_pgtx_getcfg(netdev, tb, pid, nlh->nlmsg_seq, 19672f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nlh->nlmsg_flags); 19682f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto out; 19692f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck case DCB_CMD_PGRX_GCFG: 19702f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = dcbnl_pgrx_getcfg(netdev, tb, pid, nlh->nlmsg_seq, 19712f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nlh->nlmsg_flags); 19722f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto out; 1973859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck case DCB_CMD_BCN_GCFG: 1974859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck ret = dcbnl_bcn_getcfg(netdev, tb, pid, nlh->nlmsg_seq, 1975859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck nlh->nlmsg_flags); 1976859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck goto out; 19772f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck case DCB_CMD_SSTATE: 19782f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = dcbnl_setstate(netdev, tb, pid, nlh->nlmsg_seq, 19792f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nlh->nlmsg_flags); 19802f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto out; 19812f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck case DCB_CMD_PFC_SCFG: 19822f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = dcbnl_setpfccfg(netdev, tb, pid, nlh->nlmsg_seq, 19832f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nlh->nlmsg_flags); 19842f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto out; 19852f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 19862f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck case DCB_CMD_SET_ALL: 19872f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = dcbnl_setall(netdev, tb, pid, nlh->nlmsg_seq, 19882f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nlh->nlmsg_flags); 19892f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto out; 19902f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck case DCB_CMD_PGTX_SCFG: 19912f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = dcbnl_pgtx_setcfg(netdev, tb, pid, nlh->nlmsg_seq, 19922f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nlh->nlmsg_flags); 19932f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto out; 19942f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck case DCB_CMD_PGRX_SCFG: 19952f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = dcbnl_pgrx_setcfg(netdev, tb, pid, nlh->nlmsg_seq, 19962f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck nlh->nlmsg_flags); 19972f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto out; 199846132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck case DCB_CMD_GCAP: 199946132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck ret = dcbnl_getcap(netdev, tb, pid, nlh->nlmsg_seq, 200046132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck nlh->nlmsg_flags); 200146132188bf72e22ef097f16ed5c969ee8cea1e8bAlexander Duyck goto out; 200233dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck case DCB_CMD_GNUMTCS: 200333dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck ret = dcbnl_getnumtcs(netdev, tb, pid, nlh->nlmsg_seq, 200433dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck nlh->nlmsg_flags); 200533dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck goto out; 200633dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck case DCB_CMD_SNUMTCS: 200733dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck ret = dcbnl_setnumtcs(netdev, tb, pid, nlh->nlmsg_seq, 200833dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck nlh->nlmsg_flags); 200933dbabc4a7f7bd72313c73a3c199f31f3900336fAlexander Duyck goto out; 20100eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck case DCB_CMD_PFC_GSTATE: 20110eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck ret = dcbnl_getpfcstate(netdev, tb, pid, nlh->nlmsg_seq, 20120eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck nlh->nlmsg_flags); 20130eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck goto out; 20140eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck case DCB_CMD_PFC_SSTATE: 20150eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck ret = dcbnl_setpfcstate(netdev, tb, pid, nlh->nlmsg_seq, 20160eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck nlh->nlmsg_flags); 20170eb3aa9bab20217fb42244ccdcb5bf8a002f504cAlexander Duyck goto out; 2018859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck case DCB_CMD_BCN_SCFG: 2019859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck ret = dcbnl_bcn_setcfg(netdev, tb, pid, nlh->nlmsg_seq, 2020859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck nlh->nlmsg_flags); 2021859ee3c43812051e21816c6d6d4cc04fb7ce9b2eAlexander Duyck goto out; 2022579496865cf4ea429146382d62047ffdbaab0deeYi Zou case DCB_CMD_GAPP: 2023579496865cf4ea429146382d62047ffdbaab0deeYi Zou ret = dcbnl_getapp(netdev, tb, pid, nlh->nlmsg_seq, 2024579496865cf4ea429146382d62047ffdbaab0deeYi Zou nlh->nlmsg_flags); 2025579496865cf4ea429146382d62047ffdbaab0deeYi Zou goto out; 2026579496865cf4ea429146382d62047ffdbaab0deeYi Zou case DCB_CMD_SAPP: 2027579496865cf4ea429146382d62047ffdbaab0deeYi Zou ret = dcbnl_setapp(netdev, tb, pid, nlh->nlmsg_seq, 2028579496865cf4ea429146382d62047ffdbaab0deeYi Zou nlh->nlmsg_flags); 2029579496865cf4ea429146382d62047ffdbaab0deeYi Zou goto out; 20303e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend case DCB_CMD_IEEE_SET: 20313e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend ret = dcbnl_ieee_set(netdev, tb, pid, nlh->nlmsg_seq, 2032f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend nlh->nlmsg_flags); 20333e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend goto out; 20343e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend case DCB_CMD_IEEE_GET: 20353e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend ret = dcbnl_ieee_get(netdev, tb, pid, nlh->nlmsg_seq, 2036f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend nlh->nlmsg_flags); 2037f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend goto out; 2038f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend case DCB_CMD_IEEE_DEL: 2039f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend ret = dcbnl_ieee_del(netdev, tb, pid, nlh->nlmsg_seq, 2040f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend nlh->nlmsg_flags); 20413e29027af43728c2a91fe3f735ab2822edaf54a8John Fastabend goto out; 20426241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid case DCB_CMD_GDCBX: 20436241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid ret = dcbnl_getdcbx(netdev, tb, pid, nlh->nlmsg_seq, 20446241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid nlh->nlmsg_flags); 20456241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid goto out; 20466241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid case DCB_CMD_SDCBX: 20476241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid ret = dcbnl_setdcbx(netdev, tb, pid, nlh->nlmsg_seq, 20486241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid nlh->nlmsg_flags); 20496241b6259b16aa390ff4bf50f520685b3801200bShmulik Ravid goto out; 2050ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid case DCB_CMD_GFEATCFG: 2051ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid ret = dcbnl_getfeatcfg(netdev, tb, pid, nlh->nlmsg_seq, 2052ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid nlh->nlmsg_flags); 2053ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid goto out; 2054ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid case DCB_CMD_SFEATCFG: 2055ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid ret = dcbnl_setfeatcfg(netdev, tb, pid, nlh->nlmsg_seq, 2056ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid nlh->nlmsg_flags); 2057ea45fe4e176a42d2396878f530cfdc8265bef37bShmulik Ravid goto out; 2058dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid case DCB_CMD_CEE_GET: 2059dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid ret = dcbnl_cee_get(netdev, tb, pid, nlh->nlmsg_seq, 2060dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid nlh->nlmsg_flags); 2061dc6ed1df5a5f84e45e77e2acb6fd99b995414956Shmulik Ravid goto out; 20622f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck default: 20632f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck goto errout; 20642f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck } 20652f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckerrout: 20662f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck ret = -EINVAL; 20672f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckout: 20682f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck dev_put(netdev); 20692f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return ret; 20702f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 20712f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 20729ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend/** 20739ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend * dcb_getapp - retrieve the DCBX application user priority 20749ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend * 20759ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend * On success returns a non-zero 802.1p user priority bitmap 20769ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend * otherwise returns 0 as the invalid user priority bitmap to 20779ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend * indicate an error. 20789ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend */ 20799ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabendu8 dcb_getapp(struct net_device *dev, struct dcb_app *app) 20809ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend{ 20819ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend struct dcb_app_type *itr; 20829ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend u8 prio = 0; 20839ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend 20849ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend spin_lock(&dcb_lock); 20859ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend list_for_each_entry(itr, &dcb_app_list, list) { 20869ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend if (itr->app.selector == app->selector && 20879ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend itr->app.protocol == app->protocol && 2088e290ed81307ca7d92675f0d9c683add693c2f377Mark Rustad itr->ifindex == dev->ifindex) { 20899ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend prio = itr->app.priority; 20909ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend break; 20919ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend } 20929ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend } 20939ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend spin_unlock(&dcb_lock); 20949ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend 20959ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend return prio; 20969ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend} 20979ab933ab2cc80f04690d6aa385b1110075c5e507John FastabendEXPORT_SYMBOL(dcb_getapp); 20989ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend 20999ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend/** 2100b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend * dcb_setapp - add CEE dcb application data to app list 21019ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend * 2102b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend * Priority 0 is an invalid priority in CEE spec. This routine 2103b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend * removes applications from the app list if the priority is 2104b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend * set to zero. 21059ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend */ 2106ab6baf980b095c70a56c5eb2f58166aef8a0edc8John Fastabendint dcb_setapp(struct net_device *dev, struct dcb_app *new) 21079ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend{ 21089ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend struct dcb_app_type *itr; 21097ec79270d7de0c8ca602c47cb25a9652ec28f37fJohn Fastabend struct dcb_app_type event; 21107ec79270d7de0c8ca602c47cb25a9652ec28f37fJohn Fastabend 2111e290ed81307ca7d92675f0d9c683add693c2f377Mark Rustad event.ifindex = dev->ifindex; 21127ec79270d7de0c8ca602c47cb25a9652ec28f37fJohn Fastabend memcpy(&event.app, new, sizeof(event.app)); 21136bd0e1cb10b6d14dda4a8806d0a2f4f0bbf01931John Fastabend if (dev->dcbnl_ops->getdcbx) 21146bd0e1cb10b6d14dda4a8806d0a2f4f0bbf01931John Fastabend event.dcbx = dev->dcbnl_ops->getdcbx(dev); 21159ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend 21169ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend spin_lock(&dcb_lock); 21179ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend /* Search for existing match and replace */ 21189ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend list_for_each_entry(itr, &dcb_app_list, list) { 21199ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend if (itr->app.selector == new->selector && 21209ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend itr->app.protocol == new->protocol && 2121e290ed81307ca7d92675f0d9c683add693c2f377Mark Rustad itr->ifindex == dev->ifindex) { 21229ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend if (new->priority) 21239ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend itr->app.priority = new->priority; 21249ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend else { 21259ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend list_del(&itr->list); 21269ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend kfree(itr); 21279ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend } 21289ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend goto out; 21299ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend } 21309ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend } 21319ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend /* App type does not exist add new application type */ 21329ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend if (new->priority) { 21339ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend struct dcb_app_type *entry; 21349ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend entry = kmalloc(sizeof(struct dcb_app_type), GFP_ATOMIC); 21359ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend if (!entry) { 21369ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend spin_unlock(&dcb_lock); 21379ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend return -ENOMEM; 21389ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend } 21399ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend 21409ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend memcpy(&entry->app, new, sizeof(*new)); 2141e290ed81307ca7d92675f0d9c683add693c2f377Mark Rustad entry->ifindex = dev->ifindex; 21429ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend list_add(&entry->list, &dcb_app_list); 21439ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend } 21449ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabendout: 21459ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend spin_unlock(&dcb_lock); 21467ec79270d7de0c8ca602c47cb25a9652ec28f37fJohn Fastabend call_dcbevent_notifiers(DCB_APP_EVENT, &event); 21479ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend return 0; 21489ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend} 21499ab933ab2cc80f04690d6aa385b1110075c5e507John FastabendEXPORT_SYMBOL(dcb_setapp); 21509ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend 2151b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend/** 2152a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabend * dcb_ieee_getapp_mask - retrieve the IEEE DCB application priority 2153a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabend * 2154a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabend * Helper routine which on success returns a non-zero 802.1Qaz user 2155a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabend * priority bitmap otherwise returns 0 to indicate the dcb_app was 2156a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabend * not found in APP list. 2157a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabend */ 2158a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabendu8 dcb_ieee_getapp_mask(struct net_device *dev, struct dcb_app *app) 2159a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabend{ 2160a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabend struct dcb_app_type *itr; 2161a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabend u8 prio = 0; 2162a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabend 2163a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabend spin_lock(&dcb_lock); 2164a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabend list_for_each_entry(itr, &dcb_app_list, list) { 2165a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabend if (itr->app.selector == app->selector && 2166a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabend itr->app.protocol == app->protocol && 2167e290ed81307ca7d92675f0d9c683add693c2f377Mark Rustad itr->ifindex == dev->ifindex) { 2168a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabend prio |= 1 << itr->app.priority; 2169a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabend } 2170a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabend } 2171a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabend spin_unlock(&dcb_lock); 2172a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabend 2173a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabend return prio; 2174a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabend} 2175a364c8cf80251849bab207be8c9e66253c8ca8f8John FastabendEXPORT_SYMBOL(dcb_ieee_getapp_mask); 2176a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabend 2177a364c8cf80251849bab207be8c9e66253c8ca8f8John Fastabend/** 2178b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend * dcb_ieee_setapp - add IEEE dcb application data to app list 2179b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend * 2180b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend * This adds Application data to the list. Multiple application 2181b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend * entries may exists for the same selector and protocol as long 2182b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend * as the priorities are different. 2183b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend */ 2184b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabendint dcb_ieee_setapp(struct net_device *dev, struct dcb_app *new) 2185b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend{ 2186b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend struct dcb_app_type *itr, *entry; 2187b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend struct dcb_app_type event; 2188b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend int err = 0; 2189b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend 2190e290ed81307ca7d92675f0d9c683add693c2f377Mark Rustad event.ifindex = dev->ifindex; 2191b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend memcpy(&event.app, new, sizeof(event.app)); 21926bd0e1cb10b6d14dda4a8806d0a2f4f0bbf01931John Fastabend if (dev->dcbnl_ops->getdcbx) 21936bd0e1cb10b6d14dda4a8806d0a2f4f0bbf01931John Fastabend event.dcbx = dev->dcbnl_ops->getdcbx(dev); 2194b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend 2195b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend spin_lock(&dcb_lock); 2196b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend /* Search for existing match and abort if found */ 2197b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend list_for_each_entry(itr, &dcb_app_list, list) { 2198b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend if (itr->app.selector == new->selector && 2199b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend itr->app.protocol == new->protocol && 2200b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend itr->app.priority == new->priority && 2201e290ed81307ca7d92675f0d9c683add693c2f377Mark Rustad itr->ifindex == dev->ifindex) { 2202b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend err = -EEXIST; 2203b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend goto out; 2204b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend } 2205b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend } 2206b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend 2207b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend /* App entry does not exist add new entry */ 2208b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend entry = kmalloc(sizeof(struct dcb_app_type), GFP_ATOMIC); 2209b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend if (!entry) { 2210b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend err = -ENOMEM; 2211b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend goto out; 2212b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend } 2213b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend 2214b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend memcpy(&entry->app, new, sizeof(*new)); 2215e290ed81307ca7d92675f0d9c683add693c2f377Mark Rustad entry->ifindex = dev->ifindex; 2216b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend list_add(&entry->list, &dcb_app_list); 2217b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabendout: 2218b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend spin_unlock(&dcb_lock); 2219b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend if (!err) 2220b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend call_dcbevent_notifiers(DCB_APP_EVENT, &event); 2221b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend return err; 2222b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend} 2223b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John FastabendEXPORT_SYMBOL(dcb_ieee_setapp); 2224b6db2174c59ef1e72f7bd63e0f105b1a2d7f18d3John Fastabend 2225f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend/** 2226f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend * dcb_ieee_delapp - delete IEEE dcb application data from list 2227f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend * 2228f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend * This removes a matching APP data from the APP list 2229f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend */ 2230f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabendint dcb_ieee_delapp(struct net_device *dev, struct dcb_app *del) 2231f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend{ 2232f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend struct dcb_app_type *itr; 2233f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend struct dcb_app_type event; 2234f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend int err = -ENOENT; 2235f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend 2236e290ed81307ca7d92675f0d9c683add693c2f377Mark Rustad event.ifindex = dev->ifindex; 2237f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend memcpy(&event.app, del, sizeof(event.app)); 22386bd0e1cb10b6d14dda4a8806d0a2f4f0bbf01931John Fastabend if (dev->dcbnl_ops->getdcbx) 22396bd0e1cb10b6d14dda4a8806d0a2f4f0bbf01931John Fastabend event.dcbx = dev->dcbnl_ops->getdcbx(dev); 2240f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend 2241f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend spin_lock(&dcb_lock); 2242f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend /* Search for existing match and remove it. */ 2243f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend list_for_each_entry(itr, &dcb_app_list, list) { 2244f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend if (itr->app.selector == del->selector && 2245f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend itr->app.protocol == del->protocol && 2246f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend itr->app.priority == del->priority && 2247e290ed81307ca7d92675f0d9c683add693c2f377Mark Rustad itr->ifindex == dev->ifindex) { 2248f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend list_del(&itr->list); 2249f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend kfree(itr); 2250f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend err = 0; 2251f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend goto out; 2252f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend } 2253f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend } 2254f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend 2255f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabendout: 2256f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend spin_unlock(&dcb_lock); 2257f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend if (!err) 2258f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend call_dcbevent_notifiers(DCB_APP_EVENT, &event); 2259f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend return err; 2260f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend} 2261f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John FastabendEXPORT_SYMBOL(dcb_ieee_delapp); 2262f9ae7e4b515c4d56baf6e0e84ebee2e03ae57a25John Fastabend 22637c14c3f10e6dcd7f70e49f77b6e1ae605c4861e6Shmulik Ravidstatic void dcb_flushapp(void) 22649ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend{ 22659ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend struct dcb_app_type *app; 22662a8fe003741aa90b6b9453e90af4bbb7bc42918cDan Carpenter struct dcb_app_type *tmp; 22679ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend 22689ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend spin_lock(&dcb_lock); 22692a8fe003741aa90b6b9453e90af4bbb7bc42918cDan Carpenter list_for_each_entry_safe(app, tmp, &dcb_app_list, list) { 22709ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend list_del(&app->list); 22719ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend kfree(app); 22729ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend } 22739ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend spin_unlock(&dcb_lock); 22749ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend} 22759ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend 22762f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckstatic int __init dcbnl_init(void) 22772f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 22789ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend INIT_LIST_HEAD(&dcb_app_list); 22799ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend 2280c7ac8679bec9397afe8918f788cbcef88c38da54Greg Rose rtnl_register(PF_UNSPEC, RTM_GETDCB, dcb_doit, NULL, NULL); 2281c7ac8679bec9397afe8918f788cbcef88c38da54Greg Rose rtnl_register(PF_UNSPEC, RTM_SETDCB, dcb_doit, NULL, NULL); 22822f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 22832f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck return 0; 22842f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 22852f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckmodule_init(dcbnl_init); 22862f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck 22872f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckstatic void __exit dcbnl_exit(void) 22882f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck{ 22892f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck rtnl_unregister(PF_UNSPEC, RTM_GETDCB); 22902f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck rtnl_unregister(PF_UNSPEC, RTM_SETDCB); 22919ab933ab2cc80f04690d6aa385b1110075c5e507John Fastabend dcb_flushapp(); 22922f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyck} 22932f90b8657ec942d1880f720e0177ee71df7c8e3cAlexander Duyckmodule_exit(dcbnl_exit); 2294